package services import ( "testing" ) // GetActiveScanJobs backs the refresh-survival contract: a client that // loads the page mid-scan must be able to discover pending/running jobs // (with their library) rather than only learning about scans from // websocket events emitted after the page opened. func TestGetActiveScanJobs(t *testing.T) { w := NewWorker(1, nil) seed := map[string]*JobResult{ "running-scan": {JobID: "running-scan", Status: JobStatusRunning, LibraryID: "lib-1", Progress: 0.42}, "pending-scan": {JobID: "pending-scan", Status: JobStatusPending, LibraryID: "lib-2"}, "done-scan": {JobID: "done-scan", Status: JobStatusCompleted, LibraryID: "lib-3"}, "failed-scan": {JobID: "failed-scan", Status: JobStatusFailed}, "cancelled": {JobID: "cancelled", Status: JobStatusCancelled}, } w.mu.Lock() w.results = seed w.mu.Unlock() active := w.GetActiveScanJobs() if len(active) != 2 { t.Fatalf("expected 2 active jobs, got %d (%+v)", len(active), active) } seen := map[string]JobResult{} for _, job := range active { seen[job.JobID] = job } running, ok := seen["running-scan"] if !ok { t.Fatal("running scan missing from active jobs") } if running.LibraryID != "lib-1" { t.Errorf("expected library_id lib-1, got %q", running.LibraryID) } if running.Progress != 0.42 { t.Errorf("expected progress 0.42, got %v", running.Progress) } if _, ok := seen["pending-scan"]; !ok { t.Error("pending scan missing from active jobs") } for _, id := range []string{"done-scan", "failed-scan", "cancelled"} { if _, ok := seen[id]; ok { t.Errorf("terminal job %q must not appear as active", id) } } } func TestGetActiveScanJobsEmpty(t *testing.T) { w := NewWorker(1, nil) if jobs := w.GetActiveScanJobs(); len(jobs) != 0 { t.Fatalf("expected no active jobs, got %d", len(jobs)) } }