package httpd
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"gitbay.org/gitbay/internal/config"
"gitbay.org/gitbay/internal/store"
)
// A pinned query shows on the dashboard and its page lists what it
// matches, one page at a time, never another user's private rows.
func TestSavedQueryPages(t *testing.T) {
st, err := store.Open(":memory:")
if err != nil {
t.Fatal(err)
}
defer st.Close()
if err := st.MigrateUp(); err != nil {
t.Fatal(err)
}
alice, err := st.CreateUser("alice", false)
if err != nil {
t.Fatal(err)
}
bob, err := st.CreateUser("bob", false)
if err != nil {
t.Fatal(err)
}
pub, err := st.CreateRepo("user", alice, "pub", "public")
if err != nil {
t.Fatal(err)
}
secret, err := st.CreateRepo("user", bob, "secret", "private")
if err != nil {
t.Fatal(err)
}
for i := 0; i < queryPerPage+1; i++ {
if _, err := st.CreateIssue(pub, alice, "public issue", "", "md"); err != nil {
t.Fatal(err)
}
}
if _, err := st.CreateIssue(secret, bob, "bob's secret", "", "md"); err != nil {
t.Fatal(err)
}
if err := st.SaveQuery(alice, "open", "is:open", false); err != nil {
t.Fatal(err)
}
if err := st.PinSavedQuery(alice, "open", true); err != nil {
t.Fatal(err)
}
cfg := config.Default()
cfg.Web.Mode = "accounts"
s := New(cfg, st, nil)
viewer := store.User{ID: alice, Username: "alice"}
get := func(path string) *httptest.ResponseRecorder {
rr := httptest.NewRecorder()
req := httptest.NewRequest("GET", path, nil)
if owner, rest, ok := strings.Cut(strings.TrimPrefix(req.URL.Path, "/"), "/-/queries"); ok {
req.SetPathValue("owner", owner)
req.SetPathValue("name", strings.TrimPrefix(rest, "/"))
}
if req.URL.Path == "/" {
s.dashboard(rr, req, viewer)
} else {
s.queriesPage(rr, req, viewer)
}
return rr
}
dash := get("/").Body.String()
for _, want := range []string{
`open 51`,
`is:open`,
`all 51 →`,
} {
if !strings.Contains(dash, want) {
t.Errorf("dashboard lacks %q", want)
}
}
first := get("/alice/-/queries/open")
if first.Code != http.StatusOK {
t.Fatalf("query page: %d %s", first.Code, first.Body.String())
}
body := first.Body.String()
if n := strings.Count(body, `alice/pub#`); n != queryPerPage {
t.Errorf("first page lists %d rows, want %d", n, queryPerPage)
}
if strings.Contains(body, "secret") || strings.Contains(dash, "secret") {
t.Error("a private repository of another user reached the page")
}
i := strings.Index(body, `