Files
msw/test/node/msw-api/setup-server/use.node.test.ts
T

140 lines
4.3 KiB
TypeScript

/**
* @vitest-environment node
*/
import { HttpResponse, http } from 'msw'
import { type SetupServer, setupServer } from 'msw/node'
import type { RequestHandler as ExpressRequestHandler } from 'express'
import { HttpServer } from '@open-draft/test-server/http'
const httpServer = new HttpServer((app) => {
const handler: ExpressRequestHandler = (req, res) => {
res.status(500).send('')
}
app.get('/book/:bookId', handler)
app.post('/login', handler)
})
let server: SetupServer
beforeAll(async () => {
await httpServer.listen()
server = setupServer(
http.get<{ bookId: string }>(httpServer.http.url('/book/:bookId'), () => {
return HttpResponse.json({ title: 'Original title' })
}),
)
server.listen()
})
afterEach(() => {
server.resetHandlers()
})
afterAll(async () => {
server.close()
await httpServer.close()
})
test('returns a mocked response from a runtime request handler upon match', async () => {
server.use(
http.post(httpServer.http.url('/login'), () => {
return HttpResponse.json({ accepted: true })
}),
)
// Request handlers added on runtime affect network communication as usual.
const loginResponse = await fetch(httpServer.http.url('/login'), {
method: 'POST',
})
const loginBody = await loginResponse.json()
expect(loginResponse.status).toBe(200)
expect(loginBody).toEqual({ accepted: true })
// Other request handlers are preserved, if there are no overlaps.
const bookResponse = await fetch(httpServer.http.url('/book/abc-123'))
expect(bookResponse.status).toBe(200)
expect(await bookResponse.json()).toEqual({ title: 'Original title' })
})
test('returns a mocked response from a persistent request handler override', async () => {
server.use(
http.get<{ bookId: string }>(httpServer.http.url('/book/:bookId'), () => {
return HttpResponse.json({ title: 'Permanent override' })
}),
)
const bookResponse = await fetch(httpServer.http.url('/book/abc-123'))
const bookBody = await bookResponse.json()
expect(bookResponse.status).toBe(200)
expect(bookBody).toEqual({ title: 'Permanent override' })
const anotherBookResponse = await fetch(httpServer.http.url('/book/abc-123'))
expect(anotherBookResponse.status).toBe(200)
expect(await anotherBookResponse.json()).toEqual({
title: 'Permanent override',
})
})
test('returns a mocked response from a one-time request handler override only upon first request match', async () => {
server.use(
http.get<{ bookId: string }>(
httpServer.http.url('/book/:bookId'),
() => {
return HttpResponse.json({ title: 'One-time override' })
},
{ once: true },
),
)
const bookResponse = await fetch(httpServer.http.url('/book/abc-123'))
const bookBody = await bookResponse.json()
expect(bookResponse.status).toBe(200)
expect(bookBody).toEqual({ title: 'One-time override' })
const anotherBookResponse = await fetch(httpServer.http.url('/book/abc-123'))
expect(anotherBookResponse.status).toBe(200)
expect(await anotherBookResponse.json()).toEqual({ title: 'Original title' })
})
test('returns a mocked response from a one-time request handler override only upon first request match with parallel requests', async () => {
server.use(
http.get<{ bookId: string }>(
httpServer.http.url('/book/:bookId'),
({ params }) => {
return HttpResponse.json({
title: 'One-time override',
bookId: params.bookId,
})
},
{ once: true },
),
)
const bookRequestPromise = fetch(httpServer.http.url('/book/abc-123'))
const anotherBookRequestPromise = fetch(httpServer.http.url('/book/abc-123'))
const bookResponse = await bookRequestPromise
expect(bookResponse.status).toBe(200)
expect(await bookResponse.json()).toEqual({
title: 'One-time override',
bookId: 'abc-123',
})
const anotherBookResponse = await anotherBookRequestPromise
expect(anotherBookResponse.status).toBe(200)
expect(await anotherBookResponse.json()).toEqual({ title: 'Original title' })
})
test('throws if provided the invalid handlers array', async () => {
expect(() =>
server.use(
// @ts-expect-error Intentionally invalid input.
[http.get('*', () => new Response())],
),
).toThrow(
'[MSW] Failed to call "use()" with the given request handlers: invalid input. Did you forget to spread the array of request handlers?',
)
})