@friggframework/admin-scripts 2.0.0--canary.522.cbd3d5a.0 → 2.0.0--canary.517.21b69ac.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.
- package/PR_517_REVIEW_TRACKER.md +56 -0
- package/index.js +12 -3
- package/package.json +6 -9
- package/src/application/__tests__/admin-frigg-commands.test.js +19 -19
- package/src/application/__tests__/admin-script-base.test.js +100 -84
- package/src/application/__tests__/script-runner.test.js +146 -16
- package/src/application/admin-frigg-commands.js +20 -32
- package/src/application/admin-script-base.js +20 -99
- package/src/application/script-runner.js +131 -135
- package/src/application/use-cases/__tests__/delete-schedule-use-case.test.js +168 -0
- package/src/application/use-cases/__tests__/get-effective-schedule-use-case.test.js +114 -0
- package/src/application/use-cases/__tests__/upsert-schedule-use-case.test.js +201 -0
- package/src/application/use-cases/delete-schedule-use-case.js +108 -0
- package/src/application/use-cases/get-effective-schedule-use-case.js +78 -0
- package/src/application/use-cases/index.js +18 -0
- package/src/application/use-cases/upsert-schedule-use-case.js +127 -0
- package/src/builtins/__tests__/integration-health-check.test.js +67 -60
- package/src/builtins/__tests__/oauth-token-refresh.test.js +45 -37
- package/src/builtins/integration-health-check.js +23 -24
- package/src/builtins/oauth-token-refresh.js +19 -20
- package/src/infrastructure/__tests__/admin-auth-middleware.test.js +32 -95
- package/src/infrastructure/__tests__/admin-script-router.test.js +46 -47
- package/src/infrastructure/admin-auth-middleware.js +5 -43
- package/src/infrastructure/admin-script-router.js +38 -32
- package/src/infrastructure/script-executor-handler.js +2 -2
- package/src/application/__tests__/dry-run-http-interceptor.test.js +0 -313
- package/src/application/__tests__/dry-run-repository-wrapper.test.js +0 -257
- package/src/application/__tests__/schedule-management-use-case.test.js +0 -276
- package/src/application/dry-run-http-interceptor.js +0 -296
- package/src/application/dry-run-repository-wrapper.js +0 -261
- package/src/application/schedule-management-use-case.js +0 -230
|
@@ -6,7 +6,7 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
6
6
|
expect(IntegrationHealthCheckScript.Definition.name).toBe('integration-health-check');
|
|
7
7
|
expect(IntegrationHealthCheckScript.Definition.version).toBe('1.0.0');
|
|
8
8
|
expect(IntegrationHealthCheckScript.Definition.source).toBe('BUILTIN');
|
|
9
|
-
expect(IntegrationHealthCheckScript.Definition.config.
|
|
9
|
+
expect(IntegrationHealthCheckScript.Definition.config.requireIntegrationInstance).toBe(true);
|
|
10
10
|
});
|
|
11
11
|
|
|
12
12
|
it('should have valid input schema', () => {
|
|
@@ -37,27 +37,33 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
37
37
|
it('should have appropriate timeout configuration', () => {
|
|
38
38
|
expect(IntegrationHealthCheckScript.Definition.config.timeout).toBe(900000); // 15 minutes
|
|
39
39
|
});
|
|
40
|
+
|
|
41
|
+
it('should have clean display object', () => {
|
|
42
|
+
// Display should only have UI-specific fields
|
|
43
|
+
expect(IntegrationHealthCheckScript.Definition.display.category).toBe('maintenance');
|
|
44
|
+
// Should NOT have redundant label/description - they're derived from top-level
|
|
45
|
+
});
|
|
40
46
|
});
|
|
41
47
|
|
|
42
48
|
describe('execute()', () => {
|
|
43
49
|
let script;
|
|
44
|
-
let
|
|
50
|
+
let mockContext;
|
|
45
51
|
|
|
46
52
|
beforeEach(() => {
|
|
47
|
-
|
|
48
|
-
mockFrigg = {
|
|
53
|
+
mockContext = {
|
|
49
54
|
log: jest.fn(),
|
|
50
55
|
listIntegrations: jest.fn(),
|
|
51
56
|
findIntegrationById: jest.fn(),
|
|
52
57
|
instantiate: jest.fn(),
|
|
53
58
|
updateIntegrationStatus: jest.fn(),
|
|
54
59
|
};
|
|
60
|
+
script = new IntegrationHealthCheckScript({ context: mockContext });
|
|
55
61
|
});
|
|
56
62
|
|
|
57
63
|
it('should return empty results when no integrations found', async () => {
|
|
58
|
-
|
|
64
|
+
mockContext.listIntegrations.mockResolvedValue([]);
|
|
59
65
|
|
|
60
|
-
const result = await script.execute(
|
|
66
|
+
const result = await script.execute({});
|
|
61
67
|
|
|
62
68
|
expect(result.healthy).toBe(0);
|
|
63
69
|
expect(result.unhealthy).toBe(0);
|
|
@@ -85,10 +91,10 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
85
91
|
}
|
|
86
92
|
};
|
|
87
93
|
|
|
88
|
-
|
|
89
|
-
|
|
94
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
95
|
+
mockContext.instantiate.mockResolvedValue(mockInstance);
|
|
90
96
|
|
|
91
|
-
const result = await script.execute(
|
|
97
|
+
const result = await script.execute({
|
|
92
98
|
checkCredentials: true,
|
|
93
99
|
checkConnectivity: true
|
|
94
100
|
});
|
|
@@ -112,9 +118,9 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
112
118
|
}
|
|
113
119
|
};
|
|
114
120
|
|
|
115
|
-
|
|
121
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
116
122
|
|
|
117
|
-
const result = await script.execute(
|
|
123
|
+
const result = await script.execute({
|
|
118
124
|
checkCredentials: true,
|
|
119
125
|
checkConnectivity: false
|
|
120
126
|
});
|
|
@@ -141,9 +147,9 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
141
147
|
}
|
|
142
148
|
};
|
|
143
149
|
|
|
144
|
-
|
|
150
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
145
151
|
|
|
146
|
-
const result = await script.execute(
|
|
152
|
+
const result = await script.execute({
|
|
147
153
|
checkCredentials: true,
|
|
148
154
|
checkConnectivity: false
|
|
149
155
|
});
|
|
@@ -176,10 +182,10 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
176
182
|
}
|
|
177
183
|
};
|
|
178
184
|
|
|
179
|
-
|
|
180
|
-
|
|
185
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
186
|
+
mockContext.instantiate.mockResolvedValue(mockInstance);
|
|
181
187
|
|
|
182
|
-
const result = await script.execute(
|
|
188
|
+
const result = await script.execute({
|
|
183
189
|
checkCredentials: true,
|
|
184
190
|
checkConnectivity: true
|
|
185
191
|
});
|
|
@@ -209,18 +215,18 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
209
215
|
}
|
|
210
216
|
};
|
|
211
217
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
218
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
219
|
+
mockContext.instantiate.mockResolvedValue(mockInstance);
|
|
220
|
+
mockContext.updateIntegrationStatus.mockResolvedValue(undefined);
|
|
215
221
|
|
|
216
|
-
const result = await script.execute(
|
|
222
|
+
const result = await script.execute({
|
|
217
223
|
checkCredentials: true,
|
|
218
224
|
checkConnectivity: true,
|
|
219
225
|
updateStatus: true
|
|
220
226
|
});
|
|
221
227
|
|
|
222
228
|
expect(result.healthy).toBe(1);
|
|
223
|
-
expect(
|
|
229
|
+
expect(mockContext.updateIntegrationStatus).toHaveBeenCalledWith('int-1', 'ACTIVE');
|
|
224
230
|
});
|
|
225
231
|
|
|
226
232
|
it('should update integration status to ERROR for unhealthy integrations', async () => {
|
|
@@ -232,17 +238,17 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
232
238
|
}
|
|
233
239
|
};
|
|
234
240
|
|
|
235
|
-
|
|
236
|
-
|
|
241
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
242
|
+
mockContext.updateIntegrationStatus.mockResolvedValue(undefined);
|
|
237
243
|
|
|
238
|
-
const result = await script.execute(
|
|
244
|
+
const result = await script.execute({
|
|
239
245
|
checkCredentials: true,
|
|
240
246
|
checkConnectivity: false,
|
|
241
247
|
updateStatus: true
|
|
242
248
|
});
|
|
243
249
|
|
|
244
250
|
expect(result.unhealthy).toBe(1);
|
|
245
|
-
expect(
|
|
251
|
+
expect(mockContext.updateIntegrationStatus).toHaveBeenCalledWith('int-1', 'ERROR');
|
|
246
252
|
});
|
|
247
253
|
|
|
248
254
|
it('should not update status when updateStatus is false', async () => {
|
|
@@ -265,16 +271,16 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
265
271
|
}
|
|
266
272
|
};
|
|
267
273
|
|
|
268
|
-
|
|
269
|
-
|
|
274
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
275
|
+
mockContext.instantiate.mockResolvedValue(mockInstance);
|
|
270
276
|
|
|
271
|
-
await script.execute(
|
|
277
|
+
await script.execute({
|
|
272
278
|
checkCredentials: true,
|
|
273
279
|
checkConnectivity: true,
|
|
274
280
|
updateStatus: false
|
|
275
281
|
});
|
|
276
282
|
|
|
277
|
-
expect(
|
|
283
|
+
expect(mockContext.updateIntegrationStatus).not.toHaveBeenCalled();
|
|
278
284
|
});
|
|
279
285
|
|
|
280
286
|
it('should handle status update failures gracefully', async () => {
|
|
@@ -297,18 +303,18 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
297
303
|
}
|
|
298
304
|
};
|
|
299
305
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
306
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
307
|
+
mockContext.instantiate.mockResolvedValue(mockInstance);
|
|
308
|
+
mockContext.updateIntegrationStatus.mockRejectedValue(new Error('Update failed'));
|
|
303
309
|
|
|
304
|
-
const result = await script.execute(
|
|
310
|
+
const result = await script.execute({
|
|
305
311
|
checkCredentials: true,
|
|
306
312
|
checkConnectivity: true,
|
|
307
313
|
updateStatus: true
|
|
308
314
|
});
|
|
309
315
|
|
|
310
316
|
expect(result.healthy).toBe(1); // Should still report healthy
|
|
311
|
-
expect(
|
|
317
|
+
expect(mockContext.log).toHaveBeenCalledWith(
|
|
312
318
|
'warn',
|
|
313
319
|
expect.stringContaining('Failed to update status'),
|
|
314
320
|
expect.any(Object)
|
|
@@ -325,21 +331,21 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
325
331
|
config: { type: 'salesforce', credentials: { access_token: 'token2' } }
|
|
326
332
|
};
|
|
327
333
|
|
|
328
|
-
|
|
334
|
+
mockContext.findIntegrationById.mockImplementation((id) => {
|
|
329
335
|
if (id === 'int-1') return Promise.resolve(integration1);
|
|
330
336
|
if (id === 'int-2') return Promise.resolve(integration2);
|
|
331
337
|
return Promise.reject(new Error('Not found'));
|
|
332
338
|
});
|
|
333
339
|
|
|
334
|
-
const result = await script.execute(
|
|
340
|
+
const result = await script.execute({
|
|
335
341
|
integrationIds: ['int-1', 'int-2'],
|
|
336
342
|
checkCredentials: true,
|
|
337
343
|
checkConnectivity: false
|
|
338
344
|
});
|
|
339
345
|
|
|
340
|
-
expect(
|
|
341
|
-
expect(
|
|
342
|
-
expect(
|
|
346
|
+
expect(mockContext.findIntegrationById).toHaveBeenCalledWith('int-1');
|
|
347
|
+
expect(mockContext.findIntegrationById).toHaveBeenCalledWith('int-2');
|
|
348
|
+
expect(mockContext.listIntegrations).not.toHaveBeenCalled();
|
|
343
349
|
expect(result.results).toHaveLength(2);
|
|
344
350
|
});
|
|
345
351
|
|
|
@@ -355,10 +361,10 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
355
361
|
}
|
|
356
362
|
};
|
|
357
363
|
|
|
358
|
-
|
|
359
|
-
|
|
364
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
365
|
+
mockContext.instantiate.mockRejectedValue(new Error('Instantiation failed'));
|
|
360
366
|
|
|
361
|
-
const result = await script.execute(
|
|
367
|
+
const result = await script.execute({
|
|
362
368
|
checkCredentials: true,
|
|
363
369
|
checkConnectivity: true
|
|
364
370
|
});
|
|
@@ -385,10 +391,10 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
385
391
|
}
|
|
386
392
|
};
|
|
387
393
|
|
|
388
|
-
|
|
389
|
-
|
|
394
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
395
|
+
mockContext.instantiate.mockResolvedValue(mockInstance);
|
|
390
396
|
|
|
391
|
-
const result = await script.execute(
|
|
397
|
+
const result = await script.execute({
|
|
392
398
|
checkCredentials: false,
|
|
393
399
|
checkConnectivity: true
|
|
394
400
|
});
|
|
@@ -409,16 +415,16 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
409
415
|
}
|
|
410
416
|
};
|
|
411
417
|
|
|
412
|
-
|
|
418
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
413
419
|
|
|
414
|
-
const result = await script.execute(
|
|
420
|
+
const result = await script.execute({
|
|
415
421
|
checkCredentials: true,
|
|
416
422
|
checkConnectivity: false
|
|
417
423
|
});
|
|
418
424
|
|
|
419
425
|
expect(result.results[0].checks.credentials).toBeDefined();
|
|
420
426
|
expect(result.results[0].checks.connectivity).toBeUndefined();
|
|
421
|
-
expect(
|
|
427
|
+
expect(mockContext.instantiate).not.toHaveBeenCalled();
|
|
422
428
|
});
|
|
423
429
|
});
|
|
424
430
|
|
|
@@ -426,7 +432,7 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
426
432
|
let script;
|
|
427
433
|
|
|
428
434
|
beforeEach(() => {
|
|
429
|
-
script = new IntegrationHealthCheckScript();
|
|
435
|
+
script = new IntegrationHealthCheckScript({ context: { log: jest.fn() } });
|
|
430
436
|
});
|
|
431
437
|
|
|
432
438
|
it('should return valid for integrations with valid credentials', () => {
|
|
@@ -497,13 +503,14 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
497
503
|
|
|
498
504
|
describe('checkApiConnectivity()', () => {
|
|
499
505
|
let script;
|
|
500
|
-
let
|
|
506
|
+
let mockContext;
|
|
501
507
|
|
|
502
508
|
beforeEach(() => {
|
|
503
|
-
|
|
504
|
-
|
|
509
|
+
mockContext = {
|
|
510
|
+
log: jest.fn(),
|
|
505
511
|
instantiate: jest.fn(),
|
|
506
512
|
};
|
|
513
|
+
script = new IntegrationHealthCheckScript({ context: mockContext });
|
|
507
514
|
});
|
|
508
515
|
|
|
509
516
|
it('should return valid for successful API calls', async () => {
|
|
@@ -520,9 +527,9 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
520
527
|
}
|
|
521
528
|
};
|
|
522
529
|
|
|
523
|
-
|
|
530
|
+
mockContext.instantiate.mockResolvedValue(mockInstance);
|
|
524
531
|
|
|
525
|
-
const result = await script.checkApiConnectivity(
|
|
532
|
+
const result = await script.checkApiConnectivity(integration);
|
|
526
533
|
|
|
527
534
|
expect(result.valid).toBe(true);
|
|
528
535
|
expect(result.issue).toBeNull();
|
|
@@ -543,9 +550,9 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
543
550
|
}
|
|
544
551
|
};
|
|
545
552
|
|
|
546
|
-
|
|
553
|
+
mockContext.instantiate.mockResolvedValue(mockInstance);
|
|
547
554
|
|
|
548
|
-
const result = await script.checkApiConnectivity(
|
|
555
|
+
const result = await script.checkApiConnectivity(integration);
|
|
549
556
|
|
|
550
557
|
expect(result.valid).toBe(true);
|
|
551
558
|
expect(mockInstance.primary.api.getCurrentUser).toHaveBeenCalled();
|
|
@@ -563,9 +570,9 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
563
570
|
}
|
|
564
571
|
};
|
|
565
572
|
|
|
566
|
-
|
|
573
|
+
mockContext.instantiate.mockResolvedValue(mockInstance);
|
|
567
574
|
|
|
568
|
-
const result = await script.checkApiConnectivity(
|
|
575
|
+
const result = await script.checkApiConnectivity(integration);
|
|
569
576
|
|
|
570
577
|
expect(result.valid).toBe(true);
|
|
571
578
|
expect(result.issue).toBeNull();
|
|
@@ -586,9 +593,9 @@ describe('IntegrationHealthCheckScript', () => {
|
|
|
586
593
|
}
|
|
587
594
|
};
|
|
588
595
|
|
|
589
|
-
|
|
596
|
+
mockContext.instantiate.mockResolvedValue(mockInstance);
|
|
590
597
|
|
|
591
|
-
const result = await script.checkApiConnectivity(
|
|
598
|
+
const result = await script.checkApiConnectivity(integration);
|
|
592
599
|
|
|
593
600
|
expect(result.valid).toBe(false);
|
|
594
601
|
expect(result.issue).toContain('API connectivity failed');
|
|
@@ -6,7 +6,7 @@ describe('OAuthTokenRefreshScript', () => {
|
|
|
6
6
|
expect(OAuthTokenRefreshScript.Definition.name).toBe('oauth-token-refresh');
|
|
7
7
|
expect(OAuthTokenRefreshScript.Definition.version).toBe('1.0.0');
|
|
8
8
|
expect(OAuthTokenRefreshScript.Definition.source).toBe('BUILTIN');
|
|
9
|
-
expect(OAuthTokenRefreshScript.Definition.config.
|
|
9
|
+
expect(OAuthTokenRefreshScript.Definition.config.requireIntegrationInstance).toBe(true);
|
|
10
10
|
});
|
|
11
11
|
|
|
12
12
|
it('should have valid input schema', () => {
|
|
@@ -29,32 +29,40 @@ describe('OAuthTokenRefreshScript', () => {
|
|
|
29
29
|
it('should have appropriate timeout configuration', () => {
|
|
30
30
|
expect(OAuthTokenRefreshScript.Definition.config.timeout).toBe(600000); // 10 minutes
|
|
31
31
|
});
|
|
32
|
+
|
|
33
|
+
it('should have clean display object without redundant fields', () => {
|
|
34
|
+
expect(OAuthTokenRefreshScript.Definition.display).toBeDefined();
|
|
35
|
+
expect(OAuthTokenRefreshScript.Definition.display.category).toBe('maintenance');
|
|
36
|
+
// Should NOT have redundant label/description
|
|
37
|
+
expect(OAuthTokenRefreshScript.Definition.display.label).toBeUndefined();
|
|
38
|
+
expect(OAuthTokenRefreshScript.Definition.display.description).toBeUndefined();
|
|
39
|
+
});
|
|
32
40
|
});
|
|
33
41
|
|
|
34
42
|
describe('execute()', () => {
|
|
35
43
|
let script;
|
|
36
|
-
let
|
|
44
|
+
let mockContext;
|
|
37
45
|
|
|
38
46
|
beforeEach(() => {
|
|
39
|
-
|
|
40
|
-
mockFrigg = {
|
|
47
|
+
mockContext = {
|
|
41
48
|
log: jest.fn(),
|
|
42
49
|
listIntegrations: jest.fn(),
|
|
43
50
|
findIntegrationById: jest.fn(),
|
|
44
51
|
instantiate: jest.fn(),
|
|
45
52
|
};
|
|
53
|
+
script = new OAuthTokenRefreshScript({ context: mockContext });
|
|
46
54
|
});
|
|
47
55
|
|
|
48
56
|
it('should return empty results when no integrations found', async () => {
|
|
49
|
-
|
|
57
|
+
mockContext.listIntegrations.mockResolvedValue([]);
|
|
50
58
|
|
|
51
|
-
const result = await script.execute(
|
|
59
|
+
const result = await script.execute({});
|
|
52
60
|
|
|
53
61
|
expect(result.refreshed).toBe(0);
|
|
54
62
|
expect(result.failed).toBe(0);
|
|
55
63
|
expect(result.skipped).toBe(0);
|
|
56
64
|
expect(result.details).toEqual([]);
|
|
57
|
-
expect(
|
|
65
|
+
expect(mockContext.log).toHaveBeenCalledWith('info', expect.any(String), expect.any(Object));
|
|
58
66
|
});
|
|
59
67
|
|
|
60
68
|
it('should skip integrations without OAuth credentials', async () => {
|
|
@@ -62,9 +70,9 @@ describe('OAuthTokenRefreshScript', () => {
|
|
|
62
70
|
id: 'int-1',
|
|
63
71
|
config: {} // No credentials
|
|
64
72
|
};
|
|
65
|
-
|
|
73
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
66
74
|
|
|
67
|
-
const result = await script.execute(
|
|
75
|
+
const result = await script.execute({});
|
|
68
76
|
|
|
69
77
|
expect(result.skipped).toBe(1);
|
|
70
78
|
expect(result.refreshed).toBe(0);
|
|
@@ -85,9 +93,9 @@ describe('OAuthTokenRefreshScript', () => {
|
|
|
85
93
|
}
|
|
86
94
|
}
|
|
87
95
|
};
|
|
88
|
-
|
|
96
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
89
97
|
|
|
90
|
-
const result = await script.execute(
|
|
98
|
+
const result = await script.execute({});
|
|
91
99
|
|
|
92
100
|
expect(result.skipped).toBe(1);
|
|
93
101
|
expect(result.details[0]).toMatchObject({
|
|
@@ -108,9 +116,9 @@ describe('OAuthTokenRefreshScript', () => {
|
|
|
108
116
|
}
|
|
109
117
|
}
|
|
110
118
|
};
|
|
111
|
-
|
|
119
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
112
120
|
|
|
113
|
-
const result = await script.execute(
|
|
121
|
+
const result = await script.execute({
|
|
114
122
|
expiryThresholdHours: 24
|
|
115
123
|
});
|
|
116
124
|
|
|
@@ -142,10 +150,10 @@ describe('OAuthTokenRefreshScript', () => {
|
|
|
142
150
|
}
|
|
143
151
|
};
|
|
144
152
|
|
|
145
|
-
|
|
146
|
-
|
|
153
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
154
|
+
mockContext.instantiate.mockResolvedValue(mockInstance);
|
|
147
155
|
|
|
148
|
-
const result = await script.execute(
|
|
156
|
+
const result = await script.execute({
|
|
149
157
|
expiryThresholdHours: 24
|
|
150
158
|
});
|
|
151
159
|
|
|
@@ -170,16 +178,16 @@ describe('OAuthTokenRefreshScript', () => {
|
|
|
170
178
|
}
|
|
171
179
|
};
|
|
172
180
|
|
|
173
|
-
|
|
181
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
174
182
|
|
|
175
|
-
const result = await script.execute(
|
|
183
|
+
const result = await script.execute({
|
|
176
184
|
expiryThresholdHours: 24,
|
|
177
185
|
dryRun: true
|
|
178
186
|
});
|
|
179
187
|
|
|
180
188
|
expect(result.refreshed).toBe(0);
|
|
181
189
|
expect(result.skipped).toBe(1);
|
|
182
|
-
expect(
|
|
190
|
+
expect(mockContext.instantiate).not.toHaveBeenCalled();
|
|
183
191
|
expect(result.details[0]).toMatchObject({
|
|
184
192
|
integrationId: 'int-1',
|
|
185
193
|
action: 'skipped',
|
|
@@ -207,10 +215,10 @@ describe('OAuthTokenRefreshScript', () => {
|
|
|
207
215
|
}
|
|
208
216
|
};
|
|
209
217
|
|
|
210
|
-
|
|
211
|
-
|
|
218
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
219
|
+
mockContext.instantiate.mockResolvedValue(mockInstance);
|
|
212
220
|
|
|
213
|
-
const result = await script.execute(
|
|
221
|
+
const result = await script.execute({
|
|
214
222
|
expiryThresholdHours: 24
|
|
215
223
|
});
|
|
216
224
|
|
|
@@ -243,10 +251,10 @@ describe('OAuthTokenRefreshScript', () => {
|
|
|
243
251
|
}
|
|
244
252
|
};
|
|
245
253
|
|
|
246
|
-
|
|
247
|
-
|
|
254
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
255
|
+
mockContext.instantiate.mockResolvedValue(mockInstance);
|
|
248
256
|
|
|
249
|
-
const result = await script.execute(
|
|
257
|
+
const result = await script.execute({
|
|
250
258
|
expiryThresholdHours: 24
|
|
251
259
|
});
|
|
252
260
|
|
|
@@ -268,19 +276,19 @@ describe('OAuthTokenRefreshScript', () => {
|
|
|
268
276
|
config: { credentials: { access_token: 'token2' } }
|
|
269
277
|
};
|
|
270
278
|
|
|
271
|
-
|
|
279
|
+
mockContext.findIntegrationById.mockImplementation((id) => {
|
|
272
280
|
if (id === 'int-1') return Promise.resolve(integration1);
|
|
273
281
|
if (id === 'int-2') return Promise.resolve(integration2);
|
|
274
282
|
return Promise.reject(new Error('Not found'));
|
|
275
283
|
});
|
|
276
284
|
|
|
277
|
-
const result = await script.execute(
|
|
285
|
+
const result = await script.execute({
|
|
278
286
|
integrationIds: ['int-1', 'int-2']
|
|
279
287
|
});
|
|
280
288
|
|
|
281
|
-
expect(
|
|
282
|
-
expect(
|
|
283
|
-
expect(
|
|
289
|
+
expect(mockContext.findIntegrationById).toHaveBeenCalledWith('int-1');
|
|
290
|
+
expect(mockContext.findIntegrationById).toHaveBeenCalledWith('int-2');
|
|
291
|
+
expect(mockContext.listIntegrations).not.toHaveBeenCalled();
|
|
284
292
|
expect(result.details).toHaveLength(2);
|
|
285
293
|
});
|
|
286
294
|
|
|
@@ -295,10 +303,10 @@ describe('OAuthTokenRefreshScript', () => {
|
|
|
295
303
|
}
|
|
296
304
|
};
|
|
297
305
|
|
|
298
|
-
|
|
299
|
-
|
|
306
|
+
mockContext.listIntegrations.mockResolvedValue([integration]);
|
|
307
|
+
mockContext.instantiate.mockRejectedValue(new Error('Instantiation failed'));
|
|
300
308
|
|
|
301
|
-
const result = await script.execute(
|
|
309
|
+
const result = await script.execute({
|
|
302
310
|
expiryThresholdHours: 24
|
|
303
311
|
});
|
|
304
312
|
|
|
@@ -313,14 +321,14 @@ describe('OAuthTokenRefreshScript', () => {
|
|
|
313
321
|
|
|
314
322
|
describe('processIntegration()', () => {
|
|
315
323
|
let script;
|
|
316
|
-
let
|
|
324
|
+
let mockContext;
|
|
317
325
|
|
|
318
326
|
beforeEach(() => {
|
|
319
|
-
|
|
320
|
-
mockFrigg = {
|
|
327
|
+
mockContext = {
|
|
321
328
|
log: jest.fn(),
|
|
322
329
|
instantiate: jest.fn(),
|
|
323
330
|
};
|
|
331
|
+
script = new OAuthTokenRefreshScript({ context: mockContext });
|
|
324
332
|
});
|
|
325
333
|
|
|
326
334
|
it('should return correct detail object for each scenario', async () => {
|
|
@@ -331,7 +339,7 @@ describe('OAuthTokenRefreshScript', () => {
|
|
|
331
339
|
config: {}
|
|
332
340
|
};
|
|
333
341
|
|
|
334
|
-
const result = await script.processIntegration(
|
|
342
|
+
const result = await script.processIntegration(integration, {
|
|
335
343
|
expiryThresholdHours: 24,
|
|
336
344
|
dryRun: false
|
|
337
345
|
});
|