Files
Ilker ManapandClaude Opus 5.5 bd439aca29 A docs portal at /docs and a client developer's guide
The manual the binary carries, rendered on the client port: a sidebar of
the documents in the console's reading order (now one list, llmgw.Manual,
for both), heading anchors, links between documents kept in the portal and
links to files outside the binary sent to the repository, no script.
Public by default; landing.docs_sign_in sends visitors to sign in first.

docs/clients.md shows the official OpenAI and Anthropic SDKs against
llmgw in Python, TypeScript, Go and curl, with llmgw's headers; the
portal's index, the landing page and the account page link to it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-04 23:46:42 +02:00

49 lines
1.6 KiB
Go

package router
import (
"net/http"
"net/http/httptest"
"path/filepath"
"strings"
"testing"
"gitea.mynodes.xyz/ilker/llmgw/internal/config"
)
func docsRouter(t *testing.T, signIn bool) http.Handler {
t.Helper()
cfg := baseConfig(config.Endpoint{ID: "a", URL: "http://127.0.0.1:1", Models: []string{"m"}})
cfg.Auth.Enabled = true
cfg.Auth.Store = filepath.Join(t.TempDir(), "store.db")
cfg.Landing.DocsSignIn = signIn
return newTestRouter(t, cfg).Handler()
}
// The docs are public by default on a gateway with keys: the client guide is
// for the person who has none yet, so asking for one first defeats it.
func TestTheDocsAreServedWithoutAKey(t *testing.T) {
h := docsRouter(t, false)
for _, path := range []string{"/docs", "/docs/clients"} {
w := httptest.NewRecorder()
h.ServeHTTP(w, httptest.NewRequest(http.MethodGet, path, nil))
if w.Code != http.StatusOK || !strings.Contains(w.Body.String(), "llmgw docs") {
t.Errorf("%s: %d %.200s", path, w.Code, w.Body.String())
}
}
}
func TestDocsSignInSendsAVisitorToSignIn(t *testing.T) {
h := docsRouter(t, true)
for _, path := range []string{"/docs", "/docs/install"} {
w := httptest.NewRecorder()
h.ServeHTTP(w, httptest.NewRequest(http.MethodGet, path, nil))
// The session guard, not the key check: a browser has no key.
if strings.Contains(w.Body.String(), "api key") {
t.Errorf("%s asked a browser for an API key", path)
}
if w.Code != http.StatusSeeOther || w.Header().Get("Location") != "/login" {
t.Errorf("%s: %d to %q, want a redirect to /login", path, w.Code, w.Header().Get("Location"))
}
}
}