11const  assert  =  require ( 'assert' ) ; 
22const  async  =  require ( 'async' ) ; 
3+ const  { 
4+     ListObjectsCommand, 
5+     ListObjectVersionsCommand, 
6+     DeleteObjectsCommand, 
7+ }  =  require ( '@aws-sdk/client-s3' ) ; 
38
49function  _deleteVersionList ( s3Client ,  versionList ,  bucket ,  callback )  { 
510    if  ( versionList  ===  undefined  ||  versionList . length  ===  0 )  { 
611        return  callback ( ) ; 
712    } 
8-     const  params  =  {  Bucket : bucket ,  Delete : {  Objects : [ ]  }  } ; 
9-     versionList . forEach ( version  =>  { 
10-         params . Delete . Objects . push ( { 
11-             Key : version . Key ,  VersionId : version . VersionId  } ) ; 
12-     } ) ; 
13- 
14-     return  s3Client . deleteObjects ( params ,  callback ) ; 
13+     const  params  =  { 
14+         Bucket : bucket , 
15+         Delete : { 
16+             Objects : versionList . map ( version  =>  ( { 
17+                 Key : version . Key , 
18+                 VersionId : version . VersionId , 
19+             } ) ) , 
20+         } , 
21+     } ; 
22+     return  s3Client . send ( new  DeleteObjectsCommand ( params ) ) 
23+         . then ( ( )  =>  callback ( ) ) 
24+         . catch ( callback ) ; 
1525} 
1626
1727const  testUtils  =  { } ; 
@@ -21,62 +31,94 @@ testUtils.runIfMongo = process.env.S3METADATA === 'mongodb' ?
2131
2232testUtils . runAndCheckSearch  =  ( s3Client ,  bucketName ,  encodedSearch ,  listVersions , 
2333    testResult ,  done )  =>  { 
24-     let  searchRequest ; 
25-     if  ( listVersions )  { 
26-         searchRequest  =  s3Client . listObjectVersions ( {  Bucket : bucketName  } ) ; 
27-         searchRequest . on ( 'build' ,  ( )  =>  { 
28-             searchRequest . httpRequest . path  = 
29-                 `/${ bucketName } ${ encodedSearch }  ; 
30-         } ) ; 
31-         searchRequest . on ( 'success' ,  res  =>  { 
32-             if  ( testResult )  { 
33-                 assert . notStrictEqual ( res . data . Versions [ 0 ] . VersionId ,  undefined ) ; 
34-                 if  ( Array . isArray ( testResult ) )  { 
35-                     assert . strictEqual ( res . data . Versions . length ,  testResult . length ) ; 
36-                     async . forEachOf ( testResult ,  ( expected ,  i ,  next )  =>  { 
37-                         assert . strictEqual ( res . data . Versions [ i ] . Key ,  expected ) ; 
38-                         next ( ) ; 
39-                     } ) ; 
34+     const  makeRequest  =  async  ( )  =>  { 
35+         try  { 
36+             const  input  =  {  
37+                 Bucket : bucketName , 
38+             } ; 
39+             
40+             let  command ; 
41+             if  ( listVersions )  { 
42+                 command  =  new  ListObjectVersionsCommand ( input ) ; 
43+             }  else  { 
44+                 command  =  new  ListObjectsCommand ( input ) ; 
45+             } 
46+             
47+             // Add middleware to inject the search query parameter 
48+             // SDK v3 automatically encodes query parameters, so we decode first to avoid double-encoding 
49+             command . middlewareStack . add ( 
50+                 next  =>  async  args  =>  { 
51+                     if  ( ! args . request . query )  { 
52+                         // eslint-disable-next-line no-param-reassign 
53+                         args . request . query  =  { } ; 
54+                     } 
55+                     // Decode the already-encoded search string since SDK v3 will encode it again 
56+                     // eslint-disable-next-line no-param-reassign 
57+                     args . request . query . search  =  decodeURIComponent ( encodedSearch ) ; 
58+                     if  ( listVersions )  { 
59+                         // eslint-disable-next-line no-param-reassign 
60+                         args . request . query . versions  =  '' ; 
61+                     } 
62+                     
63+                     return  next ( args ) ; 
64+                 } , 
65+                 { 
66+                     step : 'build' , 
67+                     name : 'addSearchQuery' , 
68+                 } 
69+             ) ; 
70+             
71+             const  res  =  await  s3Client . send ( command ) ; 
72+             
73+             if  ( listVersions )  { 
74+                 if  ( testResult )  { 
75+                     assert . notStrictEqual ( res . Versions [ 0 ] . VersionId ,  undefined ) ; 
76+                     if  ( Array . isArray ( testResult ) )  { 
77+                         assert . strictEqual ( res . Versions . length ,  testResult . length ) ; 
78+                         async . forEachOf ( testResult ,  ( expected ,  i ,  next )  =>  { 
79+                             assert . strictEqual ( res . Versions [ i ] . Key ,  expected ) ; 
80+                             next ( ) ; 
81+                         } ,  done ) ; 
82+                         return ; 
83+                     }  else  { 
84+                         assert ( res . Versions [ 0 ] ,  'should be Contents listed' ) ; 
85+                         assert . strictEqual ( res . Versions [ 0 ] . Key ,  testResult ) ; 
86+                         assert . strictEqual ( res . Versions . length ,  1 ) ; 
87+                     } 
4088                }  else  { 
41-                     assert ( res . data . Versions [ 0 ] ,  'should be Contents listed' ) ; 
42-                     assert . strictEqual ( res . data . Versions [ 0 ] . Key ,  testResult ) ; 
43-                     assert . strictEqual ( res . data . Versions . length ,  1 ) ; 
89+                     assert . strictEqual ( res . Versions . length ,  0 ) ; 
4490                } 
4591            }  else  { 
46-                 assert . strictEqual ( res . data . Versions . length ,  0 ) ; 
92+                 if  ( testResult  &&  typeof  testResult  ===  'object'  &&  testResult . code )  { 
93+                     // This was expected to be an error, but we got success 
94+                     done ( new  Error ( 'Expected error but got success' ) ) ; 
95+                 } 
96+                 if  ( testResult )  { 
97+                     assert ( res . Contents [ 0 ] ,  'should be Contents listed' ) ; 
98+                     assert . strictEqual ( res . Contents [ 0 ] . Key ,  testResult ) ; 
99+                     assert . strictEqual ( res . Contents . length ,  1 ) ; 
100+                 }  else  { 
101+                     assert . strictEqual ( res . Contents ?. length ,  undefined ) ; 
102+                 } 
47103            } 
48-             return  done ( ) ; 
49-         } ) ; 
50-     }  else  { 
51-         searchRequest  =  s3Client . listObjects ( {  Bucket : bucketName  } ) ; 
52-         searchRequest . on ( 'build' ,  ( )  =>  { 
53-             searchRequest . httpRequest . path  = 
54-                 `/${ bucketName } ${ encodedSearch }  ; 
55-         } ) ; 
56-         searchRequest . on ( 'success' ,  res  =>  { 
57-             if  ( testResult )  { 
58-                 assert ( res . data . Contents [ 0 ] ,  'should be Contents listed' ) ; 
59-                 assert . strictEqual ( res . data . Contents [ 0 ] . Key ,  testResult ) ; 
60-                 assert . strictEqual ( res . data . Contents . length ,  1 ) ; 
61-             }  else  { 
62-                 assert . strictEqual ( res . data . Contents . length ,  0 ) ; 
104+             done ( ) ; 
105+         }  catch  ( err )  { 
106+             if  ( testResult  &&  typeof  testResult  ===  'object'  &&  testResult . code )  { 
107+                 assert . strictEqual ( err . name ,  testResult . code ) ; 
108+                 assert . strictEqual ( err . message ,  testResult . message ) ; 
109+                 done ( ) ; 
63110            } 
64-             return  done ( ) ; 
65-         } ) ; 
66-     } 
67-     searchRequest . on ( 'error' ,  err  =>  { 
68-         if  ( testResult )  { 
69-             assert . strictEqual ( err . code ,  testResult . code ) ; 
70-             assert . strictEqual ( err . message ,  testResult . message ) ; 
111+             done ( err ) ; 
71112        } 
72-         return  done ( ) ; 
73-     } ) ; 
74-     searchRequest . send ( ) ; 
113+     } ; 
114+     makeRequest ( ) ; 
75115} ; 
76116
77117testUtils . removeAllVersions  =  ( s3Client ,  bucket ,  callback )  =>  { 
78118    async . waterfall ( [ 
79-         cb  =>  s3Client . listObjectVersions ( {  Bucket : bucket  } ,  cb ) , 
119+         cb  =>  s3Client . send ( new  ListObjectVersionsCommand ( {  Bucket : bucket  } ) ) 
120+             . then ( data  =>  cb ( null ,  data ) ) 
121+             . catch ( cb ) , 
80122        ( data ,  cb )  =>  _deleteVersionList ( s3Client ,  data . DeleteMarkers ,  bucket , 
81123            err  =>  cb ( err ,  data ) ) , 
82124        ( data ,  cb )  =>  _deleteVersionList ( s3Client ,  data . Versions ,  bucket , 
@@ -88,7 +130,7 @@ testUtils.removeAllVersions = (s3Client, bucket, callback) => {
88130                    KeyMarker : data . NextKeyMarker , 
89131                    VersionIdMarker : data . NextVersionIdMarker , 
90132                } ; 
91-                 return  this . removeAllVersions ( params ,  cb ) ; 
133+                 return  testUtils . removeAllVersions ( s3Client ,   params ,  cb ) ; 
92134            } 
93135            return  cb ( ) ; 
94136        } , 
0 commit comments