summaryrefslogtreecommitdiff
path: root/internal/storage/epic_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/storage/epic_test.go')
-rw-r--r--internal/storage/epic_test.go117
1 files changed, 117 insertions, 0 deletions
diff --git a/internal/storage/epic_test.go b/internal/storage/epic_test.go
new file mode 100644
index 0000000..dfd5be1
--- /dev/null
+++ b/internal/storage/epic_test.go
@@ -0,0 +1,117 @@
+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)
+ }
+}