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>
49 lines
1.6 KiB
Go
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"))
|
|
}
|
|
}
|
|
}
|