@friggframework/admin-scripts 2.0.0--canary.545.b4ca16d.0 → 2.0.0--canary.517.8eaf5df.0

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 (45) hide show
  1. package/README.md +277 -0
  2. package/index.js +23 -6
  3. package/package.json +6 -6
  4. package/src/adapters/__tests__/aws-scheduler-adapter.test.js +106 -45
  5. package/src/adapters/__tests__/local-scheduler-adapter.test.js +24 -10
  6. package/src/adapters/__tests__/scheduler-adapter-factory.test.js +30 -9
  7. package/src/adapters/__tests__/scheduler-adapter.test.js +6 -2
  8. package/src/adapters/aws-scheduler-adapter.js +55 -28
  9. package/src/adapters/local-scheduler-adapter.js +2 -2
  10. package/src/adapters/scheduler-adapter-factory.js +3 -1
  11. package/src/adapters/scheduler-adapter.js +9 -3
  12. package/src/application/__tests__/admin-frigg-commands.test.js +73 -30
  13. package/src/application/__tests__/admin-script-base.test.js +23 -6
  14. package/src/application/__tests__/script-factory.test.js +30 -6
  15. package/src/application/__tests__/script-runner.test.js +113 -24
  16. package/src/application/__tests__/validate-script-input.test.js +54 -15
  17. package/src/application/admin-frigg-commands.js +21 -9
  18. package/src/application/admin-script-base.js +3 -2
  19. package/src/application/script-factory.js +3 -1
  20. package/src/application/script-runner.js +90 -48
  21. package/src/application/use-cases/__tests__/delete-schedule-use-case.test.js +16 -7
  22. package/src/application/use-cases/__tests__/get-effective-schedule-use-case.test.js +9 -4
  23. package/src/application/use-cases/__tests__/upsert-schedule-use-case.test.js +21 -10
  24. package/src/application/use-cases/delete-schedule-use-case.js +6 -4
  25. package/src/application/use-cases/get-effective-schedule-use-case.js +3 -1
  26. package/src/application/use-cases/index.js +3 -1
  27. package/src/application/use-cases/upsert-schedule-use-case.js +30 -11
  28. package/src/application/validate-script-input.js +10 -3
  29. package/src/builtins/__tests__/integration-health-check.test.js +232 -127
  30. package/src/builtins/__tests__/oauth-token-refresh.test.js +128 -75
  31. package/src/builtins/index.js +1 -4
  32. package/src/builtins/integration-health-check.js +63 -30
  33. package/src/builtins/oauth-token-refresh.js +64 -29
  34. package/src/infrastructure/__tests__/admin-auth-middleware.test.js +9 -3
  35. package/src/infrastructure/__tests__/admin-script-router.test.js +125 -52
  36. package/src/infrastructure/admin-auth-middleware.js +3 -1
  37. package/src/infrastructure/admin-script-router.js +129 -14
  38. package/src/infrastructure/bootstrap.js +87 -0
  39. package/src/infrastructure/script-executor-handler.js +119 -52
  40. package/src/application/__tests__/dry-run-http-interceptor.test.js +0 -313
  41. package/src/application/__tests__/dry-run-repository-wrapper.test.js +0 -257
  42. package/src/application/__tests__/schedule-management-use-case.test.js +0 -276
  43. package/src/application/dry-run-http-interceptor.js +0 -296
  44. package/src/application/dry-run-repository-wrapper.js +0 -261
  45. package/src/application/schedule-management-use-case.js +0 -230
@@ -3,10 +3,19 @@ const { IntegrationHealthCheckScript } = require('../integration-health-check');
3
3
  describe('IntegrationHealthCheckScript', () => {
4
4
  describe('Definition', () => {
5
5
  it('should have correct name and metadata', () => {
6
- expect(IntegrationHealthCheckScript.Definition.name).toBe('integration-health-check');
7
- expect(IntegrationHealthCheckScript.Definition.version).toBe('1.0.0');
8
- expect(IntegrationHealthCheckScript.Definition.source).toBe('BUILTIN');
9
- expect(IntegrationHealthCheckScript.Definition.config.requireIntegrationInstance).toBe(true);
6
+ expect(IntegrationHealthCheckScript.Definition.name).toBe(
7
+ 'integration-health-check'
8
+ );
9
+ expect(IntegrationHealthCheckScript.Definition.version).toBe(
10
+ '1.0.0'
11
+ );
12
+ expect(IntegrationHealthCheckScript.Definition.source).toBe(
13
+ 'BUILTIN'
14
+ );
15
+ expect(
16
+ IntegrationHealthCheckScript.Definition.config
17
+ .requireIntegrationInstance
18
+ ).toBe(true);
10
19
  });
11
20
 
12
21
  it('should have valid input schema', () => {
@@ -35,12 +44,16 @@ describe('IntegrationHealthCheckScript', () => {
35
44
  });
36
45
 
37
46
  it('should have appropriate timeout configuration', () => {
38
- expect(IntegrationHealthCheckScript.Definition.config.timeout).toBe(900000); // 15 minutes
47
+ expect(IntegrationHealthCheckScript.Definition.config.timeout).toBe(
48
+ 900000
49
+ ); // 15 minutes
39
50
  });
40
51
 
41
52
  it('should have clean display object', () => {
42
53
  // Display should only have UI-specific fields
43
- expect(IntegrationHealthCheckScript.Definition.display.category).toBe('maintenance');
54
+ expect(
55
+ IntegrationHealthCheckScript.Definition.display.category
56
+ ).toBe('maintenance');
44
57
  // Should NOT have redundant label/description - they're derived from top-level
45
58
  });
46
59
  });
@@ -63,7 +76,9 @@ describe('IntegrationHealthCheckScript', () => {
63
76
  });
64
77
 
65
78
  it('should return empty results when no integrations found', async () => {
66
- mockContext.integrationRepository.findIntegrations.mockResolvedValue([]);
79
+ mockContext.integrationRepository.findIntegrations.mockResolvedValue(
80
+ []
81
+ );
67
82
 
68
83
  const result = await script.execute({});
69
84
 
@@ -80,25 +95,31 @@ describe('IntegrationHealthCheckScript', () => {
80
95
  type: 'hubspot',
81
96
  credentials: {
82
97
  access_token: 'token123',
83
- expires_at: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()
84
- }
85
- }
98
+ expires_at: new Date(
99
+ Date.now() + 24 * 60 * 60 * 1000
100
+ ).toISOString(),
101
+ },
102
+ },
86
103
  };
87
104
 
88
105
  const mockInstance = {
89
106
  primary: {
90
107
  api: {
91
- getAuthenticationInfo: jest.fn().mockResolvedValue({ user: 'test' })
92
- }
93
- }
108
+ getAuthenticationInfo: jest
109
+ .fn()
110
+ .mockResolvedValue({ user: 'test' }),
111
+ },
112
+ },
94
113
  };
95
114
 
96
- mockContext.integrationRepository.findIntegrations.mockResolvedValue([integration]);
115
+ mockContext.integrationRepository.findIntegrations.mockResolvedValue(
116
+ [integration]
117
+ );
97
118
  mockContext.instantiate.mockResolvedValue(mockInstance);
98
119
 
99
120
  const result = await script.execute({
100
121
  checkCredentials: true,
101
- checkConnectivity: true
122
+ checkConnectivity: true,
102
123
  });
103
124
 
104
125
  expect(result.healthy).toBe(1);
@@ -106,9 +127,11 @@ describe('IntegrationHealthCheckScript', () => {
106
127
  expect(result.results[0]).toMatchObject({
107
128
  integrationId: 'int-1',
108
129
  status: 'healthy',
109
- issues: []
130
+ issues: [],
110
131
  });
111
- expect(mockInstance.primary.api.getAuthenticationInfo).toHaveBeenCalled();
132
+ expect(
133
+ mockInstance.primary.api.getAuthenticationInfo
134
+ ).toHaveBeenCalled();
112
135
  });
113
136
 
114
137
  it('should return unhealthy for missing access token', async () => {
@@ -116,15 +139,17 @@ describe('IntegrationHealthCheckScript', () => {
116
139
  id: 'int-1',
117
140
  config: {
118
141
  type: 'hubspot',
119
- credentials: {} // No access_token
120
- }
142
+ credentials: {}, // No access_token
143
+ },
121
144
  };
122
145
 
123
- mockContext.integrationRepository.findIntegrations.mockResolvedValue([integration]);
146
+ mockContext.integrationRepository.findIntegrations.mockResolvedValue(
147
+ [integration]
148
+ );
124
149
 
125
150
  const result = await script.execute({
126
151
  checkCredentials: true,
127
- checkConnectivity: false
152
+ checkConnectivity: false,
128
153
  });
129
154
 
130
155
  expect(result.healthy).toBe(0);
@@ -132,7 +157,7 @@ describe('IntegrationHealthCheckScript', () => {
132
157
  expect(result.results[0]).toMatchObject({
133
158
  integrationId: 'int-1',
134
159
  status: 'unhealthy',
135
- issues: ['Missing access token']
160
+ issues: ['Missing access token'],
136
161
  });
137
162
  });
138
163
 
@@ -144,23 +169,25 @@ describe('IntegrationHealthCheckScript', () => {
144
169
  type: 'hubspot',
145
170
  credentials: {
146
171
  access_token: 'token123',
147
- expires_at: pastDate.toISOString()
148
- }
149
- }
172
+ expires_at: pastDate.toISOString(),
173
+ },
174
+ },
150
175
  };
151
176
 
152
- mockContext.integrationRepository.findIntegrations.mockResolvedValue([integration]);
177
+ mockContext.integrationRepository.findIntegrations.mockResolvedValue(
178
+ [integration]
179
+ );
153
180
 
154
181
  const result = await script.execute({
155
182
  checkCredentials: true,
156
- checkConnectivity: false
183
+ checkConnectivity: false,
157
184
  });
158
185
 
159
186
  expect(result.unhealthy).toBe(1);
160
187
  expect(result.results[0]).toMatchObject({
161
188
  integrationId: 'int-1',
162
189
  status: 'unhealthy',
163
- issues: ['Access token expired']
190
+ issues: ['Access token expired'],
164
191
  });
165
192
  });
166
193
 
@@ -171,30 +198,38 @@ describe('IntegrationHealthCheckScript', () => {
171
198
  type: 'hubspot',
172
199
  credentials: {
173
200
  access_token: 'token123',
174
- expires_at: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()
175
- }
176
- }
201
+ expires_at: new Date(
202
+ Date.now() + 24 * 60 * 60 * 1000
203
+ ).toISOString(),
204
+ },
205
+ },
177
206
  };
178
207
 
179
208
  const mockInstance = {
180
209
  primary: {
181
210
  api: {
182
- getAuthenticationInfo: jest.fn().mockRejectedValue(new Error('Network error'))
183
- }
184
- }
211
+ getAuthenticationInfo: jest
212
+ .fn()
213
+ .mockRejectedValue(new Error('Network error')),
214
+ },
215
+ },
185
216
  };
186
217
 
187
- mockContext.integrationRepository.findIntegrations.mockResolvedValue([integration]);
218
+ mockContext.integrationRepository.findIntegrations.mockResolvedValue(
219
+ [integration]
220
+ );
188
221
  mockContext.instantiate.mockResolvedValue(mockInstance);
189
222
 
190
223
  const result = await script.execute({
191
224
  checkCredentials: true,
192
- checkConnectivity: true
225
+ checkConnectivity: true,
193
226
  });
194
227
 
195
228
  expect(result.unhealthy).toBe(1);
196
229
  expect(result.results[0].status).toBe('unhealthy');
197
- expect(result.results[0].issues).toContainEqual(expect.stringContaining('API connectivity failed'));
230
+ expect(result.results[0].issues).toContainEqual(
231
+ expect.stringContaining('API connectivity failed')
232
+ );
198
233
  });
199
234
 
200
235
  it('should update integration status when updateStatus is true', async () => {
@@ -204,31 +239,41 @@ describe('IntegrationHealthCheckScript', () => {
204
239
  type: 'hubspot',
205
240
  credentials: {
206
241
  access_token: 'token123',
207
- expires_at: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()
208
- }
209
- }
242
+ expires_at: new Date(
243
+ Date.now() + 24 * 60 * 60 * 1000
244
+ ).toISOString(),
245
+ },
246
+ },
210
247
  };
211
248
 
212
249
  const mockInstance = {
213
250
  primary: {
214
251
  api: {
215
- getAuthenticationInfo: jest.fn().mockResolvedValue({ user: 'test' })
216
- }
217
- }
252
+ getAuthenticationInfo: jest
253
+ .fn()
254
+ .mockResolvedValue({ user: 'test' }),
255
+ },
256
+ },
218
257
  };
219
258
 
220
- mockContext.integrationRepository.findIntegrations.mockResolvedValue([integration]);
259
+ mockContext.integrationRepository.findIntegrations.mockResolvedValue(
260
+ [integration]
261
+ );
221
262
  mockContext.instantiate.mockResolvedValue(mockInstance);
222
- mockContext.integrationRepository.updateIntegrationStatus.mockResolvedValue(undefined);
263
+ mockContext.integrationRepository.updateIntegrationStatus.mockResolvedValue(
264
+ undefined
265
+ );
223
266
 
224
267
  const result = await script.execute({
225
268
  checkCredentials: true,
226
269
  checkConnectivity: true,
227
- updateStatus: true
270
+ updateStatus: true,
228
271
  });
229
272
 
230
273
  expect(result.healthy).toBe(1);
231
- expect(mockContext.integrationRepository.updateIntegrationStatus).toHaveBeenCalledWith('int-1', 'ACTIVE');
274
+ expect(
275
+ mockContext.integrationRepository.updateIntegrationStatus
276
+ ).toHaveBeenCalledWith('int-1', 'ACTIVE');
232
277
  });
233
278
 
234
279
  it('should update integration status to ERROR for unhealthy integrations', async () => {
@@ -236,21 +281,27 @@ describe('IntegrationHealthCheckScript', () => {
236
281
  id: 'int-1',
237
282
  config: {
238
283
  type: 'hubspot',
239
- credentials: {} // Missing credentials
240
- }
284
+ credentials: {}, // Missing credentials
285
+ },
241
286
  };
242
287
 
243
- mockContext.integrationRepository.findIntegrations.mockResolvedValue([integration]);
244
- mockContext.integrationRepository.updateIntegrationStatus.mockResolvedValue(undefined);
288
+ mockContext.integrationRepository.findIntegrations.mockResolvedValue(
289
+ [integration]
290
+ );
291
+ mockContext.integrationRepository.updateIntegrationStatus.mockResolvedValue(
292
+ undefined
293
+ );
245
294
 
246
295
  const result = await script.execute({
247
296
  checkCredentials: true,
248
297
  checkConnectivity: false,
249
- updateStatus: true
298
+ updateStatus: true,
250
299
  });
251
300
 
252
301
  expect(result.unhealthy).toBe(1);
253
- expect(mockContext.integrationRepository.updateIntegrationStatus).toHaveBeenCalledWith('int-1', 'ERROR');
302
+ expect(
303
+ mockContext.integrationRepository.updateIntegrationStatus
304
+ ).toHaveBeenCalledWith('int-1', 'ERROR');
254
305
  });
255
306
 
256
307
  it('should not update status when updateStatus is false', async () => {
@@ -260,29 +311,37 @@ describe('IntegrationHealthCheckScript', () => {
260
311
  type: 'hubspot',
261
312
  credentials: {
262
313
  access_token: 'token123',
263
- expires_at: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()
264
- }
265
- }
314
+ expires_at: new Date(
315
+ Date.now() + 24 * 60 * 60 * 1000
316
+ ).toISOString(),
317
+ },
318
+ },
266
319
  };
267
320
 
268
321
  const mockInstance = {
269
322
  primary: {
270
323
  api: {
271
- getAuthenticationInfo: jest.fn().mockResolvedValue({ user: 'test' })
272
- }
273
- }
324
+ getAuthenticationInfo: jest
325
+ .fn()
326
+ .mockResolvedValue({ user: 'test' }),
327
+ },
328
+ },
274
329
  };
275
330
 
276
- mockContext.integrationRepository.findIntegrations.mockResolvedValue([integration]);
331
+ mockContext.integrationRepository.findIntegrations.mockResolvedValue(
332
+ [integration]
333
+ );
277
334
  mockContext.instantiate.mockResolvedValue(mockInstance);
278
335
 
279
336
  await script.execute({
280
337
  checkCredentials: true,
281
338
  checkConnectivity: true,
282
- updateStatus: false
339
+ updateStatus: false,
283
340
  });
284
341
 
285
- expect(mockContext.integrationRepository.updateIntegrationStatus).not.toHaveBeenCalled();
342
+ expect(
343
+ mockContext.integrationRepository.updateIntegrationStatus
344
+ ).not.toHaveBeenCalled();
286
345
  });
287
346
 
288
347
  it('should handle status update failures gracefully', async () => {
@@ -292,27 +351,35 @@ describe('IntegrationHealthCheckScript', () => {
292
351
  type: 'hubspot',
293
352
  credentials: {
294
353
  access_token: 'token123',
295
- expires_at: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()
296
- }
297
- }
354
+ expires_at: new Date(
355
+ Date.now() + 24 * 60 * 60 * 1000
356
+ ).toISOString(),
357
+ },
358
+ },
298
359
  };
299
360
 
300
361
  const mockInstance = {
301
362
  primary: {
302
363
  api: {
303
- getAuthenticationInfo: jest.fn().mockResolvedValue({ user: 'test' })
304
- }
305
- }
364
+ getAuthenticationInfo: jest
365
+ .fn()
366
+ .mockResolvedValue({ user: 'test' }),
367
+ },
368
+ },
306
369
  };
307
370
 
308
- mockContext.integrationRepository.findIntegrations.mockResolvedValue([integration]);
371
+ mockContext.integrationRepository.findIntegrations.mockResolvedValue(
372
+ [integration]
373
+ );
309
374
  mockContext.instantiate.mockResolvedValue(mockInstance);
310
- mockContext.integrationRepository.updateIntegrationStatus.mockRejectedValue(new Error('Update failed'));
375
+ mockContext.integrationRepository.updateIntegrationStatus.mockRejectedValue(
376
+ new Error('Update failed')
377
+ );
311
378
 
312
379
  const result = await script.execute({
313
380
  checkCredentials: true,
314
381
  checkConnectivity: true,
315
- updateStatus: true
382
+ updateStatus: true,
316
383
  });
317
384
 
318
385
  expect(result.healthy).toBe(1); // Should still report healthy
@@ -326,28 +393,42 @@ describe('IntegrationHealthCheckScript', () => {
326
393
  it('should filter by specific integration IDs', async () => {
327
394
  const integration1 = {
328
395
  id: 'int-1',
329
- config: { type: 'hubspot', credentials: { access_token: 'token1' } }
396
+ config: {
397
+ type: 'hubspot',
398
+ credentials: { access_token: 'token1' },
399
+ },
330
400
  };
331
401
  const integration2 = {
332
402
  id: 'int-2',
333
- config: { type: 'salesforce', credentials: { access_token: 'token2' } }
403
+ config: {
404
+ type: 'salesforce',
405
+ credentials: { access_token: 'token2' },
406
+ },
334
407
  };
335
408
 
336
- mockContext.integrationRepository.findIntegrationById.mockImplementation((id) => {
337
- if (id === 'int-1') return Promise.resolve(integration1);
338
- if (id === 'int-2') return Promise.resolve(integration2);
339
- return Promise.reject(new Error('Not found'));
340
- });
409
+ mockContext.integrationRepository.findIntegrationById.mockImplementation(
410
+ (id) => {
411
+ if (id === 'int-1') return Promise.resolve(integration1);
412
+ if (id === 'int-2') return Promise.resolve(integration2);
413
+ return Promise.reject(new Error('Not found'));
414
+ }
415
+ );
341
416
 
342
417
  const result = await script.execute({
343
418
  integrationIds: ['int-1', 'int-2'],
344
419
  checkCredentials: true,
345
- checkConnectivity: false
420
+ checkConnectivity: false,
346
421
  });
347
422
 
348
- expect(mockContext.integrationRepository.findIntegrationById).toHaveBeenCalledWith('int-1');
349
- expect(mockContext.integrationRepository.findIntegrationById).toHaveBeenCalledWith('int-2');
350
- expect(mockContext.integrationRepository.findIntegrations).not.toHaveBeenCalled();
423
+ expect(
424
+ mockContext.integrationRepository.findIntegrationById
425
+ ).toHaveBeenCalledWith('int-1');
426
+ expect(
427
+ mockContext.integrationRepository.findIntegrationById
428
+ ).toHaveBeenCalledWith('int-2');
429
+ expect(
430
+ mockContext.integrationRepository.findIntegrations
431
+ ).not.toHaveBeenCalled();
351
432
  expect(result.results).toHaveLength(2);
352
433
  });
353
434
 
@@ -358,17 +439,23 @@ describe('IntegrationHealthCheckScript', () => {
358
439
  type: 'hubspot',
359
440
  credentials: {
360
441
  access_token: 'token123',
361
- expires_at: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()
362
- }
363
- }
442
+ expires_at: new Date(
443
+ Date.now() + 24 * 60 * 60 * 1000
444
+ ).toISOString(),
445
+ },
446
+ },
364
447
  };
365
448
 
366
- mockContext.integrationRepository.findIntegrations.mockResolvedValue([integration]);
367
- mockContext.instantiate.mockRejectedValue(new Error('Instantiation failed'));
449
+ mockContext.integrationRepository.findIntegrations.mockResolvedValue(
450
+ [integration]
451
+ );
452
+ mockContext.instantiate.mockRejectedValue(
453
+ new Error('Instantiation failed')
454
+ );
368
455
 
369
456
  const result = await script.execute({
370
457
  checkCredentials: true,
371
- checkConnectivity: true
458
+ checkConnectivity: true,
372
459
  });
373
460
 
374
461
  // Should still complete but mark as unknown or unhealthy
@@ -381,24 +468,28 @@ describe('IntegrationHealthCheckScript', () => {
381
468
  id: 'int-1',
382
469
  config: {
383
470
  type: 'hubspot',
384
- credentials: {} // Missing credentials, but check is disabled
385
- }
471
+ credentials: {}, // Missing credentials, but check is disabled
472
+ },
386
473
  };
387
474
 
388
475
  const mockInstance = {
389
476
  primary: {
390
477
  api: {
391
- getAuthenticationInfo: jest.fn().mockResolvedValue({ user: 'test' })
392
- }
393
- }
478
+ getAuthenticationInfo: jest
479
+ .fn()
480
+ .mockResolvedValue({ user: 'test' }),
481
+ },
482
+ },
394
483
  };
395
484
 
396
- mockContext.integrationRepository.findIntegrations.mockResolvedValue([integration]);
485
+ mockContext.integrationRepository.findIntegrations.mockResolvedValue(
486
+ [integration]
487
+ );
397
488
  mockContext.instantiate.mockResolvedValue(mockInstance);
398
489
 
399
490
  const result = await script.execute({
400
491
  checkCredentials: false,
401
- checkConnectivity: true
492
+ checkConnectivity: true,
402
493
  });
403
494
 
404
495
  expect(result.results[0].checks.credentials).toBeUndefined();
@@ -412,16 +503,20 @@ describe('IntegrationHealthCheckScript', () => {
412
503
  type: 'hubspot',
413
504
  credentials: {
414
505
  access_token: 'token123',
415
- expires_at: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()
416
- }
417
- }
506
+ expires_at: new Date(
507
+ Date.now() + 24 * 60 * 60 * 1000
508
+ ).toISOString(),
509
+ },
510
+ },
418
511
  };
419
512
 
420
- mockContext.integrationRepository.findIntegrations.mockResolvedValue([integration]);
513
+ mockContext.integrationRepository.findIntegrations.mockResolvedValue(
514
+ [integration]
515
+ );
421
516
 
422
517
  const result = await script.execute({
423
518
  checkCredentials: true,
424
- checkConnectivity: false
519
+ checkConnectivity: false,
425
520
  });
426
521
 
427
522
  expect(result.results[0].checks.credentials).toBeDefined();
@@ -434,7 +529,9 @@ describe('IntegrationHealthCheckScript', () => {
434
529
  let script;
435
530
 
436
531
  beforeEach(() => {
437
- script = new IntegrationHealthCheckScript({ context: { log: jest.fn() } });
532
+ script = new IntegrationHealthCheckScript({
533
+ context: { log: jest.fn() },
534
+ });
438
535
  });
439
536
 
440
537
  it('should return valid for integrations with valid credentials', () => {
@@ -443,9 +540,11 @@ describe('IntegrationHealthCheckScript', () => {
443
540
  config: {
444
541
  credentials: {
445
542
  access_token: 'token123',
446
- expires_at: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()
447
- }
448
- }
543
+ expires_at: new Date(
544
+ Date.now() + 24 * 60 * 60 * 1000
545
+ ).toISOString(),
546
+ },
547
+ },
449
548
  };
450
549
 
451
550
  const result = script.checkCredentialValidity(integration);
@@ -458,8 +557,8 @@ describe('IntegrationHealthCheckScript', () => {
458
557
  const integration = {
459
558
  id: 'int-1',
460
559
  config: {
461
- credentials: {}
462
- }
560
+ credentials: {},
561
+ },
463
562
  };
464
563
 
465
564
  const result = script.checkCredentialValidity(integration);
@@ -474,9 +573,9 @@ describe('IntegrationHealthCheckScript', () => {
474
573
  config: {
475
574
  credentials: {
476
575
  access_token: 'token123',
477
- expires_at: new Date(Date.now() - 1000).toISOString() // Expired
478
- }
479
- }
576
+ expires_at: new Date(Date.now() - 1000).toISOString(), // Expired
577
+ },
578
+ },
480
579
  };
481
580
 
482
581
  const result = script.checkCredentialValidity(integration);
@@ -490,10 +589,10 @@ describe('IntegrationHealthCheckScript', () => {
490
589
  id: 'int-1',
491
590
  config: {
492
591
  credentials: {
493
- access_token: 'token123'
592
+ access_token: 'token123',
494
593
  // No expires_at
495
- }
496
- }
594
+ },
595
+ },
497
596
  };
498
597
 
499
598
  const result = script.checkCredentialValidity(integration);
@@ -518,15 +617,17 @@ describe('IntegrationHealthCheckScript', () => {
518
617
  it('should return valid for successful API calls', async () => {
519
618
  const integration = {
520
619
  id: 'int-1',
521
- config: { type: 'hubspot' }
620
+ config: { type: 'hubspot' },
522
621
  };
523
622
 
524
623
  const mockInstance = {
525
624
  primary: {
526
625
  api: {
527
- getAuthenticationInfo: jest.fn().mockResolvedValue({ user: 'test' })
528
- }
529
- }
626
+ getAuthenticationInfo: jest
627
+ .fn()
628
+ .mockResolvedValue({ user: 'test' }),
629
+ },
630
+ },
530
631
  };
531
632
 
532
633
  mockContext.instantiate.mockResolvedValue(mockInstance);
@@ -541,15 +642,17 @@ describe('IntegrationHealthCheckScript', () => {
541
642
  it('should try getCurrentUser if getAuthenticationInfo is not available', async () => {
542
643
  const integration = {
543
644
  id: 'int-1',
544
- config: { type: 'hubspot' }
645
+ config: { type: 'hubspot' },
545
646
  };
546
647
 
547
648
  const mockInstance = {
548
649
  primary: {
549
650
  api: {
550
- getCurrentUser: jest.fn().mockResolvedValue({ user: 'test' })
551
- }
552
- }
651
+ getCurrentUser: jest
652
+ .fn()
653
+ .mockResolvedValue({ user: 'test' }),
654
+ },
655
+ },
553
656
  };
554
657
 
555
658
  mockContext.instantiate.mockResolvedValue(mockInstance);
@@ -563,13 +666,13 @@ describe('IntegrationHealthCheckScript', () => {
563
666
  it('should return note when no health check endpoint is available', async () => {
564
667
  const integration = {
565
668
  id: 'int-1',
566
- config: { type: 'hubspot' }
669
+ config: { type: 'hubspot' },
567
670
  };
568
671
 
569
672
  const mockInstance = {
570
673
  primary: {
571
- api: {} // No health check methods
572
- }
674
+ api: {}, // No health check methods
675
+ },
573
676
  };
574
677
 
575
678
  mockContext.instantiate.mockResolvedValue(mockInstance);
@@ -584,15 +687,17 @@ describe('IntegrationHealthCheckScript', () => {
584
687
  it('should return invalid for API failures', async () => {
585
688
  const integration = {
586
689
  id: 'int-1',
587
- config: { type: 'hubspot' }
690
+ config: { type: 'hubspot' },
588
691
  };
589
692
 
590
693
  const mockInstance = {
591
694
  primary: {
592
695
  api: {
593
- getAuthenticationInfo: jest.fn().mockRejectedValue(new Error('Network error'))
594
- }
595
- }
696
+ getAuthenticationInfo: jest
697
+ .fn()
698
+ .mockRejectedValue(new Error('Network error')),
699
+ },
700
+ },
596
701
  };
597
702
 
598
703
  mockContext.instantiate.mockResolvedValue(mockInstance);