@schmock/core 2.2.3 → 2.3.1
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/LICENSE +21 -0
- package/README.md +35 -0
- package/dist/abort.d.ts +3 -0
- package/dist/abort.d.ts.map +1 -0
- package/dist/abort.js +30 -0
- package/dist/binary.d.ts +8 -0
- package/dist/binary.d.ts.map +1 -0
- package/dist/binary.js +9 -0
- package/dist/builder.d.ts +31 -10
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +804 -203
- package/dist/constants.d.ts +38 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +123 -2
- package/dist/errors.d.ts +14 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +41 -6
- package/dist/helpers.d.ts +9 -0
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +18 -2
- package/dist/http-helpers.d.ts +52 -5
- package/dist/http-helpers.d.ts.map +1 -1
- package/dist/http-helpers.js +153 -37
- package/dist/index.d.ts +381 -60
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -3
- package/dist/interceptor.d.ts +11 -1
- package/dist/interceptor.d.ts.map +1 -1
- package/dist/interceptor.js +354 -156
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +12 -3
- package/dist/plugin-pipeline.d.ts +11 -4
- package/dist/plugin-pipeline.d.ts.map +1 -1
- package/dist/plugin-pipeline.js +117 -39
- package/dist/response-normalizer.d.ts +16 -0
- package/dist/response-normalizer.d.ts.map +1 -0
- package/dist/response-normalizer.js +316 -0
- package/dist/response-parser.d.ts.map +1 -1
- package/dist/response-parser.js +85 -18
- package/dist/route-matcher.d.ts +3 -0
- package/dist/route-matcher.d.ts.map +1 -1
- package/dist/route-matcher.js +12 -6
- package/dist/types.d.ts +7 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +18 -8
- package/src/audit-core-builder.test.ts +0 -218
- package/src/audit-response-guard.test.ts +0 -38
- package/src/builder.test.ts +0 -289
- package/src/builder.ts +0 -701
- package/src/constants.test.ts +0 -99
- package/src/constants.ts +0 -73
- package/src/debug.test.ts +0 -241
- package/src/delay.test.ts +0 -319
- package/src/dist-shape.test.ts +0 -35
- package/src/errors.test.ts +0 -223
- package/src/errors.ts +0 -130
- package/src/factory.test.ts +0 -133
- package/src/helpers.test.ts +0 -147
- package/src/helpers.ts +0 -58
- package/src/http-helpers.ts +0 -113
- package/src/index.ts +0 -151
- package/src/interceptor.test.ts +0 -291
- package/src/interceptor.ts +0 -320
- package/src/namespace.test.ts +0 -274
- package/src/parser.property.test.ts +0 -594
- package/src/parser.test.ts +0 -148
- package/src/parser.ts +0 -64
- package/src/plugin-pipeline.ts +0 -103
- package/src/plugin-system.test.ts +0 -602
- package/src/response-parser.ts +0 -75
- package/src/response-parsing.test.ts +0 -333
- package/src/route-matcher.ts +0 -69
- package/src/route-matching.test.ts +0 -394
- package/src/server.test.ts +0 -165
- package/src/smart-defaults.test.ts +0 -361
- package/src/steps/async-support.steps.ts +0 -400
- package/src/steps/audit-core-builder.steps.ts +0 -188
- package/src/steps/audit-onerror-tuple.steps.ts +0 -99
- package/src/steps/basic-usage.steps.ts +0 -245
- package/src/steps/developer-experience.steps.ts +0 -204
- package/src/steps/error-handling.steps.ts +0 -345
- package/src/steps/fluent-api.steps.ts +0 -255
- package/src/steps/http-methods.steps.ts +0 -331
- package/src/steps/interceptor.steps.ts +0 -260
- package/src/steps/lifecycle-events.steps.ts +0 -142
- package/src/steps/performance-reliability.steps.ts +0 -423
- package/src/steps/plugin-integration.steps.ts +0 -280
- package/src/steps/request-history.steps.ts +0 -276
- package/src/steps/response-delay.steps.ts +0 -88
- package/src/steps/route-key-format.steps.ts +0 -99
- package/src/steps/standalone-server.steps.ts +0 -233
- package/src/steps/state-concurrency.steps.ts +0 -739
- package/src/steps/stateful-workflows.steps.ts +0 -353
- package/src/types.ts +0 -36
package/src/namespace.test.ts
DELETED
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { schmock } from "./index";
|
|
3
|
-
|
|
4
|
-
describe("namespace functionality", () => {
|
|
5
|
-
describe("basic namespace behavior", () => {
|
|
6
|
-
it("applies namespace to all routes", async () => {
|
|
7
|
-
const mock = schmock({ namespace: "/api" });
|
|
8
|
-
mock("GET /users", "users");
|
|
9
|
-
mock("POST /users", "create-user");
|
|
10
|
-
|
|
11
|
-
const getResponse = await mock.handle("GET", "/api/users");
|
|
12
|
-
const postResponse = await mock.handle("POST", "/api/users");
|
|
13
|
-
|
|
14
|
-
expect(getResponse.body).toBe("users");
|
|
15
|
-
expect(postResponse.body).toBe("create-user");
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it("returns 404 for requests without namespace prefix", async () => {
|
|
19
|
-
const mock = schmock({ namespace: "/api" });
|
|
20
|
-
mock("GET /users", "users");
|
|
21
|
-
|
|
22
|
-
const response = await mock.handle("GET", "/users");
|
|
23
|
-
|
|
24
|
-
expect(response.status).toBe(404);
|
|
25
|
-
expect(response.body.error).toContain("Route not found: GET /users");
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it("handles nested namespaces", async () => {
|
|
29
|
-
const mock = schmock({ namespace: "/api/v1" });
|
|
30
|
-
mock("GET /users", "v1-users");
|
|
31
|
-
|
|
32
|
-
const response = await mock.handle("GET", "/api/v1/users");
|
|
33
|
-
|
|
34
|
-
expect(response.body).toBe("v1-users");
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it("works with root namespace", async () => {
|
|
38
|
-
const mock = schmock({ namespace: "/" });
|
|
39
|
-
mock("GET /users", "users");
|
|
40
|
-
|
|
41
|
-
const response = await mock.handle("GET", "/users");
|
|
42
|
-
|
|
43
|
-
expect(response.body).toBe("users");
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
describe("namespace with parameters", () => {
|
|
48
|
-
it("works with parameterized routes under namespace", async () => {
|
|
49
|
-
const mock = schmock({ namespace: "/api" });
|
|
50
|
-
mock("GET /users/:id", ({ params }) => ({ userId: params.id }));
|
|
51
|
-
|
|
52
|
-
const response = await mock.handle("GET", "/api/users/123");
|
|
53
|
-
|
|
54
|
-
expect(response.body).toEqual({ userId: "123" });
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("extracts parameters correctly after namespace removal", async () => {
|
|
58
|
-
const mock = schmock({ namespace: "/api/v1" });
|
|
59
|
-
mock("GET /users/:userId/posts/:postId", ({ params, path }) => ({
|
|
60
|
-
params,
|
|
61
|
-
processedPath: path,
|
|
62
|
-
}));
|
|
63
|
-
|
|
64
|
-
const response = await mock.handle("GET", "/api/v1/users/456/posts/789");
|
|
65
|
-
|
|
66
|
-
expect(response.body).toEqual({
|
|
67
|
-
params: { userId: "456", postId: "789" },
|
|
68
|
-
processedPath: "/users/456/posts/789",
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it("passes correct path to context after namespace stripping", async () => {
|
|
73
|
-
const mock = schmock({ namespace: "/api" });
|
|
74
|
-
mock("GET /test/:param", ({ path, params }) => ({
|
|
75
|
-
contextPath: path,
|
|
76
|
-
params,
|
|
77
|
-
}));
|
|
78
|
-
|
|
79
|
-
const response = await mock.handle("GET", "/api/test/value");
|
|
80
|
-
|
|
81
|
-
expect(response.body).toEqual({
|
|
82
|
-
contextPath: "/test/value",
|
|
83
|
-
params: { param: "value" },
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
describe("namespace edge cases", () => {
|
|
89
|
-
it("handles namespace with trailing slash", async () => {
|
|
90
|
-
const mock = schmock({ namespace: "/api/" });
|
|
91
|
-
mock("GET /users", "users");
|
|
92
|
-
|
|
93
|
-
// Should work with or without the trailing slash in the request
|
|
94
|
-
const response1 = await mock.handle("GET", "/api/users");
|
|
95
|
-
const response2 = await mock.handle("GET", "/api//users");
|
|
96
|
-
|
|
97
|
-
expect(response1.body).toBe("users");
|
|
98
|
-
// New logic gracefully handles double slashes by stripping the full namespace
|
|
99
|
-
expect(response2.status).toBe(200);
|
|
100
|
-
expect(response2.body).toBe("users");
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it("handles empty namespace", async () => {
|
|
104
|
-
const mock = schmock({ namespace: "" });
|
|
105
|
-
mock("GET /users", "users");
|
|
106
|
-
|
|
107
|
-
const response = await mock.handle("GET", "/users");
|
|
108
|
-
|
|
109
|
-
expect(response.body).toBe("users");
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
it("handles namespace without leading slash", async () => {
|
|
113
|
-
const mock = schmock({ namespace: "api" });
|
|
114
|
-
mock("GET /users", "users");
|
|
115
|
-
|
|
116
|
-
const response = await mock.handle("GET", "api/users");
|
|
117
|
-
|
|
118
|
-
expect(response.body).toBe("users");
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it("rejects requests that partially match namespace", async () => {
|
|
122
|
-
const mock = schmock({ namespace: "/api" });
|
|
123
|
-
mock("GET /users", "users");
|
|
124
|
-
|
|
125
|
-
const response1 = await mock.handle("GET", "/ap/users");
|
|
126
|
-
const response2 = await mock.handle("GET", "/apiextra/users");
|
|
127
|
-
|
|
128
|
-
expect(response1.status).toBe(404);
|
|
129
|
-
expect(response2.status).toBe(404);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it("handles very long namespaces", async () => {
|
|
133
|
-
const longNamespace =
|
|
134
|
-
"/api/v1/internal/microservice/health/monitoring/endpoints";
|
|
135
|
-
const mock = schmock({ namespace: longNamespace });
|
|
136
|
-
mock("GET /status", "healthy");
|
|
137
|
-
|
|
138
|
-
const response = await mock.handle("GET", `${longNamespace}/status`);
|
|
139
|
-
|
|
140
|
-
expect(response.body).toBe("healthy");
|
|
141
|
-
});
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
describe("namespace without routes", () => {
|
|
145
|
-
it("returns 404 when no routes defined", async () => {
|
|
146
|
-
const mock = schmock({ namespace: "/api" });
|
|
147
|
-
|
|
148
|
-
const response = await mock.handle("GET", "/api/anything");
|
|
149
|
-
|
|
150
|
-
expect(response.status).toBe(404);
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
it("returns 404 for namespace root when no root route", async () => {
|
|
154
|
-
const mock = schmock({ namespace: "/api" });
|
|
155
|
-
mock("GET /users", "users");
|
|
156
|
-
|
|
157
|
-
const response = await mock.handle("GET", "/api");
|
|
158
|
-
|
|
159
|
-
expect(response.status).toBe(404);
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it("supports root route under namespace", async () => {
|
|
163
|
-
const mock = schmock({ namespace: "/api" });
|
|
164
|
-
mock("GET /", "api-root");
|
|
165
|
-
|
|
166
|
-
const response = await mock.handle("GET", "/api/");
|
|
167
|
-
|
|
168
|
-
expect(response.body).toBe("api-root");
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
describe("namespace with global state", () => {
|
|
173
|
-
it("maintains global state across namespaced routes", async () => {
|
|
174
|
-
const mock = schmock({
|
|
175
|
-
namespace: "/api",
|
|
176
|
-
state: { counter: 0 },
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
mock("POST /increment", ({ state }) => {
|
|
180
|
-
state.counter++;
|
|
181
|
-
return { counter: state.counter };
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
mock("GET /count", ({ state }) => ({ counter: state.counter }));
|
|
185
|
-
|
|
186
|
-
await mock.handle("POST", "/api/increment");
|
|
187
|
-
await mock.handle("POST", "/api/increment");
|
|
188
|
-
const response = await mock.handle("GET", "/api/count");
|
|
189
|
-
|
|
190
|
-
expect(response.body).toEqual({ counter: 2 });
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
describe("namespace with plugins", () => {
|
|
195
|
-
it("works correctly with plugin pipeline", async () => {
|
|
196
|
-
const mock = schmock({ namespace: "/api" });
|
|
197
|
-
|
|
198
|
-
const plugin = {
|
|
199
|
-
name: "namespace-plugin",
|
|
200
|
-
process: (ctx: any, res: any) => {
|
|
201
|
-
return {
|
|
202
|
-
context: ctx,
|
|
203
|
-
response: {
|
|
204
|
-
...res,
|
|
205
|
-
namespacedPath: ctx.path,
|
|
206
|
-
},
|
|
207
|
-
};
|
|
208
|
-
},
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
mock("GET /users", { users: [] }).pipe(plugin);
|
|
212
|
-
|
|
213
|
-
const response = await mock.handle("GET", "/api/users");
|
|
214
|
-
|
|
215
|
-
expect(response.body).toEqual({
|
|
216
|
-
users: [],
|
|
217
|
-
namespacedPath: "/users", // Should be the path after namespace removal
|
|
218
|
-
});
|
|
219
|
-
});
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
describe("special characters in namespace", () => {
|
|
223
|
-
it("handles namespace with special characters", async () => {
|
|
224
|
-
const mock = schmock({ namespace: "/api-v1.2" });
|
|
225
|
-
mock("GET /users", "users");
|
|
226
|
-
|
|
227
|
-
const response = await mock.handle("GET", "/api-v1.2/users");
|
|
228
|
-
|
|
229
|
-
expect(response.body).toBe("users");
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
it("handles namespace with underscores", async () => {
|
|
233
|
-
const mock = schmock({ namespace: "/my_api" });
|
|
234
|
-
mock("GET /test", "test");
|
|
235
|
-
|
|
236
|
-
const response = await mock.handle("GET", "/my_api/test");
|
|
237
|
-
|
|
238
|
-
expect(response.body).toBe("test");
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
it("handles namespace with numbers", async () => {
|
|
242
|
-
const mock = schmock({ namespace: "/api2" });
|
|
243
|
-
mock("GET /version", "v2");
|
|
244
|
-
|
|
245
|
-
const response = await mock.handle("GET", "/api2/version");
|
|
246
|
-
|
|
247
|
-
expect(response.body).toBe("v2");
|
|
248
|
-
});
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
describe("namespace error messages", () => {
|
|
252
|
-
it("provides clear error message for namespace mismatch", async () => {
|
|
253
|
-
const mock = schmock({ namespace: "/api/v1" });
|
|
254
|
-
mock("GET /users", "users");
|
|
255
|
-
|
|
256
|
-
const response = await mock.handle("GET", "/api/v2/users");
|
|
257
|
-
|
|
258
|
-
expect(response.status).toBe(404);
|
|
259
|
-
expect(response.body.error).toContain(
|
|
260
|
-
"Route not found: GET /api/v2/users",
|
|
261
|
-
);
|
|
262
|
-
expect(response.body.code).toBe("ROUTE_NOT_FOUND");
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
it("includes original requested path in error", async () => {
|
|
266
|
-
const mock = schmock({ namespace: "/api" });
|
|
267
|
-
mock("GET /users", "users");
|
|
268
|
-
|
|
269
|
-
const response = await mock.handle("GET", "/wrong/path");
|
|
270
|
-
|
|
271
|
-
expect(response.body.error).toContain("/wrong/path");
|
|
272
|
-
});
|
|
273
|
-
});
|
|
274
|
-
});
|