package main import ( "os" "path/filepath" "testing" ) func TestCleanupLocalFileKeepsSharedAssetForPendingTask(t *testing.T) { db := openMigrationTestDB(t) if err := migrateDatabase(db); err != nil { t.Fatal(err) } path := filepath.Join(t.TempDir(), "shared.flac") if err := os.WriteFile(path, []byte("audio"), 0644); err != nil { t.Fatal(err) } asset := MediaAsset{AssetKey: assetKey("kw", "shared", "lossless"), Source: "kw", RID: "shared", Quality: "lossless", LocalPath: path, Format: "flac", Status: "done", Size: 5} if err := db.Create(&asset).Error; err != nil { t.Fatal(err) } first := Task{UserID: 1, AssetID: asset.ID, Source: "kw", RID: "shared", Quality: "lossless", Status: "done", LocalPath: path, RemotePath: "Music/shared.flac"} second := Task{UserID: 2, AssetID: asset.ID, Source: "kw", RID: "shared", Quality: "lossless", Status: "upload_pending", LocalPath: path} if err := db.Create(&first).Error; err != nil { t.Fatal(err) } if err := db.Create(&second).Error; err != nil { t.Fatal(err) } a := &App{db: db, cfg: Config{LocalFilePolicy: "delete_after_upload"}} a.cleanupLocalFile(&first) if _, err := os.Stat(path); err != nil { t.Fatalf("shared file deleted while needed: %v", err) } if err := db.Model(&second).Updates(map[string]any{"status": "done", "remote_path": "Music/shared.flac"}).Error; err != nil { t.Fatal(err) } a.cleanupLocalFile(&first) if _, err := os.Stat(path); !os.IsNotExist(err) { t.Fatalf("shared file still exists: %v", err) } var gotAsset MediaAsset if err := db.First(&gotAsset, asset.ID).Error; err != nil { t.Fatal(err) } if gotAsset.Status != "evicted" || gotAsset.LocalPath != "" { t.Fatalf("asset not evicted: %+v", gotAsset) } } func TestRecoverMissingLocalUploadRequeuesTask(t *testing.T) { db := openMigrationTestDB(t) if err := migrateDatabase(db); err != nil { t.Fatal(err) } path := filepath.Join(t.TempDir(), "missing.flac") asset := MediaAsset{AssetKey: assetKey("kw", "missing", "lossless"), Source: "kw", RID: "missing", Quality: "lossless", LocalPath: path, Format: "flac", Status: "done", Size: 10} if err := db.Create(&asset).Error; err != nil { t.Fatal(err) } task := Task{UserID: 1, AssetID: asset.ID, Source: "kw", RID: "missing", Quality: "lossless", Status: "upload_pending", LocalPath: path} if err := db.Create(&task).Error; err != nil { t.Fatal(err) } a := &App{db: db, queue: make(chan uint, 1)} if !a.recoverMissingLocalUpload(&task) { t.Fatal("missing local file was not requeued") } var got Task if err := db.First(&got, task.ID).Error; err != nil { t.Fatal(err) } if got.Status != "pending" { t.Fatalf("task status = %q, want pending", got.Status) } if <-a.queue != task.ID { t.Fatal("queued task id mismatch") } }