@@ -12,16 +12,18 @@ import { CryptoService } from '../../../src/services/crypto.service';
1212import { DownloadService } from '../../../src/services/network/download.service' ;
1313import { UploadService } from '../../../src/services/network/upload.service' ;
1414import { AuthService } from '../../../src/services/auth.service' ;
15- import { NotFoundError , NotImplementedError } from '../../../src/utils/errors.utils' ;
15+ import { NotFoundError } from '../../../src/utils/errors.utils' ;
1616import { SdkManager } from '../../../src/services/sdk-manager.service' ;
1717import { NetworkFacade } from '../../../src/services/network/network-facade.service' ;
1818import { WebDavUtils } from '../../../src/utils/webdav.utils' ;
1919import { WebDavRequestedResource } from '../../../src/types/webdav.types' ;
2020import { newFileItem } from '../../fixtures/drive.fixture' ;
2121import { LoginCredentials } from '../../../src/types/command.types' ;
2222import { UserCredentialsFixture } from '../../fixtures/login.fixture' ;
23+ import { randomInt } from 'node:crypto' ;
24+ import { NetworkUtils } from '../../../src/utils/network.utils' ;
2325
24- describe . skip ( 'GET request handler' , ( ) => {
26+ describe ( 'GET request handler' , ( ) => {
2527 const getNetworkMock = ( ) => {
2628 return SdkManager . instance . getNetwork ( {
2729 user : 'user' ,
@@ -33,52 +35,63 @@ describe.skip('GET request handler', () => {
3335 vi . restoreAllMocks ( ) ;
3436 } ) ;
3537
36- it ( 'When the request contains a content-range header, then it should throw a NotImplementedError' , async ( ) => {
37- const networkFacade = new NetworkFacade (
38- getNetworkMock ( ) ,
39- UploadService . instance ,
40- DownloadService . instance ,
41- CryptoService . instance ,
42- ) ;
43- const sut = new GETRequestHandler ( {
38+ it ( 'When the Drive file is not found, then it should throw a NotFoundError' , async ( ) => {
39+ const driveDatabaseManager = getDriveDatabaseManager ( ) ;
40+ const downloadService = DownloadService . instance ;
41+ const uploadService = UploadService . instance ;
42+ const cryptoService = CryptoService . instance ;
43+ const networkFacade = new NetworkFacade ( getNetworkMock ( ) , uploadService , downloadService , cryptoService ) ;
44+ const requestHandler = new GETRequestHandler ( {
4445 driveFileService : DriveFileService . instance ,
45- downloadService : DownloadService . instance ,
46- driveDatabaseManager : getDriveDatabaseManager ( ) ,
46+ downloadService,
47+ driveDatabaseManager,
4748 authService : AuthService . instance ,
48- cryptoService : CryptoService . instance ,
49+ cryptoService,
4950 networkFacade,
5051 } ) ;
5152
53+ const requestedFileResource : WebDavRequestedResource = getRequestedFileResource ( ) ;
54+
5255 const request = createWebDavRequestFixture ( {
5356 method : 'GET' ,
54- url : '/file.txt' ,
55- headers : {
56- 'content-range' : 'bytes 0-100/200' ,
57- } ,
57+ url : requestedFileResource . url ,
58+ headers : { } ,
5859 } ) ;
5960 const response = createWebDavResponseFixture ( {
6061 status : vi . fn ( ) . mockReturnValue ( { send : vi . fn ( ) } ) ,
6162 } ) ;
6263
64+ const expectedError = new NotFoundError ( `Resource not found on Internxt Drive at ${ requestedFileResource . url } ` ) ;
65+
66+ const getRequestedResourceStub = vi
67+ . spyOn ( WebDavUtils , 'getRequestedResource' )
68+ . mockResolvedValue ( requestedFileResource ) ;
69+ const getAndSearchItemFromResourceStub = vi
70+ . spyOn ( WebDavUtils , 'getAndSearchItemFromResource' )
71+ . mockRejectedValue ( expectedError ) ;
72+
6373 try {
64- await sut . handle ( request , response ) ;
74+ await requestHandler . handle ( request , response ) ;
6575 fail ( 'Expected function to throw an error, but it did not.' ) ;
6676 } catch ( error ) {
67- expect ( error ) . to . be . instanceOf ( NotImplementedError ) ;
77+ expect ( error ) . to . be . instanceOf ( NotFoundError ) ;
6878 }
79+ expect ( getRequestedResourceStub ) . toHaveBeenCalledOnce ( ) ;
80+ expect ( getAndSearchItemFromResourceStub ) . toHaveBeenCalledOnce ( ) ;
6981 } ) ;
7082
71- it ( 'When the Drive file is not found , then it should throw a NotFoundError ' , async ( ) => {
83+ it ( 'When file is requested , then it should write a response with the content ' , async ( ) => {
7284 const driveDatabaseManager = getDriveDatabaseManager ( ) ;
7385 const downloadService = DownloadService . instance ;
7486 const uploadService = UploadService . instance ;
7587 const cryptoService = CryptoService . instance ;
88+ const authService = AuthService . instance ;
7689 const networkFacade = new NetworkFacade ( getNetworkMock ( ) , uploadService , downloadService , cryptoService ) ;
7790 const requestHandler = new GETRequestHandler ( {
7891 driveFileService : DriveFileService . instance ,
7992 downloadService,
8093 driveDatabaseManager,
81- authService : AuthService . instance ,
94+ authService,
8295 cryptoService,
8396 networkFacade,
8497 } ) ;
@@ -92,28 +105,41 @@ describe.skip('GET request handler', () => {
92105 } ) ;
93106 const response = createWebDavResponseFixture ( {
94107 status : vi . fn ( ) . mockReturnValue ( { send : vi . fn ( ) } ) ,
108+ header : vi . fn ( ) ,
95109 } ) ;
96110
97- const expectedError = new NotFoundError ( `Resource not found on Internxt Drive at ${ requestedFileResource . url } ` ) ;
111+ const mockFile = newFileItem ( ) ;
112+ const mockAuthDetails : LoginCredentials = UserCredentialsFixture ;
98113
99114 const getRequestedResourceStub = vi
100115 . spyOn ( WebDavUtils , 'getRequestedResource' )
101116 . mockResolvedValue ( requestedFileResource ) ;
102117 const getAndSearchItemFromResourceStub = vi
103118 . spyOn ( WebDavUtils , 'getAndSearchItemFromResource' )
104- . mockRejectedValue ( expectedError ) ;
119+ . mockResolvedValue ( mockFile ) ;
120+ const authDetailsStub = vi . spyOn ( authService , 'getAuthDetails' ) . mockResolvedValue ( mockAuthDetails ) ;
121+ const downloadStreamStub = vi
122+ . spyOn ( networkFacade , 'downloadToStream' )
123+ . mockResolvedValue ( [ Promise . resolve ( ) , new AbortController ( ) ] ) ;
105124
106- try {
107- await requestHandler . handle ( request , response ) ;
108- fail ( 'Expected function to throw an error, but it did not.' ) ;
109- } catch ( error ) {
110- expect ( error ) . to . be . instanceOf ( NotFoundError ) ;
111- }
125+ await requestHandler . handle ( request , response ) ;
126+
127+ expect ( response . status ) . toHaveBeenCalledWith ( 200 ) ;
128+ expect ( response . header ) . toHaveBeenCalledWith ( 'Content-length' , mockFile . size . toString ( ) ) ;
129+ expect ( response . header ) . toHaveBeenCalledWith ( 'Content-Type' , 'application/octet-stream' ) ;
112130 expect ( getRequestedResourceStub ) . toHaveBeenCalledOnce ( ) ;
113131 expect ( getAndSearchItemFromResourceStub ) . toHaveBeenCalledOnce ( ) ;
132+ expect ( authDetailsStub ) . toHaveBeenCalledOnce ( ) ;
133+ expect ( downloadStreamStub ) . toHaveBeenCalledWith (
134+ mockFile . bucket ,
135+ mockAuthDetails . user . mnemonic ,
136+ mockFile . fileId ,
137+ expect . any ( Object ) ,
138+ undefined ,
139+ ) ;
114140 } ) ;
115141
116- it ( 'When the Drive file is found , then it should write a response with the content' , async ( ) => {
142+ it ( 'When file is requested with Range , then it should write a response with the ranged content' , async ( ) => {
117143 const driveDatabaseManager = getDriveDatabaseManager ( ) ;
118144 const downloadService = DownloadService . instance ;
119145 const uploadService = UploadService . instance ;
@@ -131,16 +157,29 @@ describe.skip('GET request handler', () => {
131157
132158 const requestedFileResource : WebDavRequestedResource = getRequestedFileResource ( ) ;
133159
160+ const mockSize = randomInt ( 500 , 10000 ) ;
161+ const mockFile = newFileItem ( { size : mockSize } ) ;
162+ const rangeStart = randomInt ( 0 , 450 ) ;
163+
164+ const range = `bytes=${ rangeStart } -${ mockSize } ` ;
165+
166+ const expectedRangeOptions = NetworkUtils . parseRangeHeader ( {
167+ range,
168+ totalFileSize : mockFile . size ,
169+ } ) ;
170+
134171 const request = createWebDavRequestFixture ( {
135172 method : 'GET' ,
136173 url : requestedFileResource . url ,
137- headers : { } ,
174+ headers : {
175+ range,
176+ } ,
138177 } ) ;
139178 const response = createWebDavResponseFixture ( {
140179 status : vi . fn ( ) . mockReturnValue ( { send : vi . fn ( ) } ) ,
180+ header : vi . fn ( ) ,
141181 } ) ;
142182
143- const mockFile = newFileItem ( ) ;
144183 const mockAuthDetails : LoginCredentials = UserCredentialsFixture ;
145184
146185 const getRequestedResourceStub = vi
@@ -155,7 +194,10 @@ describe.skip('GET request handler', () => {
155194 . mockResolvedValue ( [ Promise . resolve ( ) , new AbortController ( ) ] ) ;
156195
157196 await requestHandler . handle ( request , response ) ;
197+
158198 expect ( response . status ) . toHaveBeenCalledWith ( 200 ) ;
199+ expect ( response . header ) . toHaveBeenCalledWith ( 'Content-length' , ( mockSize - rangeStart ) . toString ( ) ) ;
200+ expect ( response . header ) . toHaveBeenCalledWith ( 'Content-Type' , 'application/octet-stream' ) ;
159201 expect ( getRequestedResourceStub ) . toHaveBeenCalledOnce ( ) ;
160202 expect ( getAndSearchItemFromResourceStub ) . toHaveBeenCalledOnce ( ) ;
161203 expect ( authDetailsStub ) . toHaveBeenCalledOnce ( ) ;
@@ -164,7 +206,7 @@ describe.skip('GET request handler', () => {
164206 mockAuthDetails . user . mnemonic ,
165207 mockFile . fileId ,
166208 expect . any ( Object ) ,
167- expect . any ( Object ) ,
209+ expectedRangeOptions ,
168210 ) ;
169211 } ) ;
170212} ) ;
0 commit comments