Skip to content

Commit

Permalink
feat(onUnhandledRequest): convert "next" to "print"; add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kettanaito committed Feb 12, 2022
1 parent 6247e45 commit 57f6451
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 22 deletions.
9 changes: 4 additions & 5 deletions src/utils/handleRequest.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,10 @@ test('reports request as unhandled when it has no matching request handlers', as
['request:unhandled', request],
['request:end', request],
])
expect(options.onUnhandledRequest).toHaveBeenNthCalledWith(
1,
request,
expect.anything(),
)
expect(options.onUnhandledRequest).toHaveBeenNthCalledWith(1, request, {
warning: expect.any(Function),
error: expect.any(Function),
})
expect(callbacks.onBypassResponse).toHaveBeenNthCalledWith(1, request)
expect(callbacks.onMockedResponse).not.toHaveBeenCalled()
expect(callbacks.onMockedResponseSent).not.toHaveBeenCalled()
Expand Down
60 changes: 54 additions & 6 deletions src/utils/request/onUnhandledRequest.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { onUnhandledRequest } from './onUnhandledRequest'
import {
onUnhandledRequest,
UnhandledRequestCallback,
} from './onUnhandledRequest'
import { createMockedRequest } from '../../../test/support/utils'
import { RestHandler, RESTMethods } from '../../handlers/RestHandler'
import { ResponseResolver } from '../../handlers/RequestHandler'
Expand Down Expand Up @@ -83,12 +86,57 @@ test('supports the "error" request strategy', () => {
expect(console.error).toHaveBeenCalledWith(fixtures.errorWithoutSuggestions)
})

test('supports custom callback function', () => {
const handleRequest = jest.fn()
const request = createMockedRequest()
onUnhandledRequest(request, [], handleRequest)
test('supports a custom callback function', () => {
const callback = jest.fn<void, Parameters<UnhandledRequestCallback>>(
(request) => {
console.warn(`callback: ${request.method} ${request.url.href}`)
},
)
const request = createMockedRequest({
url: new URL('/user', 'http://localhost:3000'),
})
onUnhandledRequest(request, [], callback)

expect(callback).toHaveBeenCalledTimes(1)
expect(callback).toHaveBeenCalledWith(request, {
warning: expect.any(Function),
error: expect.any(Function),
})

// Check that the custom logic in the callback was called.
expect(console.warn).toHaveBeenCalledWith(
`callback: GET http://localhost:3000/user`,
)
})

test('supports calling default strategies from the custom callback function', () => {
const callback = jest.fn<void, Parameters<UnhandledRequestCallback>>(
(request, print) => {
console.warn(`custom callback: ${request.id}`)

expect(handleRequest).toHaveBeenCalledWith(request, expect.anything())
// Call the default "error" strategy.
print.error()
},
)
const request = createMockedRequest({
id: 'request-1',
url: new URL('http://localhost/api'),
})
expect(() => onUnhandledRequest(request, [], callback)).toThrow(
`[MSW] Cannot bypass a request when using the "error" strategy for the "onUnhandledRequest" option.`,
)

expect(callback).toHaveBeenCalledTimes(1)
expect(callback).toHaveBeenCalledWith(request, {
warning: expect.any(Function),
error: expect.any(Function),
})

// Check that the custom logic in the callback was called.
expect(console.warn).toHaveBeenCalledWith('custom callback: request-1')

// Check that the default strategy was called.
expect(console.error).toHaveBeenCalledWith(fixtures.errorWithoutSuggestions)
})

test('does not print any suggestions given no handlers to suggest', () => {
Expand Down
25 changes: 14 additions & 11 deletions src/utils/request/onUnhandledRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ const MAX_MATCH_SCORE = 3
const MAX_SUGGESTION_COUNT = 4
const TYPE_MATCH_DELTA = 0.5

type HandleNext = () => {
error: (strategy: UnhandledRequestStrategy) => void
warn: (strategy: UnhandledRequestStrategy) => void
export interface UnhandledRequestPrint {
warning(): void
error(): void
}

export type UnhandledRequestCallback = (
request: MockedRequest,
next: HandleNext,
print: UnhandledRequestPrint,
) => void

export type UnhandledRequestStrategy =
Expand Down Expand Up @@ -183,8 +184,12 @@ Read more: https://mswjs.io/docs/getting-started/mocks\
return messageTemplate.join('\n\n')
}

function actionStrategy(strategy: UnhandledRequestStrategy) {
function applyStrategy(strategy: UnhandledRequestStrategy) {
// Generate handler suggestions only when applying the strategy.
// This saves bandwidth for scenarios when developers opt-out
// from the default unhandled request handling strategy.
const message = generateUnhandledRequestMessage()

switch (strategy) {
case 'error': {
// Print a developer-friendly error.
Expand Down Expand Up @@ -217,14 +222,12 @@ Read more: https://mswjs.io/docs/getting-started/mocks\
}

if (typeof strategy === 'function') {
strategy(request, () => {
return {
error: () => actionStrategy('error'),
warn: () => actionStrategy('warn'),
}
strategy(request, {
warning: applyStrategy.bind(null, 'warn'),
error: applyStrategy.bind(null, 'error'),
})
return
}

actionStrategy(strategy)
applyStrategy(strategy)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { setupWorker, rest } from 'msw'

const worker = setupWorker(
rest.get('/user', (req, res, ctx) => {
return res(ctx.json({ firstName: 'John' }))
}),
)

worker.start({
onUnhandledRequest(req, print) {
console.log(`Oops, unhandled ${req.method} ${req.url.href}`)

if (req.url.pathname.includes('/use-warn')) {
// Using "print" allows you to execute the default strategy.
print.warning()
} else {
print.error()
}
},
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import * as path from 'path'
import { pageWith } from 'page-with'

test('executes a default "warn" strategy in a custom callback', async () => {
const { request, consoleSpy } = await pageWith({
example: path.resolve(__dirname, 'callback-print.mocks.ts'),
})

const res = await request('https://mswjs.io/use-warn')
const status = res.status()

// Request is performed as-is.
expect(status).toBe(404)

// Custom callback executed.
expect(consoleSpy.get('log')).toContain(
'Oops, unhandled GET https://mswjs.io/use-warn',
)
expect(consoleSpy.get('error')).toBeUndefined()

// Prints the unhandled request warning upon `print.warning()`.
expect(consoleSpy.get('warning')).toEqual(
expect.arrayContaining([
expect.stringContaining(`\
[MSW] Warning: captured a request without a matching request handler:
• GET https://mswjs.io/use-warn
If you still wish to intercept this unhandled request, please create a request handler for it.
Read more: https://mswjs.io/docs/getting-started/mocks`),
]),
)
})

test('executes a default "error" strategy in a custom callback', async () => {
const { request, consoleSpy } = await pageWith({
example: path.resolve(__dirname, 'callback-print.mocks.ts'),
})

const res = await request('https://mswjs.io/use-error')
const status = res.status()

// Request is performed as-is.
expect(status).toBe(500)

// Custom callback executed.
expect(consoleSpy.get('log')).toContain(
'Oops, unhandled GET https://mswjs.io/use-error',
)
expect(consoleSpy.get('warning')).toBeUndefined()

// Prints the unhandled request error upon `print.error()`.
expect(consoleSpy.get('error')).toEqual(
expect.arrayContaining([
expect.stringContaining(`\
[MSW] Error: captured a request without a matching request handler:
• GET https://mswjs.io/use-error
If you still wish to intercept this unhandled request, please create a request handler for it.
Read more: https://mswjs.io/docs/getting-started/mocks`),
]),
)
})

0 comments on commit 57f6451

Please sign in to comment.