@devrev/ts-adaas 1.19.4-beta.0 → 1.19.5
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/dist/attachments-streaming/attachments-streaming-pool.test.js +3 -6
- package/dist/common/event-type-translation.test.d.ts +2 -0
- package/dist/common/event-type-translation.test.d.ts.map +1 -0
- package/dist/common/event-type-translation.test.js +175 -0
- package/dist/common/time-value-resolver.test.js +0 -1
- package/dist/multithreading/create-worker.test.js +34 -16
- package/dist/multithreading/process-task.test.d.ts +2 -0
- package/dist/multithreading/process-task.test.d.ts.map +1 -0
- package/dist/multithreading/process-task.test.js +166 -0
- package/dist/multithreading/spawn/spawn.test.d.ts +2 -0
- package/dist/multithreading/spawn/spawn.test.d.ts.map +1 -0
- package/dist/multithreading/spawn/spawn.test.js +223 -0
- package/dist/multithreading/worker-adapter/worker-adapter.emit.test.d.ts +2 -0
- package/dist/multithreading/worker-adapter/worker-adapter.emit.test.d.ts.map +1 -0
- package/dist/multithreading/worker-adapter/worker-adapter.emit.test.js +415 -0
- package/dist/multithreading/worker-adapter/worker-adapter.extraction.test.d.ts +2 -0
- package/dist/multithreading/worker-adapter/worker-adapter.extraction.test.d.ts.map +1 -0
- package/dist/multithreading/worker-adapter/worker-adapter.extraction.test.js +801 -0
- package/dist/multithreading/worker-adapter/worker-adapter.loading.test.d.ts +2 -0
- package/dist/multithreading/worker-adapter/worker-adapter.loading.test.d.ts.map +1 -0
- package/dist/multithreading/worker-adapter/worker-adapter.loading.test.js +598 -0
- package/dist/multithreading/worker-adapter/worker-adapter.serialization.test.d.ts +2 -0
- package/dist/multithreading/worker-adapter/worker-adapter.serialization.test.d.ts.map +1 -0
- package/dist/multithreading/worker-adapter/worker-adapter.serialization.test.js +71 -0
- package/dist/repo/repo.test.js +41 -0
- package/dist/state/state.extract-window.test.d.ts +2 -0
- package/dist/state/state.extract-window.test.d.ts.map +1 -0
- package/dist/state/state.extract-window.test.js +163 -0
- package/dist/state/state.pending-boundaries.test.d.ts +2 -0
- package/dist/state/state.pending-boundaries.test.d.ts.map +1 -0
- package/dist/state/state.pending-boundaries.test.js +189 -0
- package/dist/state/state.post-state.test.d.ts +2 -0
- package/dist/state/state.post-state.test.d.ts.map +1 -0
- package/dist/state/state.post-state.test.js +77 -0
- package/dist/state/state.test.js +23 -506
- package/dist/state/state.time-value-resolution.test.d.ts +2 -0
- package/dist/state/state.time-value-resolution.test.d.ts.map +1 -0
- package/dist/state/state.time-value-resolution.test.js +175 -0
- package/dist/types/extraction.test.js +57 -21
- package/dist/uploader/uploader.helpers.test.js +0 -11
- package/dist/uploader/uploader.test.js +0 -9
- package/package.json +7 -6
- package/dist/multithreading/worker-adapter/worker-adapter.test.d.ts +0 -2
- package/dist/multithreading/worker-adapter/worker-adapter.test.d.ts.map +0 -1
- package/dist/multithreading/worker-adapter/worker-adapter.test.js +0 -1243
package/dist/state/state.test.js
CHANGED
|
@@ -41,7 +41,7 @@ describe(state_1.State.name, () => {
|
|
|
41
41
|
expect(postStateSpy).not.toHaveBeenCalled();
|
|
42
42
|
expect(installInitialDomainMappingSpy).not.toHaveBeenCalled();
|
|
43
43
|
});
|
|
44
|
-
it.each(constants_1.STATEFUL_EVENT_TYPES)('should exit the process if fetching the state fails', async (eventType) => {
|
|
44
|
+
it.each(constants_1.STATEFUL_EVENT_TYPES)('should exit the process if fetching the state fails for event type %s', async (eventType) => {
|
|
45
45
|
// Arrange
|
|
46
46
|
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
47
47
|
payload: { event_type: eventType },
|
|
@@ -50,7 +50,6 @@ describe(state_1.State.name, () => {
|
|
|
50
50
|
isAxiosError: true,
|
|
51
51
|
response: { status: 500 },
|
|
52
52
|
});
|
|
53
|
-
jest.spyOn(console, 'error').mockImplementation(() => { });
|
|
54
53
|
// Act & Assert
|
|
55
54
|
await expect((0, state_1.createAdapterState)({
|
|
56
55
|
event,
|
|
@@ -59,13 +58,12 @@ describe(state_1.State.name, () => {
|
|
|
59
58
|
})).rejects.toThrow('process.exit called');
|
|
60
59
|
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
61
60
|
});
|
|
62
|
-
it.each(constants_1.STATEFUL_EVENT_TYPES)('should exit the process if parsing the state fails', async (eventType) => {
|
|
61
|
+
it.each(constants_1.STATEFUL_EVENT_TYPES)('should exit the process if parsing the state fails for event type %s', async (eventType) => {
|
|
63
62
|
// Arrange
|
|
64
63
|
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
65
64
|
payload: { event_type: eventType },
|
|
66
65
|
});
|
|
67
66
|
fetchStateSpy.mockResolvedValue({ state: 'invalid-json' });
|
|
68
|
-
jest.spyOn(console, 'error').mockImplementation(() => { });
|
|
69
67
|
// Act & Assert
|
|
70
68
|
await expect((0, state_1.createAdapterState)({
|
|
71
69
|
event,
|
|
@@ -74,13 +72,12 @@ describe(state_1.State.name, () => {
|
|
|
74
72
|
})).rejects.toThrow('process.exit called');
|
|
75
73
|
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
76
74
|
});
|
|
77
|
-
it.each(constants_1.STATEFUL_EVENT_TYPES)('should exit the process if fetching is successful but there is no state in the response', async (eventType) => {
|
|
75
|
+
it.each(constants_1.STATEFUL_EVENT_TYPES)('should exit the process if fetching is successful but there is no state in the response for event type %s', async (eventType) => {
|
|
78
76
|
// Arrange
|
|
79
77
|
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
80
78
|
payload: { event_type: eventType },
|
|
81
79
|
});
|
|
82
80
|
fetchStateSpy.mockResolvedValue({ state: null });
|
|
83
|
-
jest.spyOn(console, 'error').mockImplementation(() => { });
|
|
84
81
|
// Act & Assert
|
|
85
82
|
await expect((0, state_1.createAdapterState)({
|
|
86
83
|
event,
|
|
@@ -110,7 +107,6 @@ describe(state_1.State.name, () => {
|
|
|
110
107
|
postStateSpy.mockResolvedValue({
|
|
111
108
|
success: true,
|
|
112
109
|
});
|
|
113
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
114
110
|
// Act
|
|
115
111
|
await (0, state_1.createAdapterState)({
|
|
116
112
|
event,
|
|
@@ -141,7 +137,6 @@ describe(state_1.State.name, () => {
|
|
|
141
137
|
postStateSpy.mockResolvedValue({
|
|
142
138
|
success: true,
|
|
143
139
|
});
|
|
144
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
145
140
|
// Act
|
|
146
141
|
await (0, state_1.createAdapterState)({
|
|
147
142
|
event,
|
|
@@ -165,8 +160,6 @@ describe(state_1.State.name, () => {
|
|
|
165
160
|
test: 'test',
|
|
166
161
|
}),
|
|
167
162
|
});
|
|
168
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
169
|
-
jest.spyOn(console, 'error').mockImplementation(() => { });
|
|
170
163
|
// Act & Assert
|
|
171
164
|
await expect((0, state_1.createAdapterState)({
|
|
172
165
|
event,
|
|
@@ -188,7 +181,6 @@ describe(state_1.State.name, () => {
|
|
|
188
181
|
snapInVersionId: '1.0.0',
|
|
189
182
|
});
|
|
190
183
|
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
191
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
192
184
|
// Act & Assert
|
|
193
185
|
await (0, state_1.createAdapterState)({
|
|
194
186
|
event,
|
|
@@ -214,7 +206,6 @@ describe(state_1.State.name, () => {
|
|
|
214
206
|
installInitialDomainMappingSpy.mockResolvedValue({
|
|
215
207
|
success: true,
|
|
216
208
|
});
|
|
217
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
218
209
|
// Act
|
|
219
210
|
await (0, state_1.createAdapterState)({
|
|
220
211
|
event,
|
|
@@ -224,498 +215,6 @@ describe(state_1.State.name, () => {
|
|
|
224
215
|
// Assert
|
|
225
216
|
expect(installInitialDomainMappingSpy).toHaveBeenCalled();
|
|
226
217
|
});
|
|
227
|
-
describe('Enhanced Control Protocol - TimeValue resolution failures', () => {
|
|
228
|
-
it('should exit the process if extraction_start_time resolution fails', async () => {
|
|
229
|
-
// Arrange: WORKERS_NEWEST type but state has no workersNewest
|
|
230
|
-
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
231
|
-
payload: {
|
|
232
|
-
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
233
|
-
event_context: {
|
|
234
|
-
extraction_start_time: {
|
|
235
|
-
type: extraction_1.TimeValueType.WORKERS_NEWEST,
|
|
236
|
-
},
|
|
237
|
-
},
|
|
238
|
-
},
|
|
239
|
-
});
|
|
240
|
-
const stringifiedState = JSON.stringify({
|
|
241
|
-
snapInVersionId: 'test_snap_in_version_id',
|
|
242
|
-
workers_oldest: '',
|
|
243
|
-
workers_newest: '',
|
|
244
|
-
});
|
|
245
|
-
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
246
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
247
|
-
jest.spyOn(console, 'error').mockImplementation(() => { });
|
|
248
|
-
// Act & Assert
|
|
249
|
-
await expect((0, state_1.createAdapterState)({
|
|
250
|
-
event,
|
|
251
|
-
initialState: {},
|
|
252
|
-
initialDomainMapping: {},
|
|
253
|
-
})).rejects.toThrow('process.exit called');
|
|
254
|
-
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
255
|
-
});
|
|
256
|
-
it('should exit the process if extraction_end_time resolution fails', async () => {
|
|
257
|
-
// Arrange: WORKERS_NEWEST type but state has no workersNewest
|
|
258
|
-
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
259
|
-
payload: {
|
|
260
|
-
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
261
|
-
event_context: {
|
|
262
|
-
extraction_start_time: {
|
|
263
|
-
type: extraction_1.TimeValueType.UNBOUNDED,
|
|
264
|
-
},
|
|
265
|
-
extraction_end_time: {
|
|
266
|
-
type: extraction_1.TimeValueType.WORKERS_NEWEST,
|
|
267
|
-
},
|
|
268
|
-
},
|
|
269
|
-
},
|
|
270
|
-
});
|
|
271
|
-
const stringifiedState = JSON.stringify({
|
|
272
|
-
snapInVersionId: 'test_snap_in_version_id',
|
|
273
|
-
workers_oldest: '',
|
|
274
|
-
workers_newest: '',
|
|
275
|
-
});
|
|
276
|
-
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
277
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
278
|
-
jest.spyOn(console, 'error').mockImplementation(() => { });
|
|
279
|
-
// Act & Assert
|
|
280
|
-
await expect((0, state_1.createAdapterState)({
|
|
281
|
-
event,
|
|
282
|
-
initialState: {},
|
|
283
|
-
initialDomainMapping: {},
|
|
284
|
-
})).rejects.toThrow('process.exit called');
|
|
285
|
-
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
286
|
-
});
|
|
287
|
-
});
|
|
288
|
-
describe('Backwards compatibility - missing TimeValue type', () => {
|
|
289
|
-
it('should skip resolution when extraction_start_time has no type', async () => {
|
|
290
|
-
// Arrange: platform sends extraction_start_time without a type field (old platform version)
|
|
291
|
-
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
292
|
-
context: {
|
|
293
|
-
snap_in_version_id: 'test_snap_in_version_id',
|
|
294
|
-
},
|
|
295
|
-
payload: {
|
|
296
|
-
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
297
|
-
event_context: {
|
|
298
|
-
extraction_start_time: {},
|
|
299
|
-
extraction_end_time: {
|
|
300
|
-
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
301
|
-
value: '2025-06-01T00:00:00Z',
|
|
302
|
-
},
|
|
303
|
-
},
|
|
304
|
-
},
|
|
305
|
-
});
|
|
306
|
-
const stringifiedState = JSON.stringify({
|
|
307
|
-
snapInVersionId: 'test_snap_in_version_id',
|
|
308
|
-
});
|
|
309
|
-
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
310
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
311
|
-
// Act
|
|
312
|
-
const state = await (0, state_1.createAdapterState)({
|
|
313
|
-
event,
|
|
314
|
-
initialState: {},
|
|
315
|
-
initialDomainMapping: {},
|
|
316
|
-
});
|
|
317
|
-
// Assert: should not crash, extract_from is not set, extract_to is resolved
|
|
318
|
-
expect(processExitSpy).not.toHaveBeenCalled();
|
|
319
|
-
expect(event.payload.event_context.extract_from).toBeUndefined();
|
|
320
|
-
expect(event.payload.event_context.extract_to).toBe('2025-06-01T00:00:00.000Z');
|
|
321
|
-
expect(state.state.pendingWorkersNewest).toBe('2025-06-01T00:00:00.000Z');
|
|
322
|
-
});
|
|
323
|
-
it('should skip resolution when extraction_end_time has no type', async () => {
|
|
324
|
-
// Arrange: platform sends extraction_end_time without a type field
|
|
325
|
-
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
326
|
-
context: {
|
|
327
|
-
snap_in_version_id: 'test_snap_in_version_id',
|
|
328
|
-
},
|
|
329
|
-
payload: {
|
|
330
|
-
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
331
|
-
event_context: {
|
|
332
|
-
extraction_start_time: {
|
|
333
|
-
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
334
|
-
value: '2024-01-01T00:00:00Z',
|
|
335
|
-
},
|
|
336
|
-
extraction_end_time: {},
|
|
337
|
-
},
|
|
338
|
-
},
|
|
339
|
-
});
|
|
340
|
-
const stringifiedState = JSON.stringify({
|
|
341
|
-
snapInVersionId: 'test_snap_in_version_id',
|
|
342
|
-
});
|
|
343
|
-
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
344
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
345
|
-
// Act
|
|
346
|
-
await (0, state_1.createAdapterState)({
|
|
347
|
-
event,
|
|
348
|
-
initialState: {},
|
|
349
|
-
initialDomainMapping: {},
|
|
350
|
-
});
|
|
351
|
-
// Assert: should not crash, extract_to is not set, extract_from is resolved
|
|
352
|
-
expect(processExitSpy).not.toHaveBeenCalled();
|
|
353
|
-
expect(event.payload.event_context.extract_from).toBe('2024-01-01T00:00:00.000Z');
|
|
354
|
-
expect(event.payload.event_context.extract_to).toBeUndefined();
|
|
355
|
-
});
|
|
356
|
-
it('should skip resolution when both extraction times have no type', async () => {
|
|
357
|
-
// Arrange: platform sends both time values without type fields
|
|
358
|
-
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
359
|
-
context: {
|
|
360
|
-
snap_in_version_id: 'test_snap_in_version_id',
|
|
361
|
-
},
|
|
362
|
-
payload: {
|
|
363
|
-
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
364
|
-
event_context: {
|
|
365
|
-
extraction_start_time: {
|
|
366
|
-
value: 'some-value',
|
|
367
|
-
},
|
|
368
|
-
extraction_end_time: {
|
|
369
|
-
value: 'some-value',
|
|
370
|
-
},
|
|
371
|
-
},
|
|
372
|
-
},
|
|
373
|
-
});
|
|
374
|
-
const stringifiedState = JSON.stringify({
|
|
375
|
-
snapInVersionId: 'test_snap_in_version_id',
|
|
376
|
-
});
|
|
377
|
-
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
378
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
379
|
-
// Act
|
|
380
|
-
await (0, state_1.createAdapterState)({
|
|
381
|
-
event,
|
|
382
|
-
initialState: {},
|
|
383
|
-
initialDomainMapping: {},
|
|
384
|
-
});
|
|
385
|
-
// Assert: should not crash, neither extraction time is resolved
|
|
386
|
-
expect(processExitSpy).not.toHaveBeenCalled();
|
|
387
|
-
expect(event.payload.event_context.extract_from).toBeUndefined();
|
|
388
|
-
expect(event.payload.event_context.extract_to).toBeUndefined();
|
|
389
|
-
});
|
|
390
|
-
});
|
|
391
|
-
describe('Enhanced Control Protocol - extraction window validation', () => {
|
|
392
|
-
it('should exit the process if extract_from >= extract_to', async () => {
|
|
393
|
-
// Arrange: start is after end (inverted window)
|
|
394
|
-
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
395
|
-
payload: {
|
|
396
|
-
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
397
|
-
event_context: {
|
|
398
|
-
extraction_start_time: {
|
|
399
|
-
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
400
|
-
value: '2025-06-01T00:00:00Z',
|
|
401
|
-
},
|
|
402
|
-
extraction_end_time: {
|
|
403
|
-
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
404
|
-
value: '2024-01-01T00:00:00Z',
|
|
405
|
-
},
|
|
406
|
-
},
|
|
407
|
-
},
|
|
408
|
-
});
|
|
409
|
-
const stringifiedState = JSON.stringify({
|
|
410
|
-
snapInVersionId: 'test_snap_in_version_id',
|
|
411
|
-
});
|
|
412
|
-
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
413
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
414
|
-
jest.spyOn(console, 'error').mockImplementation(() => { });
|
|
415
|
-
// Act & Assert
|
|
416
|
-
await expect((0, state_1.createAdapterState)({
|
|
417
|
-
event,
|
|
418
|
-
initialState: {},
|
|
419
|
-
initialDomainMapping: {},
|
|
420
|
-
})).rejects.toThrow('process.exit called');
|
|
421
|
-
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
422
|
-
});
|
|
423
|
-
it('should exit the process if extract_from equals extract_to', async () => {
|
|
424
|
-
// Arrange: start equals end (zero-width window)
|
|
425
|
-
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
426
|
-
payload: {
|
|
427
|
-
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
428
|
-
event_context: {
|
|
429
|
-
extraction_start_time: {
|
|
430
|
-
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
431
|
-
value: '2024-06-01T00:00:00Z',
|
|
432
|
-
},
|
|
433
|
-
extraction_end_time: {
|
|
434
|
-
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
435
|
-
value: '2024-06-01T00:00:00Z',
|
|
436
|
-
},
|
|
437
|
-
},
|
|
438
|
-
},
|
|
439
|
-
});
|
|
440
|
-
const stringifiedState = JSON.stringify({
|
|
441
|
-
snapInVersionId: 'test_snap_in_version_id',
|
|
442
|
-
});
|
|
443
|
-
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
444
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
445
|
-
jest.spyOn(console, 'error').mockImplementation(() => { });
|
|
446
|
-
// Act & Assert
|
|
447
|
-
await expect((0, state_1.createAdapterState)({
|
|
448
|
-
event,
|
|
449
|
-
initialState: {},
|
|
450
|
-
initialDomainMapping: {},
|
|
451
|
-
})).rejects.toThrow('process.exit called');
|
|
452
|
-
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
453
|
-
});
|
|
454
|
-
it('should not exit when extract_from < extract_to', async () => {
|
|
455
|
-
// Arrange: valid window
|
|
456
|
-
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
457
|
-
payload: {
|
|
458
|
-
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
459
|
-
event_context: {
|
|
460
|
-
extraction_start_time: {
|
|
461
|
-
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
462
|
-
value: '2024-01-01T00:00:00Z',
|
|
463
|
-
},
|
|
464
|
-
extraction_end_time: {
|
|
465
|
-
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
466
|
-
value: '2025-06-01T00:00:00Z',
|
|
467
|
-
},
|
|
468
|
-
},
|
|
469
|
-
},
|
|
470
|
-
});
|
|
471
|
-
const stringifiedState = JSON.stringify({
|
|
472
|
-
snapInVersionId: 'test_snap_in_version_id',
|
|
473
|
-
});
|
|
474
|
-
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
475
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
476
|
-
// Act
|
|
477
|
-
await (0, state_1.createAdapterState)({
|
|
478
|
-
event,
|
|
479
|
-
initialState: {},
|
|
480
|
-
initialDomainMapping: {},
|
|
481
|
-
});
|
|
482
|
-
// Assert: process.exit should NOT have been called
|
|
483
|
-
expect(processExitSpy).not.toHaveBeenCalled();
|
|
484
|
-
});
|
|
485
|
-
it('should not validate when only extract_from is set', async () => {
|
|
486
|
-
// Arrange: only start, no end
|
|
487
|
-
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
488
|
-
payload: {
|
|
489
|
-
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
490
|
-
event_context: {
|
|
491
|
-
extraction_start_time: {
|
|
492
|
-
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
493
|
-
value: '2024-01-01T00:00:00Z',
|
|
494
|
-
},
|
|
495
|
-
},
|
|
496
|
-
},
|
|
497
|
-
});
|
|
498
|
-
const stringifiedState = JSON.stringify({
|
|
499
|
-
snapInVersionId: 'test_snap_in_version_id',
|
|
500
|
-
});
|
|
501
|
-
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
502
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
503
|
-
// Act
|
|
504
|
-
await (0, state_1.createAdapterState)({
|
|
505
|
-
event,
|
|
506
|
-
initialState: {},
|
|
507
|
-
initialDomainMapping: {},
|
|
508
|
-
});
|
|
509
|
-
// Assert: process.exit should NOT have been called
|
|
510
|
-
expect(processExitSpy).not.toHaveBeenCalled();
|
|
511
|
-
});
|
|
512
|
-
it('should not exit when extract_from is UNBOUNDED and extract_to is a real timestamp', async () => {
|
|
513
|
-
// Arrange: UNBOUNDED start (epoch) with a real ABSOLUTE end timestamp
|
|
514
|
-
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
515
|
-
payload: {
|
|
516
|
-
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
517
|
-
event_context: {
|
|
518
|
-
extraction_start_time: {
|
|
519
|
-
type: extraction_1.TimeValueType.UNBOUNDED,
|
|
520
|
-
},
|
|
521
|
-
extraction_end_time: {
|
|
522
|
-
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
523
|
-
value: '2025-06-01T00:00:00Z',
|
|
524
|
-
},
|
|
525
|
-
},
|
|
526
|
-
},
|
|
527
|
-
});
|
|
528
|
-
const stringifiedState = JSON.stringify({
|
|
529
|
-
snapInVersionId: 'test_snap_in_version_id',
|
|
530
|
-
});
|
|
531
|
-
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
532
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
533
|
-
// Act
|
|
534
|
-
await (0, state_1.createAdapterState)({
|
|
535
|
-
event,
|
|
536
|
-
initialState: {},
|
|
537
|
-
initialDomainMapping: {},
|
|
538
|
-
});
|
|
539
|
-
// Assert: process.exit should NOT have been called
|
|
540
|
-
expect(processExitSpy).not.toHaveBeenCalled();
|
|
541
|
-
});
|
|
542
|
-
});
|
|
543
|
-
describe('Pending extraction boundaries (pendingWorkersOldest/pendingWorkersNewest)', () => {
|
|
544
|
-
const FIXED_NOW = '2026-03-26T10:00:00.000Z';
|
|
545
|
-
beforeEach(() => {
|
|
546
|
-
jest.useFakeTimers();
|
|
547
|
-
jest.setSystemTime(new Date(FIXED_NOW));
|
|
548
|
-
});
|
|
549
|
-
afterEach(() => {
|
|
550
|
-
jest.useRealTimers();
|
|
551
|
-
});
|
|
552
|
-
it('should store resolved values in pendingWorkersOldest/pendingWorkersNewest on StartExtractingMetadata', async () => {
|
|
553
|
-
// Arrange
|
|
554
|
-
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
555
|
-
context: {
|
|
556
|
-
snap_in_version_id: '',
|
|
557
|
-
},
|
|
558
|
-
payload: {
|
|
559
|
-
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
560
|
-
event_context: {
|
|
561
|
-
extraction_start_time: {
|
|
562
|
-
type: extraction_1.TimeValueType.UNBOUNDED,
|
|
563
|
-
},
|
|
564
|
-
extraction_end_time: {
|
|
565
|
-
type: extraction_1.TimeValueType.CURRENT_TIME,
|
|
566
|
-
},
|
|
567
|
-
},
|
|
568
|
-
},
|
|
569
|
-
});
|
|
570
|
-
fetchStateSpy.mockRejectedValue({
|
|
571
|
-
isAxiosError: true,
|
|
572
|
-
response: { status: 404 },
|
|
573
|
-
});
|
|
574
|
-
installInitialDomainMappingSpy.mockResolvedValue({ success: true });
|
|
575
|
-
postStateSpy.mockResolvedValue({ success: true });
|
|
576
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
577
|
-
// Act
|
|
578
|
-
const state = await (0, state_1.createAdapterState)({
|
|
579
|
-
event,
|
|
580
|
-
initialState: {},
|
|
581
|
-
initialDomainMapping: {},
|
|
582
|
-
});
|
|
583
|
-
// Assert
|
|
584
|
-
expect(state.state.pendingWorkersOldest).toBe('1970-01-01T00:00:00.000Z');
|
|
585
|
-
expect(state.state.pendingWorkersNewest).toBe(FIXED_NOW);
|
|
586
|
-
expect(event.payload.event_context.extract_from).toBe('1970-01-01T00:00:00.000Z');
|
|
587
|
-
expect(event.payload.event_context.extract_to).toBe(FIXED_NOW);
|
|
588
|
-
});
|
|
589
|
-
it('should overwrite pending values on a retry (new StartExtractingMetadata after failure)', async () => {
|
|
590
|
-
// Arrange: state has stale pending values from a previous failed attempt
|
|
591
|
-
const staleOldest = '2026-03-25T08:00:00.000Z';
|
|
592
|
-
const staleNewest = '2026-03-25T09:00:00.000Z';
|
|
593
|
-
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
594
|
-
context: {
|
|
595
|
-
snap_in_version_id: 'test_snap_in_version_id',
|
|
596
|
-
},
|
|
597
|
-
payload: {
|
|
598
|
-
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
599
|
-
event_context: {
|
|
600
|
-
extraction_start_time: {
|
|
601
|
-
type: extraction_1.TimeValueType.UNBOUNDED,
|
|
602
|
-
},
|
|
603
|
-
extraction_end_time: {
|
|
604
|
-
type: extraction_1.TimeValueType.CURRENT_TIME,
|
|
605
|
-
},
|
|
606
|
-
},
|
|
607
|
-
},
|
|
608
|
-
});
|
|
609
|
-
const stringifiedState = JSON.stringify({
|
|
610
|
-
snapInVersionId: 'test_snap_in_version_id',
|
|
611
|
-
pendingWorkersOldest: staleOldest,
|
|
612
|
-
pendingWorkersNewest: staleNewest,
|
|
613
|
-
});
|
|
614
|
-
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
615
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
616
|
-
// Act
|
|
617
|
-
const state = await (0, state_1.createAdapterState)({
|
|
618
|
-
event,
|
|
619
|
-
initialState: {},
|
|
620
|
-
initialDomainMapping: {},
|
|
621
|
-
});
|
|
622
|
-
// Assert: pending values are overwritten with fresh resolution, not stale values
|
|
623
|
-
expect(state.state.pendingWorkersOldest).toBe('1970-01-01T00:00:00.000Z');
|
|
624
|
-
expect(state.state.pendingWorkersNewest).toBe(FIXED_NOW);
|
|
625
|
-
expect(state.state.pendingWorkersNewest).not.toBe(staleNewest);
|
|
626
|
-
});
|
|
627
|
-
it('should reuse pending values from state on ContinueExtractingData instead of re-resolving', async () => {
|
|
628
|
-
// Arrange: state has pending values from a prior StartExtractingMetadata phase
|
|
629
|
-
const pendingOldest = '1970-01-01T00:00:00.000Z';
|
|
630
|
-
const pendingNewest = '2026-03-26T08:00:00.000Z'; // Earlier than FIXED_NOW
|
|
631
|
-
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
632
|
-
context: {
|
|
633
|
-
snap_in_version_id: 'test_snap_in_version_id',
|
|
634
|
-
},
|
|
635
|
-
payload: {
|
|
636
|
-
event_type: extraction_1.EventType.ContinueExtractingData,
|
|
637
|
-
event_context: {
|
|
638
|
-
// Platform still sends TimeValue objects, but they should be ignored
|
|
639
|
-
extraction_start_time: {
|
|
640
|
-
type: extraction_1.TimeValueType.CURRENT_TIME,
|
|
641
|
-
},
|
|
642
|
-
extraction_end_time: {
|
|
643
|
-
type: extraction_1.TimeValueType.CURRENT_TIME,
|
|
644
|
-
},
|
|
645
|
-
},
|
|
646
|
-
},
|
|
647
|
-
});
|
|
648
|
-
const stringifiedState = JSON.stringify({
|
|
649
|
-
snapInVersionId: 'test_snap_in_version_id',
|
|
650
|
-
pendingWorkersOldest: pendingOldest,
|
|
651
|
-
pendingWorkersNewest: pendingNewest,
|
|
652
|
-
});
|
|
653
|
-
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
654
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
655
|
-
// Act
|
|
656
|
-
const state = await (0, state_1.createAdapterState)({
|
|
657
|
-
event,
|
|
658
|
-
initialState: {},
|
|
659
|
-
initialDomainMapping: {},
|
|
660
|
-
});
|
|
661
|
-
// Assert: uses cached pending values, NOT new Date() resolution
|
|
662
|
-
expect(event.payload.event_context.extract_from).toBe(pendingOldest);
|
|
663
|
-
expect(event.payload.event_context.extract_to).toBe(pendingNewest);
|
|
664
|
-
// Pending values in state remain unchanged
|
|
665
|
-
expect(state.state.pendingWorkersOldest).toBe(pendingOldest);
|
|
666
|
-
expect(state.state.pendingWorkersNewest).toBe(pendingNewest);
|
|
667
|
-
});
|
|
668
|
-
it('should not set extract_from/extract_to on ContinueExtractingData if no pending values exist', async () => {
|
|
669
|
-
// Arrange: state has no pending values (e.g. old state from before this feature)
|
|
670
|
-
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
671
|
-
context: {
|
|
672
|
-
snap_in_version_id: 'test_snap_in_version_id',
|
|
673
|
-
},
|
|
674
|
-
payload: { event_type: extraction_1.EventType.ContinueExtractingData },
|
|
675
|
-
});
|
|
676
|
-
const stringifiedState = JSON.stringify({
|
|
677
|
-
snapInVersionId: 'test_snap_in_version_id',
|
|
678
|
-
});
|
|
679
|
-
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
680
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
681
|
-
// Act
|
|
682
|
-
await (0, state_1.createAdapterState)({
|
|
683
|
-
event,
|
|
684
|
-
initialState: {},
|
|
685
|
-
initialDomainMapping: {},
|
|
686
|
-
});
|
|
687
|
-
// Assert: no extraction timestamps are set
|
|
688
|
-
expect(event.payload.event_context.extract_from).toBeUndefined();
|
|
689
|
-
expect(event.payload.event_context.extract_to).toBeUndefined();
|
|
690
|
-
});
|
|
691
|
-
it('should reuse pending values on StartExtractingAttachments', async () => {
|
|
692
|
-
// Arrange: state has pending values from the StartExtractingMetadata phase
|
|
693
|
-
const pendingOldest = '1970-01-01T00:00:00.000Z';
|
|
694
|
-
const pendingNewest = '2026-03-26T08:00:00.000Z';
|
|
695
|
-
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
696
|
-
context: {
|
|
697
|
-
snap_in_version_id: 'test_snap_in_version_id',
|
|
698
|
-
},
|
|
699
|
-
payload: { event_type: extraction_1.EventType.StartExtractingAttachments },
|
|
700
|
-
});
|
|
701
|
-
const stringifiedState = JSON.stringify({
|
|
702
|
-
snapInVersionId: 'test_snap_in_version_id',
|
|
703
|
-
pendingWorkersOldest: pendingOldest,
|
|
704
|
-
pendingWorkersNewest: pendingNewest,
|
|
705
|
-
});
|
|
706
|
-
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
707
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
708
|
-
// Act
|
|
709
|
-
await (0, state_1.createAdapterState)({
|
|
710
|
-
event,
|
|
711
|
-
initialState: {},
|
|
712
|
-
initialDomainMapping: {},
|
|
713
|
-
});
|
|
714
|
-
// Assert: pending values are reused
|
|
715
|
-
expect(event.payload.event_context.extract_from).toBe(pendingOldest);
|
|
716
|
-
expect(event.payload.event_context.extract_to).toBe(pendingNewest);
|
|
717
|
-
});
|
|
718
|
-
});
|
|
719
218
|
it('should populate extractionScope from API response', async () => {
|
|
720
219
|
// Arrange
|
|
721
220
|
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
@@ -731,7 +230,6 @@ describe(state_1.State.name, () => {
|
|
|
731
230
|
users: { extract: true },
|
|
732
231
|
}),
|
|
733
232
|
});
|
|
734
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
735
233
|
// Act
|
|
736
234
|
const result = await (0, state_1.createAdapterState)({
|
|
737
235
|
event,
|
|
@@ -758,7 +256,6 @@ describe(state_1.State.name, () => {
|
|
|
758
256
|
});
|
|
759
257
|
installInitialDomainMappingSpy.mockResolvedValue({ success: true });
|
|
760
258
|
postStateSpy.mockResolvedValue({ success: true });
|
|
761
|
-
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
762
259
|
// Act
|
|
763
260
|
const result = await (0, state_1.createAdapterState)({
|
|
764
261
|
event,
|
|
@@ -782,4 +279,24 @@ describe(state_1.State.name, () => {
|
|
|
782
279
|
// Assert
|
|
783
280
|
expect(result.extractionScope).toEqual({});
|
|
784
281
|
});
|
|
282
|
+
it('should continue with empty extractionScope when objects field contains invalid JSON', async () => {
|
|
283
|
+
// Arrange
|
|
284
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
285
|
+
context: { snap_in_version_id: '1.0.0' },
|
|
286
|
+
payload: { event_type: extraction_1.EventType.StartExtractingData },
|
|
287
|
+
});
|
|
288
|
+
fetchStateSpy.mockResolvedValue({
|
|
289
|
+
state: JSON.stringify({ snapInVersionId: '1.0.0' }),
|
|
290
|
+
objects: 'NOT_VALID_JSON',
|
|
291
|
+
});
|
|
292
|
+
// Act
|
|
293
|
+
const result = await (0, state_1.createAdapterState)({
|
|
294
|
+
event,
|
|
295
|
+
initialState: {},
|
|
296
|
+
initialDomainMapping: {},
|
|
297
|
+
});
|
|
298
|
+
// Assert: should not crash, extractionScope is empty (default)
|
|
299
|
+
expect(result.extractionScope).toEqual({});
|
|
300
|
+
expect(processExitSpy).not.toHaveBeenCalled();
|
|
301
|
+
});
|
|
785
302
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.time-value-resolution.test.d.ts","sourceRoot":"","sources":["../../src/state/state.time-value-resolution.test.ts"],"names":[],"mappings":""}
|