Skip to content

Commit

Permalink
fix: add "request" to response events (#1993)
Browse files Browse the repository at this point in the history
  • Loading branch information
kettanaito authored Jan 25, 2024
1 parent 5afedb1 commit bad537f
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 27 deletions.
1 change: 1 addition & 0 deletions src/browser/setupWorker/glossary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export interface SetupWorkerInternalContext {
worker: ServiceWorker | null
registration: ServiceWorkerRegistration | null
requestHandlers: Array<RequestHandler>
requests: Map<string, Request>
emitter: Emitter<LifeCycleEventsMap>
keepAliveInterval?: number
workerChannel: {
Expand Down
1 change: 1 addition & 0 deletions src/browser/setupWorker/setupWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export class SetupWorkerApi
worker: null,
registration: null,
requestHandlers: this.currentHandlers,
requests: new Map(),
emitter: this.emitter,
workerChannel: {
on: (eventType, callback) => {
Expand Down
9 changes: 9 additions & 0 deletions src/browser/setupWorker/start/createRequestListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
WorkerChannel,
} from './utils/createMessageChannel'
import { parseWorkerRequest } from '../../utils/parseWorkerRequest'
import { RequestHandler } from '~/core/handlers/RequestHandler'
import { handleRequest } from '~/core/utils/handleRequest'
import { RequiredDeep } from '~/core/typeUtils'
import { devUtils } from '~/core/utils/internal/devUtils'
Expand All @@ -30,6 +31,14 @@ export const createRequestListener = (
const request = parseWorkerRequest(message.payload)
const requestCloneForLogs = request.clone()

// Make this the first requets clone before the
// request resolution pipeline even starts.
// Store the clone in cache so the first matching
// request handler would skip the cloning phase.
const requestClone = request.clone()
RequestHandler.cache.set(request, requestClone)
context.requests.set(requestId, requestClone)

try {
await handleRequest(
request,
Expand Down
16 changes: 9 additions & 7 deletions src/browser/setupWorker/start/createResponseListener.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {
import type {
ServiceWorkerIncomingEventsMap,
SetupWorkerInternalContext,
} from '../glossary'
import { ServiceWorkerMessage } from './utils/createMessageChannel'
import type { ServiceWorkerMessage } from './utils/createMessageChannel'
import { isResponseWithoutBody } from '@mswjs/interceptors'

export function createResponseListener(context: SetupWorkerInternalContext) {
Expand All @@ -15,6 +15,12 @@ export function createResponseListener(context: SetupWorkerInternalContext) {
) => {
const { payload: responseJson } = message

// Get the Request instance reference stored in the
// request listener.
const { requestId } = responseJson
const request = context.requests.get(requestId)!
context.requests.delete(requestId)

/**
* CORS requests with `mode: "no-cors"` result in "opaque" responses.
* That kind of responses cannot be manipulated in JavaScript due
Expand Down Expand Up @@ -46,11 +52,7 @@ export function createResponseListener(context: SetupWorkerInternalContext) {
responseJson.isMockedResponse ? 'response:mocked' : 'response:bypass',
{
response,
/**
* @todo @fixme In this context, we don't know anything about
* the request.
*/
request: null as any,
request,
requestId: responseJson.requestId,
},
)
Expand Down
26 changes: 18 additions & 8 deletions test/browser/msw-api/setup-worker/life-cycle-events/on.mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,25 @@ const requestEndListener: (

worker.events.on('request:end', requestEndListener)

worker.events.on('response:mocked', async ({ response, requestId }) => {
const body = await response.clone().text()
console.warn(`[response:mocked] ${body} ${requestId}`)
})
worker.events.on(
'response:mocked',
async ({ response, request, requestId }) => {
const body = await response.clone().text()
console.warn(
`[response:mocked] ${body} ${request.method} ${request.url} ${requestId}`,
)
},
)

worker.events.on('response:bypass', async ({ response, requestId }) => {
const body = await response.clone().text()
console.warn(`[response:bypass] ${body} ${requestId}`)
})
worker.events.on(
'response:bypass',
async ({ response, request, requestId }) => {
const body = await response.clone().text()
console.warn(
`[response:bypass] ${body} ${request.method} ${request.url} ${requestId}`,
)
},
)

worker.events.on('unhandledException', ({ error, request, requestId }) => {
console.warn(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ test('emits events for a handled request and mocked response', async ({
`[request:start] GET ${url} ${requestId}`,
`[request:match] GET ${url} ${requestId}`,
`[request:end] GET ${url} ${requestId}`,
`[response:mocked] response-body ${requestId}`,
`[response:mocked] response-body GET ${url} ${requestId}`,
])
})

Expand All @@ -80,7 +80,7 @@ test('emits events for a handled request with no response', async ({
expect(consoleSpy.get('warning')).toEqual([
`[request:start] POST ${url} ${requestId}`,
`[request:end] POST ${url} ${requestId}`,
`[response:bypass] original-response ${requestId}`,
`[response:bypass] original-response POST ${url} ${requestId}`,
])
})

Expand All @@ -107,7 +107,7 @@ test('emits events for an unhandled request', async ({
`[request:start] GET ${url} ${requestId}`,
`[request:unhandled] GET ${url} ${requestId}`,
`[request:end] GET ${url} ${requestId}`,
`[response:bypass] majestic-unknown ${requestId}`,
`[response:bypass] majestic-unknown GET ${url} ${requestId}`,
])
})

Expand Down
28 changes: 19 additions & 9 deletions test/node/msw-api/setup-server/life-cycle-events/on.node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,23 @@ beforeAll(async () => {
listener(`[request:end] ${request.method} ${request.url} ${requestId}`)
})

server.events.on('response:mocked', async ({ response, requestId }) => {
listener(`[response:mocked] ${await response.text()} ${requestId}`)
})
server.events.on(
'response:mocked',
async ({ response, request, requestId }) => {
listener(
`[response:mocked] ${await response.text()} ${request.method} ${request.url} ${requestId}`,
)
},
)

server.events.on('response:bypass', async ({ response, requestId }) => {
listener(`[response:bypass] ${await response.text()} ${requestId}`)
})
server.events.on(
'response:bypass',
async ({ response, request, requestId }) => {
listener(
`[response:bypass] ${await response.text()} ${request.method} ${request.url} ${requestId}`,
)
},
)

server.events.on('unhandledException', ({ error, request, requestId }) => {
listener(
Expand Down Expand Up @@ -114,7 +124,7 @@ test('emits events for a handler request and mocked response', async () => {
)
expect(listener).toHaveBeenNthCalledWith(
4,
`[response:mocked] response-body ${requestId}`,
`[response:mocked] response-body GET ${url} ${requestId}`,
)
expect(listener).toHaveBeenCalledTimes(4)
})
Expand All @@ -140,7 +150,7 @@ test('emits events for a handled request with no response', async () => {
)
expect(listener).toHaveBeenNthCalledWith(
3,
`[response:bypass] original-response ${requestId}`,
`[response:bypass] original-response POST ${url} ${requestId}`,
)
expect(listener).toHaveBeenCalledTimes(3)
})
Expand Down Expand Up @@ -170,7 +180,7 @@ test('emits events for an unhandled request', async () => {
)
expect(listener).toHaveBeenNthCalledWith(
4,
`[response:bypass] majestic-unknown ${requestId}`,
`[response:bypass] majestic-unknown GET ${url} ${requestId}`,
)
})

Expand Down

0 comments on commit bad537f

Please sign in to comment.