@@ -245,6 +245,69 @@ describe("Authenticated API Routes", () => {
245245 } ) ;
246246
247247 describe ( "/projects/{slug}/publish" , ( ) => {
248+ test ( "publish keeps non-deleted files and does not restore deleted files" , async ( ) => {
249+ const publishTestAppId = `test_app_publish_${ Date . now ( ) } ` ;
250+ const keptFilePath = "keep.txt" ;
251+ const deletedFilePath = "deleted.txt" ;
252+ const keptFileContent = "keep this file" ;
253+
254+ const postProjectRes = await request ( app )
255+ . post ( `/api/v3/projects/${ publishTestAppId } ` )
256+ . auth ( USER1_TOKEN , { type : "bearer" } )
257+ . send ( ) ;
258+ expect ( postProjectRes . statusCode ) . toBe ( 204 ) ;
259+
260+ const uploadKeptFileRes = await request ( app )
261+ . post ( `/api/v3/projects/${ publishTestAppId } /draft/files/${ keptFilePath } ` )
262+ . auth ( USER1_TOKEN , { type : "bearer" } )
263+ . attach ( "file" , Buffer . from ( keptFileContent ) , keptFilePath ) ;
264+ expect ( uploadKeptFileRes . statusCode ) . toBe ( 204 ) ;
265+
266+ const uploadDeletedFileRes = await request ( app )
267+ . post (
268+ `/api/v3/projects/${ publishTestAppId } /draft/files/${ deletedFilePath } `
269+ )
270+ . auth ( USER1_TOKEN , { type : "bearer" } )
271+ . attach ( "file" , Buffer . from ( "delete this file" ) , deletedFilePath ) ;
272+ expect ( uploadDeletedFileRes . statusCode ) . toBe ( 204 ) ;
273+
274+ const deleteFileRes = await request ( app )
275+ . delete (
276+ `/api/v3/projects/${ publishTestAppId } /draft/files/${ deletedFilePath } `
277+ )
278+ . auth ( USER1_TOKEN , { type : "bearer" } ) ;
279+ expect ( deleteFileRes . statusCode ) . toBe ( 204 ) ;
280+
281+ const publishRes = await request ( app )
282+ . patch ( `/api/v3/projects/${ publishTestAppId } /publish` )
283+ . auth ( USER1_TOKEN , { type : "bearer" } ) ;
284+ expect ( publishRes . statusCode ) . toBe ( 204 ) ;
285+
286+ const getLatestRes = await request ( app )
287+ . get ( `/api/v3/projects/${ publishTestAppId } ` )
288+ . auth ( USER1_TOKEN , { type : "bearer" } ) ;
289+ expect ( getLatestRes . statusCode ) . toBe ( 200 ) ;
290+ expect (
291+ getLatestRes . body . version . files . map ( ( f : { full_path : string } ) => f . full_path )
292+ ) . toContain ( keptFilePath ) ;
293+ expect (
294+ getLatestRes . body . version . files . map ( ( f : { full_path : string } ) => f . full_path )
295+ ) . not . toContain ( deletedFilePath ) ;
296+
297+ const getDraftKeptFileRes = await request ( app )
298+ . get ( `/api/v3/projects/${ publishTestAppId } /draft/files/${ keptFilePath } ` )
299+ . auth ( USER1_TOKEN , { type : "bearer" } ) ;
300+ expect ( getDraftKeptFileRes . statusCode ) . toBe ( 200 ) ;
301+ expect ( getDraftKeptFileRes . text ) . toBe ( keptFileContent ) ;
302+
303+ const getDraftDeletedFileRes = await request ( app )
304+ . get (
305+ `/api/v3/projects/${ publishTestAppId } /draft/files/${ deletedFilePath } `
306+ )
307+ . auth ( USER1_TOKEN , { type : "bearer" } ) ;
308+ expect ( getDraftDeletedFileRes . statusCode ) . toBe ( 404 ) ;
309+ } ) ;
310+
248311 test ( "publish version and change metadata" , async ( ) => {
249312 // Create a new project
250313 const publishTestAppId = `test_app_publish_${ Date . now ( ) } ` ;
0 commit comments