package server import ( "crypto/hmac" "crypto/sha256" "encoding/hex" "net/http" "net/http/httptest" "strings" "testing" "time" "git.wntrmute.dev/mc/mcdoc/internal/cache" "git.wntrmute.dev/mc/mcdoc/internal/render" ) func newTestServer(t *testing.T, c *cache.Cache, secret string) *Server { t.Helper() srv, err := New(Config{ Cache: c, WebhookSecret: secret, }) if err != nil { t.Fatalf("new server: %v", err) } return srv } func TestHealthNotReady(t *testing.T) { c := cache.New() srv := newTestServer(t, c, "") handler := srv.Handler() req := httptest.NewRequest(http.MethodGet, "/health", nil) w := httptest.NewRecorder() handler.ServeHTTP(w, req) if w.Code != http.StatusServiceUnavailable { t.Fatalf("expected 503, got %d", w.Code) } } func TestHealthReady(t *testing.T) { c := cache.New() c.SetReady() srv := newTestServer(t, c, "") handler := srv.Handler() req := httptest.NewRequest(http.MethodGet, "/health", nil) w := httptest.NewRecorder() handler.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d", w.Code) } } func TestIndexNotReady(t *testing.T) { c := cache.New() srv := newTestServer(t, c, "") handler := srv.Handler() req := httptest.NewRequest(http.MethodGet, "/", nil) w := httptest.NewRecorder() handler.ServeHTTP(w, req) if w.Code != http.StatusServiceUnavailable { t.Fatalf("expected 503, got %d", w.Code) } } func TestIndexReady(t *testing.T) { c := cache.New() c.SetRepo(&cache.RepoInfo{Name: "testrepo", Description: "A test"}) c.SetReady() srv := newTestServer(t, c, "") handler := srv.Handler() req := httptest.NewRequest(http.MethodGet, "/", nil) w := httptest.NewRecorder() handler.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d", w.Code) } if !strings.Contains(w.Body.String(), "testrepo") { t.Fatal("expected testrepo in index page") } } func TestRepoPage(t *testing.T) { c := cache.New() c.SetRepo(&cache.RepoInfo{ Name: "mcr", Docs: []*cache.Document{ {Repo: "mcr", URLPath: "README", Title: "README"}, }, }) c.SetReady() srv := newTestServer(t, c, "") handler := srv.Handler() req := httptest.NewRequest(http.MethodGet, "/mcr/", nil) w := httptest.NewRecorder() handler.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d", w.Code) } if !strings.Contains(w.Body.String(), "README") { t.Fatal("expected README in repo page") } } func TestRepoPageNotFound(t *testing.T) { c := cache.New() c.SetReady() srv := newTestServer(t, c, "") handler := srv.Handler() req := httptest.NewRequest(http.MethodGet, "/nonexistent/", nil) w := httptest.NewRecorder() handler.ServeHTTP(w, req) if w.Code != http.StatusNotFound { t.Fatalf("expected 404, got %d", w.Code) } } func TestDocPage(t *testing.T) { c := cache.New() c.SetRepo(&cache.RepoInfo{ Name: "mcr", Docs: []*cache.Document{ { Repo: "mcr", URLPath: "ARCHITECTURE", Title: "Architecture", HTML: "

Architecture

content

", Headings: []render.Heading{ {Level: 1, ID: "architecture", Text: "Architecture"}, }, }, }, }) c.SetReady() srv := newTestServer(t, c, "") handler := srv.Handler() req := httptest.NewRequest(http.MethodGet, "/mcr/ARCHITECTURE", nil) w := httptest.NewRecorder() handler.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d", w.Code) } body := w.Body.String() if !strings.Contains(body, "Architecture") { t.Fatal("expected Architecture in doc page") } if !strings.Contains(body, "content") { t.Fatal("expected rendered content in doc page") } } func TestDocPageNotFound(t *testing.T) { c := cache.New() c.SetRepo(&cache.RepoInfo{Name: "mcr"}) c.SetReady() srv := newTestServer(t, c, "") handler := srv.Handler() req := httptest.NewRequest(http.MethodGet, "/mcr/nonexistent", nil) w := httptest.NewRecorder() handler.ServeHTTP(w, req) if w.Code != http.StatusNotFound { t.Fatalf("expected 404, got %d", w.Code) } } func TestHTMXPartialResponse(t *testing.T) { c := cache.New() c.SetRepo(&cache.RepoInfo{Name: "r", Description: "test"}) c.SetReady() srv := newTestServer(t, c, "") handler := srv.Handler() req := httptest.NewRequest(http.MethodGet, "/", nil) req.Header.Set("HX-Request", "true") w := httptest.NewRecorder() handler.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d", w.Code) } body := w.Body.String() // Partial should not include the full layout (no tag) if strings.Contains(body, "