package main import ( "errors" "testing" "verstak/internal/core/nodes" ) func TestListInboxNodesReturnsOnlyCapturedArtifacts(t *testing.T) { app, _ := setupTestApp(t) manual, err := app.CreateNodeFromTemplate("", "Manual Root", "folder.default") if err != nil { t.Fatalf("create manual root: %v", err) } legacyInbox, err := app.CreateNodeFromTemplate("", "Legacy Inbox Root", "folder.default") if err != nil { t.Fatalf("create legacy inbox root: %v", err) } captured, err := app.CreateNodeFromTemplate("", "Captured Artifact", "folder.default") if err != nil { t.Fatalf("create captured artifact: %v", err) } child, err := app.CreateNodeFromTemplate(captured.ID, "Nested Child", "folder.default") if err != nil { t.Fatalf("create child: %v", err) } if _, err := app.db.Exec(`UPDATE nodes SET section = 'inbox' WHERE id = ?`, legacyInbox.ID); err != nil { t.Fatalf("mark legacy inbox: %v", err) } if err := app.nodes.MetaSet(captured.ID, "capture.inbox", "true"); err != nil { t.Fatalf("mark captured: %v", err) } if err := app.nodes.MetaSet(captured.ID, "capture.kind", "text"); err != nil { t.Fatalf("mark capture kind: %v", err) } if err := app.nodes.MetaSet(captured.ID, "capture.source", "clipboard"); err != nil { t.Fatalf("mark capture source: %v", err) } list, err := app.ListInboxNodes() if err != nil { t.Fatalf("ListInboxNodes: %v", err) } got := map[string]bool{} for _, item := range list { got[item.ID] = true } if !got[captured.ID] { t.Fatal("captured artifact missing from inbox") } for _, item := range list { if item.ID == captured.ID { if item.CaptureKind != "text" { t.Fatalf("CaptureKind = %q, want text", item.CaptureKind) } if item.CaptureSource != "clipboard" { t.Fatalf("CaptureSource = %q, want clipboard", item.CaptureSource) } } } if got[manual.ID] { t.Fatal("manual root should not be in inbox") } if got[legacyInbox.ID] { t.Fatal("section=inbox root without capture metadata should not be in inbox") } if got[child.ID] { t.Fatal("nested child should not be in inbox") } workspace, err := app.ListWorkspaceTree() if err != nil { t.Fatalf("ListWorkspaceTree: %v", err) } for _, item := range workspace { if item.ID == captured.ID { t.Fatal("captured artifact should not be shown in workspace tree") } } } func TestAssignInboxNodeMovesArtifactIntoCase(t *testing.T) { app, _ := setupTestApp(t) parent, err := app.CreateNodeFromTemplate("", "Target Case", "folder.default") if err != nil { t.Fatalf("create parent: %v", err) } captured, err := app.CaptureText("Captured task material") if err != nil { t.Fatalf("CaptureText: %v", err) } moved, err := app.AssignInboxNode(captured.ID, parent.ID) if err != nil { t.Fatalf("AssignInboxNode: %v", err) } if moved.ParentID == nil || *moved.ParentID != parent.ID { t.Fatalf("ParentID = %v, want %q", moved.ParentID, parent.ID) } inbox, err := app.ListInboxNodes() if err != nil { t.Fatalf("ListInboxNodes: %v", err) } for _, item := range inbox { if item.ID == captured.ID { t.Fatal("assigned artifact should leave inbox") } } notes, err := app.ListNotes(parent.ID) if err != nil { t.Fatalf("ListNotes: %v", err) } var found bool for _, note := range notes { if note.ID == captured.ID { found = true } } if !found { t.Fatal("assigned text artifact missing from target case notes") } } func TestDeleteInboxNodeRemovesArtifactFromInbox(t *testing.T) { app, _ := setupTestApp(t) captured, err := app.CaptureText("Delete this captured material") if err != nil { t.Fatalf("CaptureText: %v", err) } if err := app.DeleteInboxNode(captured.ID); err != nil { t.Fatalf("DeleteInboxNode: %v", err) } inbox, err := app.ListInboxNodes() if err != nil { t.Fatalf("ListInboxNodes: %v", err) } for _, item := range inbox { if item.ID == captured.ID { t.Fatal("deleted artifact should leave inbox") } } if _, err := app.nodes.GetActive(captured.ID); !errors.Is(err, nodes.ErrNotFound) { t.Fatalf("GetActive err = %v, want ErrNotFound", err) } }