package web
import (
"context"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"craftdesign.group/quarry/internal/ops"
)
type namedStubIn struct {
Repo string `json:"repo"`
Number int `json:"number"`
}
type namedStubOut struct {
Tickets []namedRow `json:"tickets"`
}
// Typing a ticket's number into the tracker filter opens that ticket;
// the digits used to be searched for in titles, so "100" found #326
// ("...the edge's 100 MB cap") and never #100.
func TestATicketNumberInTheFilterOpensTheTicket(t *testing.T) {
r := viewRegistry(t, nil)
if err := ops.Register(r, ops.Op[namedStubIn, namedStubOut]{
Name: "ticket.named", Caps: "r", Doc: "test stub", Kind: ops.Query, Auth: ops.Anonymous,
Route: "GET /api/v1/r/{repo}/ticket/named/{number}",
Run: func(_ context.Context, in namedStubIn) (namedStubOut, error) {
if in.Number == 100 {
return namedStubOut{Tickets: []namedRow{{ID: "b73c6408dafe85b4"}}}, nil
}
return namedStubOut{Tickets: []namedRow{}}, nil
},
}); err != nil {
t.Fatal(err)
}
srv := httptest.NewServer(HandlerWith(r, nil, nil, nil))
defer srv.Close()
c := srv.Client()
c.CheckRedirect = func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }
for _, tc := range []struct{ q, want string }{
{"100", "/r/alpha/ticket/100"},
{"#100", "/r/alpha/ticket/100"},
{"is:closed 100", "/r/alpha/ticket/100"},
// No ticket by that number: the digits are text to search.
{"7", "/r/alpha/ticket?title=7"},
// Words around the number make it a search.
{"100 MB", "/r/alpha/ticket?title=100+MB"},
} {
resp, err := c.Get(srv.URL + "/r/alpha/ticket?q=" + url.QueryEscape(tc.q))
if err != nil {
t.Fatal(err)
}
resp.Body.Close()
if got := resp.Header.Get("Location"); resp.StatusCode != http.StatusSeeOther || got != tc.want {
t.Errorf("FAIL: q=%q went to %d %q, want %q", tc.q, resp.StatusCode, got, tc.want)
}
}
t.Log("ok: a number opens its ticket; anything else stays a search")
}