@jaypie/testkit 1.0.19 → 1.0.21
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/README.md +83 -8
- package/package.json +13 -5
- package/src/constants.js +28 -0
- package/src/index.js +5 -12
- package/src/jaypie.mock.js +206 -0
- package/src/matchers/toMatch.matcher.js +76 -0
- package/src/matchers.module.js +17 -0
- package/src/mockLog.module.js +4 -0
package/README.md
CHANGED
|
@@ -12,21 +12,33 @@ npm install --save-dev @jaypie/testkit
|
|
|
12
12
|
|
|
13
13
|
### Example
|
|
14
14
|
|
|
15
|
+
#### Mocking Jaypie
|
|
16
|
+
|
|
17
|
+
The testkit provides a complete mock for Jaypie including:
|
|
18
|
+
|
|
19
|
+
* Log spying (`expect(log.warn).toHaveBeenCalled()`)
|
|
20
|
+
* Default responses for runtime-only functions (`connect`, `sendMessage`, `submitMetric`)
|
|
21
|
+
* No automatic error handling for handlers (which is good in production but obfuscates tests)
|
|
22
|
+
* Most non-utility functions are mocked to allow simple testing
|
|
23
|
+
|
|
24
|
+
```javascript
|
|
25
|
+
vi.mock("jaypie", vi.importActual("@jaypie/testkit"));
|
|
26
|
+
```
|
|
27
|
+
|
|
15
28
|
#### Log Spying
|
|
16
29
|
|
|
17
30
|
```javascript
|
|
18
|
-
import {
|
|
19
|
-
|
|
31
|
+
import { log } from "jaypie";
|
|
32
|
+
|
|
33
|
+
vi.mock("jaypie", vi.importActual("@jaypie/testkit"));
|
|
20
34
|
|
|
21
|
-
beforeEach(() => {
|
|
22
|
-
spyLog(log);
|
|
23
|
-
});
|
|
24
35
|
afterEach(() => {
|
|
25
|
-
restoreLog(log);
|
|
26
36
|
vi.clearAllMocks();
|
|
27
37
|
});
|
|
28
38
|
|
|
29
39
|
test("log", () => {
|
|
40
|
+
expect(vi.isMockFunction(log.warn)).toBe(true);
|
|
41
|
+
expect(log.warn).not.toHaveBeenCalled();
|
|
30
42
|
log.warn("Danger");
|
|
31
43
|
expect(log.warn).toHaveBeenCalled();
|
|
32
44
|
expect(log.error).not.toHaveBeenCalled();
|
|
@@ -117,6 +129,30 @@ A [JSON Schema](https://json-schema.org/) validator for the [JSON:API](https://j
|
|
|
117
129
|
|
|
118
130
|
### `matchers`
|
|
119
131
|
|
|
132
|
+
```javascript
|
|
133
|
+
export default {
|
|
134
|
+
toBeCalledWithInitialParams,
|
|
135
|
+
toBeClass,
|
|
136
|
+
toBeJaypieError,
|
|
137
|
+
toBeValidSchema: jsonSchemaMatchers.toBeValidSchema,
|
|
138
|
+
toMatchBase64,
|
|
139
|
+
toMatchJwt,
|
|
140
|
+
toMatchMongoId,
|
|
141
|
+
toMatchSchema: jsonSchemaMatchers.toMatchSchema,
|
|
142
|
+
toMatchSignedCookie,
|
|
143
|
+
toMatchUuid4,
|
|
144
|
+
toMatchUuid5,
|
|
145
|
+
toMatchUuid,
|
|
146
|
+
toThrowBadRequestError,
|
|
147
|
+
toThrowConfigurationError,
|
|
148
|
+
toThrowForbiddenError,
|
|
149
|
+
toThrowInternalError,
|
|
150
|
+
toThrowJaypieError,
|
|
151
|
+
toThrowNotFoundError,
|
|
152
|
+
toThrowUnauthorizedError,
|
|
153
|
+
};
|
|
154
|
+
```
|
|
155
|
+
|
|
120
156
|
testSetup.js
|
|
121
157
|
|
|
122
158
|
```javascript
|
|
@@ -174,6 +210,45 @@ expect(json).not.toMatchSchema(jsonApiSchema);
|
|
|
174
210
|
|
|
175
211
|
From `jest-json-schema`; see [README](https://github.com/americanexpress/jest-json-schema?tab=readme-ov-file#tomatchschemaschema)
|
|
176
212
|
|
|
213
|
+
|
|
214
|
+
#### `expect(subject).toMatch*()` Regular Expression Matchers
|
|
215
|
+
|
|
216
|
+
Note: these regular expressions matchers so not verify the value is value, only that it matches the pattern (it "looks like" something). For example, `expect("123e4567-e89b-12d3-a456-426614174000").toMatchUuid()` will pass because the string matches a UUID pattern, even though it is not a valid UUID.
|
|
217
|
+
|
|
218
|
+
* `toMatchBase64`
|
|
219
|
+
* `toMatchJwt`
|
|
220
|
+
* `toMatchMongoId`
|
|
221
|
+
* `toMatchSignedCookie`
|
|
222
|
+
* `toMatchUuid4`
|
|
223
|
+
* `toMatchUuid5`
|
|
224
|
+
* `toMatchUuid`
|
|
225
|
+
|
|
226
|
+
#### `expect(subject).toThrowJaypieError()`
|
|
227
|
+
|
|
228
|
+
```javascript
|
|
229
|
+
import { ConfigurationError } from "@jaypie/core";
|
|
230
|
+
|
|
231
|
+
const error = new ConfigurationError();
|
|
232
|
+
expect(() => {
|
|
233
|
+
throw error;
|
|
234
|
+
}).toThrowJaypieError();
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Do not forget to `await expect` when passing `async` functions:
|
|
238
|
+
|
|
239
|
+
```javascript
|
|
240
|
+
import { ConfigurationError } from "@jaypie/core";
|
|
241
|
+
|
|
242
|
+
const error = new ConfigurationError();
|
|
243
|
+
await expect(async () => {
|
|
244
|
+
throw error;
|
|
245
|
+
}).toThrowJaypieError();
|
|
246
|
+
|
|
247
|
+
// Breaks and causes a false-positive because `expect` did not `await`
|
|
248
|
+
// expect(async () => {}).toThrowJaypieError();
|
|
249
|
+
// > Error: Expected function to throw a JaypieError, but it did not throw.
|
|
250
|
+
```
|
|
251
|
+
|
|
177
252
|
### `mockLogFactory()`
|
|
178
253
|
|
|
179
254
|
Creates a mock of the `log` provided by `@jaypie/core`.
|
|
@@ -193,7 +268,7 @@ Restores the `log` provided by `@jaypie/core`, commonly performed `afterEach` wi
|
|
|
193
268
|
|
|
194
269
|
### `spyLog(log)`
|
|
195
270
|
|
|
196
|
-
Spies on the `log` provided by `@jaypie/core`, commonly performed `beforeEach` with `restoreLog` in `afterEach`.
|
|
271
|
+
Spies on the `log` provided by `@jaypie/core`, commonly performed `beforeEach` with `restoreLog` in `afterEach`. Not necessary when mocking the entire Jaypie module.
|
|
197
272
|
|
|
198
273
|
```javascript
|
|
199
274
|
import { restoreLog, spyLog } from "@jaypie/testkit";
|
|
@@ -234,13 +309,13 @@ const event = sqsTestRecords(
|
|
|
234
309
|
* matcher toBeJaypieData
|
|
235
310
|
* matcher toBeJaypieDataObject
|
|
236
311
|
* matcher toBeJaypieDataArray
|
|
237
|
-
* matcher toThrowJaypieError
|
|
238
312
|
* ...@knowdev/jest
|
|
239
313
|
|
|
240
314
|
## 📝 Changelog
|
|
241
315
|
|
|
242
316
|
| Date | Version | Summary |
|
|
243
317
|
| ---------- | ------- | -------------- |
|
|
318
|
+
| 7/16/2024 | 1.0.21 | Export Jaypie mock as default |
|
|
244
319
|
| 3/20/2024 | 1.0.2 | Export `LOG` |
|
|
245
320
|
| 3/16/2024 | 1.0.0 | Artists ship |
|
|
246
321
|
| 3/15/2024 | 0.1.0 | Initial deploy |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jaypie/testkit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.21",
|
|
4
4
|
"author": "Finlayson Studio",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -8,11 +8,20 @@
|
|
|
8
8
|
"format": "npm run format:package && npm run format:lint",
|
|
9
9
|
"format:lint": "eslint --fix .",
|
|
10
10
|
"format:package": "sort-package-json ./package.json",
|
|
11
|
+
"init:commander": "hygen jaypie commander-init",
|
|
11
12
|
"init:deploy": "hygen jaypie workflow-npm",
|
|
12
13
|
"lint": "eslint .",
|
|
13
14
|
"new": "hygen jaypie vite",
|
|
15
|
+
"new:command": "hygen jaypie command",
|
|
16
|
+
"new:constants": "hygen jaypie constants",
|
|
17
|
+
"new:hygen": "hygen jaypie hygen",
|
|
18
|
+
"new:index": "hygen jaypie index",
|
|
19
|
+
"new:model": "hygen jaypie model",
|
|
20
|
+
"new:test": "hygen jaypie vitest",
|
|
14
21
|
"test": "vitest",
|
|
22
|
+
"test:spec:constants": "vitest run ./src/__tests__/constants.spec.js",
|
|
15
23
|
"test:spec:index": "vitest run ./src/__tests__/index.spec.js",
|
|
24
|
+
"test:spec:jaypie.mock": "vitest run ./src/__tests__/jaypie.mock.spec.js",
|
|
16
25
|
"test:spec:jsonApiSchema.module": "vitest run ./src/__tests__/jsonApiSchema.module.spec.js",
|
|
17
26
|
"test:spec:matchers.module": "vitest run ./src/__tests__/matchers.module.spec.js",
|
|
18
27
|
"test:spec:mockLog.module": "vitest run ./src/__tests__/mockLog.module.spec.js",
|
|
@@ -20,20 +29,19 @@
|
|
|
20
29
|
"test:spec:toBeCalledWithInitialParams.matcher": "vitest run ./src/matchers/__tests__/toBeCalledWithInitialParams.matcher.spec.js",
|
|
21
30
|
"test:spec:toBeClass.matcher": "vitest run ./src/matchers/__tests__/toBeClass.matcher.spec.js",
|
|
22
31
|
"test:spec:toBeJaypieError.matcher": "vitest run ./src/matchers/__tests__/toBeJaypieError.matcher.spec.js",
|
|
32
|
+
"test:spec:toMatch.matcher": "vitest run ./src/matchers/__tests__/toMatch.matcher.spec.js",
|
|
23
33
|
"test:spec:toThrowJaypieError.matcher": "vitest run ./src/matchers/__tests__/toThrowJaypieError.matcher.spec.js"
|
|
24
34
|
},
|
|
25
35
|
"dependencies": {
|
|
26
36
|
"@jaypie/core": "^1.0.33",
|
|
37
|
+
"jaypie": "^1.0.44",
|
|
27
38
|
"jest-json-schema": "^6.1.0",
|
|
28
39
|
"lodash.isequal": "^4.5.0",
|
|
29
40
|
"uuid": "^9.0.1"
|
|
30
41
|
},
|
|
31
42
|
"devDependencies": {
|
|
32
43
|
"eslint": "^8.57.0",
|
|
33
|
-
"eslint-config-
|
|
34
|
-
"eslint-plugin-import": "^2.29.1",
|
|
35
|
-
"eslint-plugin-prettier": "^5.1.3",
|
|
36
|
-
"eslint-plugin-vitest": "^0.3.26",
|
|
44
|
+
"eslint-config-jaypie": "^1.0.7",
|
|
37
45
|
"hygen": "^6.2.11",
|
|
38
46
|
"jest-extended": "^4.0.2",
|
|
39
47
|
"prettier": "^3.2.5",
|
package/src/constants.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//
|
|
2
|
+
//
|
|
3
|
+
// Constants
|
|
4
|
+
//
|
|
5
|
+
|
|
6
|
+
export const LOG = {
|
|
7
|
+
LEVEL: {
|
|
8
|
+
ALL: "all",
|
|
9
|
+
DEBUG: "debug",
|
|
10
|
+
ERROR: "error",
|
|
11
|
+
FATAL: "fatal",
|
|
12
|
+
INFO: "info",
|
|
13
|
+
SILENT: "silent",
|
|
14
|
+
TRACE: "trace",
|
|
15
|
+
WARN: "warn",
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const RE_BASE64_PATTERN = /^[a-zA-Z0-9\\+\\/]+$/;
|
|
20
|
+
export const RE_JWT_PATTERN = /^([^.]+)\.([^.]+)\.([^.]+)$/;
|
|
21
|
+
export const RE_MONGO_ID_PATTERN = /^[a-f0-9]{24}$/i;
|
|
22
|
+
export const RE_SIGNED_COOKIE_PATTERN = /^s:([^.]+)\.([^.]+)$/;
|
|
23
|
+
export const RE_UUID_4_PATTERN =
|
|
24
|
+
/^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$/i;
|
|
25
|
+
export const RE_UUID_5_PATTERN =
|
|
26
|
+
/^[a-f0-9]{8}-?[a-f0-9]{4}-?5[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$/i;
|
|
27
|
+
export const RE_UUID_PATTERN =
|
|
28
|
+
/^[a-f0-9]{8}-?[a-f0-9]{4}-?[a-f0-9]{4}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$/i;
|
package/src/index.js
CHANGED
|
@@ -1,20 +1,11 @@
|
|
|
1
|
+
import * as mockingJay from "./jaypie.mock.js";
|
|
2
|
+
|
|
1
3
|
//
|
|
2
4
|
//
|
|
3
5
|
// Constants
|
|
4
6
|
//
|
|
5
7
|
|
|
6
|
-
export
|
|
7
|
-
LEVEL: {
|
|
8
|
-
ALL: "all",
|
|
9
|
-
DEBUG: "debug",
|
|
10
|
-
ERROR: "error",
|
|
11
|
-
FATAL: "fatal",
|
|
12
|
-
INFO: "info",
|
|
13
|
-
SILENT: "silent",
|
|
14
|
-
TRACE: "trace",
|
|
15
|
-
WARN: "warn",
|
|
16
|
-
},
|
|
17
|
-
};
|
|
8
|
+
export { LOG } from "./constants.js";
|
|
18
9
|
|
|
19
10
|
//
|
|
20
11
|
//
|
|
@@ -25,3 +16,5 @@ export { jsonApiErrorSchema, jsonApiSchema } from "./jsonApiSchema.module.js";
|
|
|
25
16
|
export { default as matchers } from "./matchers.module.js";
|
|
26
17
|
export { mockLogFactory, restoreLog, spyLog } from "./mockLog.module.js";
|
|
27
18
|
export { default as sqsTestRecords } from "./sqsTestRecords.function.js";
|
|
19
|
+
|
|
20
|
+
export default mockingJay;
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { getMessages as originalGetMessages } from "@jaypie/aws";
|
|
2
|
+
import { force, uuid as originalUuid } from "@jaypie/core";
|
|
3
|
+
import { BadRequestError, JAYPIE, log, UnavailableError } from "@jaypie/core";
|
|
4
|
+
import { beforeAll, vi } from "vitest";
|
|
5
|
+
|
|
6
|
+
import { spyLog } from "./mockLog.module.js";
|
|
7
|
+
|
|
8
|
+
//
|
|
9
|
+
//
|
|
10
|
+
// Setup
|
|
11
|
+
//
|
|
12
|
+
|
|
13
|
+
const TAG = JAYPIE.LIB.TESTKIT;
|
|
14
|
+
|
|
15
|
+
// Export all the modules from Jaypie packages:
|
|
16
|
+
|
|
17
|
+
export * from "@jaypie/aws";
|
|
18
|
+
export * from "@jaypie/core";
|
|
19
|
+
export * from "@jaypie/express";
|
|
20
|
+
export * from "@jaypie/datadog";
|
|
21
|
+
export * from "@jaypie/lambda";
|
|
22
|
+
export * from "@jaypie/mongoose";
|
|
23
|
+
|
|
24
|
+
// Spy on log:
|
|
25
|
+
|
|
26
|
+
beforeAll(() => {
|
|
27
|
+
spyLog(log);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// afterEach(() => {
|
|
31
|
+
// This is not necessary because the log isn't being used outside tests:
|
|
32
|
+
// restoreLog(log);
|
|
33
|
+
// The is the client's responsibility:
|
|
34
|
+
// vi.clearAllMocks();
|
|
35
|
+
// });
|
|
36
|
+
|
|
37
|
+
//
|
|
38
|
+
//
|
|
39
|
+
// Mock Functions
|
|
40
|
+
//
|
|
41
|
+
|
|
42
|
+
// @jaypie/aws
|
|
43
|
+
|
|
44
|
+
export const getMessages = vi.fn((...params) => originalGetMessages(...params));
|
|
45
|
+
|
|
46
|
+
export const getSecret = vi.fn(() => {
|
|
47
|
+
return `_MOCK_SECRET_[${TAG}]`;
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export const sendBatchMessages = vi.fn(() => {
|
|
51
|
+
// TODO: better default value
|
|
52
|
+
return { value: `_MOCK_BATCH_MESSAGES_[${TAG}]` };
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
export const sendMessage = vi.fn(() => {
|
|
56
|
+
// TODO: better default value
|
|
57
|
+
return { value: `_MOCK_MESSAGE_[${TAG}]` };
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// @jaypie/core Functions
|
|
61
|
+
|
|
62
|
+
export const envBoolean = vi.fn(() => {
|
|
63
|
+
return true;
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
export const jaypieHandler = vi.fn(
|
|
67
|
+
(
|
|
68
|
+
handler,
|
|
69
|
+
{
|
|
70
|
+
setup = [],
|
|
71
|
+
teardown = [],
|
|
72
|
+
unavailable = force.boolean(process.env.PROJECT_UNAVAILABLE),
|
|
73
|
+
validate = [],
|
|
74
|
+
} = {},
|
|
75
|
+
) => {
|
|
76
|
+
return async (...args) => {
|
|
77
|
+
let result;
|
|
78
|
+
let thrownError;
|
|
79
|
+
if (unavailable) throw new UnavailableError();
|
|
80
|
+
for (const validator of validate) {
|
|
81
|
+
if (typeof validator === "function") {
|
|
82
|
+
const valid = await validator(...args);
|
|
83
|
+
if (valid === false) {
|
|
84
|
+
throw new BadRequestError();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
for (const setupFunction of setup) {
|
|
90
|
+
if (typeof setupFunction === "function") {
|
|
91
|
+
await setupFunction(...args);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
result = handler(...args);
|
|
95
|
+
} catch (error) {
|
|
96
|
+
thrownError = error;
|
|
97
|
+
}
|
|
98
|
+
for (const teardownFunction of teardown) {
|
|
99
|
+
if (typeof teardownFunction === "function") {
|
|
100
|
+
try {
|
|
101
|
+
await teardownFunction(...args);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
// eslint-disable-next-line no-console
|
|
104
|
+
console.error(error);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (thrownError) {
|
|
109
|
+
throw thrownError;
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
};
|
|
113
|
+
},
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
export const sleep = vi.fn(() => {
|
|
117
|
+
return true;
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
export const uuid = vi.fn(originalUuid);
|
|
121
|
+
|
|
122
|
+
// @jaypie/datadog
|
|
123
|
+
|
|
124
|
+
export const submitMetric = vi.fn(() => {
|
|
125
|
+
return true;
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
export const submitMetricSet = vi.fn(() => {
|
|
129
|
+
return true;
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// @jaypie/express
|
|
133
|
+
|
|
134
|
+
export const expressHandler = vi.fn((handler, props = {}) => {
|
|
135
|
+
if (typeof handler !== "function") {
|
|
136
|
+
throw new BadRequestError("handler must be a function");
|
|
137
|
+
}
|
|
138
|
+
if (!props) {
|
|
139
|
+
props = {};
|
|
140
|
+
}
|
|
141
|
+
props.setup = force.array(props.setup); // allows a single item
|
|
142
|
+
props.teardown = force.array(props.teardown); // allows a single item
|
|
143
|
+
if (!Array.isArray(props.setup)) {
|
|
144
|
+
props.setup = [];
|
|
145
|
+
}
|
|
146
|
+
if (props.locals === null) {
|
|
147
|
+
throw new BadRequestError("locals cannot be null");
|
|
148
|
+
}
|
|
149
|
+
if (props.locals) {
|
|
150
|
+
if (typeof props.locals !== "object" || Array.isArray(props.locals)) {
|
|
151
|
+
throw new BadRequestError("locals must be an object");
|
|
152
|
+
}
|
|
153
|
+
// Locals
|
|
154
|
+
const keys = Object.keys(props.locals);
|
|
155
|
+
if (keys.length > 0) {
|
|
156
|
+
props.setup.push((req = {}) => {
|
|
157
|
+
if (typeof req !== "object") {
|
|
158
|
+
throw new BadRequestError("req must be an object");
|
|
159
|
+
}
|
|
160
|
+
// Set req.locals if it doesn't exist
|
|
161
|
+
if (!req.locals) req.locals = {};
|
|
162
|
+
if (typeof req.locals !== "object" || Array.isArray(req.locals)) {
|
|
163
|
+
throw new BadRequestError("req.locals must be an object");
|
|
164
|
+
}
|
|
165
|
+
if (!req.locals._jaypie) req.locals._jaypie = {};
|
|
166
|
+
});
|
|
167
|
+
const localsSetup = async (localsReq, localsRes) => {
|
|
168
|
+
for (let i = 0; i < keys.length; i += 1) {
|
|
169
|
+
const key = keys[i];
|
|
170
|
+
if (typeof props.locals[key] === "function") {
|
|
171
|
+
// eslint-disable-next-line no-await-in-loop
|
|
172
|
+
localsReq.locals[key] = await props.locals[key](
|
|
173
|
+
localsReq,
|
|
174
|
+
localsRes,
|
|
175
|
+
);
|
|
176
|
+
} else {
|
|
177
|
+
localsReq.locals[key] = props.locals[key];
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
props.setup.push(localsSetup);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return jaypieHandler(handler, props);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// @jaypie/lambda
|
|
188
|
+
|
|
189
|
+
// For testing, this is the same as the jaypieHandler
|
|
190
|
+
export const lambdaHandler = vi.fn((handler, props = {}) => {
|
|
191
|
+
return jaypieHandler(handler, props);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// @jaypie/mongoose
|
|
195
|
+
|
|
196
|
+
export const connect = vi.fn(() => {
|
|
197
|
+
return true;
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
export const connectFromSecretEnv = vi.fn(() => {
|
|
201
|
+
return true;
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
export const disconnect = vi.fn(() => {
|
|
205
|
+
return true;
|
|
206
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RE_BASE64_PATTERN,
|
|
3
|
+
RE_JWT_PATTERN,
|
|
4
|
+
RE_MONGO_ID_PATTERN,
|
|
5
|
+
RE_SIGNED_COOKIE_PATTERN,
|
|
6
|
+
RE_UUID_4_PATTERN,
|
|
7
|
+
RE_UUID_5_PATTERN,
|
|
8
|
+
RE_UUID_PATTERN,
|
|
9
|
+
} from "../constants.js";
|
|
10
|
+
|
|
11
|
+
//
|
|
12
|
+
//
|
|
13
|
+
// Helper
|
|
14
|
+
//
|
|
15
|
+
|
|
16
|
+
function forSubjectToMatchPattern(
|
|
17
|
+
subject,
|
|
18
|
+
pattern,
|
|
19
|
+
{ patternName = "pattern" } = {},
|
|
20
|
+
) {
|
|
21
|
+
if (pattern.test(subject)) {
|
|
22
|
+
return {
|
|
23
|
+
message: () => `expected "${subject}" not to match ${patternName}`,
|
|
24
|
+
pass: true,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
message: () => `expected "${subject}" to match ${patternName}`,
|
|
29
|
+
pass: false,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
//
|
|
34
|
+
//
|
|
35
|
+
// Main
|
|
36
|
+
//
|
|
37
|
+
|
|
38
|
+
export const toMatchBase64 = (subject) =>
|
|
39
|
+
forSubjectToMatchPattern(subject, RE_BASE64_PATTERN, {
|
|
40
|
+
patternName: "Base64",
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export const toMatchJwt = (subject) =>
|
|
44
|
+
forSubjectToMatchPattern(subject, RE_JWT_PATTERN, {
|
|
45
|
+
patternName: "JWT",
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
export const toMatchMongoId = (subject) =>
|
|
49
|
+
forSubjectToMatchPattern(subject, RE_MONGO_ID_PATTERN, {
|
|
50
|
+
patternName: "MongoDbId",
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
export const toMatchSignedCookie = (subject) =>
|
|
54
|
+
forSubjectToMatchPattern(subject, RE_SIGNED_COOKIE_PATTERN, {
|
|
55
|
+
patternName: "Signed-Cookie",
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export const toMatchUuid4 = (subject) =>
|
|
59
|
+
forSubjectToMatchPattern(subject, RE_UUID_4_PATTERN, {
|
|
60
|
+
patternName: "UUIDv4",
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
export const toMatchUuid5 = (subject) =>
|
|
64
|
+
forSubjectToMatchPattern(subject, RE_UUID_5_PATTERN, {
|
|
65
|
+
patternName: "UUIDv5",
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Determines if subject matches a UUID pattern.
|
|
70
|
+
* Does _NOT_ check if the UUID is valid.
|
|
71
|
+
* @param {String} subject
|
|
72
|
+
*/
|
|
73
|
+
export const toMatchUuid = (subject) =>
|
|
74
|
+
forSubjectToMatchPattern(subject, RE_UUID_PATTERN, {
|
|
75
|
+
patternName: "UUID",
|
|
76
|
+
});
|
package/src/matchers.module.js
CHANGED
|
@@ -12,6 +12,16 @@ import toThrowJaypieError, {
|
|
|
12
12
|
toThrowUnauthorizedError,
|
|
13
13
|
} from "./matchers/toThrowJaypieError.matcher.js";
|
|
14
14
|
|
|
15
|
+
import {
|
|
16
|
+
toMatchBase64,
|
|
17
|
+
toMatchJwt,
|
|
18
|
+
toMatchMongoId,
|
|
19
|
+
toMatchSignedCookie,
|
|
20
|
+
toMatchUuid4,
|
|
21
|
+
toMatchUuid5,
|
|
22
|
+
toMatchUuid,
|
|
23
|
+
} from "./matchers/toMatch.matcher.js";
|
|
24
|
+
|
|
15
25
|
//
|
|
16
26
|
//
|
|
17
27
|
// Export
|
|
@@ -22,7 +32,14 @@ export default {
|
|
|
22
32
|
toBeClass,
|
|
23
33
|
toBeJaypieError,
|
|
24
34
|
toBeValidSchema: jsonSchemaMatchers.toBeValidSchema,
|
|
35
|
+
toMatchBase64,
|
|
36
|
+
toMatchJwt,
|
|
37
|
+
toMatchMongoId,
|
|
25
38
|
toMatchSchema: jsonSchemaMatchers.toMatchSchema,
|
|
39
|
+
toMatchSignedCookie,
|
|
40
|
+
toMatchUuid4,
|
|
41
|
+
toMatchUuid5,
|
|
42
|
+
toMatchUuid,
|
|
26
43
|
toThrowBadRequestError,
|
|
27
44
|
toThrowConfigurationError,
|
|
28
45
|
toThrowForbiddenError,
|
package/src/mockLog.module.js
CHANGED
|
@@ -7,6 +7,7 @@ export function mockLogFactory() {
|
|
|
7
7
|
error: vi.fn(),
|
|
8
8
|
fatal: vi.fn(),
|
|
9
9
|
info: vi.fn(),
|
|
10
|
+
init: vi.fn(),
|
|
10
11
|
lib: vi.fn(),
|
|
11
12
|
tag: vi.fn(),
|
|
12
13
|
trace: vi.fn(),
|
|
@@ -23,6 +24,7 @@ export function mockLogFactory() {
|
|
|
23
24
|
mock.trace.var = mock.var;
|
|
24
25
|
mock.warn.var = mock.var;
|
|
25
26
|
// Have modules return correct objects
|
|
27
|
+
mock.init.mockReturnValue(null);
|
|
26
28
|
mock.lib.mockReturnValue(mock);
|
|
27
29
|
mock.with.mockReturnValue(mock);
|
|
28
30
|
|
|
@@ -32,6 +34,7 @@ export function mockLogFactory() {
|
|
|
32
34
|
error: mock.error,
|
|
33
35
|
fatal: mock.fatal,
|
|
34
36
|
info: mock.info,
|
|
37
|
+
init: mock.init,
|
|
35
38
|
lib: mock.lib,
|
|
36
39
|
tag: mock.tag,
|
|
37
40
|
trace: mock.trace,
|
|
@@ -55,6 +58,7 @@ const logMethodNames = [
|
|
|
55
58
|
"error",
|
|
56
59
|
"fatal",
|
|
57
60
|
"info",
|
|
61
|
+
"init",
|
|
58
62
|
"lib",
|
|
59
63
|
"tag",
|
|
60
64
|
"trace",
|