11import { NotFound } from '@aws-sdk/client-s3' ;
22import assert from 'assert' ;
3- import { eq , inArray } from 'drizzle-orm' ;
3+ import { and , eq , inArray } from 'drizzle-orm' ;
44import FormData from 'form-data' ;
55import fs from 'fs' ;
66import { ReasonPhrases , StatusCodes } from 'http-status-codes' ;
@@ -25,8 +25,8 @@ import build, {
2525import { MULTIPLE_ITEMS_LOADING_TIME } from '../../../../../test/constants' ;
2626import { buildFile , seedFromJson } from '../../../../../test/mocks/seed' ;
2727import { db } from '../../../../drizzle/db' ;
28+ import { isDirectChild } from '../../../../drizzle/operations' ;
2829import { itemMembershipsTable , itemsRawTable } from '../../../../drizzle/schema' ;
29- import { type ItemRaw } from '../../../../drizzle/types' ;
3030import { assertIsDefined } from '../../../../utils/assertions' ;
3131import { ITEMS_ROUTE_PREFIX } from '../../../../utils/config' ;
3232import { MemberCannotAccess , MemberCannotWriteItem } from '../../../../utils/errors' ;
@@ -38,7 +38,7 @@ import {
3838 UploadFileUnexpectedError ,
3939} from '../../../file/utils/errors' ;
4040import { ThumbnailSizeFormat } from '../../../thumbnail/constants' ;
41- import { expectItem , expectManyItems } from '../../test/fixtures/items' ;
41+ import { expectItem } from '../../test/fixtures/items' ;
4242import { DEFAULT_MAX_STORAGE } from './utils/constants' ;
4343import { StorageExceeded } from './utils/errors' ;
4444
@@ -91,6 +91,18 @@ const createFormData = (form = new FormData(), filepath: string = './test/fixtur
9191 return form ;
9292} ;
9393
94+ const getItemsForActorId = async ( actorId : string , parentPath ?: string ) => {
95+ const conditions = [ eq ( itemsRawTable . creatorId , actorId ) ] ;
96+
97+ if ( parentPath ) {
98+ conditions . push ( isDirectChild ( itemsRawTable . path , parentPath ) ) ;
99+ }
100+
101+ return await db . query . itemsRawTable . findMany ( {
102+ where : and ( ...conditions ) ,
103+ } ) ;
104+ } ;
105+
94106describe ( 'File Item routes tests' , ( ) => {
95107 let app : FastifyInstance ;
96108
@@ -137,12 +149,10 @@ describe('File Item routes tests', () => {
137149 headers : form . getHeaders ( ) ,
138150 } ) ;
139151 // check response value
140- const [ newItem ] = Object . values ( response . json ( ) . data ) as ItemRaw [ ] ;
141- expect ( response . statusCode ) . toBe ( StatusCodes . OK ) ;
152+ expect ( response . statusCode ) . toBe ( StatusCodes . NO_CONTENT ) ;
142153
143154 // check item exists in db
144- const item = await getItemById ( newItem . id ) ;
145- expect ( item ) . toBeDefined ( ) ;
155+ const [ item ] = await getItemsForActorId ( actor . id ) ;
146156
147157 // s3 upload function: We expect on image AND the thumbnails
148158 expect ( uploadDoneMock ) . toHaveBeenCalledTimes (
@@ -154,7 +164,7 @@ describe('File Item routes tests', () => {
154164 expect ( item ?. extra [ ItemType . FILE ] ) . toBeTruthy ( ) ;
155165
156166 // a membership is created for this item
157- const membership = await getItemMembershipByPath ( newItem . path ) ;
167+ const membership = await getItemMembershipByPath ( item . path ) ;
158168 expect ( membership ?. permission ) . toEqual ( PermissionLevel . Admin ) ;
159169 } ) ;
160170
@@ -172,12 +182,10 @@ describe('File Item routes tests', () => {
172182 headers : form . getHeaders ( ) ,
173183 } ) ;
174184 // check response value
175- const [ newItem ] = Object . values ( response . json ( ) . data ) as ItemRaw [ ] ;
176- expect ( response . statusCode ) . toBe ( StatusCodes . OK ) ;
185+ expect ( response . statusCode ) . toBe ( StatusCodes . NO_CONTENT ) ;
177186
178187 // check item exists in db
179- const item = await getItemById ( newItem . id ) ;
180- expectItem ( item , newItem ) ;
188+ const [ item ] = await getItemsForActorId ( actor . id ) ;
181189
182190 // s3 upload function: We expect on pdf and the thumbnails
183191 expect ( uploadDoneMock ) . toHaveBeenCalledTimes (
@@ -202,17 +210,11 @@ describe('File Item routes tests', () => {
202210 } ) ;
203211
204212 // check response value
205- const items = Object . values ( response . json ( ) . data ) as ItemRaw [ ] ;
206- expect ( response . statusCode ) . toBe ( StatusCodes . OK ) ;
213+ expect ( response . statusCode ) . toBe ( StatusCodes . NO_CONTENT ) ;
207214
208- // check item exists in db
209- const newItems = await db . query . itemsRawTable . findMany ( {
210- where : inArray (
211- itemsRawTable . id ,
212- items . map ( ( { id } ) => id ) ,
213- ) ,
214- } ) ;
215- expectManyItems ( items , newItems ) ;
215+ // check items exist in db
216+ const newItems = await getItemsForActorId ( actor . id ) ;
217+ expect ( newItems ) . toHaveLength ( 2 ) ;
216218
217219 // s3 upload function: We expect on image AND the thumbnails
218220 expect ( uploadDoneMock ) . toHaveBeenCalledTimes (
@@ -228,7 +230,7 @@ describe('File Item routes tests', () => {
228230 const memberships = await db . query . itemMembershipsTable . findMany ( {
229231 where : inArray (
230232 itemMembershipsTable . itemPath ,
231- items . map ( ( { path } ) => path ) ,
233+ newItems . map ( ( { path } ) => path ) ,
232234 ) ,
233235 } ) ;
234236 for ( const m of memberships ) {
@@ -255,12 +257,10 @@ describe('File Item routes tests', () => {
255257 } ) ;
256258
257259 // check response value
258- const [ newItem ] = Object . values ( response . json ( ) . data ) as ItemRaw [ ] ;
259- expect ( response . statusCode ) . toBe ( StatusCodes . OK ) ;
260+ expect ( response . statusCode ) . toBe ( StatusCodes . NO_CONTENT ) ;
260261
261262 // check item exists in db
262- const item = await getItemById ( newItem . id ) ;
263- expectItem ( item , newItem ) ;
263+ const [ newItem ] = await getItemsForActorId ( actor . id , parentItem . path ) ;
264264
265265 // s3 upload function: We expect on image AND the thumbnails
266266 expect ( uploadDoneMock ) . toHaveBeenCalledTimes (
@@ -269,8 +269,8 @@ describe('File Item routes tests', () => {
269269
270270 // check file properties
271271 // TODO: more precise check
272- expect ( item ?. extra [ ItemType . FILE ] ) . toBeTruthy ( ) ;
273- expect ( item ?. path ) . toContain ( parentItem . path ) ;
272+ expect ( newItem ?. extra [ ItemType . FILE ] ) . toBeTruthy ( ) ;
273+ expect ( newItem ?. path ) . toContain ( parentItem . path ) ;
274274
275275 // a membership is not created for new item because it inherits parent
276276 const membership = await db . query . itemMembershipsTable . findFirst ( {
@@ -298,9 +298,9 @@ describe('File Item routes tests', () => {
298298 } ) ;
299299
300300 // check the response value
301- expect ( response . statusCode ) . toBe ( StatusCodes . OK ) ;
302- const newItems = Object . values ( response . json ( ) . data ) as ItemRaw [ ] ;
303- expect ( newItems . length ) . toBe ( 2 ) ;
301+ expect ( response . statusCode ) . toBe ( StatusCodes . NO_CONTENT ) ;
302+ const newItems = await getItemsForActorId ( actor . id ) ;
303+ expect ( newItems ) . toHaveLength ( 2 ) ;
304304
305305 // check that both items exist in db and that their types are correctly interpreted
306306 const imageItem = await getItemById ( newItems [ 0 ] . id ) ;
@@ -352,7 +352,7 @@ describe('File Item routes tests', () => {
352352 headers : form . getHeaders ( ) ,
353353 } ) ;
354354
355- expect ( response . json ( ) . errors [ 0 ] ) . toMatchObject ( new StorageExceeded ( expect . anything ( ) ) ) ;
355+ expect ( response . json ( ) ) . toMatchObject ( new StorageExceeded ( expect . anything ( ) ) ) ;
356356 } ) ;
357357
358358 it ( 'Cannot upload empty file' , async ( ) => {
@@ -374,7 +374,7 @@ describe('File Item routes tests', () => {
374374 headers : form . getHeaders ( ) ,
375375 } ) ;
376376
377- expect ( response . json ( ) . errors [ 0 ] . message ) . toEqual ( new UploadEmptyFileError ( ) . message ) ;
377+ expect ( response . json ( ) . message ) . toEqual ( new UploadEmptyFileError ( ) . message ) ;
378378 expect ( deleteObjectsMock ) . toHaveBeenCalled ( ) ;
379379 } ) ;
380380 } ) ;
@@ -404,26 +404,24 @@ describe('File Item routes tests', () => {
404404 headers : form1 . getHeaders ( ) ,
405405 } ) ;
406406
407- expect ( response . statusCode ) . toEqual ( StatusCodes . OK ) ;
407+ expect ( response . statusCode ) . not . toBe ( StatusCodes . NO_CONTENT ) ;
408+
409+ // one empty file error
410+ expect ( response . json ( ) . message ) . toEqual ( new UploadEmptyFileError ( ) . message ) ;
411+
408412 // upload 2 files and one set of thumbnails
409413 expect ( uploadDoneMock ) . toHaveBeenCalledTimes (
410414 Object . values ( ThumbnailSizeFormat ) . length + 2 ,
411415 ) ;
412416 expect ( deleteObjectsMock ) . toHaveBeenCalledTimes ( 1 ) ;
413417
414- // one empty file error
415- expect ( response . json ( ) . errors [ 0 ] . message ) . toEqual ( new UploadEmptyFileError ( ) . message ) ;
416-
417418 // one file has been uploaded
418- const uploadedItems = Object . values < ItemRaw > ( response . json ( ) . data ) ;
419+ const uploadedItems = await getItemsForActorId ( actor . id ) ;
419420 expect ( uploadedItems ) . toHaveLength ( 1 ) ;
420421
421- // check item exists in db
422- const item = await getItemById ( uploadedItems [ 0 ] . id ) ;
423- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
424- expect ( item ! . type ) . toEqual ( ItemType . FILE ) ;
422+ expect ( uploadedItems [ 0 ] . type ) . toEqual ( ItemType . FILE ) ;
425423 } ) ;
426- it ( 'Gracefully fails if s3 upload throws' , async ( ) => {
424+ it ( 'Throws if s3 upload throws' , async ( ) => {
427425 uploadDoneMock . mockImplementation ( ( ) => {
428426 throw new Error ( 'putObject throws' ) ;
429427 } ) ;
@@ -440,9 +438,7 @@ describe('File Item routes tests', () => {
440438 headers : form . getHeaders ( ) ,
441439 } ) ;
442440
443- expect ( response . json ( ) . errors [ 0 ] ) . toMatchObject (
444- new UploadFileUnexpectedError ( expect . anything ( ) ) ,
445- ) ;
441+ expect ( response . json ( ) ) . toMatchObject ( new UploadFileUnexpectedError ( expect . anything ( ) ) ) ;
446442 } ) ;
447443 } ) ;
448444 } ) ;
0 commit comments