package web import ( "context" "fmt" "net/http" "net/url" "regexp" "strings" "testing" "sourcecraft.dev/bigbes/sr-ht-ecore/pages" "sourcecraft.dev/bigbes/sr-ht-dolt/browse" "sourcecraft.dev/bigbes/sr-ht-dolt/core" ) // dummyView is a test-only View that fingerprints repos containing a table // named "issues". It renders through the shared error page, which is the one // page every service's set is guaranteed to carry and the only one that asks // nothing of the envelope beyond the .Data field every view already has. Its // Build therefore returns a pages.ErrorData. It records whether Build ran. type dummyView struct { built bool } func (d *dummyView) Name() string { return "issues" } func (d *dummyView) Label() string { return "Issues" } func (d *dummyView) Template() string { return pages.ErrorPage + ".html" } func (d *dummyView) Applies(tables []browse.TableInfo) bool { for _, t := range tables { if t.Name == "issues" { return true } } return false } func (d *dummyView) Build(_ context.Context, sess BrowseSession, _ *core.Repo, ref string, _ url.Values) (any, error) { d.built = true // Pull data through the BrowseSession surface only, mirroring how a real // view works, then hand the page the payload it reads. tables, err := sess.Tables(context.Background(), ref) if err != nil { return nil, err } return pages.Error(http.StatusOK, fmt.Sprintf("%d tables", len(tables))), nil } func issueTables() []browse.TableInfo { return []browse.TableInfo{ {Name: "issues", Columns: []browse.ColumnInfo{{Name: "id", PrimaryKey: true}}, RowCount: 2}, {Name: "labels", RowCount: 5}, } } func TestApplicableViewsFilters(t *testing.T) { v := &dummyView{} views := []View{v} got := applicableViews(views, issueTables()) if len(got) != 1 || got[0] != v { t.Fatalf("applicableViews should select the matching view; got %v", got) } // No "issues" table → no applicable views. none := applicableViews(views, []browse.TableInfo{{Name: "widgets"}}) if len(none) != 0 { t.Fatalf("applicableViews should filter out non-matching views; got %v", none) } } func TestApplicableViewsPreservesOrder(t *testing.T) { a := &dummyView{} // A second always-applies view to check registration order is preserved. b := alwaysView{} got := applicableViews([]View{b, a}, issueTables()) if len(got) != 2 || got[0] != View(b) || got[1] != View(a) { t.Fatalf("applicableViews should preserve order; got %v", got) } } // alwaysView is a trivial always-applicable view used to check ordering. type alwaysView struct{} func (alwaysView) Name() string { return "always" } func (alwaysView) Label() string { return "Always" } func (alwaysView) Template() string { return pages.ErrorPage + ".html" } func (alwaysView) Applies([]browse.TableInfo) bool { return true } func (alwaysView) Build(context.Context, BrowseSession, *core.Repo, string, url.Values) (any, error) { return pages.Error(http.StatusOK, ""), nil } func TestHandleViewSelectedAndBuilt(t *testing.T) { h := newHarness(t) h.store.add(&core.Repo{Name: "db", OwnerID: 1, OwnerName: "alice", Path: "/d", Visibility: core.VisibilityPublic}) h.browse.sess = &fakeSession{ branches: []browse.Branch{{Name: "main", Head: "abcdef1234567890"}}, tables: issueTables(), } dv := &dummyView{} // Inject the view directly on the app, without polluting the global registry. setViews(t, h, dv) rec := h.do("GET", "/~alice/db/view/issues", nil, nil) // A 200 (rather than the 404 an unknown/non-applicable view returns) proves // the view was selected and its Template rendered; dv.built proves Build ran. if rec.Code != http.StatusOK { t.Fatalf("view page: got %d, want 200; body=%s", rec.Code, rec.Body.String()) } if !dv.built { t.Fatalf("view.Build was not called") } // The view's Label flows into the page