msw 2.10.5 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/core/{HttpResponse-CC5tPhLa.d.mts → HttpResponse-DiuKTgC7.d.mts} +21 -7
- package/lib/core/{HttpResponse-CKZrrwKE.d.ts → HttpResponse-DlQEvD4q.d.ts} +21 -7
- package/lib/core/HttpResponse.d.mts +1 -1
- package/lib/core/HttpResponse.d.ts +1 -1
- package/lib/core/SetupApi.d.mts +1 -1
- package/lib/core/SetupApi.d.ts +1 -1
- package/lib/core/getResponse.d.mts +1 -1
- package/lib/core/getResponse.d.ts +1 -1
- package/lib/core/graphql.d.mts +2 -2
- package/lib/core/graphql.d.ts +2 -2
- package/lib/core/graphql.js +2 -8
- package/lib/core/graphql.js.map +1 -1
- package/lib/core/graphql.mjs +2 -8
- package/lib/core/graphql.mjs.map +1 -1
- package/lib/core/handlers/GraphQLHandler.d.mts +1 -1
- package/lib/core/handlers/GraphQLHandler.d.ts +1 -1
- package/lib/core/handlers/GraphQLHandler.js +36 -9
- package/lib/core/handlers/GraphQLHandler.js.map +1 -1
- package/lib/core/handlers/GraphQLHandler.mjs +36 -9
- package/lib/core/handlers/GraphQLHandler.mjs.map +1 -1
- package/lib/core/handlers/HttpHandler.d.mts +15 -5
- package/lib/core/handlers/HttpHandler.d.ts +15 -5
- package/lib/core/handlers/HttpHandler.js +21 -10
- package/lib/core/handlers/HttpHandler.js.map +1 -1
- package/lib/core/handlers/HttpHandler.mjs +21 -10
- package/lib/core/handlers/HttpHandler.mjs.map +1 -1
- package/lib/core/handlers/RequestHandler.d.mts +1 -1
- package/lib/core/handlers/RequestHandler.d.ts +1 -1
- package/lib/core/handlers/RequestHandler.js +1 -1
- package/lib/core/handlers/RequestHandler.js.map +1 -1
- package/lib/core/handlers/RequestHandler.mjs +1 -1
- package/lib/core/handlers/RequestHandler.mjs.map +1 -1
- package/lib/core/http.d.mts +4 -4
- package/lib/core/http.d.ts +4 -4
- package/lib/core/http.js +2 -2
- package/lib/core/http.js.map +1 -1
- package/lib/core/http.mjs +2 -2
- package/lib/core/http.mjs.map +1 -1
- package/lib/core/index.d.mts +2 -2
- package/lib/core/index.d.ts +2 -2
- package/lib/core/index.js.map +1 -1
- package/lib/core/index.mjs.map +1 -1
- package/lib/core/passthrough.d.mts +1 -1
- package/lib/core/passthrough.d.ts +1 -1
- package/lib/core/utils/HttpResponse/decorators.d.mts +1 -1
- package/lib/core/utils/HttpResponse/decorators.d.ts +1 -1
- package/lib/core/utils/executeHandlers.d.mts +1 -1
- package/lib/core/utils/executeHandlers.d.ts +1 -1
- package/lib/core/utils/handleRequest.d.mts +1 -1
- package/lib/core/utils/handleRequest.d.ts +1 -1
- package/lib/core/utils/internal/isHandlerKind.d.mts +1 -1
- package/lib/core/utils/internal/isHandlerKind.d.ts +1 -1
- package/lib/core/utils/internal/parseGraphQLRequest.d.mts +1 -1
- package/lib/core/utils/internal/parseGraphQLRequest.d.ts +1 -1
- package/lib/core/utils/internal/parseMultipartData.d.mts +1 -1
- package/lib/core/utils/internal/parseMultipartData.d.ts +1 -1
- package/lib/core/utils/internal/requestHandlerUtils.d.mts +1 -1
- package/lib/core/utils/internal/requestHandlerUtils.d.ts +1 -1
- package/lib/core/ws/handleWebSocketEvent.d.mts +1 -1
- package/lib/core/ws/handleWebSocketEvent.d.ts +1 -1
- package/lib/iife/index.js +62 -30
- package/lib/iife/index.js.map +1 -1
- package/lib/mockServiceWorker.js +1 -1
- package/package.json +2 -2
- package/src/core/graphql.ts +8 -12
- package/src/core/handlers/GraphQLHandler.test.ts +86 -51
- package/src/core/handlers/GraphQLHandler.ts +81 -17
- package/src/core/handlers/HttpHandler.test.ts +60 -30
- package/src/core/handlers/HttpHandler.ts +61 -12
- package/src/core/handlers/RequestHandler.ts +2 -2
- package/src/core/http.ts +5 -5
- package/src/core/index.ts +3 -0
- package/src/core/utils/handleRequest.test.ts +84 -0
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* @vitest-environment jsdom
|
|
3
|
-
*/
|
|
1
|
+
// @vitest-environment jsdom
|
|
4
2
|
import { createRequestId } from '@mswjs/interceptors'
|
|
5
3
|
import { HttpHandler, HttpRequestResolverExtras } from './HttpHandler'
|
|
6
4
|
import { HttpResponse } from '..'
|
|
@@ -13,7 +11,7 @@ const resolver: ResponseResolver<
|
|
|
13
11
|
}
|
|
14
12
|
|
|
15
13
|
describe('info', () => {
|
|
16
|
-
|
|
14
|
+
it('exposes request handler information', () => {
|
|
17
15
|
const handler = new HttpHandler('GET', '/user/:userId', resolver)
|
|
18
16
|
|
|
19
17
|
expect(handler.info.header).toEqual('GET /user/:userId')
|
|
@@ -24,7 +22,7 @@ describe('info', () => {
|
|
|
24
22
|
})
|
|
25
23
|
|
|
26
24
|
describe('parse', () => {
|
|
27
|
-
|
|
25
|
+
it('parses a URL given a matching request', async () => {
|
|
28
26
|
const handler = new HttpHandler('GET', '/user/:userId', resolver)
|
|
29
27
|
const request = new Request(new URL('/user/abc-123', location.href))
|
|
30
28
|
|
|
@@ -39,7 +37,7 @@ describe('parse', () => {
|
|
|
39
37
|
})
|
|
40
38
|
})
|
|
41
39
|
|
|
42
|
-
|
|
40
|
+
it('parses a URL and ignores the request method', async () => {
|
|
43
41
|
const handler = new HttpHandler('GET', '/user/:userId', resolver)
|
|
44
42
|
const request = new Request(new URL('/user/def-456', location.href), {
|
|
45
43
|
method: 'POST',
|
|
@@ -56,7 +54,7 @@ describe('parse', () => {
|
|
|
56
54
|
})
|
|
57
55
|
})
|
|
58
56
|
|
|
59
|
-
|
|
57
|
+
it('returns negative match result given a non-matching request', async () => {
|
|
60
58
|
const handler = new HttpHandler('GET', '/user/:userId', resolver)
|
|
61
59
|
const request = new Request(new URL('/login', location.href))
|
|
62
60
|
|
|
@@ -71,21 +69,21 @@ describe('parse', () => {
|
|
|
71
69
|
})
|
|
72
70
|
|
|
73
71
|
describe('predicate', () => {
|
|
74
|
-
|
|
72
|
+
it('returns true given a matching request', async () => {
|
|
75
73
|
const handler = new HttpHandler('POST', '/login', resolver)
|
|
76
74
|
const request = new Request(new URL('/login', location.href), {
|
|
77
75
|
method: 'POST',
|
|
78
76
|
})
|
|
79
77
|
|
|
80
|
-
expect(
|
|
78
|
+
await expect(
|
|
81
79
|
handler.predicate({
|
|
82
80
|
request,
|
|
83
81
|
parsedResult: await handler.parse({ request }),
|
|
84
82
|
}),
|
|
85
|
-
).toBe(true)
|
|
83
|
+
).resolves.toBe(true)
|
|
86
84
|
})
|
|
87
85
|
|
|
88
|
-
|
|
86
|
+
it('supports RegExp as the request method', async () => {
|
|
89
87
|
const handler = new HttpHandler(/.+/, '/login', resolver)
|
|
90
88
|
const requests = [
|
|
91
89
|
new Request(new URL('/login', location.href)),
|
|
@@ -94,30 +92,60 @@ describe('predicate', () => {
|
|
|
94
92
|
]
|
|
95
93
|
|
|
96
94
|
for (const request of requests) {
|
|
97
|
-
expect(
|
|
95
|
+
await expect(
|
|
98
96
|
handler.predicate({
|
|
99
97
|
request,
|
|
100
98
|
parsedResult: await handler.parse({ request }),
|
|
101
99
|
}),
|
|
102
|
-
).toBe(true)
|
|
100
|
+
).resolves.toBe(true)
|
|
103
101
|
}
|
|
104
102
|
})
|
|
105
103
|
|
|
106
|
-
|
|
104
|
+
it('returns false given a non-matching request', async () => {
|
|
107
105
|
const handler = new HttpHandler('POST', '/login', resolver)
|
|
108
106
|
const request = new Request(new URL('/user/abc-123', location.href))
|
|
109
107
|
|
|
110
|
-
expect(
|
|
108
|
+
await expect(
|
|
111
109
|
handler.predicate({
|
|
112
110
|
request,
|
|
113
111
|
parsedResult: await handler.parse({ request }),
|
|
114
112
|
}),
|
|
115
|
-
).toBe(false)
|
|
113
|
+
).resolves.toBe(false)
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('supports custom predicate function', async () => {
|
|
117
|
+
const handler = new HttpHandler(
|
|
118
|
+
'GET',
|
|
119
|
+
({ request }) => {
|
|
120
|
+
return new URL(request.url).searchParams.get('a') === '1'
|
|
121
|
+
},
|
|
122
|
+
resolver,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
{
|
|
126
|
+
const request = new Request(new URL('/login?a=1', location.href))
|
|
127
|
+
await expect(
|
|
128
|
+
handler.predicate({
|
|
129
|
+
request,
|
|
130
|
+
parsedResult: await handler.parse({ request }),
|
|
131
|
+
}),
|
|
132
|
+
).resolves.toBe(true)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
{
|
|
136
|
+
const request = new Request(new URL('/login', location.href))
|
|
137
|
+
await expect(
|
|
138
|
+
handler.predicate({
|
|
139
|
+
request,
|
|
140
|
+
parsedResult: await handler.parse({ request }),
|
|
141
|
+
}),
|
|
142
|
+
).resolves.toBe(false)
|
|
143
|
+
}
|
|
116
144
|
})
|
|
117
145
|
})
|
|
118
146
|
|
|
119
147
|
describe('test', () => {
|
|
120
|
-
|
|
148
|
+
it('returns true given a matching request', async () => {
|
|
121
149
|
const handler = new HttpHandler('GET', '/user/:userId', resolver)
|
|
122
150
|
const firstTest = await handler.test({
|
|
123
151
|
request: new Request(new URL('/user/abc-123', location.href)),
|
|
@@ -130,7 +158,7 @@ describe('test', () => {
|
|
|
130
158
|
expect(secondTest).toBe(true)
|
|
131
159
|
})
|
|
132
160
|
|
|
133
|
-
|
|
161
|
+
it('returns false given a non-matching request', async () => {
|
|
134
162
|
const handler = new HttpHandler('GET', '/user/:userId', resolver)
|
|
135
163
|
const firstTest = await handler.test({
|
|
136
164
|
request: new Request(new URL('/login', location.href)),
|
|
@@ -149,7 +177,7 @@ describe('test', () => {
|
|
|
149
177
|
})
|
|
150
178
|
|
|
151
179
|
describe('run', () => {
|
|
152
|
-
|
|
180
|
+
it('returns a mocked response given a matching request', async () => {
|
|
153
181
|
const handler = new HttpHandler('GET', '/user/:userId', resolver)
|
|
154
182
|
const request = new Request(new URL('/user/abc-123', location.href))
|
|
155
183
|
const requestId = createRequestId()
|
|
@@ -169,10 +197,12 @@ describe('run', () => {
|
|
|
169
197
|
expect(result!.request.url).toBe('http://localhost/user/abc-123')
|
|
170
198
|
expect(result!.response?.status).toBe(200)
|
|
171
199
|
expect(result!.response?.statusText).toBe('OK')
|
|
172
|
-
expect(
|
|
200
|
+
await expect(result?.response?.json()).resolves.toEqual({
|
|
201
|
+
userId: 'abc-123',
|
|
202
|
+
})
|
|
173
203
|
})
|
|
174
204
|
|
|
175
|
-
|
|
205
|
+
it('returns null given a non-matching request', async () => {
|
|
176
206
|
const handler = new HttpHandler('POST', '/login', resolver)
|
|
177
207
|
const result = await handler.run({
|
|
178
208
|
request: new Request(new URL('/users', location.href)),
|
|
@@ -182,7 +212,7 @@ describe('run', () => {
|
|
|
182
212
|
expect(result).toBeNull()
|
|
183
213
|
})
|
|
184
214
|
|
|
185
|
-
|
|
215
|
+
it('returns an empty "params" object given request with no URL parameters', async () => {
|
|
186
216
|
const handler = new HttpHandler('GET', '/users', resolver)
|
|
187
217
|
const result = await handler.run({
|
|
188
218
|
request: new Request(new URL('/users', location.href)),
|
|
@@ -192,7 +222,7 @@ describe('run', () => {
|
|
|
192
222
|
expect(result?.parsedResult?.match?.params).toEqual({})
|
|
193
223
|
})
|
|
194
224
|
|
|
195
|
-
|
|
225
|
+
it('exhausts resolver until its generator completes', async () => {
|
|
196
226
|
const handler = new HttpHandler('GET', '/users', function* () {
|
|
197
227
|
let count = 0
|
|
198
228
|
|
|
@@ -212,12 +242,12 @@ describe('run', () => {
|
|
|
212
242
|
return result?.response?.text()
|
|
213
243
|
}
|
|
214
244
|
|
|
215
|
-
expect(
|
|
216
|
-
expect(
|
|
217
|
-
expect(
|
|
218
|
-
expect(
|
|
219
|
-
expect(
|
|
220
|
-
expect(
|
|
221
|
-
expect(
|
|
245
|
+
await expect(run()).resolves.toBe('pending')
|
|
246
|
+
await expect(run()).resolves.toBe('pending')
|
|
247
|
+
await expect(run()).resolves.toBe('pending')
|
|
248
|
+
await expect(run()).resolves.toBe('pending')
|
|
249
|
+
await expect(run()).resolves.toBe('pending')
|
|
250
|
+
await expect(run()).resolves.toBe('complete')
|
|
251
|
+
await expect(run()).resolves.toBe('complete')
|
|
222
252
|
})
|
|
223
253
|
})
|
|
@@ -25,7 +25,7 @@ type HttpHandlerMethod = string | RegExp
|
|
|
25
25
|
|
|
26
26
|
export interface HttpHandlerInfo extends RequestHandlerDefaultInfo {
|
|
27
27
|
method: HttpHandlerMethod
|
|
28
|
-
path:
|
|
28
|
+
path: HttpRequestPredicate<PathParams>
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export enum HttpMethods {
|
|
@@ -52,6 +52,24 @@ export type HttpRequestResolverExtras<Params extends PathParams> = {
|
|
|
52
52
|
cookies: Record<string, string>
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
export type HttpCustomPredicate<Params extends PathParams> = (args: {
|
|
56
|
+
request: Request
|
|
57
|
+
cookies: Record<string, string>
|
|
58
|
+
}) =>
|
|
59
|
+
| HttpCustomPredicateResult<Params>
|
|
60
|
+
| Promise<HttpCustomPredicateResult<Params>>
|
|
61
|
+
|
|
62
|
+
export type HttpCustomPredicateResult<Params extends PathParams> =
|
|
63
|
+
| boolean
|
|
64
|
+
| {
|
|
65
|
+
matches: boolean
|
|
66
|
+
params: Params
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export type HttpRequestPredicate<Params extends PathParams> =
|
|
70
|
+
| Path
|
|
71
|
+
| HttpCustomPredicate<Params>
|
|
72
|
+
|
|
55
73
|
/**
|
|
56
74
|
* Request handler for HTTP requests.
|
|
57
75
|
* Provides request matching based on method and URL.
|
|
@@ -63,14 +81,17 @@ export class HttpHandler extends RequestHandler<
|
|
|
63
81
|
> {
|
|
64
82
|
constructor(
|
|
65
83
|
method: HttpHandlerMethod,
|
|
66
|
-
|
|
84
|
+
predicate: HttpRequestPredicate<PathParams>,
|
|
67
85
|
resolver: ResponseResolver<HttpRequestResolverExtras<any>, any, any>,
|
|
68
86
|
options?: RequestHandlerOptions,
|
|
69
87
|
) {
|
|
88
|
+
const displayPath =
|
|
89
|
+
typeof predicate === 'function' ? '[custom predicate]' : predicate
|
|
90
|
+
|
|
70
91
|
super({
|
|
71
92
|
info: {
|
|
72
|
-
header: `${method} ${
|
|
73
|
-
path,
|
|
93
|
+
header: `${method}${displayPath ? ` ${displayPath}` : ''}`,
|
|
94
|
+
path: predicate,
|
|
74
95
|
method,
|
|
75
96
|
},
|
|
76
97
|
resolver,
|
|
@@ -83,7 +104,7 @@ export class HttpHandler extends RequestHandler<
|
|
|
83
104
|
private checkRedundantQueryParameters() {
|
|
84
105
|
const { method, path } = this.info
|
|
85
106
|
|
|
86
|
-
if (path instanceof RegExp) {
|
|
107
|
+
if (!path || path instanceof RegExp || typeof path === 'function') {
|
|
87
108
|
return
|
|
88
109
|
}
|
|
89
110
|
|
|
@@ -95,7 +116,7 @@ export class HttpHandler extends RequestHandler<
|
|
|
95
116
|
}
|
|
96
117
|
|
|
97
118
|
const searchParams = getSearchParams(path)
|
|
98
|
-
const queryParams: string
|
|
119
|
+
const queryParams: Array<string> = []
|
|
99
120
|
|
|
100
121
|
searchParams.forEach((_, paramName) => {
|
|
101
122
|
queryParams.push(paramName)
|
|
@@ -111,20 +132,48 @@ export class HttpHandler extends RequestHandler<
|
|
|
111
132
|
resolutionContext?: ResponseResolutionContext
|
|
112
133
|
}) {
|
|
113
134
|
const url = new URL(args.request.url)
|
|
114
|
-
const match = matchRequestUrl(
|
|
115
|
-
url,
|
|
116
|
-
this.info.path,
|
|
117
|
-
args.resolutionContext?.baseUrl,
|
|
118
|
-
)
|
|
119
135
|
const cookies = getAllRequestCookies(args.request)
|
|
120
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Handle custom predicate functions.
|
|
139
|
+
* @note Invoke this during parsing so the user can parse the path parameters
|
|
140
|
+
* manually. Otherwise, `params` is always an empty object, which isn't nice.
|
|
141
|
+
*/
|
|
142
|
+
if (typeof this.info.path === 'function') {
|
|
143
|
+
const customPredicateResult = await this.info.path({
|
|
144
|
+
request: args.request,
|
|
145
|
+
cookies,
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
const match =
|
|
149
|
+
typeof customPredicateResult === 'boolean'
|
|
150
|
+
? {
|
|
151
|
+
matches: customPredicateResult,
|
|
152
|
+
params: {},
|
|
153
|
+
}
|
|
154
|
+
: customPredicateResult
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
match,
|
|
158
|
+
cookies,
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const match = this.info.path
|
|
163
|
+
? matchRequestUrl(url, this.info.path, args.resolutionContext?.baseUrl)
|
|
164
|
+
: { matches: false, params: {} }
|
|
165
|
+
|
|
121
166
|
return {
|
|
122
167
|
match,
|
|
123
168
|
cookies,
|
|
124
169
|
}
|
|
125
170
|
}
|
|
126
171
|
|
|
127
|
-
predicate(args: {
|
|
172
|
+
async predicate(args: {
|
|
173
|
+
request: Request
|
|
174
|
+
parsedResult: HttpRequestParsedResult
|
|
175
|
+
resolutionContext?: ResponseResolutionContext
|
|
176
|
+
}) {
|
|
128
177
|
const hasMatchingMethod = this.matchMethod(args.request.method)
|
|
129
178
|
const hasMatchingUrl = args.parsedResult.match.matches
|
|
130
179
|
return hasMatchingMethod && hasMatchingUrl
|
|
@@ -179,7 +179,7 @@ export abstract class RequestHandler<
|
|
|
179
179
|
request: Request
|
|
180
180
|
parsedResult: ParsedResult
|
|
181
181
|
resolutionContext?: ResponseResolutionContext
|
|
182
|
-
}): boolean
|
|
182
|
+
}): boolean | Promise<boolean>
|
|
183
183
|
|
|
184
184
|
/**
|
|
185
185
|
* Print out the successfully handled request.
|
|
@@ -273,7 +273,7 @@ export abstract class RequestHandler<
|
|
|
273
273
|
request: args.request,
|
|
274
274
|
resolutionContext: args.resolutionContext,
|
|
275
275
|
})
|
|
276
|
-
const shouldInterceptRequest = this.predicate({
|
|
276
|
+
const shouldInterceptRequest = await this.predicate({
|
|
277
277
|
request: args.request,
|
|
278
278
|
parsedResult,
|
|
279
279
|
resolutionContext: args.resolutionContext,
|
package/src/core/http.ts
CHANGED
|
@@ -7,8 +7,9 @@ import {
|
|
|
7
7
|
HttpMethods,
|
|
8
8
|
HttpHandler,
|
|
9
9
|
HttpRequestResolverExtras,
|
|
10
|
+
HttpRequestPredicate,
|
|
10
11
|
} from './handlers/HttpHandler'
|
|
11
|
-
import type {
|
|
12
|
+
import type { PathParams } from './utils/matching/matchRequestUrl'
|
|
12
13
|
|
|
13
14
|
export type HttpRequestHandler = <
|
|
14
15
|
Params extends PathParams<keyof Params> = PathParams,
|
|
@@ -18,9 +19,8 @@ export type HttpRequestHandler = <
|
|
|
18
19
|
// returns plain "Response" and the one returning "HttpResponse"
|
|
19
20
|
// to enforce a stricter response body type.
|
|
20
21
|
ResponseBodyType extends DefaultBodyType = undefined,
|
|
21
|
-
RequestPath extends Path = Path,
|
|
22
22
|
>(
|
|
23
|
-
|
|
23
|
+
predicate: HttpRequestPredicate<Params>,
|
|
24
24
|
resolver: HttpResponseResolver<Params, RequestBodyType, ResponseBodyType>,
|
|
25
25
|
options?: RequestHandlerOptions,
|
|
26
26
|
) => HttpHandler
|
|
@@ -38,8 +38,8 @@ export type HttpResponseResolver<
|
|
|
38
38
|
function createHttpHandler<Method extends HttpMethods | RegExp>(
|
|
39
39
|
method: Method,
|
|
40
40
|
): HttpRequestHandler {
|
|
41
|
-
return (
|
|
42
|
-
return new HttpHandler(method,
|
|
41
|
+
return (predicate, resolver, options = {}) => {
|
|
42
|
+
return new HttpHandler(method, predicate, resolver, options)
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
package/src/core/index.ts
CHANGED
|
@@ -42,6 +42,7 @@ export type {
|
|
|
42
42
|
export type {
|
|
43
43
|
RequestQuery,
|
|
44
44
|
HttpRequestParsedResult,
|
|
45
|
+
HttpCustomPredicate,
|
|
45
46
|
} from './handlers/HttpHandler'
|
|
46
47
|
export type { HttpRequestHandler, HttpResponseResolver } from './http'
|
|
47
48
|
|
|
@@ -51,6 +52,8 @@ export type {
|
|
|
51
52
|
GraphQLRequestBody,
|
|
52
53
|
GraphQLResponseBody,
|
|
53
54
|
GraphQLJsonRequestBody,
|
|
55
|
+
GraphQLOperationType,
|
|
56
|
+
GraphQLCustomPredicate,
|
|
54
57
|
} from './handlers/GraphQLHandler'
|
|
55
58
|
export type { GraphQLRequestHandler, GraphQLResponseResolver } from './graphql'
|
|
56
59
|
|
|
@@ -487,3 +487,87 @@ describe('[Private] - resolutionContext - used for extensions', () => {
|
|
|
487
487
|
})
|
|
488
488
|
})
|
|
489
489
|
})
|
|
490
|
+
|
|
491
|
+
describe('handler with custom predicate', () => {
|
|
492
|
+
test('matches if custom predicate returns true', async () => {
|
|
493
|
+
const { emitter, events } = setup()
|
|
494
|
+
|
|
495
|
+
const requestId = createRequestId()
|
|
496
|
+
const request = new Request(new URL('http://localhost/login'), {
|
|
497
|
+
method: 'POST',
|
|
498
|
+
body: JSON.stringify({ username: 'test', password: 'password' }),
|
|
499
|
+
headers: { 'Content-Type': 'application/json' },
|
|
500
|
+
})
|
|
501
|
+
const handlers: Array<RequestHandler> = [
|
|
502
|
+
http.post(
|
|
503
|
+
async ({ request }) => {
|
|
504
|
+
const body = await request.clone().json()
|
|
505
|
+
return body.username === 'test' && body.password === 'password'
|
|
506
|
+
},
|
|
507
|
+
() =>
|
|
508
|
+
HttpResponse.json({
|
|
509
|
+
success: true,
|
|
510
|
+
}),
|
|
511
|
+
),
|
|
512
|
+
]
|
|
513
|
+
|
|
514
|
+
const result = await handleRequest(
|
|
515
|
+
request,
|
|
516
|
+
requestId,
|
|
517
|
+
handlers,
|
|
518
|
+
options,
|
|
519
|
+
emitter,
|
|
520
|
+
handleRequestOptions,
|
|
521
|
+
)
|
|
522
|
+
|
|
523
|
+
expect(result).toBeDefined()
|
|
524
|
+
expect(await result?.json()).toStrictEqual({ success: true })
|
|
525
|
+
expect(events).toEqual([
|
|
526
|
+
['request:start', { request, requestId }],
|
|
527
|
+
['request:match', { request, requestId }],
|
|
528
|
+
['request:end', { request, requestId }],
|
|
529
|
+
])
|
|
530
|
+
expect(handleRequestOptions.onMockedResponse).toHaveBeenCalledTimes(1)
|
|
531
|
+
})
|
|
532
|
+
|
|
533
|
+
test('does not match if custom predicate returns false', async () => {
|
|
534
|
+
const { emitter, events } = setup()
|
|
535
|
+
|
|
536
|
+
const requestId = createRequestId()
|
|
537
|
+
const request = new Request(new URL('http://localhost/login'), {
|
|
538
|
+
method: 'POST',
|
|
539
|
+
body: JSON.stringify({ username: 'test', password: 'passwordd' }),
|
|
540
|
+
headers: { 'Content-Type': 'application/json' },
|
|
541
|
+
})
|
|
542
|
+
const handlers: Array<RequestHandler> = [
|
|
543
|
+
http.post(
|
|
544
|
+
async ({ request }) => {
|
|
545
|
+
const body = await request.clone().json()
|
|
546
|
+
return body.username === 'test' && body.password === 'password'
|
|
547
|
+
},
|
|
548
|
+
() =>
|
|
549
|
+
HttpResponse.json({
|
|
550
|
+
success: true,
|
|
551
|
+
}),
|
|
552
|
+
),
|
|
553
|
+
]
|
|
554
|
+
|
|
555
|
+
const result = await handleRequest(
|
|
556
|
+
request,
|
|
557
|
+
requestId,
|
|
558
|
+
handlers,
|
|
559
|
+
options,
|
|
560
|
+
emitter,
|
|
561
|
+
handleRequestOptions,
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
expect(result).toBeUndefined()
|
|
565
|
+
expect(events).toEqual([
|
|
566
|
+
['request:start', { request, requestId }],
|
|
567
|
+
['request:unhandled', { request, requestId }],
|
|
568
|
+
['request:end', { request, requestId }],
|
|
569
|
+
])
|
|
570
|
+
expect(options.onUnhandledRequest).toHaveBeenCalledTimes(1)
|
|
571
|
+
expect(handleRequestOptions.onPassthroughResponse).toHaveBeenCalledTimes(1)
|
|
572
|
+
})
|
|
573
|
+
})
|