package storage import ( "testing" "github.com/thepeterstone/claudomator/internal/story" ) func TestCreateEpic_AndGetEpic(t *testing.T) { db := testDB(t) e := &story.Epic{ ID: "epic-1", Name: "Bigger Auth Rework", Description: "Overhaul the auth flow.", DiscoverySource: "human", } if err := db.CreateEpic(e); err != nil { t.Fatalf("CreateEpic: %v", err) } // CreateEpic defaults Status to OPEN when unset. if e.Status != "OPEN" { t.Errorf("Status after create: want OPEN, got %q", e.Status) } got, err := db.GetEpic("epic-1") if err != nil { t.Fatalf("GetEpic: %v", err) } if got.Name != "Bigger Auth Rework" { t.Errorf("Name: want %q, got %q", "Bigger Auth Rework", got.Name) } if got.Description != "Overhaul the auth flow." { t.Errorf("Description: want %q, got %q", "Overhaul the auth flow.", got.Description) } if got.Status != "OPEN" { t.Errorf("Status: want OPEN, got %q", got.Status) } if got.DiscoverySource != "human" { t.Errorf("DiscoverySource: want human, got %q", got.DiscoverySource) } if got.CreatedAt.IsZero() || got.UpdatedAt.IsZero() { t.Errorf("expected CreatedAt/UpdatedAt to be set, got %+v", got) } } func TestGetEpic_NotFound(t *testing.T) { db := testDB(t) if _, err := db.GetEpic("nope"); err == nil { t.Fatal("expected error for missing epic, got nil") } } func TestListEpics(t *testing.T) { db := testDB(t) for _, e := range []*story.Epic{ {ID: "e1", Name: "alpha", Status: "OPEN"}, {ID: "e2", Name: "beta", Status: "CLOSED"}, {ID: "e3", Name: "gamma", Status: "OPEN"}, } { if err := db.CreateEpic(e); err != nil { t.Fatalf("CreateEpic(%s): %v", e.ID, err) } } all, err := db.ListEpics("") if err != nil { t.Fatalf("ListEpics: %v", err) } if len(all) != 3 { t.Errorf("want 3 epics, got %d", len(all)) } open, err := db.ListEpics("OPEN") if err != nil { t.Fatalf("ListEpics(OPEN): %v", err) } if len(open) != 2 { t.Errorf("want 2 OPEN epics, got %d", len(open)) } for _, e := range open { if e.Status != "OPEN" { t.Errorf("expected only OPEN epics, got %q", e.Status) } } } func TestUpdateEpic(t *testing.T) { db := testDB(t) e := &story.Epic{ID: "e1", Name: "original", Status: "OPEN"} if err := db.CreateEpic(e); err != nil { t.Fatalf("CreateEpic: %v", err) } e.Name = "updated" e.Description = "now with a description" e.Status = "CLOSED" if err := db.UpdateEpic(e); err != nil { t.Fatalf("UpdateEpic: %v", err) } got, err := db.GetEpic("e1") if err != nil { t.Fatalf("GetEpic: %v", err) } if got.Name != "updated" { t.Errorf("Name after update: want updated, got %q", got.Name) } if got.Description != "now with a description" { t.Errorf("Description after update: want %q, got %q", "now with a description", got.Description) } // UpdateEpic performs no status-machine validation — CLOSED is accepted // as a plain pass-through write, matching UpdateProject's trust level. if got.Status != "CLOSED" { t.Errorf("Status after update: want CLOSED, got %q", got.Status) } }