package web import ( "io" "log/slog" "net/http" "net/http/httptest" "strings" "testing" llmgw "gitea.mynodes.xyz/ilker/llmgw" "gitea.mynodes.xyz/ilker/llmgw/internal/store" ) // docsMux mounts the portal the way the router does. func docsMux(h http.HandlerFunc) *http.ServeMux { mux := http.NewServeMux() mux.HandleFunc("GET /docs", h) mux.HandleFunc("GET /docs/{doc}", h) return mux } func TestTheDocsPortalRendersADocumentWithItsHeadingsAndCode(t *testing.T) { code, body := get(t, docsMux(Docs("v1", false)), "/docs/clients", nil) if code != http.StatusOK { t.Fatalf("status %d", code) } for _, want := range []string{ `
`,
`client.chat.completions.create(`,
// Tables are GitHub's.
``,
// The sidebar offers every document and marks the open one.
`Using llmgw from code`,
``,
// And this document's sections beneath it.
`The Anthropic SDK`,
} {
if !strings.Contains(body, want) {
t.Errorf("the page lacks %q", want)
}
}
}
func TestEveryDocumentInTheManualIsAPage(t *testing.T) {
h := docsMux(Docs("v1", false))
for _, d := range llmgw.Manual() {
if code, _ := get(t, h, "/docs/"+d.Key, nil); code != http.StatusOK {
t.Errorf("/docs/%s: %d", d.Key, code)
}
}
}
func TestTheIndexLeadsWithTheClientGuide(t *testing.T) {
code, body := get(t, docsMux(Docs("v1", true)), "/docs", nil)
if code != http.StatusOK {
t.Fatalf("status %d", code)
}
lead := strings.Index(body, `Using llmgw from code shows`)
every := strings.Index(body, "Every document")
if lead < 0 || every < 0 || lead > every {
t.Errorf("the client guide is not offered first:\n%s", body)
}
if !strings.Contains(body, `Sign in`) {
t.Error("a gateway with accounts does not offer to sign in")
}
}
func TestLinksBetweenDocumentsStayInThePortal(t *testing.T) {
paths := map[string]string{"docs/install.md": "install", "docs/guardrails.md": "guardrails",
"README.md": "readme", "CHANGELOG.md": "changes"}
src := "See [install](install.md), [a section](install.md#2-the-control-plane), " +
"[here](#local), [the readme](../README.md), [proxies](../deploy/proxy/), " +
"[the plan](llmgw-plan.md) and [elsewhere](https://example.com/x.md).\n"
body, _ := renderDoc(src, "docs/guardrails.md", paths)
for _, want := range []string{
`href="/docs/install"`,
`href="/docs/install#2-the-control-plane"`,
`href="#local"`,
`href="/docs/readme"`,
// Not in the binary: the repository has it.
`href="` + repoURL + `/src/branch/main/deploy/proxy/"`,
`href="` + repoURL + `/src/branch/main/docs/llmgw-plan.md"`,
`href="https://example.com/x.md"`,
} {
if !strings.Contains(string(body), want) {
t.Errorf("rendered without %s:\n%s", want, body)
}
}
// The README links into docs/ from the repository's root.
body, _ = renderDoc("[guardrails](docs/guardrails.md)\n", "README.md", paths)
if !strings.Contains(string(body), `href="/docs/guardrails"`) {
t.Errorf("a link from the README: %s", body)
}
}
func TestNoEmbeddedDocumentLinksToAPageThePortalLacks(t *testing.T) {
// Every link a document makes into /docs/ must land on a page, or the
// portal ships its own 404s.
keys := map[string]bool{}
for _, d := range manual() {
keys[d.Key] = true
}
for _, d := range manual() {
for _, part := range strings.Split(string(d.Body), `href="/docs/`)[1:] {
key := part[:strings.IndexAny(part, `"#`)]
if !keys[key] {
t.Errorf("%s links to /docs/%s, which is not a page", d.Key, key)
}
}
}
}
func TestAnUnknownDocumentIsNotFound(t *testing.T) {
h := docsMux(Docs("v1", false))
for _, path := range []string{"/docs/no-such-doc", "/docs/..%2fgo.mod", "/docs/BACKLOG"} {
if code, _ := get(t, h, path, nil); code != http.StatusNotFound {
t.Errorf("%s: %d, want 404", path, code)
}
}
// The file name works as well as the key: it is what the documents say.
if code, _ := get(t, h, "/docs/install.md", nil); code != http.StatusOK {
t.Errorf("/docs/install.md: %d", code)
}
}
func TestTheDocsCarryThePolicyAndNoScript(t *testing.T) {
for _, path := range []string{"/docs", "/docs/clients", "/docs/reference", "/docs/readme"} {
rec := httptest.NewRecorder()
docsMux(Docs("v1", false)).ServeHTTP(rec, httptest.NewRequest("GET", path, nil))
csp := rec.Header().Get("Content-Security-Policy")
if !strings.Contains(csp, "script-src 'self';") || strings.Contains(csp, "sha256-") {
t.Errorf("%s: policy %q, want this server's scripts and no inline one", path, csp)
}
if strings.Contains(strings.ToLower(rec.Body.String()), "