@devrev/airsync-sdk 2.0.0-beta.1 → 2.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/README.md +0 -4
  2. package/dist/airsync-sdk.d.ts +2059 -0
  3. package/dist/attachments-streaming/attachments-streaming-pool.d.ts +2 -1
  4. package/dist/attachments-streaming/attachments-streaming-pool.d.ts.map +1 -1
  5. package/dist/attachments-streaming/attachments-streaming-pool.interfaces.d.ts +8 -2
  6. package/dist/attachments-streaming/attachments-streaming-pool.interfaces.d.ts.map +1 -1
  7. package/dist/attachments-streaming/attachments-streaming-pool.js +27 -16
  8. package/dist/attachments-streaming/attachments-streaming-pool.test.js +246 -27
  9. package/dist/common/constants.d.ts +16 -5
  10. package/dist/common/constants.d.ts.map +1 -1
  11. package/dist/common/constants.js +20 -6
  12. package/dist/common/control-protocol.d.ts +2 -2
  13. package/dist/common/control-protocol.d.ts.map +1 -1
  14. package/dist/common/control-protocol.js +1 -5
  15. package/dist/common/helpers.d.ts +8 -0
  16. package/dist/common/helpers.d.ts.map +1 -1
  17. package/dist/common/helpers.js +15 -0
  18. package/dist/common/install-initial-domain-mapping.d.ts +2 -2
  19. package/dist/common/install-initial-domain-mapping.test.js +5 -2
  20. package/dist/common/test-utils.d.ts +19 -0
  21. package/dist/common/test-utils.d.ts.map +1 -0
  22. package/dist/common/test-utils.js +101 -0
  23. package/dist/common/time-value-resolver.d.ts +47 -0
  24. package/dist/common/time-value-resolver.d.ts.map +1 -0
  25. package/dist/common/time-value-resolver.js +141 -0
  26. package/dist/common/time-value-resolver.test.d.ts +2 -0
  27. package/dist/common/time-value-resolver.test.d.ts.map +1 -0
  28. package/dist/common/time-value-resolver.test.js +268 -0
  29. package/dist/http/axios-client-internal.d.ts.map +1 -1
  30. package/dist/http/axios-client-internal.js +7 -0
  31. package/dist/http/axios-client-internal.test.js +21 -0
  32. package/dist/http/axios-client.d.ts.map +1 -1
  33. package/dist/http/axios-client.js +6 -3
  34. package/dist/http/index.d.ts +0 -1
  35. package/dist/http/index.d.ts.map +1 -1
  36. package/dist/http/index.js +0 -1
  37. package/dist/index.d.ts +12 -10
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +18 -13
  40. package/dist/logger/logger.d.ts +1 -17
  41. package/dist/logger/logger.d.ts.map +1 -1
  42. package/dist/logger/logger.interfaces.d.ts +2 -2
  43. package/dist/logger/logger.js +35 -27
  44. package/dist/logger/logger.test.js +66 -19
  45. package/dist/mappers/mappers.interface.d.ts +5 -5
  46. package/dist/mappers/mappers.interface.js +3 -3
  47. package/dist/mappers/mappers.test.js +8 -10
  48. package/dist/mock-server/mock-server.d.ts +47 -0
  49. package/dist/mock-server/mock-server.d.ts.map +1 -0
  50. package/dist/mock-server/mock-server.interfaces.d.ts +73 -0
  51. package/dist/mock-server/mock-server.interfaces.d.ts.map +1 -0
  52. package/dist/mock-server/mock-server.interfaces.js +4 -0
  53. package/dist/mock-server/mock-server.js +278 -0
  54. package/dist/multithreading/adapters/base-adapter.d.ts +56 -0
  55. package/dist/multithreading/adapters/base-adapter.d.ts.map +1 -0
  56. package/dist/multithreading/adapters/base-adapter.emit.test.d.ts +2 -0
  57. package/dist/multithreading/adapters/base-adapter.emit.test.d.ts.map +1 -0
  58. package/dist/multithreading/adapters/base-adapter.emit.test.js +403 -0
  59. package/dist/multithreading/adapters/base-adapter.js +105 -0
  60. package/dist/multithreading/adapters/extraction-adapter.artifacts.test.d.ts +2 -0
  61. package/dist/multithreading/adapters/extraction-adapter.artifacts.test.d.ts.map +1 -0
  62. package/dist/multithreading/{worker-adapter/worker-adapter.artifacts.test.js → adapters/extraction-adapter.artifacts.test.js} +53 -5
  63. package/dist/multithreading/adapters/extraction-adapter.d.ts +58 -0
  64. package/dist/multithreading/adapters/extraction-adapter.d.ts.map +1 -0
  65. package/dist/multithreading/adapters/extraction-adapter.js +325 -0
  66. package/dist/multithreading/adapters/extraction-adapter.test.d.ts +2 -0
  67. package/dist/multithreading/adapters/extraction-adapter.test.d.ts.map +1 -0
  68. package/dist/multithreading/adapters/extraction-adapter.test.js +789 -0
  69. package/dist/multithreading/adapters/loading-adapter.d.ts +44 -0
  70. package/dist/multithreading/adapters/loading-adapter.d.ts.map +1 -0
  71. package/dist/multithreading/{worker-adapter/worker-adapter.helpers.d.ts → adapters/loading-adapter.helpers.d.ts} +1 -1
  72. package/dist/multithreading/adapters/loading-adapter.helpers.d.ts.map +1 -0
  73. package/dist/multithreading/adapters/loading-adapter.helpers.test.d.ts +2 -0
  74. package/dist/multithreading/adapters/loading-adapter.helpers.test.d.ts.map +1 -0
  75. package/dist/multithreading/{worker-adapter/worker-adapter.helpers.test.js → adapters/loading-adapter.helpers.test.js} +26 -26
  76. package/dist/multithreading/adapters/loading-adapter.js +461 -0
  77. package/dist/multithreading/adapters/loading-adapter.test.d.ts +2 -0
  78. package/dist/multithreading/adapters/loading-adapter.test.d.ts.map +1 -0
  79. package/dist/multithreading/adapters/loading-adapter.test.js +589 -0
  80. package/dist/multithreading/adapters/serialization.test.d.ts +2 -0
  81. package/dist/multithreading/adapters/serialization.test.d.ts.map +1 -0
  82. package/dist/multithreading/adapters/serialization.test.js +71 -0
  83. package/dist/multithreading/create-worker.test.js +36 -17
  84. package/dist/multithreading/process-task.d.ts +16 -1
  85. package/dist/multithreading/process-task.d.ts.map +1 -1
  86. package/dist/multithreading/process-task.js +97 -82
  87. package/dist/multithreading/process-task.test.d.ts +2 -0
  88. package/dist/multithreading/process-task.test.d.ts.map +1 -0
  89. package/dist/multithreading/process-task.test.js +146 -0
  90. package/dist/multithreading/spawn/spawn.d.ts +3 -3
  91. package/dist/multithreading/spawn/spawn.d.ts.map +1 -1
  92. package/dist/multithreading/spawn/spawn.helpers.d.ts.map +1 -1
  93. package/dist/multithreading/spawn/spawn.helpers.js +6 -14
  94. package/dist/multithreading/spawn/spawn.helpers.test.js +8 -8
  95. package/dist/multithreading/spawn/spawn.js +20 -25
  96. package/dist/multithreading/spawn/spawn.test.d.ts +2 -0
  97. package/dist/multithreading/spawn/spawn.test.d.ts.map +1 -0
  98. package/dist/multithreading/spawn/spawn.test.js +232 -0
  99. package/dist/repo/repo.d.ts.map +1 -1
  100. package/dist/repo/repo.interfaces.d.ts +4 -2
  101. package/dist/repo/repo.interfaces.d.ts.map +1 -1
  102. package/dist/repo/repo.js +4 -3
  103. package/dist/repo/repo.test.js +60 -7
  104. package/dist/state/base-state.d.ts +75 -0
  105. package/dist/state/base-state.d.ts.map +1 -0
  106. package/dist/state/base-state.js +261 -0
  107. package/dist/state/extraction-state.d.ts +29 -0
  108. package/dist/state/extraction-state.d.ts.map +1 -0
  109. package/dist/state/extraction-state.js +122 -0
  110. package/dist/state/loading-state.d.ts +19 -0
  111. package/dist/state/loading-state.d.ts.map +1 -0
  112. package/dist/state/loading-state.js +40 -0
  113. package/dist/state/state.extract-window.test.d.ts +2 -0
  114. package/dist/state/state.extract-window.test.d.ts.map +1 -0
  115. package/dist/state/state.extract-window.test.js +163 -0
  116. package/dist/state/state.interfaces.d.ts +44 -27
  117. package/dist/state/state.interfaces.d.ts.map +1 -1
  118. package/dist/state/state.interfaces.js +18 -5
  119. package/dist/state/state.pending-boundaries.test.d.ts +2 -0
  120. package/dist/state/state.pending-boundaries.test.d.ts.map +1 -0
  121. package/dist/state/state.pending-boundaries.test.js +189 -0
  122. package/dist/state/state.post-state.test.d.ts +2 -0
  123. package/dist/state/state.post-state.test.d.ts.map +1 -0
  124. package/dist/state/state.post-state.test.js +78 -0
  125. package/dist/state/state.test.js +135 -88
  126. package/dist/state/state.time-value-resolution.test.d.ts +2 -0
  127. package/dist/state/state.time-value-resolution.test.d.ts.map +1 -0
  128. package/dist/state/state.time-value-resolution.test.js +175 -0
  129. package/dist/tsdoc-metadata.json +11 -0
  130. package/dist/types/common.d.ts +0 -25
  131. package/dist/types/common.d.ts.map +1 -1
  132. package/dist/types/common.js +1 -11
  133. package/dist/types/external-domain-metadata.d.ts +20 -1
  134. package/dist/types/external-domain-metadata.d.ts.map +1 -1
  135. package/dist/types/extraction.d.ts +92 -221
  136. package/dist/types/extraction.d.ts.map +1 -1
  137. package/dist/types/extraction.js +56 -124
  138. package/dist/types/extraction.test.js +69 -43
  139. package/dist/types/index.d.ts +3 -3
  140. package/dist/types/index.d.ts.map +1 -1
  141. package/dist/types/index.js +6 -3
  142. package/dist/types/loading.d.ts +4 -24
  143. package/dist/types/loading.d.ts.map +1 -1
  144. package/dist/types/loading.js +1 -22
  145. package/dist/types/workers.d.ts +47 -29
  146. package/dist/types/workers.d.ts.map +1 -1
  147. package/dist/types/workers.js +1 -0
  148. package/dist/uploader/uploader.d.ts +1 -0
  149. package/dist/uploader/uploader.d.ts.map +1 -1
  150. package/dist/uploader/uploader.helpers.test.js +0 -11
  151. package/dist/uploader/uploader.interfaces.d.ts +3 -3
  152. package/dist/uploader/uploader.js +53 -20
  153. package/dist/uploader/uploader.test.js +22 -10
  154. package/package.json +10 -13
  155. package/dist/common/event-type-translation.d.ts +0 -24
  156. package/dist/common/event-type-translation.d.ts.map +0 -1
  157. package/dist/common/event-type-translation.js +0 -117
  158. package/dist/deprecated/adapter/index.d.ts +0 -62
  159. package/dist/deprecated/adapter/index.d.ts.map +0 -1
  160. package/dist/deprecated/adapter/index.js +0 -151
  161. package/dist/deprecated/common/helpers.d.ts +0 -7
  162. package/dist/deprecated/common/helpers.d.ts.map +0 -1
  163. package/dist/deprecated/common/helpers.js +0 -47
  164. package/dist/deprecated/demo-extractor/external_domain_metadata.json +0 -38
  165. package/dist/deprecated/demo-extractor/index.d.ts +0 -18
  166. package/dist/deprecated/demo-extractor/index.d.ts.map +0 -1
  167. package/dist/deprecated/demo-extractor/index.js +0 -161
  168. package/dist/deprecated/http/client.d.ts +0 -22
  169. package/dist/deprecated/http/client.d.ts.map +0 -1
  170. package/dist/deprecated/http/client.js +0 -161
  171. package/dist/deprecated/uploader/index.d.ts +0 -35
  172. package/dist/deprecated/uploader/index.d.ts.map +0 -1
  173. package/dist/deprecated/uploader/index.js +0 -161
  174. package/dist/http/types.d.ts +0 -17
  175. package/dist/http/types.d.ts.map +0 -1
  176. package/dist/http/types.js +0 -2
  177. package/dist/multithreading/worker-adapter/worker-adapter.artifacts.test.d.ts +0 -2
  178. package/dist/multithreading/worker-adapter/worker-adapter.artifacts.test.d.ts.map +0 -1
  179. package/dist/multithreading/worker-adapter/worker-adapter.d.ts +0 -91
  180. package/dist/multithreading/worker-adapter/worker-adapter.d.ts.map +0 -1
  181. package/dist/multithreading/worker-adapter/worker-adapter.helpers.d.ts.map +0 -1
  182. package/dist/multithreading/worker-adapter/worker-adapter.helpers.test.d.ts +0 -2
  183. package/dist/multithreading/worker-adapter/worker-adapter.helpers.test.d.ts.map +0 -1
  184. package/dist/multithreading/worker-adapter/worker-adapter.js +0 -745
  185. package/dist/multithreading/worker-adapter/worker-adapter.test.d.ts +0 -2
  186. package/dist/multithreading/worker-adapter/worker-adapter.test.d.ts.map +0 -1
  187. package/dist/multithreading/worker-adapter/worker-adapter.test.js +0 -483
  188. package/dist/state/state.d.ts +0 -30
  189. package/dist/state/state.d.ts.map +0 -1
  190. package/dist/state/state.js +0 -166
  191. /package/dist/multithreading/{worker-adapter/worker-adapter.helpers.js → adapters/loading-adapter.helpers.js} +0 -0
@@ -8,7 +8,6 @@ exports.spawn = spawn;
8
8
  const yargs_1 = __importDefault(require("yargs"));
9
9
  const helpers_1 = require("yargs/helpers");
10
10
  const control_protocol_1 = require("../../common/control-protocol");
11
- const event_type_translation_1 = require("../../common/event-type-translation");
12
11
  const helpers_2 = require("../../common/helpers");
13
12
  const logger_1 = require("../../logger/logger");
14
13
  const extraction_1 = require("../../types/extraction");
@@ -50,42 +49,30 @@ function getWorkerPath({ event, workerBasePath, }) {
50
49
  * The class provides utilities to emit control events to the platform and exit the worker gracefully.
51
50
  * In case of lambda timeout, the class emits a lambda timeout event to the platform.
52
51
  * @param {SpawnFactoryInterface} options - The options to create a new instance of Spawn class
53
- * @param {AirdropEvent} options.event - The event object received from the platform
52
+ * @param {AirSyncEvent} options.event - The event object received from the platform
54
53
  * @param {object} options.initialState - The initial state of the adapter
55
- * @param {string} [options.workerPath] Remove getWorkerPath function and use baseWorkerPath: __dirname instead of workerPath
56
54
  * @param {string} [options.baseWorkerPath] - The base path for the worker files, usually `__dirname`
57
55
  * @returns {Promise<Spawn>} - A new instance of Spawn class
58
56
  */
59
- async function spawn({ event, initialState, workerPath, initialDomainMapping, options, baseWorkerPath, }) {
60
- // Translate incoming event type for backwards compatibility. This allows the
61
- // SDK to accept both old and new event type formats. Then update the event with the translated event type.
62
- const originalEventType = event.payload.event_type;
63
- const translatedEventType = (0, event_type_translation_1.translateIncomingEventType)(event.payload.event_type);
64
- event.payload.event_type = translatedEventType;
57
+ async function spawn({ event, initialState, initialDomainMapping, options, baseWorkerPath, }) {
65
58
  // Read the command line arguments to check if the local flag is passed.
66
59
  const argv = await (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv)).argv;
67
- if (argv._.includes('local')) {
60
+ if (argv._.includes('local') || argv.local) {
68
61
  options = Object.assign(Object.assign({}, (options || {})), { isLocalDevelopment: true });
69
62
  }
70
63
  const originalConsole = console;
71
64
  // eslint-disable-next-line no-global-assign
72
65
  console = new logger_1.Logger({ event, options });
73
- if (translatedEventType !== originalEventType) {
74
- console.log(`Event type translated from ${originalEventType} to ${translatedEventType}.`);
75
- }
76
66
  if (options === null || options === void 0 ? void 0 : options.isLocalDevelopment) {
77
67
  console.log('Snap-in is running in local development mode.');
78
68
  }
69
+ const eventType = event.payload.event_type;
79
70
  let script = null;
80
- if (workerPath != null) {
81
- script = workerPath;
82
- }
83
- else if (baseWorkerPath != null &&
71
+ if (baseWorkerPath != null &&
84
72
  (options === null || options === void 0 ? void 0 : options.workerPathOverrides) != null &&
85
- options.workerPathOverrides[translatedEventType] != null) {
73
+ options.workerPathOverrides[eventType] != null) {
86
74
  script =
87
- baseWorkerPath +
88
- options.workerPathOverrides[translatedEventType];
75
+ baseWorkerPath + options.workerPathOverrides[eventType];
89
76
  }
90
77
  else {
91
78
  script = getWorkerPath({
@@ -189,21 +176,25 @@ class Spawn {
189
176
  }
190
177
  });
191
178
  worker.on(workers_1.WorkerEvent.WorkerMessage, (message) => {
192
- var _a, _b, _c, _d;
179
+ var _a, _b, _c, _d, _e;
193
180
  // Since logs from the worker thread are handled differently in snap-in
194
181
  // platform, we need to catch the log messages from worker thread and log
195
182
  // them in main thread.
196
183
  if ((message === null || message === void 0 ? void 0 : message.subject) === workers_1.WorkerMessageSubject.WorkerMessageLog) {
197
184
  const stringifiedArgs = (_a = message.payload) === null || _a === void 0 ? void 0 : _a.stringifiedArgs;
198
185
  const level = (_b = message.payload) === null || _b === void 0 ? void 0 : _b.level;
199
- const isSdkLog = (_d = (_c = message.payload) === null || _c === void 0 ? void 0 : _c.isSdkLog) !== null && _d !== void 0 ? _d : false;
186
+ const isSdkLog = (_d = (_c = message.payload) === null || _c === void 0 ? void 0 : _c.isSdkLog) !== null && _d !== void 0 ? _d : true;
200
187
  this.logger.logFn(stringifiedArgs, level, isSdkLog);
201
188
  }
202
189
  // If worker sends a message that it has emitted an event, then set alreadyEmitted to true.
203
190
  if ((message === null || message === void 0 ? void 0 : message.subject) === workers_1.WorkerMessageSubject.WorkerMessageEmitted) {
204
- console.info('Worker has emitted message to ADaaS.');
191
+ console.info('Worker has emitted message to the AirSync platform.');
205
192
  this.alreadyEmitted = true;
206
193
  }
194
+ // If worker sends a failure message before exiting, capture it for use in the error event.
195
+ if ((message === null || message === void 0 ? void 0 : message.subject) === workers_1.WorkerMessageSubject.WorkerMessageFailed) {
196
+ this.workerFailedMessage = (_e = message.payload) === null || _e === void 0 ? void 0 : _e.message;
197
+ }
207
198
  });
208
199
  // Log memory usage every 30 seconds
209
200
  this.memoryMonitoringInterval = setInterval(() => {
@@ -250,15 +241,19 @@ class Spawn {
250
241
  event: this.event,
251
242
  data: {
252
243
  error: {
253
- message: 'Worker exited the process without emitting an event. Check other logs for more information.',
244
+ message: `Worker exited without emitting event. ${this.workerFailedMessage
245
+ ? `Error: ${this.workerFailedMessage}`
246
+ : 'Check the logs for more information.'}`,
254
247
  },
255
248
  },
256
249
  });
257
- this.resolve();
258
250
  }
259
251
  catch (error) {
260
252
  console.error('Error while emitting event.', (0, logger_1.serializeError)(error));
261
253
  }
254
+ finally {
255
+ this.resolve();
256
+ }
262
257
  }
263
258
  }
264
259
  exports.Spawn = Spawn;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=spawn.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn.test.d.ts","sourceRoot":"","sources":["../../../src/multithreading/spawn/spawn.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,232 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const events_1 = require("events");
4
+ const constants_1 = require("../../common/constants");
5
+ const extraction_1 = require("../../types/extraction");
6
+ const workers_1 = require("../../types/workers");
7
+ const test_utils_1 = require("../../common/test-utils");
8
+ // ---------------------------------------------------------------------------
9
+ // Mocks
10
+ // ---------------------------------------------------------------------------
11
+ jest.mock('../create-worker', () => ({
12
+ createWorker: jest.fn(),
13
+ }));
14
+ jest.mock('../../common/control-protocol', () => ({
15
+ emit: jest.fn().mockResolvedValue({}),
16
+ }));
17
+ jest.mock('../../logger/logger', () => ({
18
+ Logger: jest.fn().mockImplementation(() => ({
19
+ log: jest.fn(),
20
+ warn: jest.fn(),
21
+ error: jest.fn(),
22
+ info: jest.fn(),
23
+ logFn: jest.fn(),
24
+ })),
25
+ serializeError: jest.fn((e) => String(e)),
26
+ }));
27
+ jest.mock('../../common/helpers', () => ({
28
+ getLibraryVersion: jest.fn().mockReturnValue('1.0.0-test'),
29
+ getMemoryUsage: jest.fn().mockReturnValue({
30
+ formattedMessage: 'Memory: RSS 100/512MB (19.53%) [...]',
31
+ rssUsedMB: '100.00',
32
+ rssUsedPercent: '19.53%',
33
+ heapUsedPercent: '30.00%',
34
+ externalMB: '10.00',
35
+ arrayBuffersMB: '5.00',
36
+ }),
37
+ sleep: jest.fn(),
38
+ truncateFilename: jest.fn((f) => f),
39
+ truncateMessage: jest.fn((m) => m),
40
+ }));
41
+ // ---------------------------------------------------------------------------
42
+ // Imports after mocks
43
+ // ---------------------------------------------------------------------------
44
+ const spawn_1 = require("./spawn");
45
+ const create_worker_1 = require("../create-worker");
46
+ const control_protocol_1 = require("../../common/control-protocol");
47
+ const helpers_1 = require("../../common/helpers");
48
+ // ---------------------------------------------------------------------------
49
+ // Factory for a fake worker (EventEmitter with postMessage + terminate)
50
+ // ---------------------------------------------------------------------------
51
+ function makeWorker() {
52
+ const w = new events_1.EventEmitter();
53
+ w.postMessage = jest.fn();
54
+ w.terminate = jest.fn().mockResolvedValue(0);
55
+ return w;
56
+ }
57
+ // ---------------------------------------------------------------------------
58
+ // Helper: instantiate Spawn directly, injecting a mock logger via console swap
59
+ // ---------------------------------------------------------------------------
60
+ function buildSpawn(overrides) {
61
+ var _a;
62
+ const event = (0, test_utils_1.createMockEvent)('http://localhost:0', {
63
+ payload: { event_type: extraction_1.EventType.StartExtractingData },
64
+ });
65
+ const mockLogger = {
66
+ log: jest.fn(),
67
+ warn: jest.fn(),
68
+ error: jest.fn(),
69
+ info: jest.fn(),
70
+ logFn: jest.fn(),
71
+ };
72
+ const originalConsole = console;
73
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
74
+ global.console = mockLogger;
75
+ const s = new spawn_1.Spawn({
76
+ event,
77
+ worker: overrides.worker,
78
+ options: overrides.options,
79
+ resolve: (_a = overrides.resolve) !== null && _a !== void 0 ? _a : jest.fn(),
80
+ originalConsole: originalConsole,
81
+ });
82
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
83
+ global.console = originalConsole;
84
+ return s;
85
+ }
86
+ // ---------------------------------------------------------------------------
87
+ // spawn() factory tests
88
+ // ---------------------------------------------------------------------------
89
+ describe('spawn() factory', () => {
90
+ beforeEach(() => {
91
+ jest.clearAllMocks();
92
+ jest.useFakeTimers({ legacyFakeTimers: true });
93
+ });
94
+ afterEach(() => {
95
+ jest.useRealTimers();
96
+ });
97
+ it('should emit a no-script event and NOT spawn a worker for an unknown event type', async () => {
98
+ // Arrange
99
+ const event = (0, test_utils_1.createMockEvent)('http://localhost:0', {
100
+ payload: { event_type: extraction_1.EventType.UnknownEventType },
101
+ });
102
+ // Act
103
+ await (0, spawn_1.spawn)({ event, initialState: {} });
104
+ // Assert: no worker process should be started, but the platform should
105
+ // still receive a terminal event (so the run doesn't hang).
106
+ expect(create_worker_1.createWorker).not.toHaveBeenCalled();
107
+ expect(control_protocol_1.emit).toHaveBeenCalledWith(expect.objectContaining({ event, eventType: expect.any(String) }));
108
+ });
109
+ it('should reject the returned promise when createWorker throws', async () => {
110
+ // Arrange
111
+ create_worker_1.createWorker.mockRejectedValue(new Error('worker boom'));
112
+ const event = (0, test_utils_1.createMockEvent)('http://localhost:0', {
113
+ payload: { event_type: extraction_1.EventType.StartExtractingData },
114
+ });
115
+ // Act & Assert
116
+ await expect((0, spawn_1.spawn)({
117
+ event,
118
+ initialState: {},
119
+ baseWorkerPath: '/fake',
120
+ options: {
121
+ workerPathOverrides: {
122
+ [extraction_1.EventType.StartExtractingData]: '/path.js',
123
+ },
124
+ },
125
+ })).rejects.toThrow('worker boom');
126
+ });
127
+ });
128
+ // ---------------------------------------------------------------------------
129
+ // Spawn class — lifecycle tests
130
+ // ---------------------------------------------------------------------------
131
+ describe('Spawn class', () => {
132
+ let worker;
133
+ let resolveMock;
134
+ beforeEach(() => {
135
+ jest.clearAllMocks();
136
+ jest.useFakeTimers({ legacyFakeTimers: true });
137
+ worker = makeWorker();
138
+ resolveMock = jest.fn();
139
+ });
140
+ afterEach(() => {
141
+ jest.useRealTimers();
142
+ });
143
+ // -------------------------------------------------------------------------
144
+ // WorkerMessageFailed captured and propagated in error emit
145
+ // -------------------------------------------------------------------------
146
+ it('should include the WorkerMessageFailed reason in the error event emitted to the platform', async () => {
147
+ // Arrange
148
+ buildSpawn({ worker, resolve: resolveMock });
149
+ // Act
150
+ worker.emit(workers_1.WorkerEvent.WorkerMessage, {
151
+ subject: workers_1.WorkerMessageSubject.WorkerMessageFailed,
152
+ payload: { message: 'connector exploded' },
153
+ });
154
+ worker.emit(workers_1.WorkerEvent.WorkerExit, 1);
155
+ await Promise.resolve();
156
+ await Promise.resolve();
157
+ // Assert: the platform receives an error event whose message contains
158
+ // the reason sent by the worker — this is what operators see in the run log.
159
+ expect(control_protocol_1.emit).toHaveBeenCalledWith(expect.objectContaining({
160
+ data: expect.objectContaining({
161
+ error: expect.objectContaining({
162
+ message: expect.stringContaining('connector exploded'),
163
+ }),
164
+ }),
165
+ }));
166
+ expect(resolveMock).toHaveBeenCalled();
167
+ });
168
+ it('should emit a data extraction error when the worker exits without ever emitting', async () => {
169
+ // Arrange
170
+ buildSpawn({ worker, resolve: resolveMock });
171
+ // Act
172
+ worker.emit(workers_1.WorkerEvent.WorkerExit, 1);
173
+ await Promise.resolve();
174
+ await Promise.resolve();
175
+ // Assert: a silent worker exit must surface a DataExtractionError to the
176
+ // platform with a non-empty message. The event type is the upstream
177
+ // contract; the exact message wording is implementation detail.
178
+ expect(control_protocol_1.emit).toHaveBeenCalledTimes(1);
179
+ const [emitted] = control_protocol_1.emit.mock.calls[0];
180
+ expect(emitted.eventType).toBe(extraction_1.ExtractorEventType.DataExtractionError);
181
+ expect(emitted.data.error.message).toEqual(expect.any(String));
182
+ expect(emitted.data.error.message.length).toBeGreaterThan(0);
183
+ expect(resolveMock).toHaveBeenCalled();
184
+ });
185
+ // Soft-timeout and hard-timeout timer behavior is covered end-to-end by
186
+ // src/tests/timeout-handling/ (real workers, real timers). Unit tests with
187
+ // fake timers only re-asserted the mocked setTimeout call and gave no signal.
188
+ // -------------------------------------------------------------------------
189
+ // Memory monitoring — error clears the interval
190
+ // -------------------------------------------------------------------------
191
+ it('should clear the memory monitoring interval when getMemoryUsage throws to prevent repeated crashes', async () => {
192
+ // Arrange
193
+ helpers_1.getMemoryUsage.mockImplementation(() => {
194
+ throw new Error('OOM');
195
+ });
196
+ const clearIntervalSpy = jest.spyOn(global, 'clearInterval');
197
+ buildSpawn({ worker, resolve: resolveMock });
198
+ // Act
199
+ jest.advanceTimersByTime(30001); // MEMORY_LOG_INTERVAL = 30 s
200
+ await Promise.resolve();
201
+ // Assert
202
+ expect(clearIntervalSpy).toHaveBeenCalled();
203
+ });
204
+ // -------------------------------------------------------------------------
205
+ // Soft-timeout race: worker emits AFTER softTimeoutSent — no double-emit
206
+ // -------------------------------------------------------------------------
207
+ it('should NOT emit an error when the worker successfully emits just after receiving the soft-timeout signal', async () => {
208
+ // Arrange
209
+ buildSpawn({ worker, resolve: resolveMock });
210
+ // Act: trigger soft timeout — sends WorkerMessageExit to the worker
211
+ jest.advanceTimersByTime(constants_1.DEFAULT_LAMBDA_TIMEOUT + 1);
212
+ await Promise.resolve();
213
+ // Confirm the soft-timeout path actually fired — guards against a silent
214
+ // pass if the timeout constant changes and the timer never runs.
215
+ expect(worker.postMessage).toHaveBeenCalledWith(expect.objectContaining({
216
+ subject: workers_1.WorkerMessageSubject.WorkerMessageExit,
217
+ }));
218
+ // Worker responds: emits its event successfully, then exits normally
219
+ worker.emit(workers_1.WorkerEvent.WorkerMessage, {
220
+ subject: workers_1.WorkerMessageSubject.WorkerMessageEmitted,
221
+ });
222
+ worker.emit(workers_1.WorkerEvent.WorkerExit, 0);
223
+ // The exit handler defers via setImmediate when softTimeoutSent=true
224
+ jest.runAllImmediates();
225
+ await Promise.resolve();
226
+ await Promise.resolve();
227
+ // Assert: no error should reach the platform — the worker completed its job
228
+ const errorEmits = control_protocol_1.emit.mock.calls.filter((call) => { var _a, _b; return (_b = (_a = call[0]) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error; });
229
+ expect(errorEmits).toHaveLength(0);
230
+ expect(resolveMock).toHaveBeenCalled();
231
+ });
232
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/repo/repo.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAG3D,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,IAAI;IACf,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,KAAK,CAAmD;IAChE,OAAO,CAAC,SAAS,CAAC,CAAwD;IAC1E,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,OAAO,CAAC,CAAuB;IAChC,iBAAiB,EAAE,QAAQ,EAAE,CAAC;gBAEzB,EACV,KAAK,EACL,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,OAAO,GACR,EAAE,oBAAoB;IAUvB,QAAQ,IAAI,CAAC,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAAC,EAAE;IAItD,MAAM,CACV,KAAK,CAAC,EAAE,CAAC,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAAC,EAAE,GACvD,OAAO,CAAC,IAAI,GAAG,WAAW,CAAC;IAqCxB,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;CAuC5C"}
1
+ {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/repo/repo.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAI3D,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,IAAI;IACf,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,KAAK,CAAmD;IAChE,OAAO,CAAC,SAAS,CAAC,CAAwD;IAC1E,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,OAAO,CAAC,CAAuB;IAChC,iBAAiB,EAAE,QAAQ,EAAE,CAAC;gBAEzB,EACV,KAAK,EACL,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,OAAO,GACR,EAAE,oBAAoB;IAUvB,QAAQ,IAAI,CAAC,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAAC,EAAE;IAItD,MAAM,CACV,KAAK,CAAC,EAAE,CAAC,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAAC,EAAE,GACvD,OAAO,CAAC,IAAI,GAAG,WAAW,CAAC;IAqCxB,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;CAyC5C"}
@@ -1,5 +1,5 @@
1
1
  import { Artifact } from '../uploader/uploader.interfaces';
2
- import { AirdropEvent } from '../types/extraction';
2
+ import { AirSyncEvent } from '../types/extraction';
3
3
  import { WorkerAdapterOptions } from '../types/workers';
4
4
  /**
5
5
  * RepoInterface is an interface that defines the structure of a repo which is used to store and upload extracted data.
@@ -7,12 +7,13 @@ import { WorkerAdapterOptions } from '../types/workers';
7
7
  export interface RepoInterface {
8
8
  itemType: string;
9
9
  normalize?: (record: object) => NormalizedItem | NormalizedAttachment;
10
+ overridenOptions?: WorkerAdapterOptions;
10
11
  }
11
12
  /**
12
13
  * RepoFactoryInterface is an interface that defines the structure of a repo factory which is used to create a repo.
13
14
  */
14
15
  export interface RepoFactoryInterface {
15
- event: AirdropEvent;
16
+ event: AirSyncEvent;
16
17
  itemType: string;
17
18
  normalize?: (record: object) => NormalizedItem | NormalizedAttachment;
18
19
  onUpload: (artifact: Artifact) => void;
@@ -37,6 +38,7 @@ export interface NormalizedAttachment {
37
38
  parent_id: string;
38
39
  author_id?: string;
39
40
  inline?: boolean;
41
+ content_type?: string;
40
42
  grand_parent_id?: number | string;
41
43
  }
42
44
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"repo.interfaces.d.ts","sourceRoot":"","sources":["../../src/repo/repo.interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,cAAc,GAAG,oBAAoB,CAAC;CACvE;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,cAAc,GAAG,oBAAoB,CAAC;IACtE,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IAIjB,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACnC;AAED;;GAEG;AAEH,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC"}
1
+ {"version":3,"file":"repo.interfaces.d.ts","sourceRoot":"","sources":["../../src/repo/repo.interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,cAAc,GAAG,oBAAoB,CAAC;IACtE,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,cAAc,GAAG,oBAAoB,CAAC;IACtE,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IAItB,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACnC;AAED;;GAEG;AAEH,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC"}
package/dist/repo/repo.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Repo = void 0;
4
4
  const constants_1 = require("../common/constants");
5
5
  const uploader_1 = require("../uploader/uploader");
6
+ const logger_context_1 = require("../logger/logger.context");
6
7
  class Repo {
7
8
  constructor({ event, itemType, normalize, onUpload, options, }) {
8
9
  this.items = [];
@@ -46,9 +47,9 @@ class Repo {
46
47
  }
47
48
  // Normalize items if needed
48
49
  if (this.normalize &&
49
- this.itemType != constants_1.AIRDROP_DEFAULT_ITEM_TYPES.EXTERNAL_DOMAIN_METADATA &&
50
- this.itemType != constants_1.AIRDROP_DEFAULT_ITEM_TYPES.SSOR_ATTACHMENT) {
51
- recordsToPush = items.map((item) => this.normalize(item));
50
+ this.itemType != constants_1.AirSyncDefaultItemTypes.EXTERNAL_DOMAIN_METADATA &&
51
+ this.itemType != constants_1.SSOR_ATTACHMENT) {
52
+ recordsToPush = (0, logger_context_1.runWithUserLogContext)(() => items.map((item) => this.normalize(item)));
52
53
  }
53
54
  else {
54
55
  recordsToPush = items;
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const constants_1 = require("../common/constants");
4
4
  const test_helpers_1 = require("../tests/test-helpers");
5
+ const jest_setup_1 = require("../tests/jest.setup");
6
+ const test_utils_1 = require("../common/test-utils");
5
7
  const types_1 = require("../types");
6
8
  const repo_1 = require("./repo");
7
9
  jest.mock('../tests/test-helpers', () => (Object.assign(Object.assign({}, jest.requireActual('../tests/test-helpers')), { normalizeItem: jest.fn() })));
@@ -11,7 +13,9 @@ describe(repo_1.Repo.name, () => {
11
13
  beforeEach(() => {
12
14
  normalize = jest.fn();
13
15
  repo = new repo_1.Repo({
14
- event: (0, test_helpers_1.createEvent)({ eventType: types_1.EventType.ExtractionDataStart }),
16
+ event: (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
17
+ payload: { event_type: types_1.EventType.StartExtractingData },
18
+ }),
15
19
  itemType: 'test_item_type',
16
20
  normalize,
17
21
  onUpload: jest.fn(),
@@ -21,77 +25,111 @@ describe(repo_1.Repo.name, () => {
21
25
  jest.clearAllMocks();
22
26
  });
23
27
  it('should normalize and push items when array contains items', async () => {
28
+ // Arrange
24
29
  const items = (0, test_helpers_1.createItems)(10);
30
+ // Act
25
31
  await repo.push(items);
32
+ // Assert
26
33
  expect(normalize).toHaveBeenCalledTimes(10);
27
34
  const normalizedItems = items.map((item) => (0, test_helpers_1.normalizeItem)(item));
28
35
  expect(repo.getItems()).toEqual(normalizedItems);
29
36
  });
30
37
  it('should not normalize items when normalize function is not provided', async () => {
38
+ // Arrange
31
39
  repo = new repo_1.Repo({
32
- event: (0, test_helpers_1.createEvent)({ eventType: types_1.EventType.ExtractionDataStart }),
40
+ event: (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
41
+ payload: { event_type: types_1.EventType.StartExtractingData },
42
+ }),
33
43
  itemType: 'test_item_type',
34
44
  onUpload: jest.fn(),
35
45
  options: {},
36
46
  });
37
47
  const items = (0, test_helpers_1.createItems)(10);
48
+ // Act
38
49
  await repo.push(items);
50
+ // Assert
39
51
  expect(normalize).not.toHaveBeenCalled();
40
52
  });
41
53
  it('[edge] should not push items when items array is empty', async () => {
54
+ // Act
42
55
  await repo.push([]);
56
+ // Assert
43
57
  expect(repo.getItems()).toEqual([]);
44
58
  });
45
59
  it('should not normalize items when item type is external_domain_metadata', async () => {
60
+ // Arrange
46
61
  repo = new repo_1.Repo({
47
- event: (0, test_helpers_1.createEvent)({ eventType: types_1.EventType.ExtractionDataStart }),
48
- itemType: constants_1.AIRDROP_DEFAULT_ITEM_TYPES.EXTERNAL_DOMAIN_METADATA,
62
+ event: (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
63
+ payload: { event_type: types_1.EventType.StartExtractingData },
64
+ }),
65
+ itemType: constants_1.AirSyncDefaultItemTypes.EXTERNAL_DOMAIN_METADATA,
49
66
  normalize,
50
67
  onUpload: jest.fn(),
51
68
  options: {},
52
69
  });
53
70
  const items = (0, test_helpers_1.createItems)(10);
71
+ // Act
54
72
  await repo.push(items);
73
+ // Assert
55
74
  expect(normalize).not.toHaveBeenCalled();
56
75
  });
57
76
  it('should not normalize items when item type is ssor_attachment', async () => {
77
+ // Arrange
58
78
  repo = new repo_1.Repo({
59
- event: (0, test_helpers_1.createEvent)({ eventType: types_1.EventType.ExtractionDataStart }),
60
- itemType: constants_1.AIRDROP_DEFAULT_ITEM_TYPES.SSOR_ATTACHMENT,
79
+ event: (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
80
+ payload: { event_type: types_1.EventType.StartExtractingData },
81
+ }),
82
+ itemType: constants_1.SSOR_ATTACHMENT,
61
83
  normalize,
62
84
  onUpload: jest.fn(),
63
85
  options: {},
64
86
  });
65
87
  const items = (0, test_helpers_1.createItems)(10);
88
+ // Act
66
89
  await repo.push(items);
90
+ // Assert
67
91
  expect(normalize).not.toHaveBeenCalled();
68
92
  });
69
93
  it('should leave 5 items in the items array after pushing 2005 items with batch size of 2000', async () => {
94
+ // Arrange
70
95
  const items = (0, test_helpers_1.createItems)(2005);
96
+ // Act
71
97
  await repo.push(items);
98
+ // Assert
72
99
  expect(repo.getItems().length).toBe(5);
73
100
  });
74
101
  it('should normalize all items when pushing 4005 items with batch size of 2000', async () => {
102
+ // Arrange
75
103
  const items = (0, test_helpers_1.createItems)(4005);
104
+ // Act
76
105
  await repo.push(items);
106
+ // Assert
77
107
  expect(normalize).toHaveBeenCalledTimes(4005);
78
108
  });
79
109
  it('should upload 2 batches when pushing 4005 items with batch size of 2000', async () => {
110
+ // Arrange
80
111
  const uploadSpy = jest.spyOn(repo, 'upload');
81
112
  const items = (0, test_helpers_1.createItems)(4005);
113
+ // Act
82
114
  await repo.push(items);
115
+ // Assert
83
116
  expect(uploadSpy).toHaveBeenCalledTimes(2);
84
117
  uploadSpy.mockRestore();
85
118
  });
86
119
  it('should leave 5 items in array after pushing 4005 items with batch size of 2000', async () => {
120
+ // Arrange
87
121
  const items = (0, test_helpers_1.createItems)(4005);
122
+ // Act
88
123
  await repo.push(items);
124
+ // Assert
89
125
  expect(repo.getItems().length).toBe(5);
90
126
  });
91
127
  describe('should take batch size into account', () => {
92
128
  beforeEach(() => {
93
129
  repo = new repo_1.Repo({
94
- event: (0, test_helpers_1.createEvent)({ eventType: types_1.EventType.ExtractionDataStart }),
130
+ event: (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
131
+ payload: { event_type: types_1.EventType.StartExtractingData },
132
+ }),
95
133
  itemType: 'test_item_type',
96
134
  normalize,
97
135
  onUpload: jest.fn(),
@@ -101,30 +139,45 @@ describe(repo_1.Repo.name, () => {
101
139
  });
102
140
  });
103
141
  it('should empty the items array after pushing 50 items with batch size of 50', async () => {
142
+ // Arrange
104
143
  const items = (0, test_helpers_1.createItems)(50);
144
+ // Act
105
145
  await repo.push(items);
146
+ // Assert
106
147
  expect(repo.getItems()).toEqual([]);
107
148
  });
108
149
  it('should leave 5 items in the items array after pushing 205 items with batch size of 50', async () => {
150
+ // Arrange
109
151
  const items = (0, test_helpers_1.createItems)(205);
152
+ // Act
110
153
  await repo.push(items);
154
+ // Assert
111
155
  expect(repo.getItems().length).toBe(5);
112
156
  });
113
157
  it('should normalize all items when pushing 205 items with batch size of 50', async () => {
158
+ // Arrange
114
159
  const items = (0, test_helpers_1.createItems)(205);
160
+ // Act
115
161
  await repo.push(items);
162
+ // Assert
116
163
  expect(normalize).toHaveBeenCalledTimes(205);
117
164
  });
118
165
  it('should upload 4 batches when pushing 205 items with batch size of 50', async () => {
166
+ // Arrange
119
167
  const uploadSpy = jest.spyOn(repo, 'upload');
120
168
  const items = (0, test_helpers_1.createItems)(205);
169
+ // Act
121
170
  await repo.push(items);
171
+ // Assert
122
172
  expect(uploadSpy).toHaveBeenCalledTimes(4);
123
173
  uploadSpy.mockRestore();
124
174
  });
125
175
  it('should leave 5 items in array after pushing 205 items with batch size of 50', async () => {
176
+ // Arrange
126
177
  const items = (0, test_helpers_1.createItems)(205);
178
+ // Act
127
179
  await repo.push(items);
180
+ // Assert
128
181
  expect(repo.getItems().length).toBe(5);
129
182
  });
130
183
  });