getta 0.4.7 → 1.0.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/README.md +161 -7
- package/dist/main/index.mjs +621 -0
- package/dist/main/index.mjs.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/{lib → dist}/types/constants.d.ts +2 -2
- package/dist/types/constants.d.ts.map +1 -0
- package/dist/types/helpers/buildEndpoint/index.d.ts +3 -0
- package/dist/types/helpers/buildEndpoint/index.d.ts.map +1 -0
- package/{lib/types/helpers/build-endpoint → dist/types/helpers/buildEndpoint}/types.d.ts +2 -2
- package/dist/types/helpers/buildEndpoint/types.d.ts.map +1 -0
- package/dist/types/helpers/defaultPathTemplateCallback/index.d.ts +2 -0
- package/dist/types/helpers/defaultPathTemplateCallback/index.d.ts.map +1 -0
- package/dist/types/helpers/delay/index.d.ts +2 -0
- package/{lib → dist}/types/helpers/delay/index.d.ts.map +1 -1
- package/dist/types/helpers/getResponseGroup/index.d.ts +2 -0
- package/dist/types/helpers/getResponseGroup/index.d.ts.map +1 -0
- package/dist/types/helpers/isCacheabilityValid/index.d.ts +3 -0
- package/dist/types/helpers/isCacheabilityValid/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/{lib → dist}/types/main.d.ts +12 -12
- package/dist/types/main.d.ts.map +1 -0
- package/dist/types/types.d.ts +161 -0
- package/dist/types/types.d.ts.map +1 -0
- package/package.json +113 -145
- package/src/{__tests__ → __testUtils__}/data/136-7317.json +1 -1
- package/src/{__tests__ → __testUtils__}/data/180-1387.json +1 -1
- package/src/{__tests__ → __testUtils__}/data/183-3905.json +1 -1
- package/src/{__tests__ → __testUtils__}/data/202-3315.json +1 -1
- package/src/__testUtils__/data/index.ts +23 -0
- package/src/__testUtils__/helpers/index.ts +49 -0
- package/src/constants.ts +28 -28
- package/src/helpers/buildEndpoint/index.ts +34 -0
- package/src/helpers/{build-endpoint → buildEndpoint}/types.ts +2 -2
- package/src/helpers/defaultPathTemplateCallback/index.test.ts +11 -0
- package/src/helpers/defaultPathTemplateCallback/index.ts +17 -0
- package/src/helpers/delay/index.ts +2 -2
- package/src/helpers/getResponseGroup/index.ts +25 -0
- package/src/helpers/isCacheabilityValid/index.ts +6 -0
- package/src/index.ts +4 -4
- package/src/main.test.ts +283 -411
- package/src/main.ts +238 -241
- package/src/types.ts +114 -16
- package/tsconfig.build.json +14 -0
- package/tsconfig.json +9 -0
- package/CHANGELOG.md +0 -250
- package/jest.setup.js +0 -10
- package/lib/browser/index.js +0 -2
- package/lib/browser/index.js.map +0 -1
- package/lib/browser/production.analysis.txt +0 -91
- package/lib/main/constants.js +0 -97
- package/lib/main/helpers/build-endpoint/index.js +0 -38
- package/lib/main/helpers/build-endpoint/types.js +0 -1
- package/lib/main/helpers/default-path-template-callback/index.js +0 -16
- package/lib/main/helpers/delay/index.js +0 -12
- package/lib/main/helpers/get-response-group/index.js +0 -27
- package/lib/main/helpers/is-cacheability-valid/index.js +0 -13
- package/lib/main/index.js +0 -62
- package/lib/main/main.js +0 -580
- package/lib/main/types.js +0 -1
- package/lib/module/constants.mjs +0 -49
- package/lib/module/helpers/build-endpoint/index.mjs +0 -28
- package/lib/module/helpers/build-endpoint/types.mjs +0 -0
- package/lib/module/helpers/default-path-template-callback/index.mjs +0 -9
- package/lib/module/helpers/delay/index.mjs +0 -4
- package/lib/module/helpers/get-response-group/index.mjs +0 -19
- package/lib/module/helpers/is-cacheability-valid/index.mjs +0 -6
- package/lib/module/index.mjs +0 -4
- package/lib/module/main.mjs +0 -576
- package/lib/module/types.mjs +0 -0
- package/lib/types/__tests__/data/index.d.ts +0 -17
- package/lib/types/__tests__/data/index.d.ts.map +0 -1
- package/lib/types/__tests__/helpers/index.d.ts +0 -29
- package/lib/types/__tests__/helpers/index.d.ts.map +0 -1
- package/lib/types/__tests__/types.d.ts +0 -13
- package/lib/types/__tests__/types.d.ts.map +0 -1
- package/lib/types/constants.d.ts.map +0 -1
- package/lib/types/helpers/build-endpoint/index.d.ts +0 -3
- package/lib/types/helpers/build-endpoint/index.d.ts.map +0 -1
- package/lib/types/helpers/build-endpoint/types.d.ts.map +0 -1
- package/lib/types/helpers/default-path-template-callback/index.d.ts +0 -3
- package/lib/types/helpers/default-path-template-callback/index.d.ts.map +0 -1
- package/lib/types/helpers/default-path-template-callback/index.test.d.ts +0 -2
- package/lib/types/helpers/default-path-template-callback/index.test.d.ts.map +0 -1
- package/lib/types/helpers/delay/index.d.ts +0 -2
- package/lib/types/helpers/get-response-group/index.d.ts +0 -2
- package/lib/types/helpers/get-response-group/index.d.ts.map +0 -1
- package/lib/types/helpers/is-cacheability-valid/index.d.ts +0 -3
- package/lib/types/helpers/is-cacheability-valid/index.d.ts.map +0 -1
- package/lib/types/index.d.ts +0 -5
- package/lib/types/index.d.ts.map +0 -1
- package/lib/types/main.d.ts.map +0 -1
- package/lib/types/main.test.d.ts +0 -2
- package/lib/types/main.test.d.ts.map +0 -1
- package/lib/types/types.d.ts +0 -69
- package/lib/types/types.d.ts.map +0 -1
- package/src/__tests__/data/index.ts +0 -19
- package/src/__tests__/helpers/index.ts +0 -61
- package/src/__tests__/types.ts +0 -14
- package/src/helpers/build-endpoint/index.ts +0 -34
- package/src/helpers/default-path-template-callback/index.test.ts +0 -11
- package/src/helpers/default-path-template-callback/index.ts +0 -16
- package/src/helpers/get-response-group/index.ts +0 -22
- package/src/helpers/is-cacheability-valid/index.ts +0 -6
package/src/main.test.ts
CHANGED
|
@@ -1,362 +1,277 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import { PRD_136_7317 } from
|
|
1
|
+
import { jest } from '@jest/globals';
|
|
2
|
+
import { mockFetch } from 'fetch-mocked';
|
|
3
|
+
import { performance } from 'node:perf_hooks';
|
|
4
|
+
import { Md5 } from 'ts-md5';
|
|
5
|
+
import { PRD_136_7317 } from './__testUtils__/data/index.ts';
|
|
6
6
|
import {
|
|
7
7
|
basePath,
|
|
8
|
+
buildTestEndpoint,
|
|
8
9
|
defaultEtag,
|
|
10
|
+
defaultHeaders,
|
|
9
11
|
defaultPath,
|
|
10
12
|
defaultPathTemplateData,
|
|
11
13
|
defaultPayload,
|
|
12
14
|
getCache,
|
|
15
|
+
graphqlPath,
|
|
13
16
|
idPathTemplateData,
|
|
14
|
-
mockRequest,
|
|
15
17
|
pathTemplateDataWithoutID,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
import { Getta, createRestClient } from "./main";
|
|
32
|
-
import { ResponseDataWithErrors, ShortcutProperties } from "./types";
|
|
33
|
-
|
|
34
|
-
describe("Getta", () => {
|
|
35
|
-
describe("constructor", () => {
|
|
36
|
-
it("SHOULD return an instance of the Getta class", () => {
|
|
18
|
+
} from './__testUtils__/helpers/index.ts';
|
|
19
|
+
import * as consts from './constants.ts';
|
|
20
|
+
import { delay } from './helpers/delay/index.ts';
|
|
21
|
+
import { Getta, createRestClient } from './main.ts';
|
|
22
|
+
import { type FetchResponse, type ResponseDataWithErrors, type ShortcutProperties } from './types.ts';
|
|
23
|
+
|
|
24
|
+
const mockedFetch = mockFetch(jest.fn);
|
|
25
|
+
|
|
26
|
+
describe('Getta', () => {
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
mockedFetch.mockReset();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe('constructor', () => {
|
|
32
|
+
it('should return an instance of the Getta class', () => {
|
|
37
33
|
const restClient = createRestClient({ basePath, cache: getCache(), performance });
|
|
38
34
|
expect(restClient).toBeInstanceOf(Getta);
|
|
39
35
|
});
|
|
40
36
|
});
|
|
41
37
|
|
|
42
|
-
describe(
|
|
43
|
-
let restClient: Getta & ShortcutProperties<
|
|
38
|
+
describe('get method', () => {
|
|
39
|
+
let restClient: Getta & ShortcutProperties<'getProduct'>;
|
|
44
40
|
let response: ResponseDataWithErrors | ResponseDataWithErrors[];
|
|
45
41
|
|
|
46
|
-
|
|
47
|
-
restClient = createRestClient<
|
|
42
|
+
beforeEach(() => {
|
|
43
|
+
restClient = createRestClient<'getProduct'>(
|
|
48
44
|
{ basePath, cache: getCache(), performance },
|
|
49
45
|
{
|
|
50
46
|
getProduct: [
|
|
51
47
|
defaultPath,
|
|
52
48
|
{
|
|
53
|
-
method: GET_METHOD,
|
|
49
|
+
method: consts.GET_METHOD,
|
|
54
50
|
pathTemplateData: pathTemplateDataWithoutID,
|
|
55
51
|
},
|
|
56
52
|
],
|
|
57
|
-
}
|
|
53
|
+
}
|
|
58
54
|
);
|
|
59
55
|
});
|
|
60
56
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
defaultPath,
|
|
65
|
-
PRD_136_7317.body,
|
|
66
|
-
{ pathTemplateData: defaultPathTemplateData },
|
|
67
|
-
({ endpoint, ...rest }) => {
|
|
68
|
-
fetchMock.get(endpoint, rest);
|
|
69
|
-
},
|
|
70
|
-
);
|
|
57
|
+
afterEach(async () => {
|
|
58
|
+
await restClient.cache?.clear();
|
|
59
|
+
});
|
|
71
60
|
|
|
72
|
-
|
|
73
|
-
|
|
61
|
+
describe('when a resource is requested', () => {
|
|
62
|
+
beforeEach(async () => {
|
|
63
|
+
mockedFetch.mockGetOnce(buildTestEndpoint(defaultPath), {
|
|
64
|
+
body: PRD_136_7317.body,
|
|
65
|
+
headers: defaultHeaders,
|
|
66
|
+
});
|
|
74
67
|
|
|
75
|
-
|
|
76
|
-
await tearDownTest({ fetchMock, restClient });
|
|
68
|
+
response = await restClient.get(defaultPath, { pathTemplateData: defaultPathTemplateData });
|
|
77
69
|
});
|
|
78
70
|
|
|
79
|
-
it(
|
|
80
|
-
expect(
|
|
71
|
+
it('should have made one request', () => {
|
|
72
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
81
73
|
});
|
|
82
74
|
|
|
83
|
-
it(
|
|
75
|
+
it('should return the correct response', () => {
|
|
84
76
|
expect(response).toEqual(
|
|
85
77
|
expect.objectContaining({
|
|
86
78
|
data: PRD_136_7317.body,
|
|
87
|
-
})
|
|
79
|
+
})
|
|
88
80
|
);
|
|
89
81
|
});
|
|
90
82
|
});
|
|
91
83
|
|
|
92
|
-
describe(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
({ endpoint, ...rest }) => {
|
|
99
|
-
fetchMock.get(endpoint, rest);
|
|
100
|
-
},
|
|
101
|
-
);
|
|
84
|
+
describe('when a resource is requested with a shortcut', () => {
|
|
85
|
+
beforeEach(async () => {
|
|
86
|
+
mockedFetch.mockGetOnce(buildTestEndpoint(defaultPath), {
|
|
87
|
+
body: PRD_136_7317.body,
|
|
88
|
+
headers: defaultHeaders,
|
|
89
|
+
});
|
|
102
90
|
|
|
103
91
|
response = await restClient.getProduct({ pathTemplateData: idPathTemplateData });
|
|
104
92
|
});
|
|
105
93
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it("SHOULD have made one request", () => {
|
|
111
|
-
expect(fetchMock.calls().length).toBe(1);
|
|
94
|
+
it('should have made one request', () => {
|
|
95
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
112
96
|
});
|
|
113
97
|
|
|
114
|
-
it(
|
|
98
|
+
it('should return the correct response', () => {
|
|
115
99
|
expect(response).toEqual(
|
|
116
100
|
expect.objectContaining({
|
|
117
101
|
data: PRD_136_7317.body,
|
|
118
|
-
})
|
|
102
|
+
})
|
|
119
103
|
);
|
|
120
104
|
});
|
|
121
105
|
});
|
|
122
106
|
|
|
123
|
-
describe(
|
|
124
|
-
describe(
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
({ endpoint, ...rest }) => {
|
|
131
|
-
fetchMock.get(endpoint, rest);
|
|
132
|
-
},
|
|
133
|
-
);
|
|
107
|
+
describe('when a resource is in the cache', () => {
|
|
108
|
+
describe('when the cache entry is valid', () => {
|
|
109
|
+
beforeEach(async () => {
|
|
110
|
+
mockedFetch.mockGetOnce(buildTestEndpoint(defaultPath), {
|
|
111
|
+
body: PRD_136_7317.body,
|
|
112
|
+
headers: defaultHeaders,
|
|
113
|
+
});
|
|
134
114
|
|
|
135
115
|
await restClient.getProduct({ pathTemplateData: idPathTemplateData });
|
|
136
|
-
|
|
116
|
+
mockedFetch.mockClear();
|
|
137
117
|
response = await restClient.getProduct({ pathTemplateData: idPathTemplateData });
|
|
138
118
|
});
|
|
139
119
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
it("SHOULD not have made a request", () => {
|
|
145
|
-
expect(fetchMock.calls().length).toBe(0);
|
|
120
|
+
it('should not have made a request', () => {
|
|
121
|
+
expect(mockedFetch).not.toHaveBeenCalled();
|
|
146
122
|
});
|
|
147
123
|
|
|
148
|
-
it(
|
|
124
|
+
it('should return the correct response', () => {
|
|
149
125
|
expect(response).toEqual(
|
|
150
126
|
expect.objectContaining({
|
|
151
127
|
data: PRD_136_7317.body,
|
|
152
|
-
})
|
|
128
|
+
})
|
|
153
129
|
);
|
|
154
130
|
});
|
|
155
131
|
});
|
|
156
132
|
|
|
157
|
-
describe(
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
mockRequest(
|
|
164
|
-
defaultPath,
|
|
165
|
-
PRD_136_7317.body,
|
|
166
|
-
{ headers: { "cache-control": "public, max-age=1" }, pathTemplateData: defaultPathTemplateData },
|
|
167
|
-
({ endpoint, ...rest }) => {
|
|
168
|
-
fetchMock.get(endpoint, rest);
|
|
169
|
-
},
|
|
170
|
-
);
|
|
133
|
+
describe('when the cache entry is invalid', () => {
|
|
134
|
+
beforeEach(async () => {
|
|
135
|
+
mockedFetch.mockGetOnce(buildTestEndpoint(defaultPath), {
|
|
136
|
+
body: PRD_136_7317.body,
|
|
137
|
+
headers: { ...defaultHeaders, 'cache-control': 'public, max-age=1' },
|
|
138
|
+
});
|
|
171
139
|
|
|
172
140
|
await restClient.getProduct({ pathTemplateData: idPathTemplateData });
|
|
173
141
|
await delay(1000);
|
|
142
|
+
mockedFetch.mockClear();
|
|
143
|
+
});
|
|
174
144
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
await invalidCacheEntryTestSetup();
|
|
181
|
-
|
|
182
|
-
mockRequest(
|
|
183
|
-
defaultPath,
|
|
184
|
-
PRD_136_7317.body,
|
|
185
|
-
{ pathTemplateData: defaultPathTemplateData },
|
|
186
|
-
({ headers }) => {
|
|
187
|
-
fetchMock.mock(matcher, { headers, status: 304 });
|
|
188
|
-
},
|
|
145
|
+
describe('when the response returns not modified status code', () => {
|
|
146
|
+
beforeEach(async () => {
|
|
147
|
+
mockedFetch.mockGetOnce(
|
|
148
|
+
{ headers: { [consts.IF_NONE_MATCH_HEADER]: defaultEtag }, url: buildTestEndpoint(defaultPath) },
|
|
149
|
+
{ headers: defaultHeaders, status: 304 }
|
|
189
150
|
);
|
|
190
151
|
|
|
191
152
|
response = await restClient.getProduct({ pathTemplateData: idPathTemplateData });
|
|
192
153
|
});
|
|
193
154
|
|
|
194
|
-
|
|
195
|
-
|
|
155
|
+
it('should have made one request', () => {
|
|
156
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
196
157
|
});
|
|
197
158
|
|
|
198
|
-
it(
|
|
199
|
-
expect(fetchMock.calls().length).toBe(1);
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
it("SHOULD return the correct response", () => {
|
|
159
|
+
it('should return the correct response', () => {
|
|
203
160
|
expect(response).toEqual(
|
|
204
161
|
expect.objectContaining({
|
|
205
162
|
data: PRD_136_7317.body,
|
|
206
|
-
})
|
|
163
|
+
})
|
|
207
164
|
);
|
|
208
165
|
});
|
|
209
166
|
});
|
|
210
167
|
|
|
211
|
-
describe(
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
defaultPath,
|
|
217
|
-
PRD_136_7317.body,
|
|
218
|
-
{ pathTemplateData: defaultPathTemplateData },
|
|
219
|
-
({ body, headers }) => {
|
|
220
|
-
fetchMock.mock(matcher, { body, headers, status: 200 });
|
|
221
|
-
},
|
|
168
|
+
describe('when the response returns the resource', () => {
|
|
169
|
+
beforeEach(async () => {
|
|
170
|
+
mockedFetch.mockGetOnce(
|
|
171
|
+
{ headers: { [consts.IF_NONE_MATCH_HEADER]: defaultEtag }, url: buildTestEndpoint(defaultPath) },
|
|
172
|
+
{ body: PRD_136_7317.body, headers: defaultHeaders }
|
|
222
173
|
);
|
|
223
174
|
|
|
224
175
|
response = await restClient.getProduct({ pathTemplateData: idPathTemplateData });
|
|
225
176
|
});
|
|
226
177
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
it("SHOULD have made one request", () => {
|
|
232
|
-
expect(fetchMock.calls().length).toBe(1);
|
|
178
|
+
it('should have made one request', () => {
|
|
179
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
233
180
|
});
|
|
234
181
|
|
|
235
|
-
it(
|
|
182
|
+
it('should return the correct response', () => {
|
|
236
183
|
expect(response).toEqual(
|
|
237
184
|
expect.objectContaining({
|
|
238
185
|
data: PRD_136_7317.body,
|
|
239
|
-
})
|
|
186
|
+
})
|
|
240
187
|
);
|
|
241
188
|
});
|
|
242
189
|
});
|
|
243
190
|
|
|
244
|
-
describe(
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
});
|
|
191
|
+
describe('when the response returns a 404', () => {
|
|
192
|
+
beforeEach(async () => {
|
|
193
|
+
mockedFetch.mockGetOnce(
|
|
194
|
+
{ headers: { [consts.IF_NONE_MATCH_HEADER]: defaultEtag }, url: buildTestEndpoint(defaultPath) },
|
|
195
|
+
{ status: 404 }
|
|
196
|
+
);
|
|
251
197
|
|
|
252
198
|
response = await restClient.getProduct({ pathTemplateData: idPathTemplateData });
|
|
253
199
|
});
|
|
254
200
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
it("SHOULD have made one request", () => {
|
|
260
|
-
expect(fetchMock.calls().length).toBe(1);
|
|
201
|
+
it('should have made one request', () => {
|
|
202
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
261
203
|
});
|
|
262
204
|
|
|
263
|
-
it(
|
|
205
|
+
it('should return the correct response', () => {
|
|
264
206
|
expect(response).toEqual(
|
|
265
207
|
expect.objectContaining({
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
}),
|
|
208
|
+
errors: [new Error(consts.RESOURCE_NOT_FOUND_ERROR)],
|
|
209
|
+
})
|
|
269
210
|
);
|
|
270
211
|
});
|
|
271
212
|
});
|
|
272
213
|
});
|
|
273
214
|
});
|
|
274
215
|
|
|
275
|
-
describe(
|
|
276
|
-
const REDIRECT_COOKIE_FLAG =
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
beforeAll(async () => {
|
|
283
|
-
mockRequest(
|
|
284
|
-
defaultPath,
|
|
285
|
-
{},
|
|
286
|
-
{ headers: { [LOCATION_HEADER]: basePath }, pathTemplateData: defaultPathTemplateData },
|
|
287
|
-
({ body, headers }) => {
|
|
288
|
-
fetchMock.mock(matcher, { body, headers, status: 301 });
|
|
289
|
-
},
|
|
216
|
+
describe('when a request is redirected more than five times', () => {
|
|
217
|
+
const REDIRECT_COOKIE_FLAG = 'status=redirect';
|
|
218
|
+
|
|
219
|
+
beforeEach(async () => {
|
|
220
|
+
mockedFetch.mockGet(
|
|
221
|
+
{ headers: { [consts.COOKIE_HEADER]: REDIRECT_COOKIE_FLAG }, url: '*' },
|
|
222
|
+
{ headers: { ...defaultHeaders, [consts.LOCATION_HEADER]: basePath }, status: 301 }
|
|
290
223
|
);
|
|
291
224
|
|
|
292
225
|
response = await restClient.getProduct({
|
|
293
|
-
headers: { [COOKIE_HEADER]: REDIRECT_COOKIE_FLAG },
|
|
226
|
+
headers: { [consts.COOKIE_HEADER]: REDIRECT_COOKIE_FLAG },
|
|
294
227
|
pathTemplateData: idPathTemplateData,
|
|
295
228
|
});
|
|
296
229
|
});
|
|
297
230
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
it("SHOULD have made five requests", () => {
|
|
303
|
-
expect(fetchMock.calls().length).toBe(5);
|
|
231
|
+
it('should have made five requests', () => {
|
|
232
|
+
expect(mockedFetch).toHaveBeenCalledTimes(5);
|
|
304
233
|
});
|
|
305
234
|
|
|
306
|
-
it(
|
|
235
|
+
it('should return the correct response', () => {
|
|
307
236
|
expect(response).toEqual(
|
|
308
237
|
expect.objectContaining({
|
|
309
|
-
errors: [new Error(`${MAX_REDIRECTS_EXCEEDED_ERROR} 5.`)],
|
|
310
|
-
})
|
|
238
|
+
errors: [new Error(`${consts.MAX_REDIRECTS_EXCEEDED_ERROR} 5.`)],
|
|
239
|
+
})
|
|
311
240
|
);
|
|
312
241
|
});
|
|
313
242
|
});
|
|
314
243
|
|
|
315
|
-
describe(
|
|
316
|
-
const RETRY_COOKIE_FLAG =
|
|
244
|
+
describe('when a request is retried more than three times', () => {
|
|
245
|
+
const RETRY_COOKIE_FLAG = 'status=retry';
|
|
317
246
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
mockRequest(defaultPath, {}, { pathTemplateData: defaultPathTemplateData }, ({ body, headers }) => {
|
|
324
|
-
fetchMock.mock(matcher, { body, headers, status: 500 });
|
|
325
|
-
});
|
|
247
|
+
beforeEach(async () => {
|
|
248
|
+
mockedFetch.mockGet(
|
|
249
|
+
{ headers: { [consts.COOKIE_HEADER]: RETRY_COOKIE_FLAG }, url: buildTestEndpoint(defaultPath) },
|
|
250
|
+
{ body: PRD_136_7317.body, status: 500 }
|
|
251
|
+
);
|
|
326
252
|
|
|
327
253
|
response = await restClient.getProduct({
|
|
328
|
-
headers: { [COOKIE_HEADER]: RETRY_COOKIE_FLAG },
|
|
254
|
+
headers: { [consts.COOKIE_HEADER]: RETRY_COOKIE_FLAG },
|
|
329
255
|
pathTemplateData: idPathTemplateData,
|
|
330
256
|
});
|
|
331
257
|
});
|
|
332
258
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
it("SHOULD have made three requests", () => {
|
|
338
|
-
expect(fetchMock.calls().length).toBe(3);
|
|
259
|
+
it('should have made three requests', () => {
|
|
260
|
+
expect(mockedFetch).toHaveBeenCalledTimes(3);
|
|
339
261
|
});
|
|
340
262
|
|
|
341
|
-
it(
|
|
263
|
+
it('should return the correct response', () => {
|
|
342
264
|
expect(response).toEqual(
|
|
343
265
|
expect.objectContaining({
|
|
344
|
-
errors: [new Error(`${MAX_RETRIES_EXCEEDED_ERROR} 3.`)],
|
|
345
|
-
})
|
|
266
|
+
errors: [new Error(`${consts.MAX_RETRIES_EXCEEDED_ERROR} 3.`)],
|
|
267
|
+
})
|
|
346
268
|
);
|
|
347
269
|
});
|
|
348
270
|
});
|
|
349
271
|
|
|
350
|
-
describe(
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
defaultPath,
|
|
354
|
-
PRD_136_7317.body,
|
|
355
|
-
{ pathTemplateData: defaultPathTemplateData },
|
|
356
|
-
({ endpoint, ...rest }) => {
|
|
357
|
-
fetchMock.get(endpoint, rest);
|
|
358
|
-
},
|
|
359
|
-
);
|
|
272
|
+
describe('when the same resource is requested in quick succession', () => {
|
|
273
|
+
beforeEach(async () => {
|
|
274
|
+
mockedFetch.mockGet(buildTestEndpoint(defaultPath), { body: PRD_136_7317.body, headers: defaultHeaders });
|
|
360
275
|
|
|
361
276
|
response = await Promise.all([
|
|
362
277
|
restClient.get(defaultPath, { pathTemplateData: defaultPathTemplateData }),
|
|
@@ -364,336 +279,293 @@ describe("Getta", () => {
|
|
|
364
279
|
]);
|
|
365
280
|
});
|
|
366
281
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
it("SHOULD have made one request", () => {
|
|
372
|
-
expect(fetchMock.calls().length).toBe(1);
|
|
282
|
+
it('should have made one request', () => {
|
|
283
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
373
284
|
});
|
|
374
285
|
|
|
375
|
-
it(
|
|
376
|
-
expect(
|
|
286
|
+
it('should return the correct response', () => {
|
|
287
|
+
expect(response as ResponseDataWithErrors[]).toEqual([
|
|
377
288
|
expect.objectContaining({
|
|
378
289
|
data: PRD_136_7317.body,
|
|
379
290
|
}),
|
|
380
|
-
);
|
|
381
|
-
|
|
382
|
-
expect((response as ResponseDataWithErrors[])[1]).toEqual(
|
|
383
291
|
expect.objectContaining({
|
|
384
292
|
data: PRD_136_7317.body,
|
|
385
293
|
}),
|
|
386
|
-
);
|
|
294
|
+
]);
|
|
387
295
|
});
|
|
388
296
|
});
|
|
389
297
|
|
|
390
|
-
describe(
|
|
391
|
-
|
|
298
|
+
describe('when a request times out', () => {
|
|
299
|
+
beforeEach(async () => {
|
|
300
|
+
mockedFetch.mockGet(buildTestEndpoint(defaultPath), { body: PRD_136_7317.body }, { delay: 200 });
|
|
301
|
+
// @ts-expect-error property is private
|
|
302
|
+
restClient._fetchTimeout = 100;
|
|
303
|
+
|
|
304
|
+
response = await restClient.getProduct({
|
|
305
|
+
pathTemplateData: idPathTemplateData,
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
it('should have made one request', () => {
|
|
310
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it('should return the correct response', () => {
|
|
314
|
+
expect(response).toEqual(
|
|
315
|
+
expect.objectContaining({
|
|
316
|
+
errors: [new Error(`${consts.FETCH_TIMEOUT_ERROR} 100ms.`)],
|
|
317
|
+
})
|
|
318
|
+
);
|
|
319
|
+
});
|
|
392
320
|
});
|
|
393
321
|
});
|
|
394
322
|
|
|
395
|
-
describe(
|
|
396
|
-
let restClient: Getta & ShortcutProperties<
|
|
397
|
-
let response:
|
|
323
|
+
describe('post method', () => {
|
|
324
|
+
let restClient: Getta & ShortcutProperties<'postProduct'>;
|
|
325
|
+
let response: FetchResponse;
|
|
398
326
|
|
|
399
|
-
|
|
400
|
-
restClient = createRestClient<
|
|
327
|
+
beforeEach(() => {
|
|
328
|
+
restClient = createRestClient<'postProduct'>(
|
|
401
329
|
{ basePath, cache: getCache(), performance },
|
|
402
330
|
{
|
|
403
331
|
postProduct: [
|
|
404
|
-
|
|
332
|
+
graphqlPath,
|
|
405
333
|
{
|
|
406
|
-
method: POST_METHOD,
|
|
407
|
-
pathTemplateData: pathTemplateDataWithoutID,
|
|
334
|
+
method: consts.POST_METHOD,
|
|
408
335
|
},
|
|
409
336
|
],
|
|
410
|
-
}
|
|
337
|
+
}
|
|
411
338
|
);
|
|
412
339
|
});
|
|
413
340
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
}
|
|
341
|
+
afterEach(async () => {
|
|
342
|
+
await restClient.cache?.clear();
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
describe('when a resource is requested', () => {
|
|
346
|
+
beforeEach(async () => {
|
|
347
|
+
mockedFetch.mockPostOnce(
|
|
348
|
+
{ body: { mock: true }, url: buildTestEndpoint(graphqlPath) },
|
|
349
|
+
{ body: PRD_136_7317.body, headers: defaultHeaders }
|
|
423
350
|
);
|
|
424
351
|
|
|
425
|
-
response = await restClient.post(
|
|
426
|
-
body: defaultPayload,
|
|
427
|
-
pathTemplateData: defaultPathTemplateData,
|
|
352
|
+
response = await restClient.post(graphqlPath, {
|
|
353
|
+
body: JSON.stringify({ ...defaultPayload, mock: true }),
|
|
428
354
|
});
|
|
429
355
|
});
|
|
430
356
|
|
|
431
|
-
|
|
432
|
-
|
|
357
|
+
it('should have made one request', () => {
|
|
358
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
433
359
|
});
|
|
434
360
|
|
|
435
|
-
it(
|
|
436
|
-
expect(fetchMock.calls().length).toBe(1);
|
|
437
|
-
});
|
|
438
|
-
|
|
439
|
-
it("SHOULD return the correct response", () => {
|
|
361
|
+
it('should return the correct response', () => {
|
|
440
362
|
expect(response).toEqual(
|
|
441
363
|
expect.objectContaining({
|
|
442
364
|
data: PRD_136_7317.body,
|
|
443
|
-
})
|
|
365
|
+
})
|
|
444
366
|
);
|
|
445
367
|
});
|
|
446
368
|
});
|
|
447
369
|
|
|
448
|
-
describe(
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
PRD_136_7317.body,
|
|
453
|
-
{ pathTemplateData: defaultPathTemplateData },
|
|
454
|
-
({ endpoint, ...rest }) => {
|
|
455
|
-
fetchMock.post(endpoint, rest);
|
|
456
|
-
},
|
|
370
|
+
describe('when a resource is requested with a shortcut', () => {
|
|
371
|
+
beforeEach(async () => {
|
|
372
|
+
mockedFetch.mockPostOnce(
|
|
373
|
+
{ body: { mock: true }, url: buildTestEndpoint(graphqlPath) },
|
|
374
|
+
{ body: PRD_136_7317.body, headers: defaultHeaders }
|
|
457
375
|
);
|
|
458
376
|
|
|
459
|
-
response = await restClient.postProduct({ body: defaultPayload,
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
afterAll(async () => {
|
|
463
|
-
await tearDownTest({ fetchMock, restClient });
|
|
377
|
+
response = await restClient.postProduct({ body: JSON.stringify({ ...defaultPayload, mock: true }) });
|
|
464
378
|
});
|
|
465
379
|
|
|
466
|
-
it(
|
|
467
|
-
expect(
|
|
380
|
+
it('should have made one request', () => {
|
|
381
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
468
382
|
});
|
|
469
383
|
|
|
470
|
-
it(
|
|
384
|
+
it('should return the correct response', () => {
|
|
471
385
|
expect(response).toEqual(
|
|
472
386
|
expect.objectContaining({
|
|
473
387
|
data: PRD_136_7317.body,
|
|
474
|
-
})
|
|
388
|
+
})
|
|
475
389
|
);
|
|
476
390
|
});
|
|
477
391
|
});
|
|
478
392
|
});
|
|
479
393
|
|
|
480
|
-
describe(
|
|
481
|
-
let restClient: Getta & ShortcutProperties<
|
|
482
|
-
let response:
|
|
483
|
-
let requestHash: string;
|
|
394
|
+
describe('delete method', () => {
|
|
395
|
+
let restClient: Getta & ShortcutProperties<'deleteProduct'>;
|
|
396
|
+
let response: FetchResponse;
|
|
484
397
|
|
|
485
|
-
|
|
486
|
-
restClient = createRestClient<
|
|
398
|
+
beforeEach(() => {
|
|
399
|
+
restClient = createRestClient<'deleteProduct'>(
|
|
487
400
|
{ basePath, cache: getCache(), performance },
|
|
488
401
|
{
|
|
489
402
|
deleteProduct: [
|
|
490
403
|
defaultPath,
|
|
491
404
|
{
|
|
492
|
-
method: DELETE_METHOD,
|
|
405
|
+
method: consts.DELETE_METHOD,
|
|
493
406
|
pathTemplateData: pathTemplateDataWithoutID,
|
|
494
407
|
},
|
|
495
408
|
],
|
|
496
|
-
}
|
|
409
|
+
}
|
|
497
410
|
);
|
|
498
411
|
});
|
|
499
412
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
defaultPath,
|
|
504
|
-
PRD_136_7317.body,
|
|
505
|
-
{ pathTemplateData: defaultPathTemplateData },
|
|
506
|
-
({ endpoint, ...rest }) => {
|
|
507
|
-
requestHash = md5(endpoint);
|
|
508
|
-
fetchMock.get(endpoint, rest);
|
|
509
|
-
},
|
|
510
|
-
);
|
|
413
|
+
afterEach(async () => {
|
|
414
|
+
await restClient.cache?.clear();
|
|
415
|
+
});
|
|
511
416
|
|
|
512
|
-
|
|
513
|
-
|
|
417
|
+
describe('when a resource is requested to be deleted', () => {
|
|
418
|
+
beforeEach(async () => {
|
|
419
|
+
const url = buildTestEndpoint(defaultPath);
|
|
514
420
|
|
|
515
|
-
|
|
516
|
-
|
|
421
|
+
mockedFetch.mockGetOnce(url, {
|
|
422
|
+
body: PRD_136_7317.body,
|
|
423
|
+
headers: defaultHeaders,
|
|
517
424
|
});
|
|
518
425
|
|
|
426
|
+
mockedFetch.mockDeleteOnce(url);
|
|
427
|
+
await restClient.get(defaultPath, { pathTemplateData: defaultPathTemplateData });
|
|
428
|
+
mockedFetch.mockClear();
|
|
519
429
|
response = await restClient.delete(defaultPath, { pathTemplateData: defaultPathTemplateData });
|
|
520
430
|
});
|
|
521
431
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
});
|
|
525
|
-
|
|
526
|
-
it("SHOULD have made one request", () => {
|
|
527
|
-
expect(fetchMock.calls().length).toBe(1);
|
|
432
|
+
it('should have made one request', () => {
|
|
433
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
528
434
|
});
|
|
529
435
|
|
|
530
|
-
it(
|
|
531
|
-
expect(response).
|
|
532
|
-
expect.objectContaining({
|
|
533
|
-
data: {},
|
|
534
|
-
}),
|
|
535
|
-
);
|
|
436
|
+
it('should return the correct response', () => {
|
|
437
|
+
expect(response.status).toBe(200);
|
|
536
438
|
});
|
|
537
439
|
|
|
538
|
-
it(
|
|
539
|
-
expect(
|
|
440
|
+
it('should delete any matching cache entry', async () => {
|
|
441
|
+
await expect(restClient.cache?.has(Md5.hashStr(buildTestEndpoint(defaultPath)))).resolves.toBe(false);
|
|
540
442
|
});
|
|
541
443
|
});
|
|
542
444
|
|
|
543
|
-
describe(
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
defaultPath,
|
|
547
|
-
PRD_136_7317.body,
|
|
548
|
-
{ pathTemplateData: defaultPathTemplateData },
|
|
549
|
-
({ endpoint, ...rest }) => {
|
|
550
|
-
requestHash = md5(endpoint);
|
|
551
|
-
fetchMock.get(endpoint, rest);
|
|
552
|
-
},
|
|
553
|
-
);
|
|
554
|
-
|
|
555
|
-
response = await restClient.get(defaultPath, { pathTemplateData: defaultPathTemplateData });
|
|
556
|
-
fetchMock.restore();
|
|
445
|
+
describe('when a resource is requested to be deleted with a shortcut', () => {
|
|
446
|
+
beforeEach(async () => {
|
|
447
|
+
const url = buildTestEndpoint(defaultPath);
|
|
557
448
|
|
|
558
|
-
|
|
559
|
-
|
|
449
|
+
mockedFetch.mockGetOnce(url, {
|
|
450
|
+
body: PRD_136_7317.body,
|
|
451
|
+
headers: defaultHeaders,
|
|
560
452
|
});
|
|
561
453
|
|
|
454
|
+
mockedFetch.mockDeleteOnce(url);
|
|
455
|
+
await restClient.get(defaultPath, { pathTemplateData: defaultPathTemplateData });
|
|
456
|
+
mockedFetch.mockClear();
|
|
562
457
|
response = await restClient.deleteProduct({ pathTemplateData: idPathTemplateData });
|
|
563
458
|
});
|
|
564
459
|
|
|
565
|
-
|
|
566
|
-
|
|
460
|
+
it('should have made one request', () => {
|
|
461
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
567
462
|
});
|
|
568
463
|
|
|
569
|
-
it(
|
|
570
|
-
expect(
|
|
464
|
+
it('should return the correct response', () => {
|
|
465
|
+
expect(response.status).toBe(200);
|
|
571
466
|
});
|
|
572
467
|
|
|
573
|
-
it(
|
|
574
|
-
expect(
|
|
575
|
-
expect.objectContaining({
|
|
576
|
-
data: {},
|
|
577
|
-
}),
|
|
578
|
-
);
|
|
579
|
-
});
|
|
580
|
-
|
|
581
|
-
it("SHOULD delete any matching cache entry", async () => {
|
|
582
|
-
expect(await restClient?.cache?.has(requestHash)).toBe(false);
|
|
468
|
+
it('should delete any matching cache entry', async () => {
|
|
469
|
+
await expect(restClient.cache?.has(Md5.hashStr(buildTestEndpoint(defaultPath)))).resolves.toBe(false);
|
|
583
470
|
});
|
|
584
471
|
});
|
|
585
472
|
});
|
|
586
473
|
|
|
587
|
-
describe(
|
|
588
|
-
let restClient: Getta & ShortcutProperties<
|
|
589
|
-
let response:
|
|
474
|
+
describe('put method', () => {
|
|
475
|
+
let restClient: Getta & ShortcutProperties<'putProduct'>;
|
|
476
|
+
let response: FetchResponse;
|
|
590
477
|
|
|
591
|
-
|
|
592
|
-
restClient = createRestClient<
|
|
478
|
+
beforeEach(() => {
|
|
479
|
+
restClient = createRestClient<'putProduct'>(
|
|
593
480
|
{ basePath, cache: getCache(), performance },
|
|
594
481
|
{
|
|
595
482
|
putProduct: [
|
|
596
483
|
defaultPath,
|
|
597
484
|
{
|
|
598
|
-
method: PUT_METHOD,
|
|
485
|
+
method: consts.PUT_METHOD,
|
|
599
486
|
pathTemplateData: pathTemplateDataWithoutID,
|
|
600
487
|
},
|
|
601
488
|
],
|
|
602
|
-
}
|
|
489
|
+
}
|
|
603
490
|
);
|
|
604
491
|
});
|
|
605
492
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
493
|
+
afterEach(async () => {
|
|
494
|
+
await restClient.cache?.clear();
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
describe('when a resource is send', () => {
|
|
498
|
+
beforeEach(async () => {
|
|
499
|
+
mockedFetch.mockPutOnce({ body: { mock: true }, url: buildTestEndpoint(defaultPath) }, { status: 201 });
|
|
611
500
|
|
|
612
501
|
response = await restClient.put(defaultPath, {
|
|
613
|
-
body: defaultPayload,
|
|
502
|
+
body: JSON.stringify({ ...defaultPayload, mock: true }),
|
|
614
503
|
pathTemplateData: defaultPathTemplateData,
|
|
615
504
|
});
|
|
616
505
|
});
|
|
617
506
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
});
|
|
621
|
-
|
|
622
|
-
it("SHOULD have made one request", () => {
|
|
623
|
-
expect(fetchMock.calls().length).toBe(1);
|
|
507
|
+
it('should have made one request', () => {
|
|
508
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
624
509
|
});
|
|
625
510
|
|
|
626
|
-
it(
|
|
627
|
-
expect(response).
|
|
628
|
-
expect.objectContaining({
|
|
629
|
-
data: {},
|
|
630
|
-
}),
|
|
631
|
-
);
|
|
511
|
+
it('should return the correct response', () => {
|
|
512
|
+
expect(response.status).toBe(201);
|
|
632
513
|
});
|
|
633
514
|
});
|
|
634
515
|
|
|
635
|
-
describe(
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
fetchMock.put(endpoint, rest);
|
|
639
|
-
});
|
|
640
|
-
|
|
641
|
-
response = await restClient.putProduct({ body: defaultPayload, pathTemplateData: idPathTemplateData });
|
|
642
|
-
});
|
|
516
|
+
describe('when a resource is sent with a shortcut', () => {
|
|
517
|
+
beforeEach(async () => {
|
|
518
|
+
mockedFetch.mockPutOnce({ body: { mock: true }, url: buildTestEndpoint(defaultPath) }, { status: 201 });
|
|
643
519
|
|
|
644
|
-
|
|
645
|
-
|
|
520
|
+
response = await restClient.putProduct({
|
|
521
|
+
body: JSON.stringify({ ...defaultPayload, mock: true }),
|
|
522
|
+
pathTemplateData: idPathTemplateData,
|
|
523
|
+
});
|
|
646
524
|
});
|
|
647
525
|
|
|
648
|
-
it(
|
|
649
|
-
expect(
|
|
526
|
+
it('should have made one request', () => {
|
|
527
|
+
expect(mockedFetch).toHaveBeenCalledTimes(1);
|
|
650
528
|
});
|
|
651
529
|
|
|
652
|
-
it(
|
|
653
|
-
expect(response).
|
|
654
|
-
expect.objectContaining({
|
|
655
|
-
data: {},
|
|
656
|
-
}),
|
|
657
|
-
);
|
|
530
|
+
it('should return the correct response', () => {
|
|
531
|
+
expect(response.status).toBe(201);
|
|
658
532
|
});
|
|
659
533
|
});
|
|
660
534
|
});
|
|
661
535
|
|
|
662
|
-
describe(
|
|
536
|
+
describe('rate limiting', () => {
|
|
663
537
|
let restClient: Getta;
|
|
664
538
|
|
|
665
|
-
|
|
666
|
-
restClient = createRestClient({ basePath, performance });
|
|
539
|
+
beforeEach(() => {
|
|
540
|
+
restClient = createRestClient({ basePath, performance, rateLimit: true });
|
|
667
541
|
});
|
|
668
542
|
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
mockRequest(`product/${key}`, {}, {}, ({ endpoint, ...rest }) => {
|
|
675
|
-
fetchMock.get(endpoint, rest);
|
|
676
|
-
});
|
|
677
|
-
});
|
|
543
|
+
afterEach(async () => {
|
|
544
|
+
await restClient.cache?.clear();
|
|
545
|
+
// @ts-expect-error property is private
|
|
546
|
+
clearTimeout(restClient._rateLimitTimer);
|
|
547
|
+
});
|
|
678
548
|
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
.mockResolvedValue({ data: {}, headers: new Headers(), status: 200 });
|
|
549
|
+
describe('when the number of requests per second exceeds rateLimitPerSecond', () => {
|
|
550
|
+
beforeEach(async () => {
|
|
551
|
+
const requestKeys = [...Array.from({ length: 55 }).keys()];
|
|
683
552
|
|
|
684
|
-
|
|
685
|
-
|
|
553
|
+
for (const key of requestKeys) {
|
|
554
|
+
mockedFetch.mockGetOnce(buildTestEndpoint(`product/${key}`));
|
|
555
|
+
}
|
|
686
556
|
|
|
687
|
-
|
|
688
|
-
|
|
557
|
+
// @ts-expect-error property is private
|
|
558
|
+
restClient._addRequestToRateLimitedQueue = jest.fn().mockResolvedValue({ status: 200 });
|
|
559
|
+
await Promise.all(requestKeys.map(key => restClient.get(`product/${key}`, { headers: defaultHeaders })));
|
|
689
560
|
});
|
|
690
561
|
|
|
691
|
-
it(
|
|
692
|
-
expect(
|
|
562
|
+
it('should call fetch one less than the rate limit', () => {
|
|
563
|
+
expect(mockedFetch).toHaveBeenCalledTimes(49);
|
|
693
564
|
});
|
|
694
565
|
|
|
695
|
-
it(
|
|
696
|
-
// @ts-
|
|
566
|
+
it('should add the excess requests to rateLimitedRequestQueue', () => {
|
|
567
|
+
// @ts-expect-error property is private
|
|
568
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
697
569
|
expect(restClient._addRequestToRateLimitedQueue).toHaveBeenCalledTimes(6);
|
|
698
570
|
});
|
|
699
571
|
});
|