@devrev/ts-adaas 1.18.0 → 1.18.1-beta.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-adapter.d.ts","sourceRoot":"","sources":["../../../src/multithreading/worker-adapter/worker-adapter.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EACL,oBAAoB,EACpB,aAAa,EACd,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EACL,YAAY,EACZ,SAAS,EAET,kCAAkC,EAClC,yCAAyC,EACzC,kBAAkB,EAClB,2BAA2B,EAC3B,2BAA2B,EAC5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAEL,wBAAwB,EACxB,kBAAkB,EAClB,6BAA6B,EAC7B,UAAU,EACV,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EAEtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EAGrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,QAAQ,EAAkB,MAAM,oCAAoC,CAAC;AAI9E,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,EAClD,KAAK,EACL,YAAY,EACZ,OAAO,GACR,EAAE,sBAAsB,CAAC,cAAc,CAAC,GAAG,aAAa,CAAC,cAAc,CAAC,CAMxE;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,aAAa,CAAC,cAAc;IACvC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,oBAAoB,CAAC;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,EAAE,OAAO,CAAC;IAE1B,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,sBAAsB,CAAa;IAG3C,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,eAAe,CAAW;IAClC,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,QAAQ,CAAW;gBAEf,EACV,KAAK,EACL,YAAY,EACZ,OAAO,GACR,EAAE,sBAAsB,CAAC,cAAc,CAAC;IAqBzC,IAAI,KAAK,IAAI,YAAY,CAAC,cAAc,CAAC,CAExC;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,YAAY,CAAC,cAAc,CAAC,EAE5C;IAED,IAAI,OAAO,IAAI,YAAY,EAAE,CAE5B;IAED,IAAI,cAAc,IAAI,MAAM,EAAE,CAE7B;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,eAAe,kDAElB;IAED;;;OAGG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAOxC,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE;IAuCtC,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAarC,SAAS;IAMf,IAAI,SAAS,IAAI,QAAQ,EAAE,CAE1B;IAED,IAAI,SAAS,CAAC,SAAS,EAAE,QAAQ,EAAE,EAIlC;IAED;;;;;OAKG;IACG,IAAI,CACR,YAAY,EAAE,kBAAkB,GAAG,eAAe,EAClD,IAAI,CAAC,EAAE,SAAS,GACf,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"worker-adapter.d.ts","sourceRoot":"","sources":["../../../src/multithreading/worker-adapter/worker-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -286,57 +286,74 @@ class WorkerAdapter {
|
|
|
286
286
|
};
|
|
287
287
|
}
|
|
288
288
|
console.log('Files to load in state', (_a = this.adapterState.state.fromDevRev) === null || _a === void 0 ? void 0 : _a.filesToLoad);
|
|
289
|
-
|
|
290
|
-
.
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
error: {
|
|
296
|
-
message: `Item type to load not found for item type: ${fileToLoad.itemType}.`,
|
|
297
|
-
},
|
|
298
|
-
});
|
|
299
|
-
break;
|
|
300
|
-
}
|
|
301
|
-
if (!fileToLoad.completed) {
|
|
302
|
-
const { response, error: transformerFileError } = await this.uploader.getJsonObjectByArtifactId({
|
|
303
|
-
artifactId: fileToLoad.id,
|
|
304
|
-
isGzipped: true,
|
|
305
|
-
});
|
|
306
|
-
if (transformerFileError) {
|
|
307
|
-
console.error(`Transformer file not found for artifact ID: ${fileToLoad.id}.`);
|
|
289
|
+
try {
|
|
290
|
+
outerloop: for (const fileToLoad of this.adapterState.state.fromDevRev
|
|
291
|
+
.filesToLoad) {
|
|
292
|
+
const itemTypeToLoad = itemTypesToLoad.find((itemTypeToLoad) => itemTypeToLoad.itemType === fileToLoad.itemType);
|
|
293
|
+
if (!itemTypeToLoad) {
|
|
294
|
+
console.error(`Item type to load not found for item type: ${fileToLoad.itemType}.`);
|
|
308
295
|
await this.emit(loading_1.LoaderEventType.DataLoadingError, {
|
|
309
296
|
error: {
|
|
310
|
-
message: `
|
|
297
|
+
message: `Item type to load not found for item type: ${fileToLoad.itemType}.`,
|
|
311
298
|
},
|
|
312
299
|
});
|
|
300
|
+
break;
|
|
313
301
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
itemTypeToLoad,
|
|
302
|
+
if (!fileToLoad.completed) {
|
|
303
|
+
const { response, error: transformerFileError } = await this.uploader.getJsonObjectByArtifactId({
|
|
304
|
+
artifactId: fileToLoad.id,
|
|
305
|
+
isGzipped: true,
|
|
319
306
|
});
|
|
320
|
-
if (
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
307
|
+
if (transformerFileError) {
|
|
308
|
+
console.error(`Transformer file not found for artifact ID: ${fileToLoad.id}.`);
|
|
309
|
+
await this.emit(loading_1.LoaderEventType.DataLoadingError, {
|
|
310
|
+
error: {
|
|
311
|
+
message: `Transformer file not found for artifact ID: ${fileToLoad.id}.`,
|
|
312
|
+
},
|
|
325
313
|
});
|
|
326
314
|
break outerloop;
|
|
327
315
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
316
|
+
const transformerFile = response;
|
|
317
|
+
for (let i = fileToLoad.lineToProcess; i < fileToLoad.count; i++) {
|
|
318
|
+
if (this.isTimeout) {
|
|
319
|
+
console.log('Timeout detected during data loading. Emitting progress to allow continuation.');
|
|
320
|
+
await this.emit(loading_1.LoaderEventType.DataLoadingProgress);
|
|
321
|
+
process.exit(0);
|
|
322
|
+
}
|
|
323
|
+
const { report, rateLimit } = await this.loadItem({
|
|
324
|
+
item: transformerFile[i],
|
|
325
|
+
itemTypeToLoad,
|
|
332
326
|
});
|
|
333
|
-
|
|
327
|
+
if (rateLimit === null || rateLimit === void 0 ? void 0 : rateLimit.delay) {
|
|
328
|
+
await this.emit(loading_1.LoaderEventType.DataLoadingDelayed, {
|
|
329
|
+
delay: rateLimit.delay,
|
|
330
|
+
reports: this.reports,
|
|
331
|
+
processed_files: this.processedFiles,
|
|
332
|
+
});
|
|
333
|
+
break outerloop;
|
|
334
|
+
}
|
|
335
|
+
if (report) {
|
|
336
|
+
(0, worker_adapter_helpers_1.addReportToLoaderReport)({
|
|
337
|
+
loaderReports: this.loaderReports,
|
|
338
|
+
report,
|
|
339
|
+
});
|
|
340
|
+
fileToLoad.lineToProcess = fileToLoad.lineToProcess + 1;
|
|
341
|
+
}
|
|
334
342
|
}
|
|
343
|
+
fileToLoad.completed = true;
|
|
344
|
+
this._processedFiles.push(fileToLoad.id);
|
|
335
345
|
}
|
|
336
|
-
fileToLoad.completed = true;
|
|
337
|
-
this._processedFiles.push(fileToLoad.id);
|
|
338
346
|
}
|
|
339
347
|
}
|
|
348
|
+
catch (error) {
|
|
349
|
+
console.error('Error during data loading.', (0, logger_1.serializeError)(error));
|
|
350
|
+
await this.emit(loading_1.LoaderEventType.DataLoadingError, {
|
|
351
|
+
error: {
|
|
352
|
+
message: `Error during data loading. ${(0, logger_1.serializeError)(error)}`,
|
|
353
|
+
},
|
|
354
|
+
});
|
|
355
|
+
process.exit(1);
|
|
356
|
+
}
|
|
340
357
|
return {
|
|
341
358
|
reports: this.reports,
|
|
342
359
|
processed_files: this.processedFiles,
|
|
@@ -383,42 +400,63 @@ class WorkerAdapter {
|
|
|
383
400
|
};
|
|
384
401
|
}
|
|
385
402
|
const filesToLoad = (_b = this.adapterState.state.fromDevRev) === null || _b === void 0 ? void 0 : _b.filesToLoad;
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
const transformerFile = response;
|
|
393
|
-
if (transformerFileError) {
|
|
394
|
-
console.error(`Transformer file not found for artifact ID: ${fileToLoad.id}.`);
|
|
395
|
-
break outerloop;
|
|
396
|
-
}
|
|
397
|
-
for (let i = fileToLoad.lineToProcess; i < fileToLoad.count; i++) {
|
|
398
|
-
const { report, rateLimit } = await this.loadAttachment({
|
|
399
|
-
item: transformerFile[i],
|
|
400
|
-
create,
|
|
403
|
+
try {
|
|
404
|
+
outerloop: for (const fileToLoad of filesToLoad) {
|
|
405
|
+
if (!fileToLoad.completed) {
|
|
406
|
+
const { response, error: transformerFileError } = await this.uploader.getJsonObjectByArtifactId({
|
|
407
|
+
artifactId: fileToLoad.id,
|
|
408
|
+
isGzipped: true,
|
|
401
409
|
});
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
410
|
+
const transformerFile = response;
|
|
411
|
+
if (transformerFileError) {
|
|
412
|
+
console.error(`Transformer file not found for artifact ID: ${fileToLoad.id}.`);
|
|
413
|
+
await this.emit(loading_1.LoaderEventType.AttachmentLoadingError, {
|
|
414
|
+
error: {
|
|
415
|
+
message: `Transformer file not found for artifact ID: ${fileToLoad.id}.`,
|
|
416
|
+
},
|
|
407
417
|
});
|
|
408
418
|
break outerloop;
|
|
409
419
|
}
|
|
410
|
-
|
|
411
|
-
(
|
|
412
|
-
|
|
413
|
-
|
|
420
|
+
for (let i = fileToLoad.lineToProcess; i < fileToLoad.count; i++) {
|
|
421
|
+
if (this.isTimeout) {
|
|
422
|
+
console.log('Timeout detected during attachment loading. Emitting progress to allow continuation.');
|
|
423
|
+
await this.emit(loading_1.LoaderEventType.AttachmentLoadingProgress);
|
|
424
|
+
process.exit(0);
|
|
425
|
+
}
|
|
426
|
+
const { report, rateLimit } = await this.loadAttachment({
|
|
427
|
+
item: transformerFile[i],
|
|
428
|
+
create,
|
|
414
429
|
});
|
|
415
|
-
|
|
430
|
+
if (rateLimit === null || rateLimit === void 0 ? void 0 : rateLimit.delay) {
|
|
431
|
+
await this.emit(loading_1.LoaderEventType.DataLoadingDelayed, {
|
|
432
|
+
delay: rateLimit.delay,
|
|
433
|
+
reports: this.reports,
|
|
434
|
+
processed_files: this.processedFiles,
|
|
435
|
+
});
|
|
436
|
+
break outerloop;
|
|
437
|
+
}
|
|
438
|
+
if (report) {
|
|
439
|
+
(0, worker_adapter_helpers_1.addReportToLoaderReport)({
|
|
440
|
+
loaderReports: this.loaderReports,
|
|
441
|
+
report,
|
|
442
|
+
});
|
|
443
|
+
fileToLoad.lineToProcess = fileToLoad.lineToProcess + 1;
|
|
444
|
+
}
|
|
416
445
|
}
|
|
446
|
+
fileToLoad.completed = true;
|
|
447
|
+
this._processedFiles.push(fileToLoad.id);
|
|
417
448
|
}
|
|
418
|
-
fileToLoad.completed = true;
|
|
419
|
-
this._processedFiles.push(fileToLoad.id);
|
|
420
449
|
}
|
|
421
450
|
}
|
|
451
|
+
catch (error) {
|
|
452
|
+
console.error('Error during attachment loading.', (0, logger_1.serializeError)(error));
|
|
453
|
+
await this.emit(loading_1.LoaderEventType.AttachmentLoadingError, {
|
|
454
|
+
error: {
|
|
455
|
+
message: `Error during attachment loading. ${(0, logger_1.serializeError)(error)}`,
|
|
456
|
+
},
|
|
457
|
+
});
|
|
458
|
+
process.exit(1);
|
|
459
|
+
}
|
|
422
460
|
return {
|
|
423
461
|
reports: this.reports,
|
|
424
462
|
processed_files: this.processedFiles,
|
|
@@ -385,6 +385,7 @@ describe(worker_adapter_1.WorkerAdapter.name, () => {
|
|
|
385
385
|
// Mock the pool to simulate timeout happening during the first artifact
|
|
386
386
|
attachments_streaming_pool_1.AttachmentsStreamingPool.mockImplementationOnce(() => {
|
|
387
387
|
return {
|
|
388
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
388
389
|
streamAll: jest.fn().mockImplementation(async () => {
|
|
389
390
|
adapter.isTimeout = true;
|
|
390
391
|
return {};
|
|
@@ -661,7 +662,9 @@ describe(worker_adapter_1.WorkerAdapter.name, () => {
|
|
|
661
662
|
.fn()
|
|
662
663
|
.mockResolvedValue(undefined);
|
|
663
664
|
adapter.uploadAllRepos = jest.fn().mockResolvedValue(undefined);
|
|
664
|
-
adapter['loaderReports'] = [
|
|
665
|
+
adapter['loaderReports'] = [
|
|
666
|
+
{ item_type: 'tasks', [loading_1.ActionType.CREATED]: 5 },
|
|
667
|
+
];
|
|
665
668
|
adapter['_processedFiles'] = ['file-1', 'file-2'];
|
|
666
669
|
await adapter.emit(types_1.LoaderEventType.DataLoadingDone);
|
|
667
670
|
expect(mockEmit).toHaveBeenCalledWith(expect.objectContaining({
|
|
@@ -685,7 +688,9 @@ describe(worker_adapter_1.WorkerAdapter.name, () => {
|
|
|
685
688
|
adapter['_artifacts'] = [
|
|
686
689
|
{ id: 'art-1', item_count: 10, item_type: 'issues' },
|
|
687
690
|
];
|
|
688
|
-
adapter['loaderReports'] = [
|
|
691
|
+
adapter['loaderReports'] = [
|
|
692
|
+
{ item_type: 'tasks', [loading_1.ActionType.CREATED]: 5 },
|
|
693
|
+
];
|
|
689
694
|
adapter['_processedFiles'] = ['file-1'];
|
|
690
695
|
await adapter.emit('SOME_UNKNOWN_EVENT');
|
|
691
696
|
const callData = mockEmit.mock.calls[0][0].data;
|
|
@@ -770,8 +775,7 @@ describe(worker_adapter_1.WorkerAdapter.name, () => {
|
|
|
770
775
|
async function emitDone(adapterInstance, extractionStart, extractionEnd) {
|
|
771
776
|
adapterInstance.event.payload.event_context.extract_from =
|
|
772
777
|
extractionStart;
|
|
773
|
-
adapterInstance.event.payload.event_context.extract_to =
|
|
774
|
-
extractionEnd;
|
|
778
|
+
adapterInstance.event.payload.event_context.extract_to = extractionEnd;
|
|
775
779
|
// Reset the emit guard so we can emit multiple times in a single test
|
|
776
780
|
adapterInstance['hasWorkerEmitted'] = false;
|
|
777
781
|
await adapterInstance.emit(types_1.ExtractorEventType.AttachmentExtractionDone, {
|
|
@@ -973,4 +977,265 @@ describe(worker_adapter_1.WorkerAdapter.name, () => {
|
|
|
973
977
|
expect(adapter.shouldExtract('users')).toBe(true);
|
|
974
978
|
});
|
|
975
979
|
});
|
|
980
|
+
describe(worker_adapter_1.WorkerAdapter.prototype.loadItemTypes.name, () => {
|
|
981
|
+
let exitSpy;
|
|
982
|
+
let emitSpy;
|
|
983
|
+
beforeEach(() => {
|
|
984
|
+
exitSpy = jest
|
|
985
|
+
.spyOn(process, 'exit')
|
|
986
|
+
.mockImplementation(() => undefined);
|
|
987
|
+
emitSpy = jest.spyOn(adapter, 'emit').mockResolvedValue();
|
|
988
|
+
// Set event type to loading continuation (not StartLoadingData) so we can
|
|
989
|
+
// set fromDevRev state directly without mocking getLoaderBatches
|
|
990
|
+
mockEvent.payload.event_type =
|
|
991
|
+
types_1.EventType.ContinueLoadingData;
|
|
992
|
+
});
|
|
993
|
+
afterEach(() => {
|
|
994
|
+
exitSpy.mockRestore();
|
|
995
|
+
});
|
|
996
|
+
function setupFilesToLoad(items) {
|
|
997
|
+
adapter['adapterState'].state.fromDevRev = {
|
|
998
|
+
filesToLoad: [
|
|
999
|
+
{
|
|
1000
|
+
id: 'artifact-1',
|
|
1001
|
+
file_name: 'file1.json',
|
|
1002
|
+
itemType: 'tasks',
|
|
1003
|
+
count: items.length,
|
|
1004
|
+
lineToProcess: 0,
|
|
1005
|
+
completed: false,
|
|
1006
|
+
},
|
|
1007
|
+
],
|
|
1008
|
+
};
|
|
1009
|
+
adapter['uploader'].getJsonObjectByArtifactId = jest
|
|
1010
|
+
.fn()
|
|
1011
|
+
.mockResolvedValue({ response: items });
|
|
1012
|
+
}
|
|
1013
|
+
it('should emit DataLoadingProgress and exit on timeout', async () => {
|
|
1014
|
+
const items = [
|
|
1015
|
+
{
|
|
1016
|
+
id: { devrev: 'dev-1', external: 'ext-1' },
|
|
1017
|
+
created_date: '',
|
|
1018
|
+
modified_date: '',
|
|
1019
|
+
data: {},
|
|
1020
|
+
},
|
|
1021
|
+
{
|
|
1022
|
+
id: { devrev: 'dev-2', external: 'ext-2' },
|
|
1023
|
+
created_date: '',
|
|
1024
|
+
modified_date: '',
|
|
1025
|
+
data: {},
|
|
1026
|
+
},
|
|
1027
|
+
];
|
|
1028
|
+
setupFilesToLoad(items);
|
|
1029
|
+
// Set timeout before calling loadItemTypes
|
|
1030
|
+
adapter.isTimeout = true;
|
|
1031
|
+
const itemTypesToLoad = [
|
|
1032
|
+
{
|
|
1033
|
+
itemType: 'tasks',
|
|
1034
|
+
create: jest.fn(),
|
|
1035
|
+
update: jest.fn(),
|
|
1036
|
+
},
|
|
1037
|
+
];
|
|
1038
|
+
await adapter.loadItemTypes({ itemTypesToLoad });
|
|
1039
|
+
expect(emitSpy).toHaveBeenCalledWith(types_1.LoaderEventType.DataLoadingProgress);
|
|
1040
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
1041
|
+
});
|
|
1042
|
+
it('should emit DataLoadingProgress mid-loop when timeout arrives between items', async () => {
|
|
1043
|
+
const items = [
|
|
1044
|
+
{
|
|
1045
|
+
id: { devrev: 'dev-1', external: 'ext-1' },
|
|
1046
|
+
created_date: '',
|
|
1047
|
+
modified_date: '',
|
|
1048
|
+
data: {},
|
|
1049
|
+
},
|
|
1050
|
+
{
|
|
1051
|
+
id: { devrev: 'dev-2', external: 'ext-2' },
|
|
1052
|
+
created_date: '',
|
|
1053
|
+
modified_date: '',
|
|
1054
|
+
data: {},
|
|
1055
|
+
},
|
|
1056
|
+
{
|
|
1057
|
+
id: { devrev: 'dev-3', external: 'ext-3' },
|
|
1058
|
+
created_date: '',
|
|
1059
|
+
modified_date: '',
|
|
1060
|
+
data: {},
|
|
1061
|
+
},
|
|
1062
|
+
];
|
|
1063
|
+
setupFilesToLoad(items);
|
|
1064
|
+
// Mock process.exit to throw so it stops execution like a real exit would
|
|
1065
|
+
exitSpy.mockRestore();
|
|
1066
|
+
exitSpy = jest.spyOn(process, 'exit').mockImplementation((() => {
|
|
1067
|
+
throw new Error(`process.exit`);
|
|
1068
|
+
}));
|
|
1069
|
+
let loadItemCallCount = 0;
|
|
1070
|
+
// Mock loadItem to set timeout after the first call
|
|
1071
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/require-await
|
|
1072
|
+
jest.spyOn(adapter, 'loadItem').mockImplementation(async () => {
|
|
1073
|
+
loadItemCallCount++;
|
|
1074
|
+
if (loadItemCallCount === 1) {
|
|
1075
|
+
adapter.isTimeout = true;
|
|
1076
|
+
}
|
|
1077
|
+
return { report: { item_type: 'tasks', updated: 1 } };
|
|
1078
|
+
});
|
|
1079
|
+
const itemTypesToLoad = [
|
|
1080
|
+
{
|
|
1081
|
+
itemType: 'tasks',
|
|
1082
|
+
create: jest.fn(),
|
|
1083
|
+
update: jest.fn(),
|
|
1084
|
+
},
|
|
1085
|
+
];
|
|
1086
|
+
// process.exit throws, so this will throw
|
|
1087
|
+
await expect(adapter.loadItemTypes({ itemTypesToLoad })).rejects.toThrow('process.exit');
|
|
1088
|
+
// First item processed, then timeout detected on second iteration
|
|
1089
|
+
expect(loadItemCallCount).toBe(1);
|
|
1090
|
+
expect(emitSpy).toHaveBeenCalledWith(types_1.LoaderEventType.DataLoadingProgress);
|
|
1091
|
+
});
|
|
1092
|
+
it('should emit DataLoadingError and exit(1) on unexpected error', async () => {
|
|
1093
|
+
adapter['adapterState'].state.fromDevRev = {
|
|
1094
|
+
filesToLoad: [
|
|
1095
|
+
{
|
|
1096
|
+
id: 'artifact-1',
|
|
1097
|
+
file_name: 'file1.json',
|
|
1098
|
+
itemType: 'tasks',
|
|
1099
|
+
count: 1,
|
|
1100
|
+
lineToProcess: 0,
|
|
1101
|
+
completed: false,
|
|
1102
|
+
},
|
|
1103
|
+
],
|
|
1104
|
+
};
|
|
1105
|
+
// Make getJsonObjectByArtifactId throw (not return error — throw)
|
|
1106
|
+
adapter['uploader'].getJsonObjectByArtifactId = jest
|
|
1107
|
+
.fn()
|
|
1108
|
+
.mockRejectedValue(new Error('Unexpected network failure'));
|
|
1109
|
+
const itemTypesToLoad = [
|
|
1110
|
+
{
|
|
1111
|
+
itemType: 'tasks',
|
|
1112
|
+
create: jest.fn(),
|
|
1113
|
+
update: jest.fn(),
|
|
1114
|
+
},
|
|
1115
|
+
];
|
|
1116
|
+
await adapter.loadItemTypes({ itemTypesToLoad });
|
|
1117
|
+
expect(emitSpy).toHaveBeenCalledWith(types_1.LoaderEventType.DataLoadingError, expect.objectContaining({
|
|
1118
|
+
error: expect.objectContaining({
|
|
1119
|
+
message: expect.stringContaining('Error during data loading'),
|
|
1120
|
+
}),
|
|
1121
|
+
}));
|
|
1122
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
1123
|
+
});
|
|
1124
|
+
});
|
|
1125
|
+
describe(worker_adapter_1.WorkerAdapter.prototype.loadAttachments.name, () => {
|
|
1126
|
+
let exitSpy;
|
|
1127
|
+
let emitSpy;
|
|
1128
|
+
beforeEach(() => {
|
|
1129
|
+
exitSpy = jest
|
|
1130
|
+
.spyOn(process, 'exit')
|
|
1131
|
+
.mockImplementation(() => undefined);
|
|
1132
|
+
emitSpy = jest.spyOn(adapter, 'emit').mockResolvedValue();
|
|
1133
|
+
// Set event type to continuation so we can set fromDevRev state directly
|
|
1134
|
+
mockEvent.payload.event_type =
|
|
1135
|
+
types_1.EventType.ContinueLoadingAttachments;
|
|
1136
|
+
});
|
|
1137
|
+
afterEach(() => {
|
|
1138
|
+
exitSpy.mockRestore();
|
|
1139
|
+
});
|
|
1140
|
+
function setupFilesToLoad(items) {
|
|
1141
|
+
adapter['adapterState'].state.fromDevRev = {
|
|
1142
|
+
filesToLoad: [
|
|
1143
|
+
{
|
|
1144
|
+
id: 'artifact-1',
|
|
1145
|
+
file_name: 'attachments.json',
|
|
1146
|
+
itemType: 'attachment',
|
|
1147
|
+
count: items.length,
|
|
1148
|
+
lineToProcess: 0,
|
|
1149
|
+
completed: false,
|
|
1150
|
+
},
|
|
1151
|
+
],
|
|
1152
|
+
};
|
|
1153
|
+
adapter['uploader'].getJsonObjectByArtifactId = jest
|
|
1154
|
+
.fn()
|
|
1155
|
+
.mockResolvedValue({ response: items });
|
|
1156
|
+
}
|
|
1157
|
+
it('should emit AttachmentLoadingProgress and exit on timeout', async () => {
|
|
1158
|
+
const items = [
|
|
1159
|
+
{
|
|
1160
|
+
reference_id: 'ref-1',
|
|
1161
|
+
parent_type: 'task',
|
|
1162
|
+
parent_reference_id: 'parent-1',
|
|
1163
|
+
file_name: 'file.pdf',
|
|
1164
|
+
file_type: 'application/pdf',
|
|
1165
|
+
file_size: 100,
|
|
1166
|
+
url: 'https://example.com/file.pdf',
|
|
1167
|
+
valid_until: '',
|
|
1168
|
+
created_by_id: 'user-1',
|
|
1169
|
+
created_date: '',
|
|
1170
|
+
modified_by_id: 'user-1',
|
|
1171
|
+
modified_date: '',
|
|
1172
|
+
},
|
|
1173
|
+
];
|
|
1174
|
+
setupFilesToLoad(items);
|
|
1175
|
+
adapter.isTimeout = true;
|
|
1176
|
+
await adapter.loadAttachments({
|
|
1177
|
+
create: jest.fn(),
|
|
1178
|
+
});
|
|
1179
|
+
expect(emitSpy).toHaveBeenCalledWith(types_1.LoaderEventType.AttachmentLoadingProgress);
|
|
1180
|
+
expect(exitSpy).toHaveBeenCalledWith(0);
|
|
1181
|
+
});
|
|
1182
|
+
it('should emit AttachmentLoadingError on transformer file error', async () => {
|
|
1183
|
+
adapter['adapterState'].state.fromDevRev = {
|
|
1184
|
+
filesToLoad: [
|
|
1185
|
+
{
|
|
1186
|
+
id: 'bad-artifact',
|
|
1187
|
+
file_name: 'attachments.json',
|
|
1188
|
+
itemType: 'attachment',
|
|
1189
|
+
count: 1,
|
|
1190
|
+
lineToProcess: 0,
|
|
1191
|
+
completed: false,
|
|
1192
|
+
},
|
|
1193
|
+
],
|
|
1194
|
+
};
|
|
1195
|
+
adapter['uploader'].getJsonObjectByArtifactId = jest
|
|
1196
|
+
.fn()
|
|
1197
|
+
.mockResolvedValue({
|
|
1198
|
+
response: null,
|
|
1199
|
+
error: new Error('Artifact not found'),
|
|
1200
|
+
});
|
|
1201
|
+
await adapter.loadAttachments({
|
|
1202
|
+
create: jest.fn(),
|
|
1203
|
+
});
|
|
1204
|
+
expect(emitSpy).toHaveBeenCalledWith(types_1.LoaderEventType.AttachmentLoadingError, expect.objectContaining({
|
|
1205
|
+
error: expect.objectContaining({
|
|
1206
|
+
message: expect.stringContaining('Transformer file not found'),
|
|
1207
|
+
}),
|
|
1208
|
+
}));
|
|
1209
|
+
});
|
|
1210
|
+
it('should emit AttachmentLoadingError and exit(1) on unexpected error', async () => {
|
|
1211
|
+
const items = [
|
|
1212
|
+
{
|
|
1213
|
+
reference_id: 'ref-1',
|
|
1214
|
+
parent_type: 'task',
|
|
1215
|
+
parent_reference_id: 'parent-1',
|
|
1216
|
+
file_name: 'file.pdf',
|
|
1217
|
+
file_type: 'application/pdf',
|
|
1218
|
+
file_size: 100,
|
|
1219
|
+
url: 'https://example.com/file.pdf',
|
|
1220
|
+
valid_until: '',
|
|
1221
|
+
created_by_id: 'user-1',
|
|
1222
|
+
created_date: '',
|
|
1223
|
+
modified_by_id: 'user-1',
|
|
1224
|
+
modified_date: '',
|
|
1225
|
+
},
|
|
1226
|
+
];
|
|
1227
|
+
setupFilesToLoad(items);
|
|
1228
|
+
// Make the create function throw
|
|
1229
|
+
const mockCreate = jest
|
|
1230
|
+
.fn()
|
|
1231
|
+
.mockRejectedValue(new Error('Unexpected API failure'));
|
|
1232
|
+
await adapter.loadAttachments({ create: mockCreate });
|
|
1233
|
+
expect(emitSpy).toHaveBeenCalledWith(types_1.LoaderEventType.AttachmentLoadingError, expect.objectContaining({
|
|
1234
|
+
error: expect.objectContaining({
|
|
1235
|
+
message: expect.stringContaining('Error during attachment loading'),
|
|
1236
|
+
}),
|
|
1237
|
+
}));
|
|
1238
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
1239
|
+
});
|
|
1240
|
+
});
|
|
976
1241
|
});
|