@@ -85,6 +85,33 @@ func TestUploadFileAllowsReuploadAfterDelete(t *testing.T) {
8585 }
8686}
8787
88+ func TestDeleteFileIfUnreferencedSkipsReferencedFile (t * testing.T ) {
89+ ctx := context .Background ()
90+ repo := newUploadTestRepo ()
91+ store := newUploadTestStore ()
92+ service := newUploadTestService (repo , store )
93+
94+ uploaded , err := service .UploadFile (ctx , uploadTestInput ("notes.md" , "same content" ))
95+ if err != nil {
96+ t .Fatalf ("upload failed: %v" , err )
97+ }
98+ repo .referencedFileIDs [uploaded .File .FileID ] = true
99+
100+ result , deleted , err := service .DeleteFileIfUnreferenced (ctx , 1 , uploaded .File .FileID )
101+ if err != nil {
102+ t .Fatalf ("delete if unreferenced failed: %v" , err )
103+ }
104+ if deleted || result != nil {
105+ t .Fatal ("referenced file should be skipped without returning a delete result" )
106+ }
107+ if status := repo .fileStatus (uploaded .File .FileID ); status != "active" {
108+ t .Fatalf ("referenced file should remain active, got %q" , status )
109+ }
110+ if got := store .objectCount (); got != 1 {
111+ t .Fatalf ("referenced file should keep physical object, got %d objects" , got )
112+ }
113+ }
114+
88115func TestUploadFileReplacesStaleDuplicatePointer (t * testing.T ) {
89116 ctx := context .Background ()
90117 repo := newUploadTestRepo ()
@@ -301,6 +328,7 @@ type uploadTestRepo struct {
301328 quota domainconversation.StorageQuota
302329 missNextDuplicateLookup bool
303330 failNextCreateDuplicate bool
331+ referencedFileIDs map [string ]bool
304332}
305333
306334func newUploadTestRepo () * uploadTestRepo {
@@ -310,6 +338,7 @@ func newUploadTestRepo() *uploadTestRepo {
310338 UserID : 1 ,
311339 QuotaBytes : 10 * 1024 * 1024 ,
312340 },
341+ referencedFileIDs : make (map [string ]bool ),
313342 }
314343}
315344
@@ -392,14 +421,17 @@ func (r *uploadTestRepo) CreateFileObjectAndConsumeQuota(_ context.Context, item
392421 return cloneQuota (r .quota ), nil
393422}
394423
395- func (r * uploadTestRepo ) DeleteFileObjectAndReleaseQuota (_ context.Context , userID uint , fileID string , quotaLimit int64 ) (* domainconversation.FileObject , * domainconversation.StorageQuota , bool , error ) {
424+ func (r * uploadTestRepo ) DeleteFileObjectAndReleaseQuota (_ context.Context , userID uint , fileID string , quotaLimit int64 , options repository. DeleteFileObjectOptions ) (* domainconversation.FileObject , * domainconversation.StorageQuota , bool , error ) {
396425 if quotaLimit > 0 {
397426 r .quota .QuotaBytes = quotaLimit
398427 }
399428 for i := range r .files {
400429 if r .files [i ].UserID != userID || r .files [i ].FileID != fileID || r .files [i ].Status != "active" {
401430 continue
402431 }
432+ if options .RequireUnreferenced && r .referencedFileIDs [fileID ] {
433+ return nil , nil , false , repository .ErrConflict
434+ }
403435 deleted := r .files [i ]
404436 r .files [i ].Status = "deleted"
405437 remainingRefs := 0
0 commit comments