@@ -561,6 +561,49 @@ describe("composerDraftStore project draft thread mapping", () => {
561561 expect ( draftByKey ( draftId ) ) . toBeUndefined ( ) ;
562562 } ) ;
563563
564+ it ( "revokes draft image blob URLs when clearing a project's draft thread" , ( ) => {
565+ const store = useComposerDraftStore . getState ( ) ;
566+ const originalRevokeObjectUrl = URL . revokeObjectURL ;
567+ const revokeSpy = vi . fn < ( url : string ) => void > ( ) ;
568+ URL . revokeObjectURL = revokeSpy ;
569+
570+ try {
571+ store . setProjectDraftThreadId ( projectRef , draftId , { threadId } ) ;
572+ store . addImage ( draftId , makeImage ( { id : "img-project-clear" , previewUrl : "blob:clear" } ) ) ;
573+
574+ store . clearProjectDraftThreadId ( projectRef ) ;
575+
576+ expect ( useComposerDraftStore . getState ( ) . getDraftThreadByProjectRef ( projectRef ) ) . toBeNull ( ) ;
577+ expect ( useComposerDraftStore . getState ( ) . getDraftThread ( draftId ) ) . toBeNull ( ) ;
578+ expect ( revokeSpy ) . toHaveBeenCalledWith ( "blob:clear" ) ;
579+ } finally {
580+ URL . revokeObjectURL = originalRevokeObjectUrl ;
581+ }
582+ } ) ;
583+
584+ it ( "revokes draft image blob URLs when clearing a matching project draft thread by id" , ( ) => {
585+ const store = useComposerDraftStore . getState ( ) ;
586+ const originalRevokeObjectUrl = URL . revokeObjectURL ;
587+ const revokeSpy = vi . fn < ( url : string ) => void > ( ) ;
588+ URL . revokeObjectURL = revokeSpy ;
589+
590+ try {
591+ store . setProjectDraftThreadId ( projectRef , draftId , { threadId } ) ;
592+ store . addImage (
593+ draftId ,
594+ makeImage ( { id : "img-project-clear-by-id" , previewUrl : "blob:clear-by-id" } ) ,
595+ ) ;
596+
597+ store . clearProjectDraftThreadById ( projectRef , draftId ) ;
598+
599+ expect ( useComposerDraftStore . getState ( ) . getDraftThreadByProjectRef ( projectRef ) ) . toBeNull ( ) ;
600+ expect ( useComposerDraftStore . getState ( ) . getDraftThread ( draftId ) ) . toBeNull ( ) ;
601+ expect ( revokeSpy ) . toHaveBeenCalledWith ( "blob:clear-by-id" ) ;
602+ } finally {
603+ URL . revokeObjectURL = originalRevokeObjectUrl ;
604+ }
605+ } ) ;
606+
564607 it ( "clears orphaned composer drafts when remapping a project to a new draft thread" , ( ) => {
565608 const store = useComposerDraftStore . getState ( ) ;
566609 store . setProjectDraftThreadId ( projectRef , draftId , { threadId } ) ;
0 commit comments