package web import ( "context" "encoding/json" "net/http" "net/http/httptest" "testing" ) func TestHandleJobCancelAPIReportsRequestUntilWorkerAcknowledges(t *testing.T) { manager := NewJobManager() job, ok := manager.CreateJobWithResources("install", "mpv-test", "MPV", resourceMPVConfig) if !ok { t.Fatal("create job failed") } server := &Server{jobManager: manager} request := httptest.NewRequest(http.MethodDelete, "/api/jobs/"+job.ID, nil) response := httptest.NewRecorder() server.handleJobCancelAPI(response, request) if response.Code != http.StatusOK { t.Fatalf("cancel response = %d: %s", response.Code, response.Body.String()) } var body map[string]any if err := json.Unmarshal(response.Body.Bytes(), &body); err != nil { t.Fatal(err) } if body["status"] != "cancelling" { t.Fatalf("cancel response status = %v", body["status"]) } if snapshot, exists := manager.JobSnapshot(job.ID); !exists || snapshot.Status != "cancelling" { t.Fatalf("job was archived before worker acknowledgement: %+v, exists=%v", snapshot, exists) } manager.SetError(job.ID, context.Canceled, "worker stopped") recent := manager.GetRecentJobs() if len(recent) != 1 || recent[0].Status != "cancelled" { t.Fatalf("acknowledged cancellation not archived: %+v", recent) } } func TestHandleJobCancelAPIRejectsCommitBoundary(t *testing.T) { manager := NewJobManager() job, ok := manager.CreateJobWithResources("install", "mpv-test", "MPV", resourceMPVConfig) if !ok { t.Fatal("create job failed") } if err := manager.BeginCommit(job.ID); err != nil { t.Fatal(err) } server := &Server{jobManager: manager} response := httptest.NewRecorder() server.handleJobCancelAPI(response, httptest.NewRequest(http.MethodDelete, "/api/jobs/"+job.ID, nil)) if response.Code != http.StatusConflict { t.Fatalf("commit-bound cancellation response = %d: %s", response.Code, response.Body.String()) } manager.SetError(job.ID, context.Canceled, "test cleanup") }