UNPKG

msw

Version:

Seamless REST/GraphQL API mocking library for browser and Node.js.

254 lines (220 loc) 7.57 kB
// @vitest-environment jsdom import { createRequestId } from '@mswjs/interceptors' import { HttpHandler, HttpRequestResolverExtras } from './HttpHandler' import { HttpResponse } from '..' import { ResponseResolver } from './RequestHandler' const resolver: ResponseResolver< HttpRequestResolverExtras<{ userId: string }> > = ({ params }) => { return HttpResponse.json({ userId: params.userId }) } describe('info', () => { it('exposes request handler information', () => { const handler = new HttpHandler('GET', '/user/:userId', resolver) expect(handler.info.header).toEqual('GET /user/:userId') expect(handler.info.method).toEqual('GET') expect(handler.info.path).toEqual('/user/:userId') expect(handler.isUsed).toBe(false) }) }) describe('parse', () => { it('parses a URL given a matching request', async () => { const handler = new HttpHandler('GET', '/user/:userId', resolver) const request = new Request(new URL('/user/abc-123', location.href)) expect(await handler.parse({ request })).toEqual({ match: { matches: true, params: { userId: 'abc-123', }, }, cookies: {}, }) }) it('parses a URL and ignores the request method', async () => { const handler = new HttpHandler('GET', '/user/:userId', resolver) const request = new Request(new URL('/user/def-456', location.href), { method: 'POST', }) expect(await handler.parse({ request })).toEqual({ match: { matches: true, params: { userId: 'def-456', }, }, cookies: {}, }) }) it('returns negative match result given a non-matching request', async () => { const handler = new HttpHandler('GET', '/user/:userId', resolver) const request = new Request(new URL('/login', location.href)) expect(await handler.parse({ request })).toEqual({ match: { matches: false, params: {}, }, cookies: {}, }) }) }) describe('predicate', () => { it('returns true given a matching request', async () => { const handler = new HttpHandler('POST', '/login', resolver) const request = new Request(new URL('/login', location.href), { method: 'POST', }) await expect( handler.predicate({ request, parsedResult: await handler.parse({ request }), }), ).resolves.toBe(true) }) it('supports RegExp as the request method', async () => { const handler = new HttpHandler(/.+/, '/login', resolver) const requests = [ new Request(new URL('/login', location.href)), new Request(new URL('/login', location.href), { method: 'POST' }), new Request(new URL('/login', location.href), { method: 'DELETE' }), ] for (const request of requests) { await expect( handler.predicate({ request, parsedResult: await handler.parse({ request }), }), ).resolves.toBe(true) } }) it('returns false given a non-matching request', async () => { const handler = new HttpHandler('POST', '/login', resolver) const request = new Request(new URL('/user/abc-123', location.href)) await expect( handler.predicate({ request, parsedResult: await handler.parse({ request }), }), ).resolves.toBe(false) }) it('supports custom predicate function', async () => { const handler = new HttpHandler( 'GET', ({ request }) => { return new URL(request.url).searchParams.get('a') === '1' }, resolver, ) { const request = new Request(new URL('/login?a=1', location.href)) await expect( handler.predicate({ request, parsedResult: await handler.parse({ request }), }), ).resolves.toBe(true) } { const request = new Request(new URL('/login', location.href)) await expect( handler.predicate({ request, parsedResult: await handler.parse({ request }), }), ).resolves.toBe(false) } }) }) describe('test', () => { it('returns true given a matching request', async () => { const handler = new HttpHandler('GET', '/user/:userId', resolver) const firstTest = await handler.test({ request: new Request(new URL('/user/abc-123', location.href)), }) const secondTest = await handler.test({ request: new Request(new URL('/user/def-456', location.href)), }) expect(firstTest).toBe(true) expect(secondTest).toBe(true) }) it('returns false given a non-matching request', async () => { const handler = new HttpHandler('GET', '/user/:userId', resolver) const firstTest = await handler.test({ request: new Request(new URL('/login', location.href)), }) const secondTest = await handler.test({ request: new Request(new URL('/user/', location.href)), }) const thirdTest = await handler.test({ request: new Request(new URL('/user/abc-123/extra', location.href)), }) expect(firstTest).toBe(false) expect(secondTest).toBe(false) expect(thirdTest).toBe(false) }) }) describe('run', () => { it('returns a mocked response given a matching request', async () => { const handler = new HttpHandler('GET', '/user/:userId', resolver) const request = new Request(new URL('/user/abc-123', location.href)) const requestId = createRequestId() const result = await handler.run({ request, requestId }) expect(result!.handler).toEqual(handler) expect(result!.parsedResult).toEqual({ match: { matches: true, params: { userId: 'abc-123', }, }, cookies: {}, }) expect(result!.request.method).toBe('GET') expect(result!.request.url).toBe('http://localhost/user/abc-123') expect(result!.response?.status).toBe(200) expect(result!.response?.statusText).toBe('OK') await expect(result?.response?.json()).resolves.toEqual({ userId: 'abc-123', }) }) it('returns null given a non-matching request', async () => { const handler = new HttpHandler('POST', '/login', resolver) const result = await handler.run({ request: new Request(new URL('/users', location.href)), requestId: createRequestId(), }) expect(result).toBeNull() }) it('returns an empty "params" object given request with no URL parameters', async () => { const handler = new HttpHandler('GET', '/users', resolver) const result = await handler.run({ request: new Request(new URL('/users', location.href)), requestId: createRequestId(), }) expect(result?.parsedResult?.match?.params).toEqual({}) }) it('exhausts resolver until its generator completes', async () => { const handler = new HttpHandler('GET', '/users', function* () { let count = 0 while (count < 5) { count += 1 yield HttpResponse.text('pending') } return HttpResponse.text('complete') }) const run = async () => { const result = await handler.run({ request: new Request(new URL('/users', location.href)), requestId: createRequestId(), }) return result?.response?.text() } await expect(run()).resolves.toBe('pending') await expect(run()).resolves.toBe('pending') await expect(run()).resolves.toBe('pending') await expect(run()).resolves.toBe('pending') await expect(run()).resolves.toBe('pending') await expect(run()).resolves.toBe('complete') await expect(run()).resolves.toBe('complete') }) })