piper-utils 1.1.70 → 1.1.71
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/bin/main.js +52 -3
- package/bin/main.js.map +1 -1
- package/package.json +62 -62
- package/src/contract/contract.js +42 -0
- package/src/contract/contract.test.js +36 -0
- package/src/database/dbUtils/partnerAccess/accessScope.test.js +287 -287
- package/src/eventManager/handleFile.js +129 -115
- package/src/eventManager/handleFile.test.js +463 -460
- package/src/index.js +4 -0
|
@@ -1,460 +1,463 @@
|
|
|
1
|
-
import Promise from 'bluebird';
|
|
2
|
-
import {
|
|
3
|
-
import S3Util from '../s3/S3Utils/S3Utils.js';
|
|
4
|
-
|
|
5
|
-
describe('handleFile', () => {
|
|
6
|
-
it('should ignore NoSuchKey errors (SDK v2 style with code property)', async () => {
|
|
7
|
-
spyOn(S3Util, 'getObject').and.rejectWith({
|
|
8
|
-
NoSuchKey: 'The specified key does not exists',
|
|
9
|
-
message: 'The specified key does not exist.',
|
|
10
|
-
code: 'NoSuchKey',
|
|
11
|
-
region: null,
|
|
12
|
-
time: '2018-08-31T17:37:58.599Z',
|
|
13
|
-
requestId: '22DC04A07A54BD91',
|
|
14
|
-
extendedRequestId:
|
|
15
|
-
'csziWftoyoFinWJDya8eF1TGyNoT/lf+zLkdFQsHD2N0w7XDku0JgKO9qms9Ok+52tMuK+ENx1U=',
|
|
16
|
-
cfId: undefined,
|
|
17
|
-
statusCode: 404,
|
|
18
|
-
retryable: false,
|
|
19
|
-
retryDelay: 71.30459621135599
|
|
20
|
-
});
|
|
21
|
-
const deleteSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve({}));
|
|
22
|
-
const putSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve({}));
|
|
23
|
-
const creator = {
|
|
24
|
-
createFunc: () => {
|
|
25
|
-
return Promise.resolve();
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
spyOn(creator, 'createFunc').and.returnValue(Promise.resolve({}));
|
|
30
|
-
const response = await handleFile();
|
|
31
|
-
|
|
32
|
-
expect(deleteSpy).not.toHaveBeenCalled();
|
|
33
|
-
expect(putSpy).not.toHaveBeenCalled();
|
|
34
|
-
expect(response).toBe(undefined);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('should ignore NoSuchKey errors (SDK v3 style with name property)', async () => {
|
|
38
|
-
// AWS SDK v3 uses 'name' property for error identification
|
|
39
|
-
spyOn(S3Util, 'getObject').and.rejectWith({
|
|
40
|
-
name: 'NoSuchKey',
|
|
41
|
-
message: 'The specified key does not exist.',
|
|
42
|
-
$metadata: {
|
|
43
|
-
httpStatusCode: 404,
|
|
44
|
-
requestId: '22DC04A07A54BD91'
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
const deleteSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve({}));
|
|
48
|
-
const putSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve({}));
|
|
49
|
-
const creator = {
|
|
50
|
-
createFunc: () => {
|
|
51
|
-
return Promise.resolve();
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
spyOn(creator, 'createFunc').and.returnValue(Promise.resolve({}));
|
|
56
|
-
const response = await handleFile('some/path', 'someBucket', creator.createFunc);
|
|
57
|
-
|
|
58
|
-
expect(deleteSpy).not.toHaveBeenCalled();
|
|
59
|
-
expect(putSpy).not.toHaveBeenCalled();
|
|
60
|
-
expect(response).toBe(undefined);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('should rethrow non-NoSuchKey S3 errors', async () => {
|
|
64
|
-
const s3Error = {
|
|
65
|
-
name: 'AccessDenied',
|
|
66
|
-
message: 'Access Denied',
|
|
67
|
-
$metadata: {
|
|
68
|
-
httpStatusCode: 403
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
spyOn(S3Util, 'getObject').and.rejectWith(s3Error);
|
|
72
|
-
const deleteSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve({}));
|
|
73
|
-
const putSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve({}));
|
|
74
|
-
|
|
75
|
-
try {
|
|
76
|
-
await handleFile('some/path', 'someBucket', () => Promise.resolve());
|
|
77
|
-
fail('Expected error to be thrown');
|
|
78
|
-
} catch (err) {
|
|
79
|
-
expect(err).toEqual(s3Error);
|
|
80
|
-
expect(deleteSpy).not.toHaveBeenCalled();
|
|
81
|
-
expect(putSpy).not.toHaveBeenCalled();
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('handle file receives proper params', () => {
|
|
86
|
-
const creator = {
|
|
87
|
-
createFunc: () => {
|
|
88
|
-
return Promise.resolve();
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
93
|
-
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
94
|
-
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
95
|
-
spyOn(creator, 'createFunc').and.returnValue(Promise.resolve({ foo: 'bar' }));
|
|
96
|
-
|
|
97
|
-
return handleFile('somePath', 'someBucket', creator.createFunc).then((response) => {
|
|
98
|
-
expect(response).toEqual({ foo: 'bar' });
|
|
99
|
-
expect(putObjectSpy).not.toHaveBeenCalled();
|
|
100
|
-
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'somePath' });
|
|
101
|
-
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'somePath' });
|
|
102
|
-
expect(creator.createFunc).toHaveBeenCalled();
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('handle file errors correctly', () => {
|
|
107
|
-
const creator = {
|
|
108
|
-
createFunc: () => {
|
|
109
|
-
return Promise.resolve();
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
114
|
-
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
115
|
-
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
116
|
-
|
|
117
|
-
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
118
|
-
|
|
119
|
-
return handleFile('somePath', 'someBucket', creator.createFunc).then(() => {
|
|
120
|
-
throw new Error('This function should have rejected');
|
|
121
|
-
}).catch((err) => {
|
|
122
|
-
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
123
|
-
Bucket: 'someBucket',
|
|
124
|
-
Key: 'failed-once/somePath',
|
|
125
|
-
Body: '{ "test": "val" }'
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'somePath' });
|
|
129
|
-
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'somePath' });
|
|
130
|
-
expect(creator.createFunc).toHaveBeenCalled();
|
|
131
|
-
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
it('handle file errors correctly with delayUntil', () => {
|
|
136
|
-
const creator = {
|
|
137
|
-
createFunc: () => {
|
|
138
|
-
return Promise.resolve();
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
143
|
-
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
144
|
-
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
145
|
-
|
|
146
|
-
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
147
|
-
|
|
148
|
-
return handleFile('delayUntil/202001011234/somePath', 'someBucket', creator.createFunc).then(() => {
|
|
149
|
-
throw new Error('This function should have rejected');
|
|
150
|
-
}).catch((err) => {
|
|
151
|
-
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
152
|
-
Bucket: 'someBucket',
|
|
153
|
-
Key: 'failed-once/somePath',
|
|
154
|
-
Body: '{ "test": "val" }'
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'delayUntil/202001011234/somePath' });
|
|
158
|
-
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'delayUntil/202001011234/somePath' });
|
|
159
|
-
expect(creator.createFunc).toHaveBeenCalled();
|
|
160
|
-
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
it('handle file errors correctly for failed-once', () => {
|
|
165
|
-
const creator = {
|
|
166
|
-
createFunc: () => {
|
|
167
|
-
return Promise.resolve();
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
172
|
-
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
173
|
-
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
174
|
-
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
175
|
-
|
|
176
|
-
return handleFile('failed-once/somePath', 'someBucket', creator.createFunc).then(() => {
|
|
177
|
-
throw new Error('This function should have rejected');
|
|
178
|
-
}).catch((err) => {
|
|
179
|
-
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
180
|
-
Bucket: 'someBucket',
|
|
181
|
-
Key: 'failed-twice/somePath',
|
|
182
|
-
Body: '{ "test": "val" }'
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'failed-once/somePath' });
|
|
186
|
-
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'failed-once/somePath' });
|
|
187
|
-
expect(creator.createFunc).toHaveBeenCalled();
|
|
188
|
-
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
it('handle file errors correctly for failed-twice', () => {
|
|
193
|
-
const creator = {
|
|
194
|
-
createFunc: () => {
|
|
195
|
-
return Promise.resolve();
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
200
|
-
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
201
|
-
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
202
|
-
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
203
|
-
|
|
204
|
-
return handleFile('failed-twice/somePath', 'someBucket', creator.createFunc).then(() => {
|
|
205
|
-
throw new Error('This function should have rejected');
|
|
206
|
-
}).catch((err) => {
|
|
207
|
-
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
208
|
-
Bucket: 'someBucket',
|
|
209
|
-
Key: 'error/somePath',
|
|
210
|
-
Body: '{ "test": "val" }'
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'failed-twice/somePath' });
|
|
214
|
-
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'failed-twice/somePath' });
|
|
215
|
-
expect(creator.createFunc).toHaveBeenCalled();
|
|
216
|
-
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
217
|
-
});
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
it('handle file errors correctly for shouldSkipFailedFolders', () => {
|
|
221
|
-
const creator = {
|
|
222
|
-
createFunc: () => {
|
|
223
|
-
return Promise.resolve();
|
|
224
|
-
}
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
228
|
-
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
229
|
-
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
230
|
-
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
231
|
-
|
|
232
|
-
return handleFile('somePath', 'someBucket', creator.createFunc, { shouldSkipFailedFolders: true }).then(() => {
|
|
233
|
-
throw new Error('This function should have rejected');
|
|
234
|
-
}).catch((err) => {
|
|
235
|
-
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
236
|
-
Bucket: 'someBucket',
|
|
237
|
-
Key: 'error/somePath',
|
|
238
|
-
Body: '{ "test": "val" }'
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'somePath' });
|
|
242
|
-
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'somePath' });
|
|
243
|
-
expect(creator.createFunc).toHaveBeenCalled();
|
|
244
|
-
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
it('handle file userImportTypes & shouldSkipFailedFolders', () => {
|
|
249
|
-
const creator = {
|
|
250
|
-
createFunc: () => {
|
|
251
|
-
return Promise.resolve();
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
256
|
-
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
257
|
-
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(
|
|
258
|
-
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' }));
|
|
259
|
-
|
|
260
|
-
const userImportTypes = {
|
|
261
|
-
kovo: 'kovo',
|
|
262
|
-
zoobooks: 'zoobooks'
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
return handleFile('kovo/file.json', 'someBucket', creator.createFunc, { shouldSkipFailedFolders: true, userImportTypes }).then(() => {
|
|
266
|
-
throw new Error('This function should have rejected');
|
|
267
|
-
}).catch((err) => {
|
|
268
|
-
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
269
|
-
Bucket: 'someBucket',
|
|
270
|
-
Key: 'kovo/error/file.json',
|
|
271
|
-
Body: '{ "test": "val" }'
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'kovo/file.json' });
|
|
275
|
-
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'kovo/file.json' });
|
|
276
|
-
expect(creator.createFunc).toHaveBeenCalled();
|
|
277
|
-
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
278
|
-
});
|
|
279
|
-
});
|
|
280
|
-
it('userImportTypes & handle file errors correctly for failed-once', () => {
|
|
281
|
-
const creator = {
|
|
282
|
-
createFunc: () => {
|
|
283
|
-
return Promise.resolve();
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
288
|
-
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
289
|
-
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
290
|
-
|
|
291
|
-
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
292
|
-
const userImportTypes = {
|
|
293
|
-
kovo: 'kovo',
|
|
294
|
-
zoobooks: 'zoobooks'
|
|
295
|
-
};
|
|
296
|
-
return handleFile('kovo/failed-once/file.json', 'someBucket', creator.createFunc, { userImportTypes }).then(() => {
|
|
297
|
-
throw new Error('This function should have rejected');
|
|
298
|
-
}).catch((err) => {
|
|
299
|
-
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
300
|
-
Bucket: 'someBucket',
|
|
301
|
-
Key: 'kovo/failed-twice/file.json',
|
|
302
|
-
Body: '{ "test": "val" }'
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'kovo/failed-once/file.json' });
|
|
306
|
-
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'kovo/failed-once/file.json' });
|
|
307
|
-
expect(creator.createFunc).toHaveBeenCalled();
|
|
308
|
-
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
309
|
-
});
|
|
310
|
-
});
|
|
311
|
-
it('userImportTypes & handle file errors correctly for failed-twice', () => {
|
|
312
|
-
const creator = {
|
|
313
|
-
createFunc: () => {
|
|
314
|
-
return Promise.resolve();
|
|
315
|
-
}
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
319
|
-
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
320
|
-
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
321
|
-
|
|
322
|
-
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
323
|
-
const userImportTypes = {
|
|
324
|
-
kovo: 'kovo',
|
|
325
|
-
zoobooks: 'zoobooks'
|
|
326
|
-
};
|
|
327
|
-
return handleFile('kovo/failed-twice/file.json', 'someBucket', creator.createFunc, { userImportTypes }).then(() => {
|
|
328
|
-
throw new Error('This function should have rejected');
|
|
329
|
-
}).catch((err) => {
|
|
330
|
-
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
331
|
-
Bucket: 'someBucket',
|
|
332
|
-
Key: 'kovo/error/file.json',
|
|
333
|
-
Body: '{ "test": "val" }'
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'kovo/failed-twice/file.json' });
|
|
337
|
-
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'kovo/failed-twice/file.json' });
|
|
338
|
-
expect(creator.createFunc).toHaveBeenCalled();
|
|
339
|
-
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
340
|
-
});
|
|
341
|
-
});
|
|
342
|
-
it('userImportTypes & handle file errors correctly', () => {
|
|
343
|
-
const creator = {
|
|
344
|
-
createFunc: () => {
|
|
345
|
-
return Promise.resolve();
|
|
346
|
-
}
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
350
|
-
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
351
|
-
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
352
|
-
|
|
353
|
-
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
354
|
-
const userImportTypes = {
|
|
355
|
-
kovo: 'kovo',
|
|
356
|
-
zoobooks: 'zoobooks'
|
|
357
|
-
};
|
|
358
|
-
|
|
359
|
-
return handleFile('kovo/file.json', 'someBucket', creator.createFunc, { userImportTypes }).then(() => {
|
|
360
|
-
throw new Error('This function should have rejected');
|
|
361
|
-
}).catch((err) => {
|
|
362
|
-
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
363
|
-
Bucket: 'someBucket',
|
|
364
|
-
Key: 'kovo/failed-once/file.json',
|
|
365
|
-
Body: '{ "test": "val" }'
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'kovo/file.json' });
|
|
369
|
-
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'kovo/file.json' });
|
|
370
|
-
expect(creator.createFunc).toHaveBeenCalled();
|
|
371
|
-
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
372
|
-
});
|
|
373
|
-
});
|
|
374
|
-
it('userImportTypes & handle file with bad userImportTypes', () => {
|
|
375
|
-
const creator = {
|
|
376
|
-
createFunc: () => {
|
|
377
|
-
return Promise.resolve();
|
|
378
|
-
}
|
|
379
|
-
};
|
|
380
|
-
|
|
381
|
-
spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
382
|
-
spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
383
|
-
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
384
|
-
|
|
385
|
-
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
386
|
-
const userImportTypes = {
|
|
387
|
-
duck: 'duck'
|
|
388
|
-
};
|
|
389
|
-
|
|
390
|
-
return handleFile('kovo/file.json', 'someBucket', creator.createFunc, { userImportTypes }).then(() => {
|
|
391
|
-
throw new Error('This function should have rejected');
|
|
392
|
-
}).catch(() => {
|
|
393
|
-
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
394
|
-
Bucket: 'someBucket',
|
|
395
|
-
Key: 'pathAndEventMisMatchError/kovo/file.json',
|
|
396
|
-
Body: '{ "test": "val" }'
|
|
397
|
-
});
|
|
398
|
-
});
|
|
399
|
-
});
|
|
400
|
-
it('should throw if nesting error folders', async () => {
|
|
401
|
-
const creator = {
|
|
402
|
-
createFunc: () => {
|
|
403
|
-
return Promise.resolve();
|
|
404
|
-
}
|
|
405
|
-
};
|
|
406
|
-
|
|
407
|
-
spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
408
|
-
spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
409
|
-
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
410
|
-
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
411
|
-
|
|
412
|
-
try {
|
|
413
|
-
await handleFile('error/error/file.json', 'someBucket', creator.createFunc);
|
|
414
|
-
} catch (e) {
|
|
415
|
-
expect(e).toBeDefined();
|
|
416
|
-
expect(putObjectSpy).not.toHaveBeenCalled();
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
});
|
|
420
|
-
it('
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
const
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
const
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
expect(
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
const
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
expect(
|
|
459
|
-
|
|
460
|
-
|
|
1
|
+
import Promise from 'bluebird';
|
|
2
|
+
import { isNestedFailurePath, handleFile } from './handleFile.js';
|
|
3
|
+
import S3Util from '../s3/S3Utils/S3Utils.js';
|
|
4
|
+
|
|
5
|
+
describe('handleFile', () => {
|
|
6
|
+
it('should ignore NoSuchKey errors (SDK v2 style with code property)', async () => {
|
|
7
|
+
spyOn(S3Util, 'getObject').and.rejectWith({
|
|
8
|
+
NoSuchKey: 'The specified key does not exists',
|
|
9
|
+
message: 'The specified key does not exist.',
|
|
10
|
+
code: 'NoSuchKey',
|
|
11
|
+
region: null,
|
|
12
|
+
time: '2018-08-31T17:37:58.599Z',
|
|
13
|
+
requestId: '22DC04A07A54BD91',
|
|
14
|
+
extendedRequestId:
|
|
15
|
+
'csziWftoyoFinWJDya8eF1TGyNoT/lf+zLkdFQsHD2N0w7XDku0JgKO9qms9Ok+52tMuK+ENx1U=',
|
|
16
|
+
cfId: undefined,
|
|
17
|
+
statusCode: 404,
|
|
18
|
+
retryable: false,
|
|
19
|
+
retryDelay: 71.30459621135599
|
|
20
|
+
});
|
|
21
|
+
const deleteSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve({}));
|
|
22
|
+
const putSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve({}));
|
|
23
|
+
const creator = {
|
|
24
|
+
createFunc: () => {
|
|
25
|
+
return Promise.resolve();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
spyOn(creator, 'createFunc').and.returnValue(Promise.resolve({}));
|
|
30
|
+
const response = await handleFile();
|
|
31
|
+
|
|
32
|
+
expect(deleteSpy).not.toHaveBeenCalled();
|
|
33
|
+
expect(putSpy).not.toHaveBeenCalled();
|
|
34
|
+
expect(response).toBe(undefined);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should ignore NoSuchKey errors (SDK v3 style with name property)', async () => {
|
|
38
|
+
// AWS SDK v3 uses 'name' property for error identification
|
|
39
|
+
spyOn(S3Util, 'getObject').and.rejectWith({
|
|
40
|
+
name: 'NoSuchKey',
|
|
41
|
+
message: 'The specified key does not exist.',
|
|
42
|
+
$metadata: {
|
|
43
|
+
httpStatusCode: 404,
|
|
44
|
+
requestId: '22DC04A07A54BD91'
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
const deleteSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve({}));
|
|
48
|
+
const putSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve({}));
|
|
49
|
+
const creator = {
|
|
50
|
+
createFunc: () => {
|
|
51
|
+
return Promise.resolve();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
spyOn(creator, 'createFunc').and.returnValue(Promise.resolve({}));
|
|
56
|
+
const response = await handleFile('some/path', 'someBucket', creator.createFunc);
|
|
57
|
+
|
|
58
|
+
expect(deleteSpy).not.toHaveBeenCalled();
|
|
59
|
+
expect(putSpy).not.toHaveBeenCalled();
|
|
60
|
+
expect(response).toBe(undefined);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('should rethrow non-NoSuchKey S3 errors', async () => {
|
|
64
|
+
const s3Error = {
|
|
65
|
+
name: 'AccessDenied',
|
|
66
|
+
message: 'Access Denied',
|
|
67
|
+
$metadata: {
|
|
68
|
+
httpStatusCode: 403
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
spyOn(S3Util, 'getObject').and.rejectWith(s3Error);
|
|
72
|
+
const deleteSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve({}));
|
|
73
|
+
const putSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve({}));
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
await handleFile('some/path', 'someBucket', () => Promise.resolve());
|
|
77
|
+
fail('Expected error to be thrown');
|
|
78
|
+
} catch (err) {
|
|
79
|
+
expect(err).toEqual(s3Error);
|
|
80
|
+
expect(deleteSpy).not.toHaveBeenCalled();
|
|
81
|
+
expect(putSpy).not.toHaveBeenCalled();
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('handle file receives proper params', () => {
|
|
86
|
+
const creator = {
|
|
87
|
+
createFunc: () => {
|
|
88
|
+
return Promise.resolve();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
93
|
+
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
94
|
+
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
95
|
+
spyOn(creator, 'createFunc').and.returnValue(Promise.resolve({ foo: 'bar' }));
|
|
96
|
+
|
|
97
|
+
return handleFile('somePath', 'someBucket', creator.createFunc).then((response) => {
|
|
98
|
+
expect(response).toEqual({ foo: 'bar' });
|
|
99
|
+
expect(putObjectSpy).not.toHaveBeenCalled();
|
|
100
|
+
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'somePath' });
|
|
101
|
+
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'somePath' });
|
|
102
|
+
expect(creator.createFunc).toHaveBeenCalled();
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('handle file errors correctly', () => {
|
|
107
|
+
const creator = {
|
|
108
|
+
createFunc: () => {
|
|
109
|
+
return Promise.resolve();
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
114
|
+
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
115
|
+
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
116
|
+
|
|
117
|
+
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
118
|
+
|
|
119
|
+
return handleFile('somePath', 'someBucket', creator.createFunc).then(() => {
|
|
120
|
+
throw new Error('This function should have rejected');
|
|
121
|
+
}).catch((err) => {
|
|
122
|
+
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
123
|
+
Bucket: 'someBucket',
|
|
124
|
+
Key: 'failed-once/somePath',
|
|
125
|
+
Body: '{ "test": "val" }'
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'somePath' });
|
|
129
|
+
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'somePath' });
|
|
130
|
+
expect(creator.createFunc).toHaveBeenCalled();
|
|
131
|
+
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('handle file errors correctly with delayUntil', () => {
|
|
136
|
+
const creator = {
|
|
137
|
+
createFunc: () => {
|
|
138
|
+
return Promise.resolve();
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
143
|
+
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
144
|
+
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
145
|
+
|
|
146
|
+
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
147
|
+
|
|
148
|
+
return handleFile('delayUntil/202001011234/somePath', 'someBucket', creator.createFunc).then(() => {
|
|
149
|
+
throw new Error('This function should have rejected');
|
|
150
|
+
}).catch((err) => {
|
|
151
|
+
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
152
|
+
Bucket: 'someBucket',
|
|
153
|
+
Key: 'failed-once/somePath',
|
|
154
|
+
Body: '{ "test": "val" }'
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'delayUntil/202001011234/somePath' });
|
|
158
|
+
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'delayUntil/202001011234/somePath' });
|
|
159
|
+
expect(creator.createFunc).toHaveBeenCalled();
|
|
160
|
+
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('handle file errors correctly for failed-once', () => {
|
|
165
|
+
const creator = {
|
|
166
|
+
createFunc: () => {
|
|
167
|
+
return Promise.resolve();
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
172
|
+
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
173
|
+
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
174
|
+
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
175
|
+
|
|
176
|
+
return handleFile('failed-once/somePath', 'someBucket', creator.createFunc).then(() => {
|
|
177
|
+
throw new Error('This function should have rejected');
|
|
178
|
+
}).catch((err) => {
|
|
179
|
+
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
180
|
+
Bucket: 'someBucket',
|
|
181
|
+
Key: 'failed-twice/somePath',
|
|
182
|
+
Body: '{ "test": "val" }'
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'failed-once/somePath' });
|
|
186
|
+
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'failed-once/somePath' });
|
|
187
|
+
expect(creator.createFunc).toHaveBeenCalled();
|
|
188
|
+
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('handle file errors correctly for failed-twice', () => {
|
|
193
|
+
const creator = {
|
|
194
|
+
createFunc: () => {
|
|
195
|
+
return Promise.resolve();
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
200
|
+
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
201
|
+
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
202
|
+
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
203
|
+
|
|
204
|
+
return handleFile('failed-twice/somePath', 'someBucket', creator.createFunc).then(() => {
|
|
205
|
+
throw new Error('This function should have rejected');
|
|
206
|
+
}).catch((err) => {
|
|
207
|
+
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
208
|
+
Bucket: 'someBucket',
|
|
209
|
+
Key: 'error/somePath',
|
|
210
|
+
Body: '{ "test": "val" }'
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'failed-twice/somePath' });
|
|
214
|
+
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'failed-twice/somePath' });
|
|
215
|
+
expect(creator.createFunc).toHaveBeenCalled();
|
|
216
|
+
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it('handle file errors correctly for shouldSkipFailedFolders', () => {
|
|
221
|
+
const creator = {
|
|
222
|
+
createFunc: () => {
|
|
223
|
+
return Promise.resolve();
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
228
|
+
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
229
|
+
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
230
|
+
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
231
|
+
|
|
232
|
+
return handleFile('somePath', 'someBucket', creator.createFunc, { shouldSkipFailedFolders: true }).then(() => {
|
|
233
|
+
throw new Error('This function should have rejected');
|
|
234
|
+
}).catch((err) => {
|
|
235
|
+
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
236
|
+
Bucket: 'someBucket',
|
|
237
|
+
Key: 'error/somePath',
|
|
238
|
+
Body: '{ "test": "val" }'
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'somePath' });
|
|
242
|
+
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'somePath' });
|
|
243
|
+
expect(creator.createFunc).toHaveBeenCalled();
|
|
244
|
+
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it('handle file userImportTypes & shouldSkipFailedFolders', () => {
|
|
249
|
+
const creator = {
|
|
250
|
+
createFunc: () => {
|
|
251
|
+
return Promise.resolve();
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
256
|
+
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
257
|
+
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(
|
|
258
|
+
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' }));
|
|
259
|
+
|
|
260
|
+
const userImportTypes = {
|
|
261
|
+
kovo: 'kovo',
|
|
262
|
+
zoobooks: 'zoobooks'
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
return handleFile('kovo/file.json', 'someBucket', creator.createFunc, { shouldSkipFailedFolders: true, userImportTypes }).then(() => {
|
|
266
|
+
throw new Error('This function should have rejected');
|
|
267
|
+
}).catch((err) => {
|
|
268
|
+
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
269
|
+
Bucket: 'someBucket',
|
|
270
|
+
Key: 'kovo/error/file.json',
|
|
271
|
+
Body: '{ "test": "val" }'
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'kovo/file.json' });
|
|
275
|
+
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'kovo/file.json' });
|
|
276
|
+
expect(creator.createFunc).toHaveBeenCalled();
|
|
277
|
+
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
it('userImportTypes & handle file errors correctly for failed-once', () => {
|
|
281
|
+
const creator = {
|
|
282
|
+
createFunc: () => {
|
|
283
|
+
return Promise.resolve();
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
288
|
+
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
289
|
+
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
290
|
+
|
|
291
|
+
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
292
|
+
const userImportTypes = {
|
|
293
|
+
kovo: 'kovo',
|
|
294
|
+
zoobooks: 'zoobooks'
|
|
295
|
+
};
|
|
296
|
+
return handleFile('kovo/failed-once/file.json', 'someBucket', creator.createFunc, { userImportTypes }).then(() => {
|
|
297
|
+
throw new Error('This function should have rejected');
|
|
298
|
+
}).catch((err) => {
|
|
299
|
+
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
300
|
+
Bucket: 'someBucket',
|
|
301
|
+
Key: 'kovo/failed-twice/file.json',
|
|
302
|
+
Body: '{ "test": "val" }'
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'kovo/failed-once/file.json' });
|
|
306
|
+
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'kovo/failed-once/file.json' });
|
|
307
|
+
expect(creator.createFunc).toHaveBeenCalled();
|
|
308
|
+
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
it('userImportTypes & handle file errors correctly for failed-twice', () => {
|
|
312
|
+
const creator = {
|
|
313
|
+
createFunc: () => {
|
|
314
|
+
return Promise.resolve();
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
319
|
+
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
320
|
+
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
321
|
+
|
|
322
|
+
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
323
|
+
const userImportTypes = {
|
|
324
|
+
kovo: 'kovo',
|
|
325
|
+
zoobooks: 'zoobooks'
|
|
326
|
+
};
|
|
327
|
+
return handleFile('kovo/failed-twice/file.json', 'someBucket', creator.createFunc, { userImportTypes }).then(() => {
|
|
328
|
+
throw new Error('This function should have rejected');
|
|
329
|
+
}).catch((err) => {
|
|
330
|
+
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
331
|
+
Bucket: 'someBucket',
|
|
332
|
+
Key: 'kovo/error/file.json',
|
|
333
|
+
Body: '{ "test": "val" }'
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'kovo/failed-twice/file.json' });
|
|
337
|
+
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'kovo/failed-twice/file.json' });
|
|
338
|
+
expect(creator.createFunc).toHaveBeenCalled();
|
|
339
|
+
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
it('userImportTypes & handle file errors correctly', () => {
|
|
343
|
+
const creator = {
|
|
344
|
+
createFunc: () => {
|
|
345
|
+
return Promise.resolve();
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
const getObjectSpy = spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
350
|
+
const deleteObjectSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
351
|
+
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
352
|
+
|
|
353
|
+
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
354
|
+
const userImportTypes = {
|
|
355
|
+
kovo: 'kovo',
|
|
356
|
+
zoobooks: 'zoobooks'
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
return handleFile('kovo/file.json', 'someBucket', creator.createFunc, { userImportTypes }).then(() => {
|
|
360
|
+
throw new Error('This function should have rejected');
|
|
361
|
+
}).catch((err) => {
|
|
362
|
+
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
363
|
+
Bucket: 'someBucket',
|
|
364
|
+
Key: 'kovo/failed-once/file.json',
|
|
365
|
+
Body: '{ "test": "val" }'
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
expect(deleteObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'kovo/file.json' });
|
|
369
|
+
expect(getObjectSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'kovo/file.json' });
|
|
370
|
+
expect(creator.createFunc).toHaveBeenCalled();
|
|
371
|
+
expect(err).toEqual({ message: 'THIS FUNCTION FAILED' });
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
it('userImportTypes & handle file with bad userImportTypes', () => {
|
|
375
|
+
const creator = {
|
|
376
|
+
createFunc: () => {
|
|
377
|
+
return Promise.resolve();
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
382
|
+
spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
383
|
+
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
384
|
+
|
|
385
|
+
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
386
|
+
const userImportTypes = {
|
|
387
|
+
duck: 'duck'
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
return handleFile('kovo/file.json', 'someBucket', creator.createFunc, { userImportTypes }).then(() => {
|
|
391
|
+
throw new Error('This function should have rejected');
|
|
392
|
+
}).catch(() => {
|
|
393
|
+
expect(putObjectSpy).toHaveBeenCalledWith({
|
|
394
|
+
Bucket: 'someBucket',
|
|
395
|
+
Key: 'pathAndEventMisMatchError/kovo/file.json',
|
|
396
|
+
Body: '{ "test": "val" }'
|
|
397
|
+
});
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
it('should throw if nesting error folders', async () => {
|
|
401
|
+
const creator = {
|
|
402
|
+
createFunc: () => {
|
|
403
|
+
return Promise.resolve();
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{ "test": "val" }'));
|
|
408
|
+
spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve('{}'));
|
|
409
|
+
const putObjectSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve('{}'));
|
|
410
|
+
spyOn(creator, 'createFunc').and.rejectWith({ message: 'THIS FUNCTION FAILED' });
|
|
411
|
+
|
|
412
|
+
try {
|
|
413
|
+
await handleFile('error/error/file.json', 'someBucket', creator.createFunc);
|
|
414
|
+
} catch (e) {
|
|
415
|
+
expect(e).toBeDefined();
|
|
416
|
+
expect(putObjectSpy).not.toHaveBeenCalled();
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
});
|
|
420
|
+
it('isNestedFailurePath: true when the folder path stacks two failure stages', () => {
|
|
421
|
+
expect(isNestedFailurePath('failed-once/error/file.json')).toBe(true);
|
|
422
|
+
});
|
|
423
|
+
it('isNestedFailurePath: false for a single failure stage', () => {
|
|
424
|
+
expect(isNestedFailurePath('error/file.json')).toBe(false);
|
|
425
|
+
});
|
|
426
|
+
it('isNestedFailurePath: false when only the FILENAME contains a stage token', () => {
|
|
427
|
+
// Regression for audit finding #8: a user file named "errors.csv" is not nested, so it
|
|
428
|
+
// ladders normally to error/ and dead-letters instead of looping forever.
|
|
429
|
+
expect(isNestedFailurePath('failed-once/errors.csv')).toBe(false);
|
|
430
|
+
expect(isNestedFailurePath('error/failed-once-list.csv')).toBe(false);
|
|
431
|
+
});
|
|
432
|
+
it('should skip blank-string bodies', async () => {
|
|
433
|
+
const creator = { createFunc: () => Promise.resolve() };
|
|
434
|
+
|
|
435
|
+
spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve(' '));
|
|
436
|
+
const deleteSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve({}));
|
|
437
|
+
const putSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve({}));
|
|
438
|
+
const txSpy = spyOn(creator, 'createFunc').and.returnValue(Promise.resolve({}));
|
|
439
|
+
|
|
440
|
+
const res = await handleFile('somePath', 'someBucket', creator.createFunc);
|
|
441
|
+
|
|
442
|
+
expect(res).toBeUndefined();
|
|
443
|
+
expect(deleteSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'somePath' });
|
|
444
|
+
expect(putSpy).not.toHaveBeenCalled();
|
|
445
|
+
expect(txSpy).not.toHaveBeenCalled();
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
it('should skip bodies that parse to an empty object', async () => {
|
|
449
|
+
const creator = { createFunc: () => Promise.resolve() };
|
|
450
|
+
|
|
451
|
+
spyOn(S3Util, 'getObject').and.returnValue(Promise.resolve('{}'));
|
|
452
|
+
const deleteSpy = spyOn(S3Util, 'deleteObject').and.returnValue(Promise.resolve({}));
|
|
453
|
+
const putSpy = spyOn(S3Util, 'putObject').and.returnValue(Promise.resolve({}));
|
|
454
|
+
const txSpy = spyOn(creator, 'createFunc').and.returnValue(Promise.resolve({}));
|
|
455
|
+
|
|
456
|
+
const res = await handleFile('somePath', 'someBucket', creator.createFunc);
|
|
457
|
+
|
|
458
|
+
expect(res).toBeUndefined();
|
|
459
|
+
expect(deleteSpy).toHaveBeenCalledWith({ Bucket: 'someBucket', Key: 'somePath' });
|
|
460
|
+
expect(putSpy).not.toHaveBeenCalled();
|
|
461
|
+
expect(txSpy).not.toHaveBeenCalled();
|
|
462
|
+
});
|
|
463
|
+
});
|