mock-config-server 3.2.0 → 3.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.
Files changed (89) hide show
  1. package/README.md +153 -3
  2. package/dist/bin/validateMockServerConfig/helpers/isDescriptorValueValid/isDescriptorValueValid.d.ts +2 -1
  3. package/dist/bin/validateMockServerConfig/helpers/isDescriptorValueValid/isDescriptorValueValid.js +30 -7
  4. package/dist/bin/validateMockServerConfig/validateGraphqlConfig/validateGraphqlConfig.js +9 -3
  5. package/dist/bin/validateMockServerConfig/validateGraphqlConfig/validateRoutes/validateRoutes.js +67 -18
  6. package/dist/bin/validateMockServerConfig/validateQueue/validateQueue.d.ts +1 -0
  7. package/dist/bin/validateMockServerConfig/validateQueue/validateQueue.js +29 -0
  8. package/dist/bin/validateMockServerConfig/validateRestConfig/validateRoutes/validateRoutes.js +67 -18
  9. package/dist/bin/validateMockServerConfig/validateSettings/validateSettings.d.ts +1 -0
  10. package/dist/bin/validateMockServerConfig/validateSettings/validateSettings.js +34 -0
  11. package/dist/src/core/database/createDatabaseRoutes/createDatabaseRoutes.test.ts +112 -0
  12. package/dist/src/core/database/createDatabaseRoutes/helpers/array/createNewId/createNewId.test.ts +13 -0
  13. package/dist/src/core/database/createDatabaseRoutes/helpers/array/findIndexById/findIndexById.test.ts +17 -0
  14. package/dist/src/core/database/createDatabaseRoutes/helpers/array/isIndex/isIndex.test.ts +30 -0
  15. package/dist/src/core/database/createDatabaseRoutes/helpers/createNestedDatabaseRoutes/createNestedDatabaseRoutes.js +45 -2
  16. package/dist/src/core/database/createDatabaseRoutes/helpers/createNestedDatabaseRoutes/createNestedDatabaseRoutes.test.ts +399 -0
  17. package/dist/src/core/database/createDatabaseRoutes/helpers/createShallowDatabaseRoutes/createShallowDatabaseRoutes.test.ts +118 -0
  18. package/dist/src/core/database/createDatabaseRoutes/helpers/filter/filter.d.ts +2 -1
  19. package/dist/src/core/database/createDatabaseRoutes/helpers/operators/operators.d.ts +3 -0
  20. package/dist/src/core/database/createDatabaseRoutes/helpers/operators/operators.js +30 -0
  21. package/dist/src/core/database/createDatabaseRoutes/helpers/pagination/pagination.d.ts +13 -0
  22. package/dist/src/core/database/createDatabaseRoutes/helpers/pagination/pagination.js +36 -0
  23. package/dist/src/core/database/createDatabaseRoutes/helpers/search/search.d.ts +3 -0
  24. package/dist/src/core/database/createDatabaseRoutes/helpers/search/search.js +31 -0
  25. package/dist/src/core/database/createDatabaseRoutes/helpers/sort/sort.d.ts +2 -0
  26. package/dist/src/core/database/createDatabaseRoutes/helpers/sort/sort.js +42 -0
  27. package/dist/src/core/database/createDatabaseRoutes/helpers/splitDatabaseByNesting/splitDatabaseByNesting.test.ts +25 -0
  28. package/dist/src/core/database/createDatabaseRoutes/storages/File/FileStorage.test.ts +156 -0
  29. package/dist/src/core/database/createDatabaseRoutes/storages/File/FileWriter.test.ts +48 -0
  30. package/dist/src/core/database/createDatabaseRoutes/storages/Memory/MemoryStorage.test.ts +96 -0
  31. package/dist/src/core/graphql/createGraphQLRoutes/createGraphQLRoutes.d.ts +7 -1
  32. package/dist/src/core/graphql/createGraphQLRoutes/createGraphQLRoutes.js +65 -24
  33. package/dist/src/core/graphql/createGraphQLRoutes/createGraphQLRoutes.test.ts +851 -0
  34. package/dist/src/core/graphql/createGraphQLRoutes/helpers/prepareGraphQLRequestConfigs/prepareGraphQLRequestConfigs.test.ts +116 -0
  35. package/dist/src/core/middlewares/cookieParseMiddleware/cookieParseMiddleware.test.ts +22 -0
  36. package/dist/src/core/middlewares/cookieParseMiddleware/helpers/parseCookie/parseCookie.test.ts +45 -0
  37. package/dist/src/core/middlewares/corsMiddleware/corsMiddleware.test.ts +152 -0
  38. package/dist/src/core/middlewares/corsMiddleware/helpers/getAllowedOrigins/getAllowedOrigins.test.ts +15 -0
  39. package/dist/src/core/middlewares/errorMiddleware/errorMiddleware.test.ts +29 -0
  40. package/dist/src/core/middlewares/noCorsMiddleware/noCorsMiddleware.test.ts +49 -0
  41. package/dist/src/core/middlewares/notFoundMiddleware/helpers/getGraphqlUrlSuggestions/getGraphqlUrlSuggestions.test.ts +27 -0
  42. package/dist/src/core/middlewares/notFoundMiddleware/helpers/getLevenshteinDistance/getLevenshteinDistance.test.ts +12 -0
  43. package/dist/src/core/middlewares/notFoundMiddleware/helpers/getRestUrlSuggestions/getRestUrlSuggestions.test.ts +54 -0
  44. package/dist/src/core/middlewares/notFoundMiddleware/helpers/getRestUrlSuggestions/helpers/getActualRestUrlMeaningfulString/getActualRestUrlMeaningfulString.test.ts +12 -0
  45. package/dist/src/core/middlewares/notFoundMiddleware/helpers/getRestUrlSuggestions/helpers/getPatternRestUrlMeaningfulString/getPatternRestUrlMeaningfulString.test.ts +10 -0
  46. package/dist/src/core/middlewares/notFoundMiddleware/notFoundMiddleware.js +1 -3
  47. package/dist/src/core/middlewares/notFoundMiddleware/notFoundMiddleware.test.ts +285 -0
  48. package/dist/src/core/middlewares/requestInterceptorMiddleware/requestInterceptorMiddleware.d.ts +7 -1
  49. package/dist/src/core/middlewares/requestInterceptorMiddleware/requestInterceptorMiddleware.js +6 -2
  50. package/dist/src/core/rest/createRestRoutes/createRestRoutes.d.ts +7 -1
  51. package/dist/src/core/rest/createRestRoutes/createRestRoutes.js +55 -12
  52. package/dist/src/core/rest/createRestRoutes/createRestRoutes.test.ts +648 -0
  53. package/dist/src/core/rest/createRestRoutes/helpers/prepareRestRequestConfigs/prepareRestRequestConfigs.test.ts +154 -0
  54. package/dist/src/server/createDatabaseMockServer/createDatabaseMockServer.js +4 -1
  55. package/dist/src/server/createGraphQLMockServer/createGraphQLMockServer.js +11 -4
  56. package/dist/src/server/createMockServer/createMockServer.js +28 -9
  57. package/dist/src/server/createRestMockServer/createRestMockServer.js +11 -4
  58. package/dist/src/server/index.d.ts +3 -3
  59. package/dist/src/server/index.js +23 -23
  60. package/dist/src/static/views/features/scheme/index.js +31 -31
  61. package/dist/src/utils/helpers/config/resolveEntityValues/resolveEntityValues.test.ts +1452 -0
  62. package/dist/src/utils/helpers/entities/convertToEntityDescriptor/convertToEntityDescriptor.test.ts +27 -0
  63. package/dist/src/utils/helpers/entities/isEntityDescriptor/isEntityDescriptor.d.ts +2 -1
  64. package/dist/src/utils/helpers/entities/isEntityDescriptor/isEntityDescriptor.test.ts +15 -0
  65. package/dist/src/utils/helpers/graphql/getGraphQLInput/getGraphQLInput.d.ts +7 -2
  66. package/dist/src/utils/helpers/graphql/getGraphQLInput/getGraphQLInput.js +6 -4
  67. package/dist/src/utils/helpers/graphql/getGraphQLInput/getGraphQLInput.test.ts +140 -0
  68. package/dist/src/utils/helpers/graphql/parseQuery/parseQuery.d.ts +1 -1
  69. package/dist/src/utils/helpers/graphql/parseQuery/parseQuery.js +1 -1
  70. package/dist/src/utils/helpers/graphql/parseQuery/parseQuery.test.ts +32 -0
  71. package/dist/src/utils/helpers/interceptors/callRequestInterceptor/callRequestInterceptors.test.ts +53 -0
  72. package/dist/src/utils/helpers/interceptors/callResponseInterceptors/callResponseInterceptors.js +19 -10
  73. package/dist/src/utils/helpers/interceptors/callResponseInterceptors/callResponseInterceptors.test.ts +262 -0
  74. package/dist/src/utils/helpers/isPlainObject/isPlainObject.test.ts +20 -0
  75. package/dist/src/utils/helpers/isPrimitive/isPrimitive.test.ts +26 -0
  76. package/dist/src/utils/helpers/isRegExp/isRegExp.test.ts +20 -0
  77. package/dist/src/utils/helpers/url/convertWin32PathToUnix/convertWin32PathToUnix.test.ts +21 -0
  78. package/dist/src/utils/helpers/url/getUrlParts/getUrlParts.test.ts +8 -0
  79. package/dist/src/utils/helpers/url/removeLeadingAndTrailingSlashes/removeLeadingAndTrailingSlashes.test.ts +10 -0
  80. package/dist/src/utils/helpers/url/urlJoin/urlJoin.test.ts +9 -0
  81. package/dist/src/utils/types/graphql.d.ts +60 -51
  82. package/dist/src/utils/types/index.d.ts +1 -0
  83. package/dist/src/utils/types/index.js +11 -0
  84. package/dist/src/utils/types/interceptors.d.ts +1 -1
  85. package/dist/src/utils/types/rest.d.ts +47 -40
  86. package/dist/src/utils/types/utils.d.ts +8 -0
  87. package/dist/src/utils/types/utils.js +1 -0
  88. package/dist/src/utils/types/values.d.ts +0 -1
  89. package/package.json +2 -3
@@ -0,0 +1,27 @@
1
+ import { convertToEntityDescriptor } from './convertToEntityDescriptor';
2
+
3
+ describe('convertToEntityDescriptor', () => {
4
+ test('Should correctly convert value to descriptor', () => {
5
+ expect(convertToEntityDescriptor(null)).toEqual({ checkMode: 'equals', value: null });
6
+ expect(convertToEntityDescriptor(undefined)).toEqual({ checkMode: 'equals', value: undefined });
7
+ expect(convertToEntityDescriptor(true)).toEqual({ checkMode: 'equals', value: true });
8
+ expect(convertToEntityDescriptor(1)).toEqual({ checkMode: 'equals', value: 1 });
9
+ expect(convertToEntityDescriptor('string')).toEqual({ checkMode: 'equals', value: 'string' });
10
+ expect(convertToEntityDescriptor([])).toEqual({
11
+ checkMode: 'equals',
12
+ value: []
13
+ });
14
+ expect(convertToEntityDescriptor({ key: 'value' })).toEqual({
15
+ checkMode: 'equals',
16
+ value: { key: 'value' }
17
+ });
18
+ });
19
+
20
+ test('Should return same value if descriptor provided', () => {
21
+ expect(convertToEntityDescriptor({ checkMode: 'exists' })).toEqual({ checkMode: 'exists' });
22
+ expect(convertToEntityDescriptor({ checkMode: 'equals', value: 'string' })).toEqual({
23
+ checkMode: 'equals',
24
+ value: 'string'
25
+ });
26
+ });
27
+ });
@@ -1 +1,2 @@
1
- export declare const isEntityDescriptor: (value: any) => boolean;
1
+ import type { EntityDescriptor } from '../../../types';
2
+ export declare const isEntityDescriptor: (value: any) => value is EntityDescriptor;
@@ -0,0 +1,15 @@
1
+ import { isEntityDescriptor } from './isEntityDescriptor';
2
+
3
+ describe('isEntityDescriptor', () => {
4
+ test('Should correctly define descriptor', () => {
5
+ expect(isEntityDescriptor(null)).toEqual(false);
6
+ expect(isEntityDescriptor(undefined)).toEqual(false);
7
+ expect(isEntityDescriptor(true)).toEqual(false);
8
+ expect(isEntityDescriptor(1)).toEqual(false);
9
+ expect(isEntityDescriptor('string')).toEqual(false);
10
+ expect(isEntityDescriptor([])).toEqual(false);
11
+ expect(isEntityDescriptor({ key: 'value' })).toEqual(false);
12
+ expect(isEntityDescriptor({ checkMode: 'exists' })).toEqual(true);
13
+ expect(isEntityDescriptor({ checkMode: 'equals', value: 'string' })).toEqual(true);
14
+ });
15
+ });
@@ -1,3 +1,8 @@
1
1
  import type { Request } from 'express';
2
- import type { GraphQLInput } from '../../../types';
3
- export declare const getGraphQLInput: (request: Request) => GraphQLInput;
2
+ import type { PlainObject } from '../../../types';
3
+ interface GetGraphQLInputResult {
4
+ query: string | undefined;
5
+ variables: PlainObject | undefined;
6
+ }
7
+ export declare const getGraphQLInput: (request: Request) => GetGraphQLInputResult;
8
+ export {};
@@ -6,14 +6,16 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.getGraphQLInput = void 0;
7
7
  const getGraphQLInput = request => {
8
8
  if (request.method === 'GET') {
9
- var _ref;
10
9
  const {
11
10
  query,
12
11
  variables
13
12
  } = request.query;
13
+
14
+ // ✅ important:
15
+ // if 'variables' was sent as encoded uri component then it already decoded into object and we do not need to use JSON.parse
14
16
  return {
15
17
  query: query === null || query === void 0 ? void 0 : query.toString(),
16
- variables: JSON.parse((_ref = variables) !== null && _ref !== void 0 ? _ref : '{}')
18
+ variables: typeof variables === 'string' ? JSON.parse(variables) : variables
17
19
  };
18
20
  }
19
21
  if (request.method === 'POST') {
@@ -23,9 +25,9 @@ const getGraphQLInput = request => {
23
25
  } = request.body;
24
26
  return {
25
27
  query,
26
- variables: variables !== null && variables !== void 0 ? variables : {}
28
+ variables
27
29
  };
28
30
  }
29
- throw new Error('Not allowed request method for graphql request');
31
+ throw new Error(`Not allowed request method ${request.method} for graphql request`);
30
32
  };
31
33
  exports.getGraphQLInput = getGraphQLInput;
@@ -0,0 +1,140 @@
1
+ import type { Request } from 'express';
2
+
3
+ import { getGraphQLInput } from './getGraphQLInput';
4
+
5
+ describe('getGraphQLInput', () => {
6
+ test('Should get correct graphQL input from GET request (with object variables)', () => {
7
+ const mockRequest = {
8
+ method: 'GET',
9
+ query: {
10
+ query: 'query GetCharacters { characters { name } }',
11
+ variables: { limit: 10 }
12
+ }
13
+ } as unknown as Request;
14
+
15
+ const graphQLInput = getGraphQLInput(mockRequest);
16
+
17
+ expect(graphQLInput).toStrictEqual({
18
+ query: 'query GetCharacters { characters { name } }',
19
+ variables: { limit: 10 }
20
+ });
21
+ });
22
+
23
+ test('Should get correct graphQL input from GET request (with string variables)', () => {
24
+ const mockRequest = {
25
+ method: 'GET',
26
+ query: {
27
+ query: 'query GetCharacters { characters { name } }',
28
+ variables: '{ "limit": 10 }'
29
+ }
30
+ } as unknown as Request;
31
+
32
+ const graphQLInput = getGraphQLInput(mockRequest);
33
+
34
+ expect(graphQLInput).toStrictEqual({
35
+ query: 'query GetCharacters { characters { name } }',
36
+ variables: { limit: 10 }
37
+ });
38
+ });
39
+
40
+ test('Should get correct graphQL input from GET request with empty variables', () => {
41
+ const mockRequest = {
42
+ method: 'GET',
43
+ query: {
44
+ query: 'query GetCharacters { characters { name } }'
45
+ }
46
+ } as unknown as Request;
47
+
48
+ const graphQLInput = getGraphQLInput(mockRequest);
49
+
50
+ expect(graphQLInput).toStrictEqual({
51
+ query: 'query GetCharacters { characters { name } }',
52
+ variables: undefined
53
+ });
54
+ });
55
+
56
+ test('Should get correct graphQL input from GET request with empty query and variables', () => {
57
+ const mockRequest = {
58
+ method: 'GET',
59
+ query: {}
60
+ } as unknown as Request;
61
+
62
+ const graphQLInput = getGraphQLInput(mockRequest);
63
+
64
+ expect(graphQLInput).toStrictEqual({
65
+ query: undefined,
66
+ variables: undefined
67
+ });
68
+ });
69
+
70
+ test('Should get correct graphQL input from POST request', () => {
71
+ const mockRequest = {
72
+ method: 'POST',
73
+ body: {
74
+ query: 'query GetCharacters { characters { name } }',
75
+ variables: { limit: 10 }
76
+ }
77
+ } as unknown as Request;
78
+
79
+ const graphQLInput = getGraphQLInput(mockRequest);
80
+
81
+ expect(graphQLInput).toStrictEqual({
82
+ query: 'query GetCharacters { characters { name } }',
83
+ variables: { limit: 10 }
84
+ });
85
+ });
86
+
87
+ test('Should get correct graphQL input from POST with empty variables', () => {
88
+ const mockRequest = {
89
+ method: 'POST',
90
+ body: {
91
+ query: 'query GetCharacters { characters { name } }'
92
+ }
93
+ } as unknown as Request;
94
+
95
+ const graphQLInput = getGraphQLInput(mockRequest);
96
+
97
+ expect(graphQLInput).toStrictEqual({
98
+ query: 'query GetCharacters { characters { name } }',
99
+ variables: undefined
100
+ });
101
+ });
102
+
103
+ test('Should get correct graphQL input from POST with empty query and variables', () => {
104
+ const mockRequest = {
105
+ method: 'POST',
106
+ body: {}
107
+ } as unknown as Request;
108
+
109
+ const graphQLInput = getGraphQLInput(mockRequest);
110
+
111
+ expect(graphQLInput).toStrictEqual({
112
+ query: undefined,
113
+ variables: undefined
114
+ });
115
+ });
116
+
117
+ test('Should throw error if request method is not GET or POST', () => {
118
+ const deleteMockRequest = {
119
+ method: 'DELETE',
120
+ query: {
121
+ query: 'query GetCharacters { characters { name } }'
122
+ }
123
+ } as unknown as Request;
124
+
125
+ expect(() => getGraphQLInput(deleteMockRequest)).toThrow(
126
+ 'Not allowed request method DELETE for graphql request'
127
+ );
128
+
129
+ const putMockRequest = {
130
+ method: 'PUT',
131
+ body: {
132
+ query: 'query GetCharacters { characters { name } }'
133
+ }
134
+ } as unknown as Request;
135
+
136
+ expect(() => getGraphQLInput(putMockRequest)).toThrow(
137
+ 'Not allowed request method PUT for graphql request'
138
+ );
139
+ });
140
+ });
@@ -1,7 +1,7 @@
1
1
  import type { OperationTypeNode } from 'graphql';
2
2
  interface ParseDocumentNodeResult {
3
3
  operationType: OperationTypeNode;
4
- operationName: string;
4
+ operationName: string | undefined;
5
5
  }
6
6
  export declare const parseQuery: (query: string) => ParseDocumentNodeResult | null;
7
7
  export {};
@@ -10,7 +10,7 @@ const parseDocumentNode = node => {
10
10
  const operationDefinition = node.definitions.find(definition => definition.kind === 'OperationDefinition');
11
11
  return {
12
12
  operationType: operationDefinition.operation,
13
- operationName: (_operationDefinition$ = (_operationDefinition$2 = operationDefinition.name) === null || _operationDefinition$2 === void 0 ? void 0 : _operationDefinition$2.value) !== null && _operationDefinition$ !== void 0 ? _operationDefinition$ : ''
13
+ operationName: (_operationDefinition$ = (_operationDefinition$2 = operationDefinition.name) === null || _operationDefinition$2 === void 0 ? void 0 : _operationDefinition$2.value) !== null && _operationDefinition$ !== void 0 ? _operationDefinition$ : undefined
14
14
  };
15
15
  };
16
16
  const parseQuery = query => {
@@ -0,0 +1,32 @@
1
+ import { parseQuery } from './parseQuery';
2
+
3
+ describe('parseQuery', () => {
4
+ test('Should parse graphQL query', () => {
5
+ const parsedQuery = parseQuery('query GetCharacters { characters { name } }');
6
+
7
+ expect(parsedQuery).toStrictEqual({
8
+ operationType: 'query',
9
+ operationName: 'GetCharacters'
10
+ });
11
+ });
12
+
13
+ test('Should parse graphQL mutation', () => {
14
+ const parsedQuery = parseQuery(
15
+ 'mutation CreateCharacters($name: String!) { createCharacters(name: $name) { name } }'
16
+ );
17
+
18
+ expect(parsedQuery).toStrictEqual({
19
+ operationType: 'mutation',
20
+ operationName: 'CreateCharacters'
21
+ });
22
+ });
23
+
24
+ test('Should parse graphQL query with empty operationName', () => {
25
+ const parsedQuery = parseQuery('query { characters { name } }');
26
+
27
+ expect(parsedQuery).toStrictEqual({
28
+ operationType: 'query',
29
+ operationName: undefined
30
+ });
31
+ });
32
+ });
@@ -0,0 +1,53 @@
1
+ import type { Request } from 'express';
2
+
3
+ import type { RequestInterceptor } from '@/utils/types';
4
+
5
+ import { callRequestInterceptor } from './callRequestInterceptor';
6
+
7
+ describe('callRequestInterceptors: order of calls', () => {
8
+ test('Should call passed request interceptor', () => {
9
+ const request = {} as Request;
10
+ const interceptor = jest.fn();
11
+
12
+ callRequestInterceptor({ request, interceptor });
13
+ expect(interceptor.mock.calls.length).toBe(1);
14
+ });
15
+ });
16
+
17
+ describe('callRequestInterceptors: params functions', () => {
18
+ test('Should correctly get header from request.headers object when use getHeader param', () => {
19
+ const request = { headers: { name: 'value' } };
20
+ const getHeaderRequestInterceptor: RequestInterceptor = ({ getHeader }) => {
21
+ expect(getHeader('name')).toBe('value');
22
+ };
23
+
24
+ callRequestInterceptor({
25
+ request: request as unknown as Request,
26
+ interceptor: getHeaderRequestInterceptor
27
+ });
28
+ });
29
+
30
+ test('Should correctly get headers as request.headers object when use getHeaders param', () => {
31
+ const request = { headers: { name: 'value' } };
32
+ const getHeadersRequestInterceptor: RequestInterceptor = ({ getHeaders }) => {
33
+ expect(getHeaders()).toStrictEqual({ name: 'value' });
34
+ };
35
+
36
+ callRequestInterceptor({
37
+ request: request as unknown as Request,
38
+ interceptor: getHeadersRequestInterceptor
39
+ });
40
+ });
41
+
42
+ test('Should correctly get cookie from request.cookies object when use getCookie param', () => {
43
+ const request = { cookies: { name: 'value' } };
44
+ const getCookieRequestInterceptor: RequestInterceptor = ({ getCookie }) => {
45
+ expect(getCookie('name')).toBe('value');
46
+ };
47
+
48
+ callRequestInterceptor({
49
+ request: request as unknown as Request,
50
+ interceptor: getCookieRequestInterceptor
51
+ });
52
+ });
53
+ });
@@ -14,21 +14,30 @@ const callResponseInterceptors = async params => {
14
14
  } = params;
15
15
  const getHeader = field => response.getHeader(field);
16
16
  const getHeaders = () => response.getHeaders();
17
- const getCookie = name => request.cookies[name];
17
+ const setHeader = (field, value) => {
18
+ response.set(field, value);
19
+ };
20
+ const appendHeader = (field, value) => {
21
+ response.append(field, value);
22
+ };
18
23
  const setStatusCode = statusCode => {
19
24
  response.statusCode = statusCode;
20
25
  };
21
- const setHeader = (field, value) => response.set(field, value);
22
- const appendHeader = (field, value) => response.append(field, value);
26
+ const getCookie = name => request.cookies[name];
23
27
  const setCookie = (name, value, options) => {
24
28
  if (options) {
25
29
  response.cookie(name, value, options);
30
+ return;
26
31
  }
27
32
  response.cookie(name, value);
28
33
  };
29
- const clearCookie = (name, options) => response.clearCookie(name, options);
30
- const attachment = filename => response.attachment(filename);
31
- const ResponseInterceptorParams = {
34
+ const clearCookie = (name, options) => {
35
+ response.clearCookie(name, options);
36
+ };
37
+ const attachment = filename => {
38
+ response.attachment(filename);
39
+ };
40
+ const responseInterceptorParams = {
32
41
  request,
33
42
  response,
34
43
  setDelay: _setDelay.setDelay,
@@ -44,16 +53,16 @@ const callResponseInterceptors = async params => {
44
53
  };
45
54
  let updatedData = data;
46
55
  if (interceptors !== null && interceptors !== void 0 && interceptors.routeInterceptor) {
47
- updatedData = await interceptors.routeInterceptor(updatedData, ResponseInterceptorParams);
56
+ updatedData = await interceptors.routeInterceptor(updatedData, responseInterceptorParams);
48
57
  }
49
58
  if (interceptors !== null && interceptors !== void 0 && interceptors.requestInterceptor) {
50
- updatedData = await interceptors.requestInterceptor(updatedData, ResponseInterceptorParams);
59
+ updatedData = await interceptors.requestInterceptor(updatedData, responseInterceptorParams);
51
60
  }
52
61
  if (interceptors !== null && interceptors !== void 0 && interceptors.apiInterceptor) {
53
- updatedData = await interceptors.apiInterceptor(updatedData, ResponseInterceptorParams);
62
+ updatedData = await interceptors.apiInterceptor(updatedData, responseInterceptorParams);
54
63
  }
55
64
  if (interceptors !== null && interceptors !== void 0 && interceptors.serverInterceptor) {
56
- updatedData = await interceptors.serverInterceptor(updatedData, ResponseInterceptorParams);
65
+ updatedData = await interceptors.serverInterceptor(updatedData, responseInterceptorParams);
57
66
  }
58
67
  return updatedData;
59
68
  };
@@ -0,0 +1,262 @@
1
+ import type { Request, Response } from 'express';
2
+
3
+ import type { ResponseInterceptor } from '@/utils/types';
4
+
5
+ import { callResponseInterceptors } from './callResponseInterceptors';
6
+
7
+ describe('callResponseInterceptors: order of calls', () => {
8
+ test('Should call all passed response interceptors in order: route -> request -> api -> server', async () => {
9
+ const initialData = '';
10
+ const request = {} as Request;
11
+ const response = {} as Response;
12
+ const routeInterceptor = jest.fn((data) => `${data}routeInterceptor;`);
13
+ const requestInterceptor = jest.fn((data) => `${data}requestInterceptor;`);
14
+ const apiInterceptor = jest.fn((data) => `${data}apiInterceptor;`);
15
+ const serverInterceptor = jest.fn((data) => `${data}serverInterceptor`);
16
+
17
+ expect(
18
+ await callResponseInterceptors({
19
+ data: initialData,
20
+ request,
21
+ response
22
+ })
23
+ ).toBe('');
24
+ expect(routeInterceptor.mock.calls.length).toBe(0);
25
+ expect(requestInterceptor.mock.calls.length).toBe(0);
26
+ expect(apiInterceptor.mock.calls.length).toBe(0);
27
+ expect(serverInterceptor.mock.calls.length).toBe(0);
28
+
29
+ expect(
30
+ await callResponseInterceptors({
31
+ data: initialData,
32
+ request,
33
+ response,
34
+ interceptors: {
35
+ routeInterceptor,
36
+ apiInterceptor,
37
+ requestInterceptor,
38
+ serverInterceptor
39
+ }
40
+ })
41
+ ).toBe('routeInterceptor;requestInterceptor;apiInterceptor;serverInterceptor');
42
+ expect(routeInterceptor.mock.calls.length).toBe(1);
43
+ expect(requestInterceptor.mock.calls.length).toBe(1);
44
+ expect(apiInterceptor.mock.calls.length).toBe(1);
45
+ expect(serverInterceptor.mock.calls.length).toBe(1);
46
+
47
+ expect(routeInterceptor.mock.invocationCallOrder[0]).toBeLessThan(
48
+ requestInterceptor.mock.invocationCallOrder[0]
49
+ );
50
+ expect(requestInterceptor.mock.invocationCallOrder[0]).toBeLessThan(
51
+ apiInterceptor.mock.invocationCallOrder[0]
52
+ );
53
+ expect(apiInterceptor.mock.invocationCallOrder[0]).toBeLessThan(
54
+ serverInterceptor.mock.invocationCallOrder[0]
55
+ );
56
+ });
57
+ });
58
+
59
+ describe('callResponseInterceptors: params functions', () => {
60
+ test('Should correctly call response getHeader method when use getHeader param', async () => {
61
+ const data = null;
62
+ const request = {};
63
+ const response = { getHeader: jest.fn() };
64
+
65
+ const getHeaderRouteInterceptor: ResponseInterceptor = (data, { getHeader }) => {
66
+ getHeader('header');
67
+ return data;
68
+ };
69
+ await callResponseInterceptors({
70
+ data,
71
+ request: request as Request,
72
+ response: response as unknown as Response,
73
+ interceptors: {
74
+ routeInterceptor: getHeaderRouteInterceptor
75
+ }
76
+ });
77
+ expect(response.getHeader).toHaveBeenCalledWith('header');
78
+ expect(response.getHeader).toHaveBeenCalledTimes(1);
79
+ });
80
+
81
+ test('Should correctly call response getHeaders method when use getHeaders param', async () => {
82
+ const data = null;
83
+ const request = {};
84
+ const response = { getHeaders: jest.fn() };
85
+
86
+ const getHeadersRouteInterceptor: ResponseInterceptor = (data, { getHeaders }) => {
87
+ getHeaders();
88
+ return data;
89
+ };
90
+ await callResponseInterceptors({
91
+ data,
92
+ request: request as Request,
93
+ response: response as unknown as Response,
94
+ interceptors: {
95
+ routeInterceptor: getHeadersRouteInterceptor
96
+ }
97
+ });
98
+ expect(response.getHeaders).toHaveBeenCalledWith();
99
+ expect(response.getHeaders).toHaveBeenCalledTimes(1);
100
+ });
101
+
102
+ test('Should correctly call response set method when use setHeader param', async () => {
103
+ const data = null;
104
+ const request = {};
105
+ const response = { set: jest.fn() };
106
+
107
+ const setHeaderRouteInterceptor: ResponseInterceptor = (data, { setHeader }) => {
108
+ setHeader('name', 'value');
109
+ return data;
110
+ };
111
+ await callResponseInterceptors({
112
+ data,
113
+ request: request as Request,
114
+ response: response as unknown as Response,
115
+ interceptors: {
116
+ routeInterceptor: setHeaderRouteInterceptor
117
+ }
118
+ });
119
+ expect(response.set).toHaveBeenCalledWith('name', 'value');
120
+ expect(response.set).toHaveBeenCalledTimes(1);
121
+ });
122
+
123
+ test('Should correctly call response append method when use appendHeader param', async () => {
124
+ const data = null;
125
+ const request = {};
126
+ const response = { append: jest.fn() };
127
+
128
+ const appendHeaderRouteInterceptor: ResponseInterceptor = (data, { appendHeader }) => {
129
+ appendHeader('name', 'value');
130
+ return data;
131
+ };
132
+ await callResponseInterceptors({
133
+ data,
134
+ request: request as Request,
135
+ response: response as unknown as Response,
136
+ interceptors: {
137
+ routeInterceptor: appendHeaderRouteInterceptor
138
+ }
139
+ });
140
+ expect(response.append).toHaveBeenCalledWith('name', 'value');
141
+ expect(response.append).toHaveBeenCalledTimes(1);
142
+ });
143
+
144
+ test('Should correctly set statusCode into response when use setStatusCode param', async () => {
145
+ const data = null;
146
+ const request = {} as Request;
147
+ const response = {} as Response;
148
+
149
+ const setStatusCodeRouteInterceptor: ResponseInterceptor = (data, { setStatusCode }) => {
150
+ setStatusCode(204);
151
+ return data;
152
+ };
153
+ await callResponseInterceptors({
154
+ data,
155
+ request,
156
+ response,
157
+ interceptors: {
158
+ routeInterceptor: setStatusCodeRouteInterceptor
159
+ }
160
+ });
161
+ expect(response.statusCode).toBe(204);
162
+ });
163
+
164
+ test('Should correctly get cookie from request.cookies object when use getCookie param', async () => {
165
+ const data = null;
166
+ const request = { cookies: { name: 'value' } };
167
+ const response = {};
168
+
169
+ const getCookieRouteInterceptor: ResponseInterceptor = (data, { getCookie }) => {
170
+ expect(getCookie('name')).toBe('value');
171
+ return data;
172
+ };
173
+ await callResponseInterceptors({
174
+ data,
175
+ request: request as unknown as Request,
176
+ response: response as Response,
177
+ interceptors: {
178
+ routeInterceptor: getCookieRouteInterceptor
179
+ }
180
+ });
181
+ });
182
+
183
+ test('Should correctly call response cookie method with/without options when use setCookie param', async () => {
184
+ const data = null;
185
+ const request = {};
186
+ const response = { cookie: jest.fn() };
187
+
188
+ const setCookieWithoutOptionsRouteInterceptor: ResponseInterceptor = (data, { setCookie }) => {
189
+ setCookie('name', 'value');
190
+ return data;
191
+ };
192
+ await callResponseInterceptors({
193
+ data,
194
+ request: request as Request,
195
+ response: response as unknown as Response,
196
+ interceptors: {
197
+ routeInterceptor: setCookieWithoutOptionsRouteInterceptor
198
+ }
199
+ });
200
+ expect(response.cookie).toHaveBeenCalledWith('name', 'value');
201
+ expect(response.cookie).toHaveBeenCalledTimes(1);
202
+
203
+ response.cookie.mockClear();
204
+
205
+ const setCookieWithOptionsRouteInterceptor: ResponseInterceptor = (data, { setCookie }) => {
206
+ setCookie('name', 'value', { path: '/your/path' });
207
+ return data;
208
+ };
209
+ await callResponseInterceptors({
210
+ data,
211
+ request: request as Request,
212
+ response: response as unknown as Response,
213
+ interceptors: {
214
+ routeInterceptor: setCookieWithOptionsRouteInterceptor
215
+ }
216
+ });
217
+ expect(response.cookie).toHaveBeenCalledWith('name', 'value', { path: '/your/path' });
218
+ expect(response.cookie).toBeCalledTimes(1);
219
+ });
220
+
221
+ test('Should correctly call response clearCookie method when use clearCookie param', async () => {
222
+ const data = null;
223
+ const request = {};
224
+ const response = { clearCookie: jest.fn() };
225
+
226
+ const clearCookieRouteInterceptor: ResponseInterceptor = (data, { clearCookie }) => {
227
+ clearCookie('name', { path: '/your/path' });
228
+ return data;
229
+ };
230
+ await callResponseInterceptors({
231
+ data,
232
+ request: request as Request,
233
+ response: response as unknown as Response,
234
+ interceptors: {
235
+ routeInterceptor: clearCookieRouteInterceptor
236
+ }
237
+ });
238
+ expect(response.clearCookie).toHaveBeenCalledWith('name', { path: '/your/path' });
239
+ expect(response.clearCookie).toHaveBeenCalledTimes(1);
240
+ });
241
+
242
+ test('Should correctly call response attachment method when use attachment param', async () => {
243
+ const data = null;
244
+ const request = {};
245
+ const response = { attachment: jest.fn() };
246
+
247
+ const attachmentRouteInterceptor: ResponseInterceptor = (data, { attachment }) => {
248
+ attachment('filename');
249
+ return data;
250
+ };
251
+ await callResponseInterceptors({
252
+ data,
253
+ request: request as Request,
254
+ response: response as unknown as Response,
255
+ interceptors: {
256
+ routeInterceptor: attachmentRouteInterceptor
257
+ }
258
+ });
259
+ expect(response.attachment).toHaveBeenCalledWith('filename');
260
+ expect(response.attachment).toHaveBeenCalledTimes(1);
261
+ });
262
+ });
@@ -0,0 +1,20 @@
1
+ import { isPlainObject } from './isPlainObject';
2
+
3
+ describe('isPlainObject', () => {
4
+ test('Object value should return true', () => {
5
+ expect(isPlainObject(Object({}))).toBe(true);
6
+ });
7
+
8
+ test('All Primitive, array, function values should return false', () => {
9
+ expect(isPlainObject(Number(1))).toBe(false);
10
+ expect(isPlainObject(BigInt(9007199254740991n))).toBe(false);
11
+ expect(isPlainObject(String('test'))).toBe(false);
12
+ expect(isPlainObject(Boolean(true))).toBe(false);
13
+ expect(isPlainObject(Symbol('test'))).toBe(false);
14
+ expect(isPlainObject(Array([]))).toBe(false);
15
+ expect(isPlainObject(() => {})).toBe(false);
16
+ expect(isPlainObject(undefined)).toBe(false);
17
+ expect(isPlainObject(null)).toBe(false);
18
+ expect(isPlainObject(/\d/)).toBe(false);
19
+ });
20
+ });