@@ -265,3 +265,273 @@ describe('POST /request/:requestId/retry', () => {
265265 assert . ok ( persisted . updatedAt > failed . updatedAt ) ;
266266 } ) ;
267267} ) ;
268+
269+ describe ( 'DELETE /request/:requestId, deleted media status restoration' , ( ) => {
270+ async function seedDeletedMediaScenario ( ) {
271+ const userRepo = getRepository ( User ) ;
272+ const mediaRepo = getRepository ( Media ) ;
273+ const requestRepo = getRepository ( MediaRequest ) ;
274+
275+ const admin = await userRepo . findOneOrFail ( {
276+ where : { email : 'admin@seerr.dev' } ,
277+ } ) ;
278+
279+ const media = await mediaRepo . save (
280+ new Media ( {
281+ mediaType : MediaType . MOVIE ,
282+ tmdbId : 99001 ,
283+ status : MediaStatus . DELETED ,
284+ status4k : MediaStatus . UNKNOWN ,
285+ } )
286+ ) ;
287+
288+ const staleRequest = await requestRepo . save (
289+ new MediaRequest ( {
290+ type : MediaType . MOVIE ,
291+ status : MediaRequestStatus . COMPLETED ,
292+ media,
293+ requestedBy : admin ,
294+ is4k : false ,
295+ isAutoRequest : true ,
296+ } )
297+ ) ;
298+
299+ media . status = MediaStatus . PENDING ;
300+ await mediaRepo . save ( media ) ;
301+
302+ const newRequest = await requestRepo . save (
303+ new MediaRequest ( {
304+ type : MediaType . MOVIE ,
305+ status : MediaRequestStatus . APPROVED ,
306+ media,
307+ requestedBy : admin ,
308+ is4k : false ,
309+ } )
310+ ) ;
311+
312+ return { media, staleRequest, newRequest, admin } ;
313+ }
314+
315+ it ( 'restores media status to DELETED when the re-request is deleted and a stale completed request remains' , async ( ) => {
316+ const mediaRepo = getRepository ( Media ) ;
317+ const { media, newRequest } = await seedDeletedMediaScenario ( ) ;
318+
319+ const agent = await loginAs ( 'admin@seerr.dev' , 'test1234' ) ;
320+ const res = await agent . delete ( `/request/${ newRequest . id } ` ) ;
321+
322+ assert . strictEqual ( res . status , 204 ) ;
323+
324+ const updated = await mediaRepo . findOneOrFail ( { where : { id : media . id } } ) ;
325+ assert . strictEqual ( updated . status , MediaStatus . DELETED ) ;
326+ } ) ;
327+
328+ it ( 'restores media status4k to DELETED when the re-request is deleted and a stale completed request remains' , async ( ) => {
329+ const userRepo = getRepository ( User ) ;
330+ const mediaRepo = getRepository ( Media ) ;
331+ const requestRepo = getRepository ( MediaRequest ) ;
332+
333+ const admin = await userRepo . findOneOrFail ( {
334+ where : { email : 'admin@seerr.dev' } ,
335+ } ) ;
336+
337+ const media = await mediaRepo . save (
338+ new Media ( {
339+ mediaType : MediaType . MOVIE ,
340+ tmdbId : 99003 ,
341+ status : MediaStatus . UNKNOWN ,
342+ status4k : MediaStatus . DELETED ,
343+ } )
344+ ) ;
345+
346+ await requestRepo . save (
347+ new MediaRequest ( {
348+ type : MediaType . MOVIE ,
349+ status : MediaRequestStatus . COMPLETED ,
350+ media,
351+ requestedBy : admin ,
352+ is4k : true ,
353+ isAutoRequest : true ,
354+ } )
355+ ) ;
356+
357+ media . status4k = MediaStatus . PENDING ;
358+ await mediaRepo . save ( media ) ;
359+
360+ const newRequest = await requestRepo . save (
361+ new MediaRequest ( {
362+ type : MediaType . MOVIE ,
363+ status : MediaRequestStatus . APPROVED ,
364+ media,
365+ requestedBy : admin ,
366+ is4k : true ,
367+ } )
368+ ) ;
369+
370+ const agent = await loginAs ( 'admin@seerr.dev' , 'test1234' ) ;
371+ const res = await agent . delete ( `/request/${ newRequest . id } ` ) ;
372+
373+ assert . strictEqual ( res . status , 204 ) ;
374+
375+ const updated = await mediaRepo . findOneOrFail ( { where : { id : media . id } } ) ;
376+ assert . strictEqual ( updated . status4k , MediaStatus . DELETED ) ;
377+ } ) ;
378+
379+ it ( 'resets media status to UNKNOWN when the stale completed request is also deleted' , async ( ) => {
380+ const mediaRepo = getRepository ( Media ) ;
381+ const requestRepo = getRepository ( MediaRequest ) ;
382+ const { media, newRequest, staleRequest } =
383+ await seedDeletedMediaScenario ( ) ;
384+
385+ const agent = await loginAs ( 'admin@seerr.dev' , 'test1234' ) ;
386+
387+ await agent . delete ( `/request/${ newRequest . id } ` ) ;
388+
389+ const res = await agent . delete ( `/request/${ staleRequest . id } ` ) ;
390+ assert . strictEqual ( res . status , 204 ) ;
391+
392+ const updated = await mediaRepo . findOneOrFail ( { where : { id : media . id } } ) ;
393+ assert . strictEqual ( updated . status , MediaStatus . UNKNOWN ) ;
394+
395+ const remaining = await requestRepo . find ( {
396+ where : { media : { id : media . id } } ,
397+ } ) ;
398+ assert . strictEqual ( remaining . length , 0 ) ;
399+ } ) ;
400+
401+ it ( 'resets media status4k to UNKNOWN when the stale completed 4K request is also deleted' , async ( ) => {
402+ const userRepo = getRepository ( User ) ;
403+ const mediaRepo = getRepository ( Media ) ;
404+ const requestRepo = getRepository ( MediaRequest ) ;
405+
406+ const admin = await userRepo . findOneOrFail ( {
407+ where : { email : 'admin@seerr.dev' } ,
408+ } ) ;
409+
410+ const media = await mediaRepo . save (
411+ new Media ( {
412+ mediaType : MediaType . MOVIE ,
413+ tmdbId : 99004 ,
414+ status : MediaStatus . UNKNOWN ,
415+ status4k : MediaStatus . DELETED ,
416+ } )
417+ ) ;
418+
419+ const staleRequest = await requestRepo . save (
420+ new MediaRequest ( {
421+ type : MediaType . MOVIE ,
422+ status : MediaRequestStatus . COMPLETED ,
423+ media,
424+ requestedBy : admin ,
425+ is4k : true ,
426+ isAutoRequest : true ,
427+ } )
428+ ) ;
429+
430+ media . status4k = MediaStatus . PENDING ;
431+ await mediaRepo . save ( media ) ;
432+
433+ const newRequest = await requestRepo . save (
434+ new MediaRequest ( {
435+ type : MediaType . MOVIE ,
436+ status : MediaRequestStatus . APPROVED ,
437+ media,
438+ requestedBy : admin ,
439+ is4k : true ,
440+ } )
441+ ) ;
442+
443+ const agent = await loginAs ( 'admin@seerr.dev' , 'test1234' ) ;
444+
445+ await agent . delete ( `/request/${ newRequest . id } ` ) ;
446+
447+ const res = await agent . delete ( `/request/${ staleRequest . id } ` ) ;
448+ assert . strictEqual ( res . status , 204 ) ;
449+
450+ const updated = await mediaRepo . findOneOrFail ( { where : { id : media . id } } ) ;
451+ assert . strictEqual ( updated . status4k , MediaStatus . UNKNOWN ) ;
452+ } ) ;
453+
454+ it ( 'does not reset media status when other active requests still exist' , async ( ) => {
455+ const userRepo = getRepository ( User ) ;
456+ const mediaRepo = getRepository ( Media ) ;
457+ const requestRepo = getRepository ( MediaRequest ) ;
458+
459+ const admin = await userRepo . findOneOrFail ( {
460+ where : { email : 'admin@seerr.dev' } ,
461+ } ) ;
462+
463+ const media = await mediaRepo . save (
464+ new Media ( {
465+ mediaType : MediaType . MOVIE ,
466+ tmdbId : 99002 ,
467+ status : MediaStatus . PENDING ,
468+ status4k : MediaStatus . UNKNOWN ,
469+ } )
470+ ) ;
471+
472+ const req1 = await requestRepo . save (
473+ new MediaRequest ( {
474+ type : MediaType . MOVIE ,
475+ status : MediaRequestStatus . PENDING ,
476+ media,
477+ requestedBy : admin ,
478+ is4k : false ,
479+ } )
480+ ) ;
481+
482+ await requestRepo . save (
483+ new MediaRequest ( {
484+ type : MediaType . MOVIE ,
485+ status : MediaRequestStatus . PENDING ,
486+ media,
487+ requestedBy : admin ,
488+ is4k : false ,
489+ } )
490+ ) ;
491+
492+ const agent = await loginAs ( 'admin@seerr.dev' , 'test1234' ) ;
493+ const res = await agent . delete ( `/request/${ req1 . id } ` ) ;
494+
495+ assert . strictEqual ( res . status , 204 ) ;
496+
497+ const updated = await mediaRepo . findOneOrFail ( { where : { id : media . id } } ) ;
498+ assert . strictEqual ( updated . status , MediaStatus . PENDING ) ;
499+ } ) ;
500+
501+ it ( 'does not reset media status when status is PARTIALLY_AVAILABLE and only completed requests remain' , async ( ) => {
502+ const userRepo = getRepository ( User ) ;
503+ const mediaRepo = getRepository ( Media ) ;
504+ const requestRepo = getRepository ( MediaRequest ) ;
505+
506+ const admin = await userRepo . findOneOrFail ( {
507+ where : { email : 'admin@seerr.dev' } ,
508+ } ) ;
509+
510+ const media = await mediaRepo . save (
511+ new Media ( {
512+ mediaType : MediaType . MOVIE ,
513+ tmdbId : 99005 ,
514+ status : MediaStatus . PARTIALLY_AVAILABLE ,
515+ status4k : MediaStatus . UNKNOWN ,
516+ } )
517+ ) ;
518+
519+ const completedRequest = await requestRepo . save (
520+ new MediaRequest ( {
521+ type : MediaType . MOVIE ,
522+ status : MediaRequestStatus . COMPLETED ,
523+ media,
524+ requestedBy : admin ,
525+ is4k : false ,
526+ } )
527+ ) ;
528+
529+ const agent = await loginAs ( 'admin@seerr.dev' , 'test1234' ) ;
530+ const res = await agent . delete ( `/request/${ completedRequest . id } ` ) ;
531+
532+ assert . strictEqual ( res . status , 204 ) ;
533+
534+ const updated = await mediaRepo . findOneOrFail ( { where : { id : media . id } } ) ;
535+ assert . strictEqual ( updated . status , MediaStatus . PARTIALLY_AVAILABLE ) ;
536+ } ) ;
537+ } ) ;
0 commit comments