1- /**
2- * Tests for file delete API route
3- *
4- * @vitest -environment node
5- */
61import { afterEach , beforeEach , describe , expect , it , vi } from 'vitest'
72import { createMockRequest } from '@/app/api/__test-utils__/utils'
83
94describe ( 'File Delete API Route' , ( ) => {
10- // Mock file system modules
115 const mockUnlink = vi . fn ( ) . mockResolvedValue ( undefined )
126 const mockExistsSync = vi . fn ( ) . mockReturnValue ( true )
13- const mockDeleteFromS3 = vi . fn ( ) . mockResolvedValue ( undefined )
14- const mockEnsureUploadsDirectory = vi . fn ( ) . mockResolvedValue ( true )
7+ const mockDeleteFile = vi . fn ( ) . mockResolvedValue ( undefined )
8+ const mockIsUsingCloudStorage = vi . fn ( ) . mockReturnValue ( false )
159
1610 beforeEach ( ( ) => {
1711 vi . resetModules ( )
1812
19- // Mock filesystem operations
2013 vi . doMock ( 'fs' , ( ) => ( {
2114 existsSync : mockExistsSync ,
2215 } ) )
@@ -25,12 +18,11 @@ describe('File Delete API Route', () => {
2518 unlink : mockUnlink ,
2619 } ) )
2720
28- // Mock the S3 client
29- vi . doMock ( '@/lib/uploads/s3-client' , ( ) => ( {
30- deleteFromS3 : mockDeleteFromS3 ,
21+ vi . doMock ( '@/lib/uploads' , ( ) => ( {
22+ deleteFile : mockDeleteFile ,
23+ isUsingCloudStorage : mockIsUsingCloudStorage ,
3124 } ) )
3225
33- // Mock the logger
3426 vi . doMock ( '@/lib/logs/console-logger' , ( ) => ( {
3527 createLogger : vi . fn ( ) . mockReturnValue ( {
3628 info : vi . fn ( ) ,
@@ -40,18 +32,12 @@ describe('File Delete API Route', () => {
4032 } ) ,
4133 } ) )
4234
43- // Configure upload directory and S3 mode with all required exports
4435 vi . doMock ( '@/lib/uploads/setup' , ( ) => ( {
4536 UPLOAD_DIR : '/test/uploads' ,
4637 USE_S3_STORAGE : false ,
47- ensureUploadsDirectory : mockEnsureUploadsDirectory ,
48- S3_CONFIG : {
49- bucket : 'test-bucket' ,
50- region : 'test-region' ,
51- } ,
38+ USE_BLOB_STORAGE : false ,
5239 } ) )
5340
54- // Skip setup.server.ts side effects
5541 vi . doMock ( '@/lib/uploads/setup.server' , ( ) => ( { } ) )
5642 } )
5743
@@ -60,111 +46,114 @@ describe('File Delete API Route', () => {
6046 } )
6147
6248 it ( 'should handle local file deletion successfully' , async ( ) => {
63- // Configure upload directory and S3 mode for this test
6449 vi . doMock ( '@/lib/uploads/setup' , ( ) => ( {
6550 UPLOAD_DIR : '/test/uploads' ,
6651 USE_S3_STORAGE : false ,
6752 } ) )
6853
69- // Create request with file path
7054 const req = createMockRequest ( 'POST' , {
7155 filePath : '/api/files/serve/test-file.txt' ,
7256 } )
7357
74- // Import the handler after mocks are set up
7558 const { POST } = await import ( './route' )
7659
77- // Call the handler
7860 const response = await POST ( req )
7961 const data = await response . json ( )
8062
81- // Verify response
8263 expect ( response . status ) . toBe ( 200 )
8364 expect ( data ) . toHaveProperty ( 'success' , true )
8465 expect ( data ) . toHaveProperty ( 'message' , 'File deleted successfully' )
8566
86- // Verify unlink was called with correct path
8767 expect ( mockUnlink ) . toHaveBeenCalledWith ( '/test/uploads/test-file.txt' )
8868 } )
8969
9070 it ( 'should handle file not found gracefully' , async ( ) => {
91- // Mock file not existing
9271 mockExistsSync . mockReturnValueOnce ( false )
9372
94- // Create request with file path
9573 const req = createMockRequest ( 'POST' , {
9674 filePath : '/api/files/serve/nonexistent.txt' ,
9775 } )
9876
99- // Import the handler after mocks are set up
10077 const { POST } = await import ( './route' )
10178
102- // Call the handler
10379 const response = await POST ( req )
10480 const data = await response . json ( )
10581
106- // Verify response
10782 expect ( response . status ) . toBe ( 200 )
10883 expect ( data ) . toHaveProperty ( 'success' , true )
10984 expect ( data ) . toHaveProperty ( 'message' , "File not found, but that's okay" )
11085
111- // Verify unlink was not called
11286 expect ( mockUnlink ) . not . toHaveBeenCalled ( )
11387 } )
11488
11589 it ( 'should handle S3 file deletion successfully' , async ( ) => {
116- // Configure upload directory and S3 mode for this test
11790 vi . doMock ( '@/lib/uploads/setup' , ( ) => ( {
11891 UPLOAD_DIR : '/test/uploads' ,
11992 USE_S3_STORAGE : true ,
93+ USE_BLOB_STORAGE : false ,
12094 } ) )
12195
122- // Create request with S3 file path
96+ mockIsUsingCloudStorage . mockReturnValue ( true )
97+
12398 const req = createMockRequest ( 'POST' , {
12499 filePath : '/api/files/serve/s3/1234567890-test-file.txt' ,
125100 } )
126101
127- // Import the handler after mocks are set up
128102 const { POST } = await import ( './route' )
129103
130- // Call the handler
131104 const response = await POST ( req )
132105 const data = await response . json ( )
133106
134- // Verify response
135107 expect ( response . status ) . toBe ( 200 )
136108 expect ( data ) . toHaveProperty ( 'success' , true )
137- expect ( data ) . toHaveProperty ( 'message' , 'File deleted successfully from S3' )
109+ expect ( data ) . toHaveProperty ( 'message' , 'File deleted successfully from cloud storage' )
110+
111+ expect ( mockDeleteFile ) . toHaveBeenCalledWith ( '1234567890-test-file.txt' )
112+ } )
113+
114+ it ( 'should handle Azure Blob file deletion successfully' , async ( ) => {
115+ vi . doMock ( '@/lib/uploads/setup' , ( ) => ( {
116+ UPLOAD_DIR : '/test/uploads' ,
117+ USE_S3_STORAGE : false ,
118+ USE_BLOB_STORAGE : true ,
119+ } ) )
120+
121+ mockIsUsingCloudStorage . mockReturnValue ( true )
122+
123+ const req = createMockRequest ( 'POST' , {
124+ filePath : '/api/files/serve/blob/1234567890-test-document.pdf' ,
125+ } )
126+
127+ const { POST } = await import ( './route' )
128+
129+ const response = await POST ( req )
130+ const data = await response . json ( )
131+
132+ expect ( response . status ) . toBe ( 200 )
133+ expect ( data ) . toHaveProperty ( 'success' , true )
134+ expect ( data ) . toHaveProperty ( 'message' , 'File deleted successfully from cloud storage' )
138135
139- // Verify deleteFromS3 was called with correct key
140- expect ( mockDeleteFromS3 ) . toHaveBeenCalledWith ( '1234567890-test-file.txt' )
136+ expect ( mockDeleteFile ) . toHaveBeenCalledWith ( '1234567890-test-document.pdf' )
141137 } )
142138
143139 it ( 'should handle missing file path' , async ( ) => {
144- // Create request with no file path
145140 const req = createMockRequest ( 'POST' , { } )
146141
147- // Import the handler after mocks are set up
148142 const { POST } = await import ( './route' )
149143
150- // Call the handler
151144 const response = await POST ( req )
152145 const data = await response . json ( )
153146
154- // Verify error response
155147 expect ( response . status ) . toBe ( 400 )
156148 expect ( data ) . toHaveProperty ( 'error' , 'InvalidRequestError' )
157149 expect ( data ) . toHaveProperty ( 'message' , 'No file path provided' )
158150 } )
159151
160152 it ( 'should handle CORS preflight requests' , async ( ) => {
161- // Import the handler after mocks are set up
162153 const { OPTIONS } = await import ( './route' )
163154
164- // Call the handler
165155 const response = await OPTIONS ( )
166156
167- // Verify response
168157 expect ( response . status ) . toBe ( 204 )
169158 expect ( response . headers . get ( 'Access-Control-Allow-Methods' ) ) . toBe ( 'GET, POST, DELETE, OPTIONS' )
170159 expect ( response . headers . get ( 'Access-Control-Allow-Headers' ) ) . toBe ( 'Content-Type' )
0 commit comments