package web import ( "context" "net/url" "os" "testing" "sourcecraft.dev/bigbes/sr-ht-dolt/beads" "sourcecraft.dev/bigbes/sr-ht-dolt/browse" ) // TestRealBeadsStore is a manual smoke test against a real beads database. It // is skipped unless BEADS_REAL_DB points at a *bare* NBS store dir (the shape // production serves — an embedded working store has a chunk journal and won't // open; push it to a file remote first: `dolt push file:///path/bare main`). // Optionally set BEADS_REAL_ISSUE= to dump one issue's epic rollup and // merged history. Kept because browse reaches into version-fragile dolt // internals, so a module bump should be re-verified against real data here. // // dolt push file:///tmp/bare main # from the working store // BEADS_REAL_DB=/tmp/bare BEADS_REAL_ISSUE= \ // go test -tags gms_pure_go -run TestRealBeadsStore -v ./web/ func TestRealBeadsStore(t *testing.T) { path := os.Getenv("BEADS_REAL_DB") if path == "" { t.Skip("set BEADS_REAL_DB to a real beads noms store dir") } ctx := context.Background() dbh, err := browse.Open(ctx, path) if err != nil { t.Fatalf("open: %v", err) } defer dbh.Close() branches, err := dbh.Branches(ctx) if err != nil { t.Fatalf("branches: %v", err) } ref := browse.DefaultBranch(branches) t.Logf("branches=%v default=%q", branches, ref) tables, err := dbh.Tables(ctx, ref) if err != nil { t.Fatalf("tables: %v", err) } var names []string for _, tb := range tables { names = append(names, tb.Name) } t.Logf("tables=%v", names) issues, err := dbh.Rows(ctx, ref, "issues", 0, 5) if err != nil { t.Fatalf("rows: %v", err) } t.Logf("issues cols=%v total=%d", issues.Columns, issues.Total) v := &beadsView{} // Board mode: dump the filter options, then the effect of a type filter. board, err := v.Build(ctx, dbh, nil, ref, url.Values{}) if err != nil { t.Fatalf("board build: %v", err) } bd := board.(*beads.BeadsData) t.Logf("board total=%d types=%v priorities=%v labels=%v", bd.Total, bd.FilterOpts.Types, bd.FilterOpts.Priorities, bd.FilterOpts.Labels) if len(bd.FilterOpts.Types) > 0 { ft := bd.FilterOpts.Types[0] filtered, _ := v.Build(ctx, dbh, nil, ref, url.Values{"type": {ft}}) t.Logf("filter type=%q → %d issues (of %d)", ft, filtered.(*beads.BeadsData).Total, bd.Total) } readyN := 0 for i := range bd.Lanes { for _, c := range bd.Lanes[i].Issues { if c.Ready { readyN++ } } } t.Logf("ready cards=%d", readyN) // Milestones view. msRaw, err := (&milestonesView{}).Build(ctx, dbh, nil, ref, url.Values{}) if err != nil { t.Fatalf("milestones build: %v", err) } ms := msRaw.(*beads.MilestoneView) t.Logf("milestones (%d, %d unlabeled of %d):", len(ms.Milestones), ms.Unlabeled, ms.Total) for _, m := range ms.Milestones { t.Logf(" %-24s %d/%d done (%d%%), %d heads, %d epics, %d loose", m.Name, m.Done, m.Total, m.Pct(), len(m.Heads), len(m.Epics), len(m.Loose)) for _, e := range m.Epics { t.Logf(" epic %s %d/%d: %s", e.Card.ID, e.Done, e.Total, e.Card.Title) } } // Drive the detail view. With BEADS_REAL_ISSUE set to an epic id, dump the // subtask rollup and merged history so a human can eyeball the output. want := os.Getenv("BEADS_REAL_ISSUE") if want == "" { return } raw, err := v.Build(ctx, dbh, nil, ref, url.Values{"issue": {want}}) if err != nil { t.Fatalf("build: %v", err) } data := raw.(*beads.BeadsData) if data.Issue == nil { t.Fatalf("issue %q not found", want) } t.Logf("mode=%q issue=%q type=%q", data.Mode, data.Issue.Title, data.Issue.IssueType) t.Logf("desc=%.80q closeReason=%.80q", data.Issue.Description, data.Issue.CloseReason) t.Logf("subtasks %d/%d done (%d%%):", data.SubtaskDone, data.SubtaskTotal, data.SubtaskPct()) for _, s := range data.Subtasks { t.Logf(" - %s [%s/%s] %s @%s", s.ID, s.Category, s.Status, s.Title, s.Assignee) } t.Logf("history (%d entries):", len(data.History)) for _, a := range data.History { t.Logf(" %s | %s: %s %s | %s", a.CreatedAt, a.Kind, a.Actor, a.Summary, a.Text) } t.Logf("prerequisite chain (%d nodes):", len(data.DependsTree)) for _, n := range data.DependsTree { t.Logf(" %*s%s %s [%s]", n.Depth*2, "", n.ID, n.Title, n.Status) } t.Logf("unblocks (%d nodes):", len(data.DependentTree)) for _, n := range data.DependentTree { t.Logf(" %*s%s %s [%s]", n.Depth*2, "", n.ID, n.Title, n.Status) } }