@@ -130,6 +130,13 @@ describe("Destructive Command Guard manager", () => {
130130
131131 it ( "allows trusted relative redirects and rejects unsafe or exhausted redirects" , ( ) => {
132132 expect ( resolveTrustedRedirect ( "https://github.com/release" , "/asset" , 5 ) ) . toBe ( "https://github.com/asset" )
133+ expect (
134+ resolveTrustedRedirect (
135+ "https://github.com/release" ,
136+ "https://release-assets.githubusercontent.com/asset" ,
137+ 5 ,
138+ ) ,
139+ ) . toBe ( "https://release-assets.githubusercontent.com/asset" )
133140 expect ( ( ) => resolveTrustedRedirect ( "https://github.com/release" , "https://example.com/asset" , 5 ) ) . toThrow (
134141 "DCG download redirected to an untrusted host" ,
135142 )
@@ -322,56 +329,59 @@ describe("Destructive Command Guard manager", () => {
322329 }
323330 } )
324331
325- it ( "downloads, verifies, extracts, and installs a ZIP archive" , async ( ) => {
326- const info = getDcgArchiveInfo ( )
327- if ( ! info ?. archive . endsWith ( ".zip" ) ) return
328-
329- const archive = Buffer . from ( "test ZIP archive" )
330- const originalChecksum = info . sha256
331- Object . defineProperty ( info , "sha256" , {
332- value : createHash ( "sha256" ) . update ( archive ) . digest ( "hex" ) ,
333- configurable : true ,
334- } )
335- const response = Object . assign ( new PassThrough ( ) , {
336- statusCode : 200 ,
337- headers : { "content-length" : String ( archive . length ) } ,
338- } )
339- const request = Object . assign ( new EventEmitter ( ) , { setTimeout : vi . fn ( ) , destroy : vi . fn ( ) } )
340- mockGet . mockImplementation ( ( _url , optionsOrCallback , optionalCallback ) => {
341- const callback = typeof optionsOrCallback === "function" ? optionsOrCallback : optionalCallback
342- setImmediate ( ( ) => {
343- callback ?.( response as unknown as IncomingMessage )
344- response . end ( archive )
332+ it . skipIf ( ! getDcgArchiveInfo ( ) ?. archive . endsWith ( ".zip" ) ) (
333+ "downloads, verifies, extracts, and installs a ZIP archive" ,
334+ async ( ) => {
335+ const info = getDcgArchiveInfo ( )
336+ if ( ! info ) throw new Error ( "Expected a ZIP archive in this test" )
337+
338+ const archive = Buffer . from ( "test ZIP archive" )
339+ const originalChecksum = info . sha256
340+ Object . defineProperty ( info , "sha256" , {
341+ value : createHash ( "sha256" ) . update ( archive ) . digest ( "hex" ) ,
342+ configurable : true ,
345343 } )
346- return request as unknown as ReturnType < typeof get >
347- } )
348- mockSpawn . mockImplementation ( ( _executable , args ) => {
349- const child = Object . assign ( new EventEmitter ( ) , {
350- stdout : new PassThrough ( ) ,
351- stderr : new PassThrough ( ) ,
352- kill : vi . fn ( ) ,
344+ const response = Object . assign ( new PassThrough ( ) , {
345+ statusCode : 200 ,
346+ headers : { "content-length" : String ( archive . length ) } ,
353347 } )
354- setImmediate ( async ( ) => {
355- const destinationIndex = args . indexOf (
356- "$archivePath = $args[0]; $destination = $args[1]; Expand-Archive -LiteralPath $archivePath -DestinationPath $destination -Force" ,
357- )
358- const stagingDir = args [ destinationIndex + 2 ]
359- await writeFile ( path . join ( stagingDir , info . binary ) , "ZIP executable" )
360- child . emit ( "close" , 0 )
348+ const request = Object . assign ( new EventEmitter ( ) , { setTimeout : vi . fn ( ) , destroy : vi . fn ( ) } )
349+ mockGet . mockImplementation ( ( _url , optionsOrCallback , optionalCallback ) => {
350+ const callback = typeof optionsOrCallback === "function" ? optionsOrCallback : optionalCallback
351+ setImmediate ( ( ) => {
352+ callback ?.( response as unknown as IncomingMessage )
353+ response . end ( archive )
354+ } )
355+ return request as unknown as ReturnType < typeof get >
356+ } )
357+ mockSpawn . mockImplementation ( ( _executable , args ) => {
358+ const child = Object . assign ( new EventEmitter ( ) , {
359+ stdout : new PassThrough ( ) ,
360+ stderr : new PassThrough ( ) ,
361+ kill : vi . fn ( ) ,
362+ } )
363+ setImmediate ( async ( ) => {
364+ const destinationIndex = args . indexOf (
365+ "$archivePath = $args[0]; $destination = $args[1]; Expand-Archive -LiteralPath $archivePath -DestinationPath $destination -Force" ,
366+ )
367+ const stagingDir = args [ destinationIndex + 2 ]
368+ await writeFile ( path . join ( stagingDir , info . binary ) , "ZIP executable" )
369+ child . emit ( "close" , 0 )
370+ } )
371+ return child as unknown as ReturnType < typeof spawn >
361372 } )
362- return child as unknown as ReturnType < typeof spawn >
363- } )
364373
365- try {
366- const binaryPath = await ensureDcgInstalled ( tempDir )
367- if ( ! binaryPath ) throw new Error ( "Expected DCG to be supported in this test" )
368- expect ( await readFile ( binaryPath , "utf8" ) ) . toBe ( "ZIP executable" )
369- expect ( await readFile ( path . join ( tempDir , "destructive-command-guard" , ".dcg-version" ) , "utf8" ) ) . toBe (
370- DCG_VERSION ,
371- )
372- await expect ( access ( path . join ( tempDir , `${ DCG_VERSION } -${ info . archive } ` ) ) ) . rejects . toThrow ( )
373- } finally {
374- Object . defineProperty ( info , "sha256" , { value : originalChecksum , configurable : true } )
375- }
376- } )
374+ try {
375+ const binaryPath = await ensureDcgInstalled ( tempDir )
376+ if ( ! binaryPath ) throw new Error ( "Expected DCG to be supported in this test" )
377+ expect ( await readFile ( binaryPath , "utf8" ) ) . toBe ( "ZIP executable" )
378+ expect ( await readFile ( path . join ( tempDir , "destructive-command-guard" , ".dcg-version" ) , "utf8" ) ) . toBe (
379+ DCG_VERSION ,
380+ )
381+ await expect ( access ( path . join ( tempDir , `${ DCG_VERSION } -${ info . archive } ` ) ) ) . rejects . toThrow ( )
382+ } finally {
383+ Object . defineProperty ( info , "sha256" , { value : originalChecksum , configurable : true } )
384+ }
385+ } ,
386+ )
377387} )
0 commit comments