@@ -2,8 +2,7 @@ import { afterEach, beforeEach, describe, it, mock } from 'node:test';
2
2
import path from 'path' ;
3
3
import watcher from '@parcel/watcher' ;
4
4
import {
5
- CDK_BOOTSTRAP_STACK_NAME ,
6
- CDK_BOOTSTRAP_VERSION_KEY ,
5
+ CDK_DEFAULT_BOOTSTRAP_VERSION_PARAMETER_NAME ,
7
6
FileWatchingSandbox ,
8
7
getBootstrapUrl ,
9
8
} from './file_watching_sandbox.js' ;
@@ -15,7 +14,6 @@ import {
15
14
} from '@aws-amplify/backend-deployer' ;
16
15
import fs from 'fs' ;
17
16
import parseGitIgnore from 'parse-gitignore' ;
18
- import { CloudFormationClient } from '@aws-sdk/client-cloudformation' ;
19
17
import _open from 'open' ;
20
18
import { SecretListItem , getSecretClient } from '@aws-amplify/backend-secret' ;
21
19
import { Sandbox , SandboxOptions } from './sandbox.js' ;
@@ -29,6 +27,7 @@ import {
29
27
import { fileURLToPath } from 'url' ;
30
28
import { BackendIdentifier } from '@aws-amplify/plugin-types' ;
31
29
import { AmplifyUserError } from '@aws-amplify/platform-core' ;
30
+ import { SSMClient } from '@aws-sdk/client-ssm' ;
32
31
33
32
// Watcher mocks
34
33
const unsubscribeMockFn = mock . fn ( ) ;
@@ -85,24 +84,15 @@ const backendDeployerDestroyMock = mock.method(backendDeployer, 'destroy', () =>
85
84
Promise . resolve ( )
86
85
) ;
87
86
const region = 'test-region' ;
88
- const cfnClientMock = new CloudFormationClient ( { region } ) ;
89
- const cfnClientSendMock = mock . fn ( ) ;
90
- mock . method ( cfnClientMock , 'send' , cfnClientSendMock ) ;
91
- cfnClientSendMock . mock . mockImplementation ( ( ) =>
87
+ const ssmClientMock = new SSMClient ( { region } ) ;
88
+ const ssmClientSendMock = mock . fn ( ) ;
89
+ mock . method ( ssmClientMock , 'send' , ssmClientSendMock ) ;
90
+ ssmClientSendMock . mock . mockImplementation ( ( ) =>
92
91
Promise . resolve ( {
93
- Stacks : [
94
- {
95
- Name : CDK_BOOTSTRAP_STACK_NAME ,
96
- Outputs : [
97
- {
98
- Description :
99
- 'The version of the bootstrap resources that are currently mastered in this stack' ,
100
- OutputKey : CDK_BOOTSTRAP_VERSION_KEY ,
101
- OutputValue : '18' ,
102
- } ,
103
- ] ,
104
- } ,
105
- ] ,
92
+ Parameter : {
93
+ Name : CDK_DEFAULT_BOOTSTRAP_VERSION_PARAMETER_NAME ,
94
+ Value : '18' ,
95
+ } ,
106
96
} )
107
97
) ;
108
98
const openMock = mock . fn ( _open , ( url : string ) => Promise . resolve ( url ) ) ;
@@ -140,19 +130,19 @@ void describe('Sandbox to check if region is bootstrapped', () => {
140
130
sandboxInstance = new FileWatchingSandbox (
141
131
async ( ) => testSandboxBackendId ,
142
132
sandboxExecutor ,
143
- cfnClientMock ,
133
+ ssmClientMock ,
144
134
printer as unknown as Printer ,
145
135
openMock as never
146
136
) ;
147
137
148
- cfnClientSendMock . mock . resetCalls ( ) ;
138
+ ssmClientSendMock . mock . resetCalls ( ) ;
149
139
openMock . mock . resetCalls ( ) ;
150
140
backendDeployerDestroyMock . mock . resetCalls ( ) ;
151
141
backendDeployerDeployMock . mock . resetCalls ( ) ;
152
142
} ) ;
153
143
154
144
afterEach ( async ( ) => {
155
- cfnClientSendMock . mock . resetCalls ( ) ;
145
+ ssmClientSendMock . mock . resetCalls ( ) ;
156
146
openMock . mock . resetCalls ( ) ;
157
147
backendDeployerDestroyMock . mock . resetCalls ( ) ;
158
148
backendDeployerDeployMock . mock . resetCalls ( ) ;
@@ -164,7 +154,7 @@ void describe('Sandbox to check if region is bootstrapped', () => {
164
154
} ) ;
165
155
166
156
void it ( 'when region has not bootstrapped, then opens console to initiate bootstrap' , async ( ) => {
167
- cfnClientSendMock . mock . mockImplementationOnce ( ( ) => {
157
+ ssmClientSendMock . mock . mockImplementationOnce ( ( ) => {
168
158
throw new Error ( 'Stack with id CDKToolkit does not exist' ) ;
169
159
} ) ;
170
160
@@ -173,7 +163,7 @@ void describe('Sandbox to check if region is bootstrapped', () => {
173
163
exclude : [ 'exclude1' , 'exclude2' ] ,
174
164
} ) ;
175
165
176
- assert . strictEqual ( cfnClientSendMock . mock . callCount ( ) , 1 ) ;
166
+ assert . strictEqual ( ssmClientSendMock . mock . callCount ( ) , 1 ) ;
177
167
assert . strictEqual ( openMock . mock . callCount ( ) , 1 ) ;
178
168
assert . strictEqual (
179
169
openMock . mock . calls [ 0 ] . arguments [ 0 ] ,
@@ -182,21 +172,12 @@ void describe('Sandbox to check if region is bootstrapped', () => {
182
172
} ) ;
183
173
184
174
void it ( 'when region has bootstrapped, but with a version lower than the minimum (6), then opens console to initiate bootstrap' , async ( ) => {
185
- cfnClientSendMock . mock . mockImplementationOnce ( ( ) =>
175
+ ssmClientSendMock . mock . mockImplementationOnce ( ( ) =>
186
176
Promise . resolve ( {
187
- Stacks : [
188
- {
189
- Name : CDK_BOOTSTRAP_STACK_NAME ,
190
- Outputs : [
191
- {
192
- Description :
193
- 'The version of the bootstrap resources that are currently mastered in this stack' ,
194
- OutputKey : CDK_BOOTSTRAP_VERSION_KEY ,
195
- OutputValue : '5' ,
196
- } ,
197
- ] ,
198
- } ,
199
- ] ,
177
+ Parameter : {
178
+ Name : CDK_DEFAULT_BOOTSTRAP_VERSION_PARAMETER_NAME ,
179
+ Value : '5' ,
180
+ } ,
200
181
} )
201
182
) ;
202
183
@@ -205,7 +186,7 @@ void describe('Sandbox to check if region is bootstrapped', () => {
205
186
exclude : [ 'exclude1' , 'exclude2' ] ,
206
187
} ) ;
207
188
208
- assert . strictEqual ( cfnClientSendMock . mock . callCount ( ) , 1 ) ;
189
+ assert . strictEqual ( ssmClientSendMock . mock . callCount ( ) , 1 ) ;
209
190
assert . strictEqual ( openMock . mock . callCount ( ) , 1 ) ;
210
191
assert . strictEqual (
211
192
openMock . mock . calls [ 0 ] . arguments [ 0 ] ,
@@ -219,7 +200,7 @@ void describe('Sandbox to check if region is bootstrapped', () => {
219
200
exclude : [ 'exclude1' , 'exclude2' ] ,
220
201
} ) ;
221
202
222
- assert . strictEqual ( cfnClientSendMock . mock . callCount ( ) , 1 ) ;
203
+ assert . strictEqual ( ssmClientSendMock . mock . callCount ( ) , 1 ) ;
223
204
assert . strictEqual ( openMock . mock . callCount ( ) , 0 ) ;
224
205
} ) ;
225
206
} ) ;
@@ -244,7 +225,7 @@ void describe('Sandbox using local project name resolver', () => {
244
225
backendDeployerDestroyMock . mock . resetCalls ( ) ;
245
226
backendDeployerDeployMock . mock . resetCalls ( ) ;
246
227
subscribeMock . mock . resetCalls ( ) ;
247
- cfnClientSendMock . mock . resetCalls ( ) ;
228
+ ssmClientSendMock . mock . resetCalls ( ) ;
248
229
await sandboxInstance . stop ( ) ;
249
230
250
231
// Printer mocks are reset after the sandbox stop to reset the "Shutting down" call as well.
@@ -256,7 +237,7 @@ void describe('Sandbox using local project name resolver', () => {
256
237
( { sandboxInstance } = await setupAndStartSandbox (
257
238
{
258
239
executor : sandboxExecutor ,
259
- cfnClient : cfnClientMock ,
240
+ ssmClient : ssmClientMock ,
260
241
} ,
261
242
undefined ,
262
243
false
@@ -279,7 +260,7 @@ void describe('Sandbox using local project name resolver', () => {
279
260
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox (
280
261
{
281
262
executor : sandboxExecutor ,
282
- cfnClient : cfnClientMock ,
263
+ ssmClient : ssmClientMock ,
283
264
} ,
284
265
{
285
266
// imaginary dir does not have any ts files
@@ -309,7 +290,7 @@ void describe('Sandbox using local project name resolver', () => {
309
290
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox (
310
291
{
311
292
executor : sandboxExecutor ,
312
- cfnClient : cfnClientMock ,
293
+ ssmClient : ssmClientMock ,
313
294
} ,
314
295
{
315
296
dir : testDir ,
@@ -335,7 +316,7 @@ void describe('Sandbox using local project name resolver', () => {
335
316
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox (
336
317
{
337
318
executor : sandboxExecutor ,
338
- cfnClient : cfnClientMock ,
319
+ ssmClient : ssmClientMock ,
339
320
} ,
340
321
{
341
322
dir : 'testDir' ,
@@ -364,13 +345,13 @@ void describe('Sandbox using local project name resolver', () => {
364
345
validateAppSources : true ,
365
346
} ,
366
347
] ) ;
367
- assert . strictEqual ( cfnClientSendMock . mock . callCount ( ) , 0 ) ;
348
+ assert . strictEqual ( ssmClientSendMock . mock . callCount ( ) , 0 ) ;
368
349
} ) ;
369
350
370
351
void it ( 'calls watcher subscribe with the default "./amplify" if no `dir` specified' , async ( ) => {
371
352
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox ( {
372
353
executor : sandboxExecutor ,
373
- cfnClient : cfnClientMock ,
354
+ ssmClient : ssmClientMock ,
374
355
} ) ) ;
375
356
await fileChangeEventCallback ( null , [
376
357
{ type : 'update' , path : 'foo/test1.ts' } ,
@@ -383,7 +364,7 @@ void describe('Sandbox using local project name resolver', () => {
383
364
void it ( 'calls BackendDeployer only once when multiple file changes are present' , async ( ) => {
384
365
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox ( {
385
366
executor : sandboxExecutor ,
386
- cfnClient : cfnClientMock ,
367
+ ssmClient : ssmClientMock ,
387
368
} ) ) ;
388
369
await fileChangeEventCallback ( null , [
389
370
{ type : 'update' , path : 'foo/test2.ts' } ,
@@ -403,7 +384,7 @@ void describe('Sandbox using local project name resolver', () => {
403
384
void it ( 'skips type checking if no typescript change is detected' , async ( ) => {
404
385
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox ( {
405
386
executor : sandboxExecutor ,
406
- cfnClient : cfnClientMock ,
387
+ ssmClient : ssmClientMock ,
407
388
} ) ) ;
408
389
await fileChangeEventCallback ( null , [
409
390
{ type : 'update' , path : 'foo/test2.txt' } ,
@@ -423,7 +404,7 @@ void describe('Sandbox using local project name resolver', () => {
423
404
void it ( 'calls BackendDeployer once when multiple file changes are within few milliseconds (debounce)' , async ( ) => {
424
405
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox ( {
425
406
executor : sandboxExecutor ,
426
- cfnClient : cfnClientMock ,
407
+ ssmClient : ssmClientMock ,
427
408
} ) ) ;
428
409
// Not awaiting for this file event to be processed and submitting another one right away
429
410
const firstFileChange = fileChangeEventCallback ( null , [
@@ -449,7 +430,7 @@ void describe('Sandbox using local project name resolver', () => {
449
430
void it ( 'waits for file changes after completing a deployment and deploys again' , async ( ) => {
450
431
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox ( {
451
432
executor : sandboxExecutor ,
452
- cfnClient : cfnClientMock ,
433
+ ssmClient : ssmClientMock ,
453
434
} ) ) ;
454
435
await fileChangeEventCallback ( null , [
455
436
{ type : 'update' , path : 'foo/test5.ts' } ,
@@ -479,7 +460,7 @@ void describe('Sandbox using local project name resolver', () => {
479
460
void it ( 'queues deployment if a file change is detected during an ongoing deployment' , async ( ) => {
480
461
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox ( {
481
462
executor : sandboxExecutor ,
482
- cfnClient : cfnClientMock ,
463
+ ssmClient : ssmClientMock ,
483
464
} ) ) ;
484
465
// Mimic BackendDeployer taking 200 ms.
485
466
backendDeployerDeployMock . mock . mockImplementationOnce ( async ( ) => {
@@ -524,7 +505,7 @@ void describe('Sandbox using local project name resolver', () => {
524
505
void it ( 'calls BackendDeployer destroy when delete is called' , async ( ) => {
525
506
( { sandboxInstance } = await setupAndStartSandbox ( {
526
507
executor : sandboxExecutor ,
527
- cfnClient : cfnClientMock ,
508
+ ssmClient : ssmClientMock ,
528
509
} ) ) ;
529
510
await sandboxInstance . delete ( { } ) ;
530
511
@@ -541,7 +522,7 @@ void describe('Sandbox using local project name resolver', () => {
541
522
const mockListener = mock . fn ( ) ;
542
523
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox ( {
543
524
executor : sandboxExecutor ,
544
- cfnClient : cfnClientMock ,
525
+ ssmClient : ssmClientMock ,
545
526
} ) ) ;
546
527
sandboxInstance . on ( 'successfulDeployment' , mockListener ) ;
547
528
const contextualBackendDeployerMock = contextual . mock . method (
@@ -578,7 +559,7 @@ void describe('Sandbox using local project name resolver', () => {
578
559
void it ( 'handles UpdateNotSupported error while deploying and offers to reset sandbox and customer says yes' , async ( contextual ) => {
579
560
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox ( {
580
561
executor : sandboxExecutor ,
581
- cfnClient : cfnClientMock ,
562
+ ssmClient : ssmClientMock ,
582
563
} ) ) ;
583
564
const contextualBackendDeployerMock = contextual . mock . method (
584
565
backendDeployer ,
@@ -621,7 +602,7 @@ void describe('Sandbox using local project name resolver', () => {
621
602
void it ( 'handles UpdateNotSupported error while deploying and offers to reset sandbox and customer says no, continues running sandbox' , async ( contextual ) => {
622
603
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox ( {
623
604
executor : sandboxExecutor ,
624
- cfnClient : cfnClientMock ,
605
+ ssmClient : ssmClientMock ,
625
606
} ) ) ;
626
607
const contextualBackendDeployerMock = contextual . mock . method (
627
608
backendDeployer ,
@@ -669,7 +650,7 @@ void describe('Sandbox using local project name resolver', () => {
669
650
( { sandboxInstance } = await setupAndStartSandbox (
670
651
{
671
652
executor : sandboxExecutor ,
672
- cfnClient : cfnClientMock ,
653
+ ssmClient : ssmClientMock ,
673
654
} ,
674
655
{
675
656
dir : 'testDir' ,
@@ -694,7 +675,7 @@ void describe('Sandbox using local project name resolver', () => {
694
675
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox (
695
676
{
696
677
executor : sandboxExecutor ,
697
- cfnClient : cfnClientMock ,
678
+ ssmClient : ssmClientMock ,
698
679
} ,
699
680
{ identifier : 'customSandboxName' }
700
681
) ) ;
@@ -724,7 +705,7 @@ void describe('Sandbox using local project name resolver', () => {
724
705
( { sandboxInstance } = await setupAndStartSandbox (
725
706
{
726
707
executor : sandboxExecutor ,
727
- cfnClient : cfnClientMock ,
708
+ ssmClient : ssmClientMock ,
728
709
} ,
729
710
{ identifier : 'customSandboxName' }
730
711
) ) ;
@@ -759,7 +740,7 @@ void describe('Sandbox using local project name resolver', () => {
759
740
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox (
760
741
{
761
742
executor : sandboxExecutor ,
762
- cfnClient : cfnClientMock ,
743
+ ssmClient : ssmClientMock ,
763
744
} ,
764
745
{
765
746
exclude : [ 'customer_exclude1' , 'customer_exclude2' ] ,
@@ -804,7 +785,7 @@ void describe('Sandbox using local project name resolver', () => {
804
785
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox (
805
786
{
806
787
executor : sandboxExecutor ,
807
- cfnClient : cfnClientMock ,
788
+ ssmClient : ssmClientMock ,
808
789
} ,
809
790
{
810
791
exclude : [ 'customer_exclude1' , 'customer_exclude2' ] ,
@@ -836,7 +817,7 @@ void describe('Sandbox using local project name resolver', () => {
836
817
const mockListener = mock . fn ( ) ;
837
818
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox ( {
838
819
executor : sandboxExecutor ,
839
- cfnClient : cfnClientMock ,
820
+ ssmClient : ssmClientMock ,
840
821
} ) ) ;
841
822
842
823
sandboxInstance . on ( 'successfulDeployment' , mockListener ) ;
@@ -852,7 +833,7 @@ void describe('Sandbox using local project name resolver', () => {
852
833
const mockListener = mock . fn ( ) ;
853
834
( { sandboxInstance, fileChangeEventCallback } = await setupAndStartSandbox ( {
854
835
executor : sandboxExecutor ,
855
- cfnClient : cfnClientMock ,
836
+ ssmClient : ssmClientMock ,
856
837
} ) ) ;
857
838
858
839
sandboxInstance . on ( 'successfulDeletion' , mockListener ) ;
@@ -866,7 +847,7 @@ void describe('Sandbox using local project name resolver', () => {
866
847
await setupAndStartSandbox (
867
848
{
868
849
executor : sandboxExecutor ,
869
- cfnClient : cfnClientMock ,
850
+ ssmClient : ssmClientMock ,
870
851
} ,
871
852
{ watchForChanges : false }
872
853
) ;
@@ -894,7 +875,7 @@ const setupAndStartSandbox = async (
894
875
type : 'sandbox' ,
895
876
} ) ,
896
877
testData . executor ,
897
- testData . cfnClient ,
878
+ testData . ssmClient ,
898
879
printer as unknown as Printer ,
899
880
testData . open ?? _open
900
881
) ;
@@ -909,7 +890,7 @@ const setupAndStartSandbox = async (
909
890
// Reset all the calls to avoid extra startup call
910
891
backendDeployerDestroyMock . mock . resetCalls ( ) ;
911
892
backendDeployerDeployMock . mock . resetCalls ( ) ;
912
- cfnClientSendMock . mock . resetCalls ( ) ;
893
+ ssmClientSendMock . mock . resetCalls ( ) ;
913
894
listSecretMock . mock . resetCalls ( ) ;
914
895
}
915
896
@@ -946,6 +927,6 @@ type SandboxTestData = {
946
927
// To instantiate sandbox
947
928
sandboxName ?: string ;
948
929
executor : AmplifySandboxExecutor ;
949
- cfnClient : CloudFormationClient ;
930
+ ssmClient : SSMClient ;
950
931
open ?: typeof _open ;
951
932
} ;
0 commit comments