package refinery import ( "encoding/json" "os" "path/filepath" "testing" "time" "github.com/steveyegge/gastown/internal/rig" ) func setupTestManager(t *testing.T) (*Manager, string) { t.Helper() // Create temp directory structure tmpDir := t.TempDir() rigPath := filepath.Join(tmpDir, "testrig") if err := os.MkdirAll(filepath.Join(rigPath, ".runtime"), 0755); err != nil { t.Fatalf("mkdir .runtime: %v", err) } r := &rig.Rig{ Name: "testrig", Path: rigPath, } return NewManager(r), rigPath } func TestManager_GetMR(t *testing.T) { mgr, _ := setupTestManager(t) // Create a test MR in the pending queue mr := &MergeRequest{ ID: "gt-mr-abc123", Branch: "polecat/Toast/gt-xyz", Worker: "Toast", IssueID: "gt-xyz", Status: MROpen, Error: "test failure", } if err := mgr.RegisterMR(mr); err != nil { t.Fatalf("RegisterMR: %v", err) } t.Run("find existing MR", func(t *testing.T) { found, err := mgr.GetMR("gt-mr-abc123") if err != nil { t.Errorf("GetMR() unexpected error: %v", err) } if found == nil { t.Fatal("GetMR() returned nil") } if found.ID != mr.ID { t.Errorf("GetMR() ID = %s, want %s", found.ID, mr.ID) } }) t.Run("MR not found", func(t *testing.T) { _, err := mgr.GetMR("nonexistent-mr") if err != ErrMRNotFound { t.Errorf("GetMR() error = %v, want %v", err, ErrMRNotFound) } }) } func TestManager_Retry(t *testing.T) { t.Run("retry failed MR clears error", func(t *testing.T) { mgr, _ := setupTestManager(t) // Create a failed MR mr := &MergeRequest{ ID: "gt-mr-failed", Branch: "polecat/Toast/gt-xyz", Worker: "Toast", Status: MROpen, Error: "merge conflict", } if err := mgr.RegisterMR(mr); err != nil { t.Fatalf("RegisterMR: %v", err) } // Retry without processing err := mgr.Retry("gt-mr-failed", false) if err != nil { t.Errorf("Retry() unexpected error: %v", err) } // Verify error was cleared found, _ := mgr.GetMR("gt-mr-failed") if found.Error != "" { t.Errorf("Retry() error not cleared, got %s", found.Error) } }) t.Run("retry non-failed MR fails", func(t *testing.T) { mgr, _ := setupTestManager(t) // Create a successful MR (no error) mr := &MergeRequest{ ID: "gt-mr-success", Branch: "polecat/Toast/gt-abc", Worker: "Toast", Status: MROpen, Error: "", // No error } if err := mgr.RegisterMR(mr); err != nil { t.Fatalf("RegisterMR: %v", err) } err := mgr.Retry("gt-mr-success", false) if err != ErrMRNotFailed { t.Errorf("Retry() error = %v, want %v", err, ErrMRNotFailed) } }) t.Run("retry nonexistent MR fails", func(t *testing.T) { mgr, _ := setupTestManager(t) err := mgr.Retry("nonexistent", false) if err != ErrMRNotFound { t.Errorf("Retry() error = %v, want %v", err, ErrMRNotFound) } }) } func TestManager_RegisterMR(t *testing.T) { mgr, rigPath := setupTestManager(t) mr := &MergeRequest{ ID: "gt-mr-new", Branch: "polecat/Cheedo/gt-123", Worker: "Cheedo", IssueID: "gt-123", TargetBranch: "main", CreatedAt: time.Now(), Status: MROpen, } if err := mgr.RegisterMR(mr); err != nil { t.Fatalf("RegisterMR: %v", err) } // Verify it was saved to disk stateFile := filepath.Join(rigPath, ".runtime", "refinery.json") data, err := os.ReadFile(stateFile) if err != nil { t.Fatalf("reading state file: %v", err) } var ref Refinery if err := json.Unmarshal(data, &ref); err != nil { t.Fatalf("unmarshal state: %v", err) } if ref.PendingMRs == nil { t.Fatal("PendingMRs is nil") } saved, ok := ref.PendingMRs["gt-mr-new"] if !ok { t.Fatal("MR not found in PendingMRs") } if saved.Worker != "Cheedo" { t.Errorf("saved MR worker = %s, want Cheedo", saved.Worker) } }