-
-
Notifications
You must be signed in to change notification settings - Fork 133
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: add response decompression tests in the browser
- Loading branch information
1 parent
858e18e
commit ee8dc4c
Showing
4 changed files
with
220 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
190 changes: 190 additions & 0 deletions
190
test/modules/fetch/compliance/response-content-encoding.browser.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
import { HttpServer } from '@open-draft/test-server/http' | ||
import { test, expect } from '../../../playwright.extend' | ||
import { compressResponse, useCors } from '../../../helpers' | ||
import { parseContentEncoding } from '../../../../src/interceptors/fetch/utils/decompression' | ||
import { FetchInterceptor } from '../../../../src/interceptors/fetch' | ||
|
||
declare namespace window { | ||
const interceptor: FetchInterceptor | ||
} | ||
|
||
const server = new HttpServer((app) => { | ||
app.use(useCors) | ||
app.get('/resource', (req, res) => { | ||
const acceptEncoding = req.header('x-accept-encoding') | ||
const codings = parseContentEncoding(acceptEncoding || '') | ||
|
||
res | ||
.set('content-encoding', acceptEncoding) | ||
.end(compressResponse(codings)('hello world')) | ||
}) | ||
}) | ||
|
||
test.beforeAll(async () => { | ||
await server.listen() | ||
}) | ||
|
||
test.afterAll(async () => { | ||
await server.close() | ||
}) | ||
|
||
test('decompresses a mocked "content-encoding: gzip" response body', async ({ | ||
loadExample, | ||
page, | ||
}) => { | ||
await loadExample(require.resolve('../fetch.runtime.js')) | ||
|
||
await page.evaluate(() => { | ||
window.interceptor.on('request', ({ controller }) => { | ||
const stream = new ReadableStream({ | ||
start(controller) { | ||
controller.enqueue(new TextEncoder().encode('hello world')) | ||
controller.close() | ||
}, | ||
}) | ||
|
||
return controller.respondWith( | ||
new Response(stream.pipeThrough(new CompressionStream('gzip')), { | ||
headers: { 'content-encoding': 'gzip' }, | ||
}) | ||
) | ||
}) | ||
window.interceptor.apply() | ||
}) | ||
|
||
const responseText = await page.evaluate(async (url) => { | ||
const response = await fetch(url) | ||
return response.text() | ||
}, 'http://localhost/resource') | ||
|
||
expect(responseText).toBe('hello world') | ||
}) | ||
|
||
test('decompresses a bypassed "content-encoding: gzip" response body', async ({ | ||
loadExample, | ||
page, | ||
}) => { | ||
await loadExample(require.resolve('../fetch.runtime.js')) | ||
|
||
await page.evaluate(() => { | ||
window.interceptor.apply() | ||
}) | ||
|
||
const responseText = await page.evaluate(async (url) => { | ||
const response = await fetch(url, { | ||
/** | ||
* @note `accept-encoding` is a forbidden browser header. | ||
* Setting it will have no effect. Instead, rely on a custom header | ||
* to communicate the expected encoding to the test server. | ||
*/ | ||
headers: { 'x-accept-encoding': 'gzip' }, | ||
}) | ||
return response.text() | ||
}, server.http.url('/resource')) | ||
|
||
expect(responseText).toBe('hello world') | ||
}) | ||
|
||
test('decompresses a mocked "content-encoding: x-gzip" response body', async ({ | ||
loadExample, | ||
page, | ||
}) => { | ||
await loadExample(require.resolve('../fetch.runtime.js')) | ||
|
||
await page.evaluate(() => { | ||
window.interceptor.on('request', ({ controller }) => { | ||
const stream = new ReadableStream({ | ||
start(controller) { | ||
controller.enqueue(new TextEncoder().encode('hello world')) | ||
controller.close() | ||
}, | ||
}) | ||
|
||
return controller.respondWith( | ||
new Response(stream.pipeThrough(new CompressionStream('gzip')), { | ||
headers: { 'content-encoding': 'x-gzip' }, | ||
}) | ||
) | ||
}) | ||
window.interceptor.apply() | ||
}) | ||
|
||
const responseText = await page.evaluate(async (url) => { | ||
const response = await fetch(url) | ||
return response.text() | ||
}, 'http://localhost/resource') | ||
|
||
expect(responseText).toBe('hello world') | ||
}) | ||
|
||
test('decompresses a bypassed "content-encoding: x-gzip" response body', async ({ | ||
loadExample, | ||
page, | ||
}) => { | ||
await loadExample(require.resolve('../fetch.runtime.js')) | ||
|
||
await page.evaluate(() => { | ||
window.interceptor.apply() | ||
}) | ||
|
||
const responseText = await page.evaluate(async (url) => { | ||
const response = await fetch(url, { | ||
headers: { 'x-accept-encoding': 'x-gzip' }, | ||
}) | ||
return response.text() | ||
}, server.http.url('/resource')) | ||
|
||
expect(responseText).toBe('hello world') | ||
}) | ||
|
||
test('decompresses a mocked "content-encoding: deflate" response body', async ({ | ||
loadExample, | ||
page, | ||
}) => { | ||
await loadExample(require.resolve('../fetch.runtime.js')) | ||
|
||
await page.evaluate(() => { | ||
window.interceptor.on('request', ({ controller }) => { | ||
const stream = new ReadableStream({ | ||
start(controller) { | ||
controller.enqueue(new TextEncoder().encode('hello world')) | ||
controller.close() | ||
}, | ||
}) | ||
|
||
return controller.respondWith( | ||
new Response(stream.pipeThrough(new CompressionStream('deflate')), { | ||
headers: { 'content-encoding': 'deflate' }, | ||
}) | ||
) | ||
}) | ||
window.interceptor.apply() | ||
}) | ||
|
||
const responseText = await page.evaluate(async (url) => { | ||
const response = await fetch(url) | ||
return response.text() | ||
}, 'http://localhost/resource') | ||
|
||
expect(responseText).toBe('hello world') | ||
}) | ||
|
||
test('decompresses a bypassed "content-encoding: deflate" response body', async ({ | ||
loadExample, | ||
page, | ||
}) => { | ||
await loadExample(require.resolve('../fetch.runtime.js')) | ||
|
||
await page.evaluate(() => { | ||
window.interceptor.apply() | ||
}) | ||
|
||
const responseText = await page.evaluate(async (url) => { | ||
const response = await fetch(url, { | ||
headers: { 'x-accept-encoding': 'deflate' }, | ||
}) | ||
return response.text() | ||
}, server.http.url('/resource')) | ||
|
||
expect(responseText).toBe('hello world') | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { FetchInterceptor } from '@mswjs/interceptors/fetch' | ||
|
||
const interceptor = new FetchInterceptor() | ||
window.interceptor = interceptor |