payload 0.15.1 → 0.15.2

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.
Files changed (30) hide show
  1. package/.eslintrc.js +6 -0
  2. package/CHANGELOG.md +7 -0
  3. package/dist/admin/components/elements/elements.spec.d.ts +1 -0
  4. package/dist/admin/components/elements/elements.spec.js +12 -0
  5. package/dist/auth/auth.spec.d.ts +1 -0
  6. package/dist/auth/auth.spec.js +198 -0
  7. package/dist/collections/graphql/resolvers/resolvers.spec.d.ts +1 -0
  8. package/dist/collections/graphql/resolvers/resolvers.spec.js +360 -0
  9. package/dist/collections/operations/local/local.spec.d.ts +1 -0
  10. package/dist/collections/operations/local/local.spec.js +175 -0
  11. package/dist/collections/tests/collections.spec.d.ts +1 -0
  12. package/dist/collections/tests/collections.spec.js +725 -0
  13. package/dist/collections/tests/hooks.spec.d.ts +1 -0
  14. package/dist/collections/tests/hooks.spec.js +152 -0
  15. package/dist/collections/tests/pointField.spec.d.ts +1 -0
  16. package/dist/collections/tests/pointField.spec.js +208 -0
  17. package/dist/collections/tests/relationships.spec.d.ts +1 -0
  18. package/dist/collections/tests/relationships.spec.js +174 -0
  19. package/dist/collections/tests/uploads.spec.d.ts +1 -0
  20. package/dist/collections/tests/uploads.spec.js +328 -0
  21. package/dist/errors/errors.spec.d.ts +1 -0
  22. package/dist/errors/errors.spec.js +29 -0
  23. package/dist/express/middleware/errorHandler.spec.d.ts +1 -0
  24. package/dist/express/middleware/errorHandler.spec.js +91 -0
  25. package/dist/globals/requestHandlers/globals.spec.d.ts +4 -0
  26. package/dist/globals/requestHandlers/globals.spec.js +161 -0
  27. package/dist/preferences/graphql/resolvers.spec.d.ts +1 -0
  28. package/dist/preferences/graphql/resolvers.spec.js +115 -0
  29. package/dist/versions/drafts/appendVersionToQueryKey.js +8 -5
  30. package/package.json +1 -1
@@ -0,0 +1,328 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fs_1 = __importDefault(require("fs"));
7
+ const path_1 = __importDefault(require("path"));
8
+ const form_data_1 = __importDefault(require("form-data"));
9
+ const graphql_request_1 = require("graphql-request");
10
+ const util_1 = require("util");
11
+ const load_1 = __importDefault(require("../../config/load"));
12
+ const testCredentials_1 = require("../../mongoose/testCredentials");
13
+ const stat = (0, util_1.promisify)(fs_1.default.stat);
14
+ require('isomorphic-fetch');
15
+ const config = (0, load_1.default)();
16
+ const api = `${config.serverURL}${config.routes.api}`;
17
+ let client;
18
+ let token;
19
+ let headers;
20
+ describe('Collections - Uploads', () => {
21
+ beforeAll(async (done) => {
22
+ const response = await fetch(`${api}/admins/login`, {
23
+ body: JSON.stringify({
24
+ email: testCredentials_1.email,
25
+ password: testCredentials_1.password,
26
+ }),
27
+ headers: {
28
+ 'Content-Type': 'application/json',
29
+ },
30
+ method: 'post',
31
+ });
32
+ const data = await response.json();
33
+ ({ token } = data);
34
+ headers = {
35
+ Authorization: `JWT ${token}`,
36
+ };
37
+ done();
38
+ });
39
+ describe('REST', () => {
40
+ const mediaDir = path_1.default.join(__dirname, '../../../demo', 'media');
41
+ beforeAll(async () => {
42
+ // Clear demo/media directory
43
+ const mediaDirExists = await fileExists(mediaDir);
44
+ if (!mediaDirExists)
45
+ return;
46
+ fs_1.default.readdir(mediaDir, (err, files) => {
47
+ if (err)
48
+ throw err;
49
+ // eslint-disable-next-line no-restricted-syntax
50
+ for (const file of files) {
51
+ fs_1.default.unlink(path_1.default.join(mediaDir, file), (unlinkErr) => {
52
+ if (unlinkErr)
53
+ throw unlinkErr;
54
+ });
55
+ }
56
+ });
57
+ });
58
+ describe('create', () => {
59
+ it('creates', async () => {
60
+ const formData = new form_data_1.default();
61
+ formData.append('file', fs_1.default.createReadStream(path_1.default.join(__dirname, '../../..', 'tests/api/assets/image.png')));
62
+ formData.append('alt', 'test media');
63
+ formData.append('locale', 'en');
64
+ const response = await fetch(`${api}/media`, {
65
+ body: formData,
66
+ headers,
67
+ method: 'post',
68
+ });
69
+ const data = await response.json();
70
+ expect(response.status).toBe(201);
71
+ // Check for files
72
+ expect(await fileExists(path_1.default.join(mediaDir, 'image.png'))).toBe(true);
73
+ expect(await fileExists(path_1.default.join(mediaDir, 'image-16x16.png'))).toBe(true);
74
+ expect(await fileExists(path_1.default.join(mediaDir, 'image-320x240.png'))).toBe(true);
75
+ expect(await fileExists(path_1.default.join(mediaDir, 'image-640x480.png'))).toBe(true);
76
+ // Check api response
77
+ expect(data).toMatchObject({
78
+ doc: {
79
+ alt: 'test media',
80
+ filename: 'image.png',
81
+ mimeType: 'image/png',
82
+ sizes: {
83
+ icon: {
84
+ filename: 'image-16x16.png',
85
+ width: 16,
86
+ height: 16,
87
+ },
88
+ mobile: {
89
+ filename: 'image-320x240.png',
90
+ width: 320,
91
+ height: 240,
92
+ },
93
+ tablet: {
94
+ filename: 'image-640x480.png',
95
+ width: 640,
96
+ height: 480,
97
+ },
98
+ },
99
+ // We have a hook to check if upload sizes
100
+ // are properly bound to the Payload `req`.
101
+ // This field should be automatically set
102
+ // if they are found.
103
+ foundUploadSizes: true,
104
+ },
105
+ });
106
+ });
107
+ it('creates media without storing a file', async () => {
108
+ const formData = new form_data_1.default();
109
+ formData.append('file', fs_1.default.createReadStream(path_1.default.join(__dirname, '../../..', 'tests/api/assets/image.png')));
110
+ formData.append('alt', 'test media');
111
+ formData.append('locale', 'en');
112
+ const response = await fetch(`${api}/unstored-media`, {
113
+ body: formData,
114
+ headers,
115
+ method: 'post',
116
+ });
117
+ const data = await response.json();
118
+ expect(response.status).toBe(201);
119
+ // Check for files
120
+ expect(await !fileExists(path_1.default.join(mediaDir, 'image.png'))).toBe(false);
121
+ expect(await !fileExists(path_1.default.join(mediaDir, 'image-640x480.png'))).toBe(false);
122
+ // Check api response
123
+ expect(data).toMatchObject({
124
+ doc: {
125
+ alt: 'test media',
126
+ filename: 'image.png',
127
+ mimeType: 'image/png',
128
+ sizes: {
129
+ tablet: {
130
+ filename: 'image-640x480.png',
131
+ width: 640,
132
+ height: 480,
133
+ },
134
+ },
135
+ },
136
+ });
137
+ });
138
+ it('creates with same name', async () => {
139
+ const formData = new form_data_1.default();
140
+ formData.append('file', fs_1.default.createReadStream(path_1.default.join(__dirname, '../../..', 'tests/api/assets/samename.png')));
141
+ formData.append('alt', 'test media');
142
+ formData.append('locale', 'en');
143
+ const firstResponse = await fetch(`${api}/media`, {
144
+ body: formData,
145
+ headers,
146
+ method: 'post',
147
+ });
148
+ expect(firstResponse.status).toBe(201);
149
+ const sameForm = new form_data_1.default();
150
+ sameForm.append('file', fs_1.default.createReadStream(path_1.default.join(__dirname, '../../..', 'tests/api/assets/samename.png')));
151
+ sameForm.append('alt', 'test media');
152
+ sameForm.append('locale', 'en');
153
+ const response = await fetch(`${api}/media`, {
154
+ body: sameForm,
155
+ headers,
156
+ method: 'post',
157
+ });
158
+ expect(response.status).toBe(201);
159
+ const data = await response.json();
160
+ // Check for files
161
+ expect(await fileExists(path_1.default.join(mediaDir, 'samename-1.png'))).toBe(true);
162
+ expect(await fileExists(path_1.default.join(mediaDir, 'samename-1-16x16.png'))).toBe(true);
163
+ expect(await fileExists(path_1.default.join(mediaDir, 'samename-1-320x240.png'))).toBe(true);
164
+ expect(await fileExists(path_1.default.join(mediaDir, 'samename-1-640x480.png'))).toBe(true);
165
+ expect(data).toMatchObject({
166
+ doc: {
167
+ alt: 'test media',
168
+ filename: 'samename-1.png',
169
+ mimeType: 'image/png',
170
+ sizes: {
171
+ icon: {
172
+ filename: 'samename-1-16x16.png',
173
+ width: 16,
174
+ height: 16,
175
+ },
176
+ mobile: {
177
+ filename: 'samename-1-320x240.png',
178
+ width: 320,
179
+ height: 240,
180
+ },
181
+ tablet: {
182
+ filename: 'samename-1-640x480.png',
183
+ width: 640,
184
+ height: 480,
185
+ },
186
+ },
187
+ },
188
+ });
189
+ });
190
+ });
191
+ it('update', async () => {
192
+ const formData = new form_data_1.default();
193
+ formData.append('file', fs_1.default.createReadStream(path_1.default.join(__dirname, '../../..', 'tests/api/assets/update.png')));
194
+ formData.append('alt', 'test media');
195
+ formData.append('locale', 'en');
196
+ const response = await fetch(`${api}/media`, {
197
+ body: formData,
198
+ headers,
199
+ method: 'post',
200
+ });
201
+ const data = await response.json();
202
+ expect(response.status).toBe(201);
203
+ const updateFormData = new form_data_1.default();
204
+ const newAlt = 'my new alt';
205
+ updateFormData.append('filename', data.doc.filename);
206
+ updateFormData.append('alt', newAlt);
207
+ const updateResponse = await fetch(`${api}/media/${data.doc.id}`, {
208
+ body: updateFormData,
209
+ headers,
210
+ method: 'put',
211
+ });
212
+ expect(updateResponse.status).toBe(200);
213
+ const updateResponseData = await updateResponse.json();
214
+ // Check that files weren't affected
215
+ expect(await fileExists(path_1.default.join(mediaDir, 'update.png'))).toBe(true);
216
+ expect(await fileExists(path_1.default.join(mediaDir, 'update-16x16.png'))).toBe(true);
217
+ expect(await fileExists(path_1.default.join(mediaDir, 'update-320x240.png'))).toBe(true);
218
+ expect(await fileExists(path_1.default.join(mediaDir, 'update-640x480.png'))).toBe(true);
219
+ // Check api response
220
+ expect(updateResponseData).toMatchObject({
221
+ doc: {
222
+ alt: newAlt,
223
+ filename: 'update.png',
224
+ mimeType: 'image/png',
225
+ sizes: {
226
+ icon: {
227
+ filename: 'update-16x16.png',
228
+ width: 16,
229
+ height: 16,
230
+ },
231
+ mobile: {
232
+ filename: 'update-320x240.png',
233
+ width: 320,
234
+ height: 240,
235
+ },
236
+ tablet: {
237
+ filename: 'update-640x480.png',
238
+ width: 640,
239
+ height: 480,
240
+ },
241
+ maintainedAspectRatio: {},
242
+ },
243
+ },
244
+ });
245
+ });
246
+ it('delete', async () => {
247
+ const formData = new form_data_1.default();
248
+ formData.append('file', fs_1.default.createReadStream(path_1.default.join(__dirname, '../../..', 'tests/api/assets/delete.png')));
249
+ formData.append('alt', 'test media');
250
+ formData.append('locale', 'en');
251
+ const createResponse = await fetch(`${api}/media`, {
252
+ body: formData,
253
+ headers,
254
+ method: 'post',
255
+ });
256
+ const createData = await createResponse.json();
257
+ expect(createResponse.status).toBe(201);
258
+ const docId = createData.doc.id;
259
+ const response = await fetch(`${api}/media/${docId}`, {
260
+ headers,
261
+ method: 'delete',
262
+ });
263
+ const data = await response.json();
264
+ expect(response.status).toBe(200);
265
+ expect(data.id).toBe(docId);
266
+ const imageExists = await fileExists(path_1.default.join(mediaDir, 'delete.png'));
267
+ expect(imageExists).toBe(false);
268
+ });
269
+ });
270
+ describe('GraphQL', () => {
271
+ // graphql cannot submit formData to create files, we only need to test getting relationship data on upload fields
272
+ let media;
273
+ let image;
274
+ const alt = 'alt text';
275
+ beforeAll(async (done) => {
276
+ client = new graphql_request_1.GraphQLClient(`${api}${config.routes.graphQL}`, {
277
+ headers: { Authorization: `JWT ${token}` },
278
+ });
279
+ // create media using REST
280
+ const formData = new form_data_1.default();
281
+ formData.append('file', fs_1.default.createReadStream(path_1.default.join(__dirname, '../../..', 'tests/api/assets/image.png')));
282
+ formData.append('alt', alt);
283
+ formData.append('locale', 'en');
284
+ const mediaResponse = await fetch(`${api}/media`, {
285
+ body: formData,
286
+ headers,
287
+ method: 'post',
288
+ });
289
+ const mediaData = await mediaResponse.json();
290
+ media = mediaData.doc;
291
+ // create image that relates to media
292
+ headers['Content-Type'] = 'application/json';
293
+ const imageResponse = await fetch(`${api}/images`, {
294
+ body: JSON.stringify({
295
+ upload: media.id,
296
+ }),
297
+ headers,
298
+ method: 'post',
299
+ });
300
+ const data = await imageResponse.json();
301
+ image = data.doc;
302
+ done();
303
+ });
304
+ it('should query uploads relationship fields', async () => {
305
+ // language=graphQL
306
+ const query = `query {
307
+ Image(id: "${image.id}") {
308
+ id
309
+ upload {
310
+ alt
311
+ }
312
+ }
313
+ }`;
314
+ const response = await client.request(query);
315
+ expect(response.Image.upload.alt).toStrictEqual(alt);
316
+ });
317
+ });
318
+ });
319
+ async function fileExists(fileName) {
320
+ try {
321
+ await stat(fileName);
322
+ return true;
323
+ }
324
+ catch (err) {
325
+ return false;
326
+ }
327
+ }
328
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2Fkcy5zcGVjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbGxlY3Rpb25zL3Rlc3RzL3VwbG9hZHMuc3BlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDRDQUFvQjtBQUNwQixnREFBd0I7QUFDeEIsMERBQWlDO0FBQ2pDLHFEQUFnRDtBQUNoRCwrQkFBaUM7QUFDakMsNkRBQTBDO0FBQzFDLG9FQUFpRTtBQUVqRSxNQUFNLElBQUksR0FBRyxJQUFBLGdCQUFTLEVBQUMsWUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBRWhDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0FBRTVCLE1BQU0sTUFBTSxHQUFHLElBQUEsY0FBUyxHQUFFLENBQUM7QUFDM0IsTUFBTSxHQUFHLEdBQUcsR0FBRyxNQUFNLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUM7QUFFdEQsSUFBSSxNQUFNLENBQUM7QUFDWCxJQUFJLEtBQUssQ0FBQztBQUNWLElBQUksT0FBTyxDQUFDO0FBRVosUUFBUSxDQUFDLHVCQUF1QixFQUFFLEdBQUcsRUFBRTtJQUNyQyxTQUFTLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFO1FBQ3ZCLE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLEdBQUcsR0FBRyxlQUFlLEVBQUU7WUFDbEQsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUM7Z0JBQ25CLEtBQUssRUFBTCx1QkFBSztnQkFDTCxRQUFRLEVBQVIsMEJBQVE7YUFDVCxDQUFDO1lBQ0YsT0FBTyxFQUFFO2dCQUNQLGNBQWMsRUFBRSxrQkFBa0I7YUFDbkM7WUFDRCxNQUFNLEVBQUUsTUFBTTtTQUNmLENBQUMsQ0FBQztRQUVILE1BQU0sSUFBSSxHQUFHLE1BQU0sUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO1FBRW5DLENBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxJQUFJ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
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const _1 = require(".");
4
+ describe('Errors', () => {
5
+ describe('APIError', () => {
6
+ it('should handle an error message', () => {
7
+ const error = new _1.APIError('my message', 400, false);
8
+ expect(error.message).toStrictEqual('my message');
9
+ });
10
+ // it('should handle an array', () => {
11
+ // const errors = [
12
+ // {
13
+ // error: 'some error description',
14
+ // },
15
+ // {
16
+ // error: 'some error description 2',
17
+ // },
18
+ // ];
19
+ // const error = new APIError(errors, 400, false);
20
+ // expect(error.message).toStrictEqual(JSON.stringify(errors));
21
+ // });
22
+ // it('should handle an object', () => {
23
+ // const myFancyErrorObject = { someProp: 'someDetail ' };
24
+ // const error = new APIError(myFancyErrorObject, 400, false);
25
+ // expect(error.message).toStrictEqual(JSON.stringify(myFancyErrorObject));
26
+ // });
27
+ });
28
+ });
29
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLnNwZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZXJyb3JzL2Vycm9ycy5zcGVjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsd0JBQTZCO0FBRTdCLFFBQVEsQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFO0lBQ3RCLFFBQVEsQ0FBQyxVQUFVLEVBQUUsR0FBRyxFQUFFO1FBQ3hCLEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBRSxHQUFHLEVBQUU7WUFDeEMsTUFBTSxLQUFLLEdBQUcsSUFBSSxXQUFRLENBQUMsWUFBWSxFQUFFLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNyRCxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNwRCxDQUFDLENBQUMsQ0FBQztRQUVILHVDQUF1QztRQUN2QyxxQkFBcUI7UUFDckIsUUFBUTtRQUNSLHlDQUF5QztRQUN6QyxTQUFTO1FBQ1QsUUFBUTtRQUNSLDJDQUEyQztRQUMzQyxTQUFTO1FBQ1QsT0FBTztRQUNQLG9EQUFvRDtRQUNwRCxpRUFBaUU7UUFDakUsTUFBTTtRQUVOLHdDQUF3QztRQUN4Qyw0REFBNEQ7UUFDNUQsZ0VBQWdFO1FBQ2hFLDZFQUE2RTtRQUM3RSxNQUFNO0lBQ1IsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyJ9
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const logger_1 = __importDefault(require("../../utilities/logger"));
7
+ const errorHandler_1 = __importDefault(require("./errorHandler"));
8
+ const errors_1 = require("../../errors");
9
+ const logger = (0, logger_1.default)();
10
+ const testError = new errors_1.APIError('test error', 503);
11
+ describe('errorHandler', () => {
12
+ const res = generateResponse();
13
+ const next = jest.fn();
14
+ const req = generateRequest();
15
+ it('should send the response with the error', async () => {
16
+ const handler = (0, errorHandler_1.default)(generateConfig({ debug: true }), logger);
17
+ await handler(testError, req, res, next);
18
+ expect(res.send).toHaveBeenCalledWith(expect.objectContaining({ errors: [{ message: 'test error' }] }));
19
+ });
20
+ it('should include stack trace when config debug is on', async () => {
21
+ const handler = (0, errorHandler_1.default)(generateConfig({ debug: true }), logger);
22
+ await handler(testError, req, res, next);
23
+ expect(res.send).toHaveBeenCalledWith(expect.objectContaining({ stack: expect.any(String) }));
24
+ });
25
+ it('should not include stack trace when config debug is not set', async () => {
26
+ const handler = (0, errorHandler_1.default)(generateConfig({ debug: undefined }), logger);
27
+ await handler(testError, req, res, next);
28
+ expect(res.send).toHaveBeenCalledWith(expect.not.objectContaining({ stack: expect.any(String) }));
29
+ });
30
+ it('should not include stack trace when config debug is false', async () => {
31
+ const handler = (0, errorHandler_1.default)(generateConfig({ debug: false }), logger);
32
+ await handler(testError, req, res, next);
33
+ expect(res.send).toHaveBeenCalledWith(expect.not.objectContaining({ stack: expect.any(String) }));
34
+ });
35
+ it('should show the status code when given an error with a code', async () => {
36
+ const handler = (0, errorHandler_1.default)(generateConfig(), logger);
37
+ await handler(testError, req, res, next);
38
+ expect(res.status).toHaveBeenCalledWith(503);
39
+ });
40
+ it('should default to 500 when an error does not have a status code', async () => {
41
+ const handler = (0, errorHandler_1.default)(generateConfig(), logger);
42
+ testError.status = undefined;
43
+ await handler(testError, req, res, next);
44
+ expect(res.status).toHaveBeenCalledWith(500);
45
+ });
46
+ it('should call payload config afterError hook', async () => {
47
+ const afterError = jest.fn();
48
+ const handler = (0, errorHandler_1.default)(generateConfig({
49
+ hooks: { afterError },
50
+ }), logger);
51
+ await handler(testError, req, res, next);
52
+ expect(afterError)
53
+ // eslint-disable-next-line jest/prefer-called-with
54
+ .toHaveBeenCalled();
55
+ });
56
+ it('should call collection config afterError hook', async () => {
57
+ const handler = (0, errorHandler_1.default)(generateConfig(), logger);
58
+ await handler(testError, req, res, next);
59
+ expect(req.collection.config.hooks.afterError)
60
+ // eslint-disable-next-line jest/prefer-called-with
61
+ .toHaveBeenCalled();
62
+ });
63
+ });
64
+ function generateResponse() {
65
+ const res = {
66
+ status: jest.fn(),
67
+ send: jest.fn(),
68
+ };
69
+ jest.spyOn(res, 'status').mockImplementation().mockReturnValue(res);
70
+ jest.spyOn(res, 'send').mockImplementation().mockReturnValue(res);
71
+ return res;
72
+ }
73
+ function generateRequest() {
74
+ return {
75
+ collection: {
76
+ config: {
77
+ hooks: {
78
+ afterError: jest.fn(),
79
+ },
80
+ },
81
+ },
82
+ };
83
+ }
84
+ function generateConfig(overrides) {
85
+ return {
86
+ debug: false,
87
+ hooks: { afterError: jest.fn() },
88
+ ...overrides,
89
+ };
90
+ }
91
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JIYW5kbGVyLnNwZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZXhwcmVzcy9taWRkbGV3YXJlL2Vycm9ySGFuZGxlci5zcGVjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQ0Esb0VBQTRDO0FBQzVDLGtFQUEwQztBQUMxQyx5Q0FBd0M7QUFJeEMsTUFBTSxNQUFNLEdBQUcsSUFBQSxnQkFBTSxHQUFFLENBQUM7QUFFeEIsTUFBTSxTQUFTLEdBQUcsSUFBSSxpQkFBUSxDQUFDLFlBQVksRUFBRSxHQUFHLENBQUMsQ0FBQztBQUVsRCxRQUFRLENBQUMsY0FBYyxFQUFFLEdBQUcsRUFBRTtJQUM1QixNQUFNLEdBQUcsR0FBRyxnQkFBZ0IsRUFBRSxDQUFDO0lBQy9CLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztJQUN2QixNQUFNLEdBQUcsR0FBRyxlQUFlLEVBQW9CLENBQUM7SUFFaEQsRUFBRSxDQUFDLHlDQUF5QyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3ZELE1BQU0sT0FBTyxHQUFHLElBQUEsc0JBQVksRUFBQyxjQUFjLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUN0RSxNQUFNLE9BQU8sQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN6QyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLG9CQUFvQixDQUNuQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FDakUsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLG9EQUFvRCxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ2xFLE1BQU0sT0FBTyxHQUFHLElBQUEsc0JBQVks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
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @jest-environment node
3
+ */
4
+ export {};