@schmock/core 1.0.3 → 1.1.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/dist/builder.d.ts +13 -5
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +147 -60
- package/dist/constants.d.ts +6 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +20 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +3 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -11
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +2 -17
- package/dist/types.d.ts +17 -210
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/package.json +4 -4
- package/src/builder.test.ts +2 -2
- package/src/builder.ts +232 -108
- package/src/constants.test.ts +59 -0
- package/src/constants.ts +25 -0
- package/src/errors.ts +3 -1
- package/src/index.ts +41 -29
- package/src/namespace.test.ts +3 -2
- package/src/parser.property.test.ts +495 -0
- package/src/parser.ts +2 -20
- package/src/route-matching.test.ts +1 -1
- package/src/steps/async-support.steps.ts +101 -91
- package/src/steps/basic-usage.steps.ts +49 -36
- package/src/steps/developer-experience.steps.ts +110 -94
- package/src/steps/error-handling.steps.ts +90 -66
- package/src/steps/fluent-api.steps.ts +75 -72
- package/src/steps/http-methods.steps.ts +33 -33
- package/src/steps/performance-reliability.steps.ts +52 -88
- package/src/steps/plugin-integration.steps.ts +176 -176
- package/src/steps/request-history.steps.ts +333 -0
- package/src/steps/state-concurrency.steps.ts +418 -316
- package/src/steps/stateful-workflows.steps.ts +138 -136
- package/src/types.ts +20 -259
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describeFeature, loadFeature } from "@amiceli/vitest-cucumber";
|
|
2
2
|
import { expect } from "vitest";
|
|
3
3
|
import { schmock } from "../index";
|
|
4
|
-
import type { CallableMockInstance } from "../types";
|
|
4
|
+
import type { CallableMockInstance, Plugin, PluginContext } from "../types";
|
|
5
5
|
|
|
6
6
|
const feature = await loadFeature("../../features/developer-experience.feature");
|
|
7
7
|
|
|
@@ -9,12 +9,11 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
9
9
|
let mock: CallableMockInstance;
|
|
10
10
|
let response: any;
|
|
11
11
|
let responses: any[] = [];
|
|
12
|
-
let error: Error | null = null;
|
|
13
12
|
|
|
14
13
|
Scenario("Forgetting to provide response data", ({ Given, When, Then, And }) => {
|
|
15
|
-
Given("I create a mock
|
|
14
|
+
Given("I create a mock with no response data on {string}", (_, route: string) => {
|
|
16
15
|
mock = schmock();
|
|
17
|
-
mock(
|
|
16
|
+
mock(route as Schmock.RouteKey, undefined);
|
|
18
17
|
});
|
|
19
18
|
|
|
20
19
|
When("I request {string}", async (_, request: string) => {
|
|
@@ -32,9 +31,9 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
32
31
|
});
|
|
33
32
|
|
|
34
33
|
Scenario("Using wrong parameter name in route", ({ Given, When, Then }) => {
|
|
35
|
-
Given("I create a mock with parameter
|
|
34
|
+
Given("I create a mock with a mismatched parameter name on {string}", (_, route: string) => {
|
|
36
35
|
mock = schmock();
|
|
37
|
-
mock(
|
|
36
|
+
mock(route as Schmock.RouteKey, ({ params }) => ({ id: params.id }));
|
|
38
37
|
});
|
|
39
38
|
|
|
40
39
|
When("I request {string}", async (_, request: string) => {
|
|
@@ -48,9 +47,9 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
48
47
|
});
|
|
49
48
|
|
|
50
49
|
Scenario("Correct parameter usage", ({ Given, When, Then }) => {
|
|
51
|
-
Given("I create a mock with
|
|
50
|
+
Given("I create a mock with a matching parameter name on {string}", (_, route: string) => {
|
|
52
51
|
mock = schmock();
|
|
53
|
-
mock(
|
|
52
|
+
mock(route as Schmock.RouteKey, ({ params }) => ({ id: params.userId }));
|
|
54
53
|
});
|
|
55
54
|
|
|
56
55
|
When("I request {string}", async (_, request: string) => {
|
|
@@ -65,20 +64,20 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
65
64
|
});
|
|
66
65
|
|
|
67
66
|
Scenario("Mixing content types without explicit configuration", ({ Given, When, Then, And }) => {
|
|
68
|
-
Given("I create a mock with
|
|
67
|
+
Given("I create a mock with JSON, text, number, and boolean routes", () => {
|
|
69
68
|
mock = schmock();
|
|
70
|
-
mock(
|
|
71
|
-
mock(
|
|
72
|
-
mock(
|
|
73
|
-
mock(
|
|
69
|
+
mock("GET /json", { data: "json" });
|
|
70
|
+
mock("GET /text", "plain text");
|
|
71
|
+
mock("GET /number", 42);
|
|
72
|
+
mock("GET /boolean", true);
|
|
74
73
|
});
|
|
75
74
|
|
|
76
75
|
When("I test all mixed content type routes", async () => {
|
|
77
76
|
responses = [];
|
|
78
|
-
responses.push(await mock.handle(
|
|
79
|
-
responses.push(await mock.handle(
|
|
80
|
-
responses.push(await mock.handle(
|
|
81
|
-
responses.push(await mock.handle(
|
|
77
|
+
responses.push(await mock.handle("GET", "/json"));
|
|
78
|
+
responses.push(await mock.handle("GET", "/text"));
|
|
79
|
+
responses.push(await mock.handle("GET", "/number"));
|
|
80
|
+
responses.push(await mock.handle("GET", "/boolean"));
|
|
82
81
|
});
|
|
83
82
|
|
|
84
83
|
Then("JSON route should have content-type {string}", (_, contentType: string) => {
|
|
@@ -99,9 +98,9 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
99
98
|
});
|
|
100
99
|
|
|
101
100
|
Scenario("Expecting JSON but getting string conversion", ({ Given, When, Then, And }) => {
|
|
102
|
-
Given("I create a mock
|
|
101
|
+
Given("I create a mock returning a decimal number on {string}", (_, route: string) => {
|
|
103
102
|
mock = schmock();
|
|
104
|
-
mock(
|
|
103
|
+
mock(route as Schmock.RouteKey, 19.99);
|
|
105
104
|
});
|
|
106
105
|
|
|
107
106
|
When("I request {string}", async (_, request: string) => {
|
|
@@ -119,9 +118,9 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
119
118
|
});
|
|
120
119
|
|
|
121
120
|
Scenario("Forgetting await with async generators", ({ Given, When, Then, And }) => {
|
|
122
|
-
Given("I create a mock with async
|
|
121
|
+
Given("I create a mock with an async handler on {string}", (_, route: string) => {
|
|
123
122
|
mock = schmock();
|
|
124
|
-
mock(
|
|
123
|
+
mock(route as Schmock.RouteKey, async () => ({ async: true }));
|
|
125
124
|
});
|
|
126
125
|
|
|
127
126
|
When("I request {string}", async (_, request: string) => {
|
|
@@ -140,10 +139,11 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
140
139
|
});
|
|
141
140
|
|
|
142
141
|
Scenario("State confusion between global and local state", ({ Given, When, Then, And }) => {
|
|
143
|
-
Given("I create a mock with state
|
|
142
|
+
Given("I create a mock with global state and a local state counter", () => {
|
|
144
143
|
mock = schmock({ state: { global: 1 } });
|
|
145
|
-
mock(
|
|
146
|
-
|
|
144
|
+
mock("GET /counter", ({ state }) => {
|
|
145
|
+
const current = (state.local as number | undefined) || 0;
|
|
146
|
+
state.local = current + 1;
|
|
147
147
|
return { global: state.global, local: state.local };
|
|
148
148
|
});
|
|
149
149
|
});
|
|
@@ -167,19 +167,19 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
167
167
|
});
|
|
168
168
|
|
|
169
169
|
Scenario("Query parameter edge cases", ({ Given, When, Then }) => {
|
|
170
|
-
Given("I create a mock
|
|
170
|
+
Given("I create a mock that echoes query parameters on {string}", (_, route: string) => {
|
|
171
171
|
mock = schmock();
|
|
172
|
-
mock(
|
|
172
|
+
mock(route as Schmock.RouteKey, ({ query }) => ({
|
|
173
173
|
term: query.q,
|
|
174
174
|
page: query.page,
|
|
175
|
-
empty: query.empty
|
|
175
|
+
empty: query.empty,
|
|
176
176
|
}));
|
|
177
177
|
});
|
|
178
178
|
|
|
179
179
|
When("I request {string}", async (_, request: string) => {
|
|
180
180
|
const [method, fullPath] = request.split(" ");
|
|
181
181
|
const [path, queryString] = fullPath.split("?");
|
|
182
|
-
|
|
182
|
+
|
|
183
183
|
const query: Record<string, string> = {};
|
|
184
184
|
if (queryString) {
|
|
185
185
|
queryString.split("&").forEach((param) => {
|
|
@@ -187,7 +187,7 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
187
187
|
query[key] = value || "";
|
|
188
188
|
});
|
|
189
189
|
}
|
|
190
|
-
|
|
190
|
+
|
|
191
191
|
response = await mock.handle(method as any, path, { query });
|
|
192
192
|
});
|
|
193
193
|
|
|
@@ -198,12 +198,12 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
198
198
|
});
|
|
199
199
|
|
|
200
200
|
Scenario("Headers case sensitivity", ({ Given, When, Then }) => {
|
|
201
|
-
Given("I create a mock
|
|
201
|
+
Given("I create a mock that echoes headers on {string}", (_, route: string) => {
|
|
202
202
|
mock = schmock();
|
|
203
|
-
mock(
|
|
203
|
+
mock(route as Schmock.RouteKey, ({ headers }) => ({
|
|
204
204
|
auth: headers.authorization,
|
|
205
205
|
authUpper: headers.Authorization,
|
|
206
|
-
contentType: headers[
|
|
206
|
+
contentType: headers["content-type"],
|
|
207
207
|
}));
|
|
208
208
|
});
|
|
209
209
|
|
|
@@ -214,25 +214,25 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
214
214
|
});
|
|
215
215
|
|
|
216
216
|
Then("the header case sensitivity should show expected values", () => {
|
|
217
|
-
expect(response.body).toEqual({
|
|
218
|
-
auth: undefined,
|
|
219
|
-
authUpper: "Bearer token",
|
|
220
|
-
contentType: undefined
|
|
217
|
+
expect(response.body).toEqual({
|
|
218
|
+
auth: undefined,
|
|
219
|
+
authUpper: "Bearer token",
|
|
220
|
+
contentType: undefined,
|
|
221
221
|
});
|
|
222
222
|
});
|
|
223
223
|
});
|
|
224
224
|
|
|
225
225
|
Scenario("Route precedence with similar paths", ({ Given, When, Then, And }) => {
|
|
226
|
-
Given("I create a mock with
|
|
226
|
+
Given("I create a mock with an exact route and a parameterized route on {string}", (_, basePath: string) => {
|
|
227
227
|
mock = schmock();
|
|
228
|
-
mock(
|
|
229
|
-
mock(
|
|
228
|
+
mock(`GET ${basePath}/profile`, { type: "profile" });
|
|
229
|
+
mock(`GET ${basePath}/:id`, ({ params }) => ({ type: "user", id: params.id }));
|
|
230
230
|
});
|
|
231
231
|
|
|
232
232
|
When("I test both route precedence scenarios", async () => {
|
|
233
233
|
responses = [];
|
|
234
|
-
responses.push(await mock.handle(
|
|
235
|
-
responses.push(await mock.handle(
|
|
234
|
+
responses.push(await mock.handle("GET", "/users/profile"));
|
|
235
|
+
responses.push(await mock.handle("GET", "/users/123"));
|
|
236
236
|
});
|
|
237
237
|
|
|
238
238
|
Then("the profile route should return exact match:", (_, docString: string) => {
|
|
@@ -247,25 +247,23 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
247
247
|
});
|
|
248
248
|
|
|
249
249
|
Scenario("Plugin order affecting results", ({ Given, When, Then }) => {
|
|
250
|
-
Given("I create a mock with
|
|
250
|
+
Given("I create a mock with two plugins that each set a step number", () => {
|
|
251
251
|
mock = schmock();
|
|
252
|
-
const plugin1 = {
|
|
253
|
-
name:
|
|
254
|
-
process: (ctx:
|
|
252
|
+
const plugin1: Plugin = {
|
|
253
|
+
name: "first",
|
|
254
|
+
process: (ctx: PluginContext, response: unknown) => ({
|
|
255
255
|
context: ctx,
|
|
256
|
-
response: { ...response, step: 1 }
|
|
257
|
-
})
|
|
256
|
+
response: { ...(response as Record<string, unknown>), step: 1 },
|
|
257
|
+
}),
|
|
258
258
|
};
|
|
259
|
-
const plugin2 = {
|
|
260
|
-
name:
|
|
261
|
-
process: (ctx:
|
|
259
|
+
const plugin2: Plugin = {
|
|
260
|
+
name: "second",
|
|
261
|
+
process: (ctx: PluginContext, response: unknown) => ({
|
|
262
262
|
context: ctx,
|
|
263
|
-
response: { ...response, step: 2 }
|
|
264
|
-
})
|
|
263
|
+
response: { ...(response as Record<string, unknown>), step: 2 },
|
|
264
|
+
}),
|
|
265
265
|
};
|
|
266
|
-
mock(
|
|
267
|
-
.pipe(plugin1)
|
|
268
|
-
.pipe(plugin2);
|
|
266
|
+
mock("GET /order", { original: true }).pipe(plugin1).pipe(plugin2);
|
|
269
267
|
});
|
|
270
268
|
|
|
271
269
|
When("I request {string}", async (_, request: string) => {
|
|
@@ -280,15 +278,15 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
280
278
|
});
|
|
281
279
|
|
|
282
280
|
Scenario("Namespace confusion with absolute paths", ({ Given, When, Then, And }) => {
|
|
283
|
-
Given("I create a mock with namespace
|
|
284
|
-
mock = schmock({ namespace
|
|
285
|
-
mock(
|
|
281
|
+
Given("I create a mock with namespace {string} and a users route", (_, namespace: string) => {
|
|
282
|
+
mock = schmock({ namespace });
|
|
283
|
+
mock("GET /users", []);
|
|
286
284
|
});
|
|
287
285
|
|
|
288
286
|
When("I test both namespace scenarios", async () => {
|
|
289
287
|
responses = [];
|
|
290
|
-
responses.push(await mock.handle(
|
|
291
|
-
responses.push(await mock.handle(
|
|
288
|
+
responses.push(await mock.handle("GET", "/users"));
|
|
289
|
+
responses.push(await mock.handle("GET", "/api/v1/users"));
|
|
292
290
|
});
|
|
293
291
|
|
|
294
292
|
Then("the wrong namespace should receive status {int}", (_, status: number) => {
|
|
@@ -302,27 +300,27 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
302
300
|
});
|
|
303
301
|
|
|
304
302
|
Scenario("Plugin expecting different context structure", ({ Given, When, Then }) => {
|
|
305
|
-
Given("I create a mock with context
|
|
303
|
+
Given("I create a mock with a plugin that reads context properties", () => {
|
|
306
304
|
mock = schmock();
|
|
307
|
-
const plugin = {
|
|
308
|
-
name:
|
|
309
|
-
process: (ctx:
|
|
305
|
+
const plugin: Plugin = {
|
|
306
|
+
name: "context-reader",
|
|
307
|
+
process: (ctx: PluginContext, _response: unknown) => ({
|
|
310
308
|
context: ctx,
|
|
311
309
|
response: {
|
|
312
310
|
method: ctx.method,
|
|
313
311
|
path: ctx.path,
|
|
314
312
|
hasBody: !!ctx.body,
|
|
315
|
-
hasQuery: !!ctx.query && Object.keys(ctx.query).length > 0
|
|
316
|
-
}
|
|
317
|
-
})
|
|
313
|
+
hasQuery: !!ctx.query && Object.keys(ctx.query).length > 0,
|
|
314
|
+
},
|
|
315
|
+
}),
|
|
318
316
|
};
|
|
319
|
-
mock(
|
|
317
|
+
mock("POST /analyze", null).pipe(plugin);
|
|
320
318
|
});
|
|
321
319
|
|
|
322
320
|
When("I request {string} with body:", async (_, request: string, docString: string) => {
|
|
323
321
|
const [method, fullPath] = request.split(" ");
|
|
324
322
|
const [path, queryString] = fullPath.split("?");
|
|
325
|
-
|
|
323
|
+
|
|
326
324
|
const query: Record<string, string> = {};
|
|
327
325
|
if (queryString) {
|
|
328
326
|
queryString.split("&").forEach((param) => {
|
|
@@ -330,7 +328,7 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
330
328
|
query[key] = value || "";
|
|
331
329
|
});
|
|
332
330
|
}
|
|
333
|
-
|
|
331
|
+
|
|
334
332
|
const body = JSON.parse(docString);
|
|
335
333
|
response = await mock.handle(method as any, path, { body, query });
|
|
336
334
|
});
|
|
@@ -342,18 +340,18 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
342
340
|
});
|
|
343
341
|
|
|
344
342
|
Scenario("Response tuple format edge cases", ({ Given, When, Then, And }) => {
|
|
345
|
-
Given("I create a mock with tuple
|
|
343
|
+
Given("I create a mock with three tuple response routes", () => {
|
|
346
344
|
mock = schmock();
|
|
347
|
-
mock(
|
|
348
|
-
mock(
|
|
349
|
-
mock(
|
|
345
|
+
mock("GET /created", [201]);
|
|
346
|
+
mock("GET /with-headers", [200, { data: true }, { "x-custom": "header" }]);
|
|
347
|
+
mock("GET /empty-with-status", [204, null]);
|
|
350
348
|
});
|
|
351
349
|
|
|
352
350
|
When("I test all tuple response formats", async () => {
|
|
353
351
|
responses = [];
|
|
354
|
-
responses.push(await mock.handle(
|
|
355
|
-
responses.push(await mock.handle(
|
|
356
|
-
responses.push(await mock.handle(
|
|
352
|
+
responses.push(await mock.handle("GET", "/created"));
|
|
353
|
+
responses.push(await mock.handle("GET", "/with-headers"));
|
|
354
|
+
responses.push(await mock.handle("GET", "/empty-with-status"));
|
|
357
355
|
});
|
|
358
356
|
|
|
359
357
|
Then("the created endpoint should return status 201 with empty body", () => {
|
|
@@ -364,7 +362,7 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
364
362
|
And("the headers endpoint should return status 200 with data and custom header", () => {
|
|
365
363
|
expect(responses[1].status).toBe(200);
|
|
366
364
|
expect(responses[1].body).toEqual({ data: true });
|
|
367
|
-
expect(responses[1].headers?.[
|
|
365
|
+
expect(responses[1].headers?.["x-custom"]).toBe("header");
|
|
368
366
|
});
|
|
369
367
|
|
|
370
368
|
And("the empty endpoint should return status 204 with null body", () => {
|
|
@@ -376,18 +374,18 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
376
374
|
Scenario("Common typos in method names", ({ Given, When, Then, And }) => {
|
|
377
375
|
let errors: Error[] = [];
|
|
378
376
|
|
|
379
|
-
Given("I
|
|
377
|
+
Given("I create an empty mock for testing method typos", () => {
|
|
380
378
|
mock = schmock();
|
|
381
379
|
});
|
|
382
380
|
|
|
383
381
|
When("I test all common method typos", () => {
|
|
384
382
|
errors = [];
|
|
385
|
-
const typos = [
|
|
386
|
-
|
|
383
|
+
const typos = ["GETS /users", "post /users", "GET/users"];
|
|
384
|
+
|
|
387
385
|
for (const typo of typos) {
|
|
388
386
|
try {
|
|
389
|
-
mock(typo,
|
|
390
|
-
errors.push(new Error(
|
|
387
|
+
mock(typo as Schmock.RouteKey, "test");
|
|
388
|
+
errors.push(new Error("No error thrown"));
|
|
391
389
|
} catch (e) {
|
|
392
390
|
errors.push(e as Error);
|
|
393
391
|
}
|
|
@@ -396,31 +394,49 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
396
394
|
|
|
397
395
|
Then("the wrong method typo should throw RouteParseError", () => {
|
|
398
396
|
expect(errors[0]).not.toBeNull();
|
|
399
|
-
expect(errors[0].constructor.name).toBe(
|
|
400
|
-
expect(errors[0].message).toContain(
|
|
397
|
+
expect(errors[0].constructor.name).toBe("RouteParseError");
|
|
398
|
+
expect(errors[0].message).toContain("Invalid route key format");
|
|
401
399
|
});
|
|
402
400
|
|
|
403
401
|
And("the lowercase method typo should throw RouteParseError", () => {
|
|
404
402
|
expect(errors[1]).not.toBeNull();
|
|
405
|
-
expect(errors[1].constructor.name).toBe(
|
|
406
|
-
expect(errors[1].message).toContain(
|
|
403
|
+
expect(errors[1].constructor.name).toBe("RouteParseError");
|
|
404
|
+
expect(errors[1].message).toContain("Invalid route key format");
|
|
407
405
|
});
|
|
408
406
|
|
|
409
407
|
And("the missing space typo should throw RouteParseError", () => {
|
|
410
408
|
expect(errors[2]).not.toBeNull();
|
|
411
|
-
expect(errors[2].constructor.name).toBe(
|
|
412
|
-
expect(errors[2].message).toContain(
|
|
409
|
+
expect(errors[2].constructor.name).toBe("RouteParseError");
|
|
410
|
+
expect(errors[2].message).toContain("Invalid route key format");
|
|
411
|
+
});
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
Scenario("Registering duplicate routes first route wins", ({ Given, When, Then }) => {
|
|
415
|
+
Given("I create a mock with two routes on {string} with different data", (_, route: string) => {
|
|
416
|
+
mock = schmock();
|
|
417
|
+
mock(route as Schmock.RouteKey, [{ id: 1 }]);
|
|
418
|
+
mock(route as Schmock.RouteKey, [{ id: 2 }]);
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
When("I request {string}", async (_, request: string) => {
|
|
422
|
+
const [method, path] = request.split(" ");
|
|
423
|
+
response = await mock.handle(method as any, path);
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
Then("the first route response should win:", (_, docString: string) => {
|
|
427
|
+
const expected = JSON.parse(docString);
|
|
428
|
+
expect(response.body).toEqual(expected);
|
|
413
429
|
});
|
|
414
430
|
});
|
|
415
431
|
|
|
416
432
|
Scenario("Plugin returning unexpected structure", ({ Given, When, Then, And }) => {
|
|
417
|
-
Given("I create a mock with
|
|
433
|
+
Given("I create a mock with a plugin that returns an invalid structure", () => {
|
|
418
434
|
mock = schmock();
|
|
419
435
|
const badPlugin = {
|
|
420
|
-
name:
|
|
421
|
-
process: () => ({ wrong:
|
|
436
|
+
name: "bad-structure",
|
|
437
|
+
process: () => ({ wrong: "structure" }),
|
|
422
438
|
};
|
|
423
|
-
mock(
|
|
439
|
+
mock("GET /bad", "original").pipe(badPlugin as any);
|
|
424
440
|
});
|
|
425
441
|
|
|
426
442
|
When("I request {string}", async (_, request: string) => {
|
|
@@ -436,4 +452,4 @@ describeFeature(feature, ({ Scenario }) => {
|
|
|
436
452
|
expect(response.body.error).toContain(errorMessage);
|
|
437
453
|
});
|
|
438
454
|
});
|
|
439
|
-
});
|
|
455
|
+
});
|