package api
import (
"context"
"encoding/json"
"net/http/httptest"
"strings"
"testing"
"craftdesign.group/quarry/internal/oltp"
"craftdesign.group/quarry/internal/ops"
)
// The base path lists every op, and a path one letter from a route is
// told the route.
func TestTheBasePathListsTheOpsAndANearMissIsTold(t *testing.T) {
r := ops.NewRegistry()
for _, route := range []string{"GET /api/v1/r/{repo}/landing/{id}", "GET /api/v1/r/{repo}/ci/runs/{runId}"} {
if err := ops.Register(r, ops.Op[ownerIn, struct{}]{Name: "t." + strings.Fields(route)[1], Kind: ops.Query, Auth: ops.Anonymous,
Route: route, Doc: "A test double. More words.",
Run: func(context.Context, ownerIn) (struct{}, error) { return struct{}{}, nil }}); err != nil {
t.Fatal(err)
}
}
h, err := RouterWithCaps(r, "test", func(_, _ string) CapSet { return oltp.CapSet("s") }, nil)
if err != nil {
t.Fatal(err)
}
get := func(path string) *httptest.ResponseRecorder {
w := httptest.NewRecorder()
h.ServeHTTP(w, httptest.NewRequest("GET", path, nil))
return w
}
for _, p := range []string{"/api/", "/api/v1", "/api/v1/"} {
w := get(p)
var idx struct {
OpenAPI string `json:"openapi"`
Ops []struct{ Op, Method, Route, Doc string }
}
if w.Code != 200 || json.Unmarshal(w.Body.Bytes(), &idx) != nil || idx.OpenAPI == "" || len(idx.Ops) != 2 || idx.Ops[0].Doc != "A test double" {
t.Errorf("FAIL: %s answered %d %s", p, w.Code, w.Body.String())
}
}
for _, c := range []struct{ path, want string }{
{"/api/v1/r/quarry/landings/1015", "/api/v1/r/quarry/landing/1015"},
{"/api/v1/r/quarry/ci/run/1b82c372", "/api/v1/r/quarry/ci/runs/1b82c372"},
{"/api/v1/r/quarry/nosuchop", ""},
} {
w := get(c.path)
body := w.Body.String()
if w.Code != 404 || !strings.Contains(body, "/api/v1") || (c.want != "") != strings.Contains(body, "did you mean") ||
(c.want != "" && !strings.Contains(body, c.want)) {
t.Errorf("FAIL: %s answered %d %s", c.path, w.Code, body)
}
}
}