@@ -40,6 +40,7 @@ describe('Individual Folder API Route', () => {
4040 }
4141
4242 const { mockAuthenticatedUser, mockUnauthenticated } = mockAuth ( TEST_USER )
43+ const mockGetUserEntityPermissions = vi . fn ( )
4344
4445 function createFolderDbMock ( options : FolderDbMockOptions = { } ) {
4546 const {
@@ -109,6 +110,12 @@ describe('Individual Folder API Route', () => {
109110 vi . resetModules ( )
110111 vi . clearAllMocks ( )
111112 setupCommonApiMocks ( )
113+
114+ mockGetUserEntityPermissions . mockResolvedValue ( 'admin' )
115+
116+ vi . doMock ( '@/lib/permissions/utils' , ( ) => ( {
117+ getUserEntityPermissions : mockGetUserEntityPermissions ,
118+ } ) )
112119 } )
113120
114121 afterEach ( ( ) => {
@@ -181,6 +188,72 @@ describe('Individual Folder API Route', () => {
181188 expect ( data ) . toHaveProperty ( 'error' , 'Unauthorized' )
182189 } )
183190
191+ it ( 'should return 403 when user has only read permissions' , async ( ) => {
192+ mockAuthenticatedUser ( )
193+ mockGetUserEntityPermissions . mockResolvedValue ( 'read' ) // Read-only permissions
194+
195+ const dbMock = createFolderDbMock ( )
196+ vi . doMock ( '@/db' , ( ) => dbMock )
197+
198+ const req = createMockRequest ( 'PUT' , {
199+ name : 'Updated Folder' ,
200+ } )
201+ const params = Promise . resolve ( { id : 'folder-1' } )
202+
203+ const { PUT } = await import ( './route' )
204+
205+ const response = await PUT ( req , { params } )
206+
207+ expect ( response . status ) . toBe ( 403 )
208+
209+ const data = await response . json ( )
210+ expect ( data ) . toHaveProperty ( 'error' , 'Write access required to update folders' )
211+ } )
212+
213+ it ( 'should allow folder update for write permissions' , async ( ) => {
214+ mockAuthenticatedUser ( )
215+ mockGetUserEntityPermissions . mockResolvedValue ( 'write' ) // Write permissions
216+
217+ const dbMock = createFolderDbMock ( )
218+ vi . doMock ( '@/db' , ( ) => dbMock )
219+
220+ const req = createMockRequest ( 'PUT' , {
221+ name : 'Updated Folder' ,
222+ } )
223+ const params = Promise . resolve ( { id : 'folder-1' } )
224+
225+ const { PUT } = await import ( './route' )
226+
227+ const response = await PUT ( req , { params } )
228+
229+ expect ( response . status ) . toBe ( 200 )
230+
231+ const data = await response . json ( )
232+ expect ( data ) . toHaveProperty ( 'folder' )
233+ } )
234+
235+ it ( 'should allow folder update for admin permissions' , async ( ) => {
236+ mockAuthenticatedUser ( )
237+ mockGetUserEntityPermissions . mockResolvedValue ( 'admin' ) // Admin permissions
238+
239+ const dbMock = createFolderDbMock ( )
240+ vi . doMock ( '@/db' , ( ) => dbMock )
241+
242+ const req = createMockRequest ( 'PUT' , {
243+ name : 'Updated Folder' ,
244+ } )
245+ const params = Promise . resolve ( { id : 'folder-1' } )
246+
247+ const { PUT } = await import ( './route' )
248+
249+ const response = await PUT ( req , { params } )
250+
251+ expect ( response . status ) . toBe ( 200 )
252+
253+ const data = await response . json ( )
254+ expect ( data ) . toHaveProperty ( 'folder' )
255+ } )
256+
184257 it ( 'should return 400 when trying to set folder as its own parent' , async ( ) => {
185258 mockAuthenticatedUser ( )
186259
@@ -387,6 +460,68 @@ describe('Individual Folder API Route', () => {
387460 expect ( data ) . toHaveProperty ( 'error' , 'Unauthorized' )
388461 } )
389462
463+ it ( 'should return 403 when user has only read permissions for delete' , async ( ) => {
464+ mockAuthenticatedUser ( )
465+ mockGetUserEntityPermissions . mockResolvedValue ( 'read' ) // Read-only permissions
466+
467+ const dbMock = createFolderDbMock ( )
468+ vi . doMock ( '@/db' , ( ) => dbMock )
469+
470+ const req = createMockRequest ( 'DELETE' )
471+ const params = Promise . resolve ( { id : 'folder-1' } )
472+
473+ const { DELETE } = await import ( './route' )
474+
475+ const response = await DELETE ( req , { params } )
476+
477+ expect ( response . status ) . toBe ( 403 )
478+
479+ const data = await response . json ( )
480+ expect ( data ) . toHaveProperty ( 'error' , 'Admin access required to delete folders' )
481+ } )
482+
483+ it ( 'should return 403 when user has only write permissions for delete' , async ( ) => {
484+ mockAuthenticatedUser ( )
485+ mockGetUserEntityPermissions . mockResolvedValue ( 'write' ) // Write permissions (not enough for delete)
486+
487+ const dbMock = createFolderDbMock ( )
488+ vi . doMock ( '@/db' , ( ) => dbMock )
489+
490+ const req = createMockRequest ( 'DELETE' )
491+ const params = Promise . resolve ( { id : 'folder-1' } )
492+
493+ const { DELETE } = await import ( './route' )
494+
495+ const response = await DELETE ( req , { params } )
496+
497+ expect ( response . status ) . toBe ( 403 )
498+
499+ const data = await response . json ( )
500+ expect ( data ) . toHaveProperty ( 'error' , 'Admin access required to delete folders' )
501+ } )
502+
503+ it ( 'should allow folder deletion for admin permissions' , async ( ) => {
504+ mockAuthenticatedUser ( )
505+ mockGetUserEntityPermissions . mockResolvedValue ( 'admin' ) // Admin permissions
506+
507+ const dbMock = createFolderDbMock ( {
508+ folderLookupResult : mockFolder ,
509+ } )
510+ vi . doMock ( '@/db' , ( ) => dbMock )
511+
512+ const req = createMockRequest ( 'DELETE' )
513+ const params = Promise . resolve ( { id : 'folder-1' } )
514+
515+ const { DELETE } = await import ( './route' )
516+
517+ const response = await DELETE ( req , { params } )
518+
519+ expect ( response . status ) . toBe ( 200 )
520+
521+ const data = await response . json ( )
522+ expect ( data ) . toHaveProperty ( 'success' , true )
523+ } )
524+
390525 it ( 'should handle database errors during deletion' , async ( ) => {
391526 mockAuthenticatedUser ( )
392527
0 commit comments