@@ -126,83 +126,95 @@ Resources:`;
126126 ] ,
127127 } ) ;
128128
129- await new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ;
129+ // Wait for guard diagnostics after adding a resource type
130+ await WaitFor . waitFor ( ( ) => {
131+ const diags = client . receivedDiagnostics ;
132+ const latest = diags [ diags . length - 1 ] ;
133+ if ( latest ?. uri !== uri || latest . diagnostics . length === 0 ) {
134+ throw new Error ( 'No diagnostics received yet for typed resource' ) ;
135+ }
136+ } , 5000 ) ;
137+
138+ const latest = client . receivedDiagnostics [ client . receivedDiagnostics . length - 1 ] ;
139+ expect ( latest . uri ) . toBe ( uri ) ;
140+ expect ( latest . diagnostics . length ) . toBeGreaterThan ( 0 ) ;
130141
131- // Test validates incremental resource creation triggers diagnostics
132- expect ( uri ) . toBeDefined ( ) ;
142+ const guardDiags = latest . diagnostics . filter ( ( d : any ) => d . source === 'cfn-guard' ) ;
143+ expect ( guardDiags . length ) . toBeGreaterThan ( 0 ) ;
133144
134145 await client . closeDocument ( { textDocument : { uri } } ) ;
135146 } ) ;
136147
137- it ( 'should handle typing workflow for public access violations' , async ( ) => {
138- // Start with basic bucket
148+ it ( 'should receive diagnostics for public access violations' , async ( ) => {
149+ // Create bucket with public access explicitly disabled
139150 const template = `AWSTemplateFormatVersion: '2010-09-09'
140151Resources:
141152 MyBucket:
142153 Type: AWS::S3::Bucket
143154 Properties:
144- BucketName: public-bucket` ;
155+ BucketName: public-bucket
156+ PublicAccessBlockConfiguration:
157+ BlockPublicAcls: false
158+ BlockPublicPolicy: false
159+ IgnorePublicAcls: false
160+ RestrictPublicBuckets: false` ;
145161
146162 const uri = await client . openYamlTemplate ( template ) ;
147- await new Promise ( ( resolve ) => setTimeout ( resolve , 300 ) ) ;
148163
149- // Type PublicAccessBlockConfiguration incrementally
150- await client . changeDocument ( {
151- textDocument : { uri, version : 2 } ,
152- contentChanges : [
153- {
154- range : {
155- start : { line : 5 , character : 33 } ,
156- end : { line : 5 , character : 33 } ,
157- } ,
158- text : `
159- PublicAccessBlockConfiguration:` ,
160- } ,
161- ] ,
162- } ) ;
164+ // Wait for guard diagnostics about public access
165+ await WaitFor . waitFor ( ( ) => {
166+ const diags = client . receivedDiagnostics ;
167+ const latest = diags [ diags . length - 1 ] ;
168+ if ( latest ?. uri !== uri || latest . diagnostics . length === 0 ) {
169+ throw new Error ( 'No diagnostics received yet' ) ;
170+ }
171+ } , 5000 ) ;
163172
164- await new Promise ( ( resolve ) => setTimeout ( resolve , 200 ) ) ;
173+ const latest = client . receivedDiagnostics [ client . receivedDiagnostics . length - 1 ] ;
174+ expect ( latest . uri ) . toBe ( uri ) ;
165175
166- // Add BlockPublicAcls: false
167- await client . changeDocument ( {
168- textDocument : { uri, version : 3 } ,
169- contentChanges : [
170- {
171- range : {
172- start : { line : 6 , character : 34 } ,
173- end : { line : 6 , character : 34 } ,
174- } ,
175- text : `
176- BlockPublicAcls: false` ,
177- } ,
178- ] ,
179- } ) ;
176+ const guardDiags = latest . diagnostics . filter ( ( d : any ) => d . source === 'cfn-guard' ) ;
177+ expect ( guardDiags . length ) . toBeGreaterThan ( 0 ) ;
180178
181- await new Promise ( ( resolve ) => setTimeout ( resolve , 200 ) ) ;
179+ // Should flag the public access configuration
180+ const publicAccessDiag = guardDiags . find ( ( d : any ) => / P u b l i c A c c e s s B l o c k | p u b l i c / i. test ( d . message ) ) ;
181+ expect ( publicAccessDiag ) . toBeDefined ( ) ;
182182
183- // Add remaining properties incrementally
184- await client . changeDocument ( {
185- textDocument : { uri, version : 4 } ,
186- contentChanges : [
187- {
188- range : {
189- start : { line : 7 , character : 23 } ,
190- end : { line : 7 , character : 23 } ,
191- } ,
192- text : `
193- BlockPublicPolicy: false
194- IgnorePublicAcls: false
195- RestrictPublicBuckets: false` ,
196- } ,
197- ] ,
198- } ) ;
183+ await client . closeDocument ( { textDocument : { uri } } ) ;
184+ } ) ;
199185
200- await new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ;
186+ it ( 'should clear diagnostics when document is closed' , async ( ) => {
187+ const template = `AWSTemplateFormatVersion: '2010-09-09'
188+ Resources:
189+ MyBucket:
190+ Type: AWS::S3::Bucket` ;
201191
202- // Test validates incremental typing of public access configuration
203- expect ( uri ) . toBeDefined ( ) ;
192+ const uri = await client . openYamlTemplate ( template ) ;
204193
194+ // Wait for diagnostics to arrive
195+ await WaitFor . waitFor ( ( ) => {
196+ const latest = client . receivedDiagnostics [ client . receivedDiagnostics . length - 1 ] ;
197+ if ( latest ?. uri !== uri || latest . diagnostics . length === 0 ) {
198+ throw new Error ( 'No diagnostics received yet' ) ;
199+ }
200+ } , 5000 ) ;
201+
202+ // Close the document
205203 await client . closeDocument ( { textDocument : { uri } } ) ;
204+
205+ // Wait for empty diagnostics to be published for the closed URI
206+ await WaitFor . waitFor ( ( ) => {
207+ const clearEvent = client . receivedDiagnostics . find (
208+ ( d : any ) => d . uri === uri && d . diagnostics . length === 0 ,
209+ ) ;
210+ if ( ! clearEvent ) {
211+ throw new Error ( 'Diagnostics not cleared after close' ) ;
212+ }
213+ } , 5000 ) ;
214+
215+ const clearEvent = client . receivedDiagnostics . find ( ( d : any ) => d . uri === uri && d . diagnostics . length === 0 ) ;
216+ expect ( clearEvent ) . toBeDefined ( ) ;
217+ expect ( clearEvent . diagnostics ) . toHaveLength ( 0 ) ;
206218 } ) ;
207219 } ) ;
208220} ) ;
0 commit comments