1+ import { S3 , S3Client } from "@aws-sdk/client-s3" ;
2+ import { TransferCompleteEvent , TransferEvent } from "@aws-sdk/lib-storage/dist-types/s3-transfer-manager/types" ;
13import { beforeAll , describe , expect , test as it , vi } from "vitest" ;
24
35import { S3TransferManager } from "./S3TransferManager" ;
@@ -13,11 +15,138 @@ import { S3TransferManager } from "./S3TransferManager";
1315 */
1416
1517describe ( "S3TransferManager Unit Tests" , ( ) => {
18+ let client : S3 ;
19+ let Bucket : string ;
20+ let region : string ;
21+
22+ beforeAll ( async ( ) => {
23+ region = "us-west-1" ;
24+ Bucket = "lukachad-us-west-2" ;
25+
26+ client = new S3 ( {
27+ region,
28+ responseChecksumValidation : "WHEN_REQUIRED" ,
29+ } ) ;
30+ } ) ;
31+ describe ( "S3TransferManager Constructor" , ( ) => {
32+ it ( "Should create an instance of S3TransferManager with defaults given no parameters" , ( ) => {
33+ const defaultS3Client = new S3Client ( {
34+ requestChecksumCalculation : "WHEN_SUPPORTED" ,
35+ responseChecksumValidation : "WHEN_SUPPORTED" ,
36+ } ) ;
37+ const tm = new S3TransferManager ( ) as any ;
38+
39+ expect ( tm . s3ClientInstance ) . toBeInstanceOf ( S3Client ) ;
40+ expect ( tm . targetPartSizeBytes ) . toBe ( 8 * 1024 * 1024 ) ;
41+ expect ( tm . multipartUploadThresholdBytes ) . toBe ( 16 * 1024 * 1024 ) ;
42+ expect ( tm . checksumValidationEnabled ) . toBe ( true ) ;
43+ expect ( tm . checksumAlgorithm ) . toBe ( "CRC32" ) ;
44+ expect ( tm . multipartDownloadType ) . toBe ( "PART" ) ;
45+ expect ( tm . eventListeners ) . toEqual ( {
46+ transferInitiated : [ ] ,
47+ bytesTransferred : [ ] ,
48+ transferComplete : [ ] ,
49+ transferFailed : [ ] ,
50+ } ) ;
51+ } ) ;
52+
53+ it ( "Should create an instance of S3TransferManager with all given parameters" , ( ) => {
54+ const eventListeners = {
55+ transferInitiated : [ ( ) => console . log ( "transferInitiated" ) ] ,
56+ bytesTransferred : [ ( ) => console . log ( "bytesTransferred" ) ] ,
57+ transferComplete : [ ( ) => console . log ( "transferComplete" ) ] ,
58+ transferFailed : [ ( ) => console . log ( "transferFailed" ) ] ,
59+ } ;
60+ const tm = new S3TransferManager ( {
61+ s3ClientInstance : client ,
62+ targetPartSizeBytes : 8 * 1024 * 1024 ,
63+ checksumValidationEnabled : true ,
64+ checksumAlgorithm : "CRC32" ,
65+ multipartDownloadType : "RANGE" ,
66+ eventListeners : eventListeners ,
67+ } ) as any ;
68+
69+ expect ( tm . s3ClientInstance ) . toBe ( client ) ;
70+ expect ( tm . targetPartSizeBytes ) . toBe ( 8 * 1024 * 1024 ) ;
71+ expect ( tm . checksumValidationEnabled ) . toBe ( true ) ;
72+ expect ( tm . checksumAlgorithm ) . toBe ( "CRC32" ) ;
73+ expect ( tm . multipartDownloadType ) . toBe ( "RANGE" ) ;
74+ expect ( tm . eventListeners ) . toEqual ( eventListeners ) ;
75+ } ) ;
76+
77+ it ( "Should throw an error given targetPartSizeBytes smaller than minimum" , ( ) => {
78+ expect ( ( ) => {
79+ new S3TransferManager ( {
80+ targetPartSizeBytes : 2 * 1024 * 1024 ,
81+ } ) ;
82+ } ) . toThrow ( `targetPartSizeBytes must be at least ${ 5 * 1024 * 1024 } bytes` ) ;
83+ } ) ;
84+ } ) ;
85+
86+ describe ( "EventListener functions" , ( ) => {
87+ let tm : S3TransferManager ;
88+
89+ function initiated ( event : TransferEvent ) {
90+ return {
91+ request : event . request ,
92+ snapshot : event . snapshot ,
93+ } ;
94+ }
95+ function transferring ( event : TransferEvent ) {
96+ return {
97+ request : event . request ,
98+ snapshot : event . snapshot ,
99+ } ;
100+ }
101+ function completed ( event : TransferCompleteEvent ) {
102+ return {
103+ request : event . request ,
104+ snapshot : event . snapshot ,
105+ response : event . response ,
106+ } ;
107+ }
108+ function failed ( event : TransferEvent ) {
109+ return {
110+ request : event . request ,
111+ snapshot : event . snapshot ,
112+ } ;
113+ }
114+
115+ beforeAll ( async ( ) => {
116+ tm = new S3TransferManager ( {
117+ s3ClientInstance : client ,
118+ } ) ;
119+ } ) ;
120+
121+ describe ( "addEventListener" , ( ) => {
122+ it ( "Should add a new listener for each callback" , ( ) => {
123+ tm . addEventListener ( "transferInitiated" , initiated ) ;
124+ tm . addEventListener ( "bytesTransferred" , transferring ) ;
125+ tm . addEventListener ( "transferComplete" , completed ) ;
126+ tm . addEventListener ( "transferFailed" , failed ) ;
127+
128+ expect ( ( tm as any ) . eventListeners ) . toEqual ( {
129+ transferInitiated : [ initiated ] ,
130+ bytesTransferred : [ transferring ] ,
131+ transferComplete : [ completed ] ,
132+ transferFailed : [ failed ] ,
133+ } ) ;
134+ } ) ;
135+
136+ it ( "Should append new listeners for a callback" ) ;
137+ } ) ;
138+
139+ describe . skip ( "dispatchEvent" ) , ( ) => { } ;
140+
141+ describe . skip ( "removeEventListener" ) , ( ) => { } ;
142+ } ) ;
143+
16144 describe ( "validateExpectedRanges()" , ( ) => {
17145 let tm : any ;
18146 beforeAll ( async ( ) => {
19147 tm = new S3TransferManager ( ) as any ;
20148 } , 120_000 ) ;
149+
21150 it ( "Should pass correct sequential ranges without throwing an error" , ( ) => {
22151 const ranges = [
23152 "bytes 0-5242879/13631488" ,
@@ -31,6 +160,7 @@ describe("S3TransferManager Unit Tests", () => {
31160 } ) . not . toThrow ( ) ;
32161 }
33162 } ) ;
163+
34164 it ( "Should throw error for incomplete download" , ( ) => {
35165 const ranges = [
36166 "bytes 0-5242879/13631488" ,
@@ -44,40 +174,15 @@ describe("S3TransferManager Unit Tests", () => {
44174 "Range validation failed: Final part did not cover total range of 13631488. Expected range of bytes 10485760-314572"
45175 ) ;
46176 } ) ;
47- it ( "Should throw error for non-sequential ranges" , ( ) => {
48- const previousRange = "bytes 0-5242879/13631488" ;
49- const invalidRange = "bytes 5242881-10485759/13631488" ; // 1 byte off
50177
178+ it . each ( [
179+ [ "bytes 5242881-10485759/13631488" , "Expected part 2 to start at 5242880 but got 5242881" ] , // 1 byte off
180+ [ "bytes 5242879-10485759/13631488" , "Expected part 2 to start at 5242880 but got 5242879" ] , // overlap
181+ [ "bytes 0-5242879/13631488" , "Expected part 2 to start at 5242880 but got 0" ] , // duplicate
182+ ] ) ( "Should throw error for non-sequential range: %s" , ( invalidRange , expectedError ) => {
51183 expect ( ( ) => {
52- tm . validateExpectedRanges ( previousRange , invalidRange , 2 ) ;
53- } ) . toThrow ( "Expected part 2 to start at 5242880 but got 5242881" ) ;
54- } ) ;
55- it ( "Should throw error for non-sequential ranges" , ( ) => {
56- const previousRange = "bytes 0-5242879/13631488" ;
57- const invalidRange = "bytes 5242879-10485759/13631488" ;
58-
59- expect ( ( ) => {
60- tm . validateExpectedRanges ( previousRange , invalidRange , 2 ) ;
61- } ) . toThrow ( "Expected part 2 to start at 5242880 but got 5242879" ) ;
62- } ) ;
63- it ( "Should throw error for non-sequential ranges" , ( ) => {
64- const previousRange = "bytes 0-5242879/13631488" ;
65- const invalidRange = "bytes 0-5242879/13631488" ;
66-
67- expect ( ( ) => {
68- tm . validateExpectedRanges ( previousRange , invalidRange , 2 ) ;
69- } ) . toThrow ( "Expected part 2 to start at 5242880 but got 0" ) ;
70- } ) ;
71- it ( "Should throw error for non-sequential ranges" , ( ) => {
72- const previousRange = "bytes 0-5242879/13631488" ;
73- const invalidRange = "bytes 0-5242879/13631488" ;
74-
75- expect ( ( ) => {
76- tm . validateExpectedRanges ( previousRange , invalidRange , 2 ) ;
77- } ) . toThrow ( "Expected part 2 to start at 5242880 but got 0" ) ;
184+ tm . validateExpectedRanges ( "bytes 0-5242879/13631488" , invalidRange , 2 ) ;
185+ } ) . toThrow ( expectedError ) ;
78186 } ) ;
79187 } ) ;
80- // describe("EventTarget functions tests", () => {
81-
82- // })
83188} ) ;
0 commit comments