Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: add "listHandlers" method to server and worker (#1369)
* feat(createsetupserver.ts): add listHandlers method that returns active handlers * fix(setupServer): return readonly array in "listHandlers()" * feat(setupWorker): add "listHandlers()" method * test(toReadonlyArray): ensure source is intact Co-authored-by: Artem Zakharchenko <kettanaito@gmail.com>
- Loading branch information
1 parent
62f7c4d
commit 18f5778
Showing
10 changed files
with
268 additions
and
5 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
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
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,30 @@ | ||
import { toReadonlyArray } from './toReadonlyArray' | ||
|
||
it('creates a copy of an array', () => { | ||
expect(toReadonlyArray([1, 2, 3])).toEqual([1, 2, 3]) | ||
}) | ||
|
||
it('does not affect the source array', () => { | ||
const source = ['a', 'b', 'c'] | ||
toReadonlyArray(source) | ||
|
||
expect(source.push('d')).toBe(4) | ||
expect(source).toEqual(['a', 'b', 'c', 'd']) | ||
}) | ||
|
||
it('forbids modifying the array copy', () => { | ||
const source = [1, 2, 3] | ||
const copy = toReadonlyArray(source) | ||
|
||
expect(() => { | ||
// @ts-expect-error Intentional runtime misusage. | ||
copy[2] = 1 | ||
}).toThrow(/Cannot assign to read only property '\d+' of object/) | ||
|
||
expect(() => { | ||
// @ts-expect-error Intentional runtime misusage. | ||
copy.push(4) | ||
}).toThrow(/Cannot add property \d+, object is not extensible/) | ||
|
||
expect(source).toEqual([1, 2, 3]) | ||
}) |
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,8 @@ | ||
/** | ||
* Creates an immutable copy of the given array. | ||
*/ | ||
export function toReadonlyArray<T>(source: Array<T>): ReadonlyArray<T> { | ||
const clone = [...source] as Array<T> | ||
Object.freeze(clone) | ||
return clone | ||
} |
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,78 @@ | ||
/** | ||
* @jest-environment node | ||
*/ | ||
import { rest, graphql } from 'msw' | ||
import { setupServer } from 'msw/node' | ||
|
||
const resolver = () => null | ||
const github = graphql.link('https://api.github.com') | ||
|
||
const server = setupServer( | ||
rest.get('https://test.mswjs.io/book/:bookId', resolver), | ||
graphql.query('GetUser', resolver), | ||
graphql.mutation('UpdatePost', resolver), | ||
graphql.operation(resolver), | ||
github.query('GetRepo', resolver), | ||
github.operation(resolver), | ||
) | ||
|
||
beforeAll(() => { | ||
server.listen() | ||
}) | ||
|
||
afterEach(() => { | ||
server.resetHandlers() | ||
}) | ||
|
||
afterAll(() => { | ||
server.close() | ||
}) | ||
|
||
test('lists all current request handlers', () => { | ||
const handlers = server.listHandlers() | ||
const handlerHeaders = handlers.map((handler) => handler.info.header) | ||
|
||
expect(handlerHeaders).toEqual([ | ||
'GET https://test.mswjs.io/book/:bookId', | ||
'query GetUser (origin: *)', | ||
'mutation UpdatePost (origin: *)', | ||
'all (origin: *)', | ||
'query GetRepo (origin: https://api.github.com)', | ||
'all (origin: https://api.github.com)', | ||
]) | ||
}) | ||
|
||
test('forbids from modifying the list of handlers', () => { | ||
const handlers = server.listHandlers() | ||
|
||
expect(() => { | ||
// @ts-expect-error Intentional runtime misusage. | ||
handlers[0] = 1 | ||
}).toThrow(/Cannot assign to read only property '\d+' of object/) | ||
|
||
expect(() => { | ||
// @ts-expect-error Intentional runtime misusage. | ||
handlers.push(1) | ||
}).toThrow(/Cannot add property \d+, object is not extensible/) | ||
}) | ||
|
||
test('includes runtime request handlers when listing handlers', () => { | ||
server.use( | ||
rest.get('https://test.mswjs.io/book/:bookId', resolver), | ||
graphql.query('GetRandomNumber', resolver), | ||
) | ||
|
||
const handlers = server.listHandlers() | ||
const handlerHeaders = handlers.map((handler) => handler.info.header) | ||
|
||
expect(handlerHeaders).toEqual([ | ||
'GET https://test.mswjs.io/book/:bookId', | ||
'query GetRandomNumber (origin: *)', | ||
'GET https://test.mswjs.io/book/:bookId', | ||
'query GetUser (origin: *)', | ||
'mutation UpdatePost (origin: *)', | ||
'all (origin: *)', | ||
'query GetRepo (origin: https://api.github.com)', | ||
'all (origin: https://api.github.com)', | ||
]) | ||
}) |
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,21 @@ | ||
import { setupWorker, rest, graphql } from 'msw' | ||
|
||
const resolver = () => null | ||
|
||
const github = graphql.link('https://api.github.com') | ||
|
||
const worker = setupWorker( | ||
rest.get('https://test.mswjs.io/book/:bookId', resolver), | ||
graphql.query('GetUser', resolver), | ||
graphql.mutation('UpdatePost', resolver), | ||
graphql.operation(resolver), | ||
github.query('GetRepo', resolver), | ||
github.operation(resolver), | ||
) | ||
|
||
// @ts-ignore | ||
window.msw = { | ||
worker, | ||
rest, | ||
graphql, | ||
} |
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,76 @@ | ||
import * as path from 'path' | ||
import { pageWith } from 'page-with' | ||
import { SetupWorkerApi, rest, graphql } from 'msw' | ||
|
||
declare namespace window { | ||
export const msw: { | ||
worker: SetupWorkerApi | ||
rest: typeof rest | ||
graphql: typeof graphql | ||
} | ||
} | ||
|
||
function createRuntime() { | ||
return pageWith({ | ||
example: path.resolve(__dirname, 'printHandlers.mocks.ts'), | ||
}) | ||
} | ||
|
||
test('lists all current request handlers', async () => { | ||
const runtime = await createRuntime() | ||
|
||
const handlerHeaders = await runtime.page.evaluate(() => { | ||
const handlers = window.msw.worker.listHandlers() | ||
return handlers.map((handler) => handler.info.header) | ||
}) | ||
|
||
expect(handlerHeaders).toEqual([ | ||
'GET https://test.mswjs.io/book/:bookId', | ||
'query GetUser (origin: *)', | ||
'mutation UpdatePost (origin: *)', | ||
'all (origin: *)', | ||
'query GetRepo (origin: https://api.github.com)', | ||
'all (origin: https://api.github.com)', | ||
]) | ||
}) | ||
|
||
test('forbids from modifying the list of handlers', async () => { | ||
const runtime = await createRuntime() | ||
|
||
/** | ||
* @note For some reason, property assignment on frozen object | ||
* does not throw an error: handlers[0] = 1 | ||
*/ | ||
await expect( | ||
runtime.page.evaluate(() => { | ||
const handlers = window.msw.worker.listHandlers() | ||
// @ts-expect-error Intentional runtime misusage. | ||
handlers.push(1) | ||
}), | ||
).rejects.toThrow(/Cannot add property \d+, object is not extensible/) | ||
}) | ||
|
||
test('includes runtime request handlers when listing handlers', async () => { | ||
const runtime = await createRuntime() | ||
|
||
const handlerHeaders = await runtime.page.evaluate(() => { | ||
const { worker, rest, graphql } = window.msw | ||
worker.use( | ||
rest.get('https://test.mswjs.io/book/:bookId', () => void 0), | ||
graphql.query('GetRandomNumber', () => void 0), | ||
) | ||
const handlers = worker.listHandlers() | ||
return handlers.map((handler) => handler.info.header) | ||
}) | ||
|
||
expect(handlerHeaders).toEqual([ | ||
'GET https://test.mswjs.io/book/:bookId', | ||
'query GetRandomNumber (origin: *)', | ||
'GET https://test.mswjs.io/book/:bookId', | ||
'query GetUser (origin: *)', | ||
'mutation UpdatePost (origin: *)', | ||
'all (origin: *)', | ||
'query GetRepo (origin: https://api.github.com)', | ||
'all (origin: https://api.github.com)', | ||
]) | ||
}) |
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