package server import ( "net/http" "net/http/httptest" "testing" ) func TestDocsList(t *testing.T) { srv := setupTestServer(t) req := httptest.NewRequest(http.MethodGet, "/docs", nil) w := httptest.NewRecorder() srv.Router.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String()) } body := w.Body.String() if !containsStr(body, "CLAUDE.md") { t.Error("expected CLAUDE.md in docs list") } if !containsStr(body, "README.md") { t.Error("expected README.md in docs list") } if !containsStr(body, "agents/coder/CLAUDE.md") { t.Error("expected agents/coder/CLAUDE.md in docs list") } } func TestDocsView_CLAUDE(t *testing.T) { srv := setupTestServer(t) req := httptest.NewRequest(http.MethodGet, "/docs/CLAUDE.md", nil) w := httptest.NewRecorder() srv.Router.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String()) } body := w.Body.String() if !containsStr(body, "Glavni fajl") { t.Error("expected rendered markdown content") } // Should have table rendered as HTML if !containsStr(body, "") || !containsStr(body, "
") { t.Error("expected HTML table from markdown") } } func TestDocsView_NestedFile(t *testing.T) { srv := setupTestServer(t) req := httptest.NewRequest(http.MethodGet, "/docs/agents/coder/CLAUDE.md", nil) w := httptest.NewRecorder() srv.Router.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String()) } body := w.Body.String() if !containsStr(body, "Coder Agent") { t.Error("expected nested file content") } // Breadcrumbs if !containsStr(body, "agents") { t.Error("expected breadcrumb for agents") } } func TestDocsView_PathTraversal(t *testing.T) { srv := setupTestServer(t) req := httptest.NewRequest(http.MethodGet, "/docs/../../etc/passwd", nil) w := httptest.NewRecorder() srv.Router.ServeHTTP(w, req) if w.Code != http.StatusForbidden { t.Fatalf("expected 403 for path traversal, got %d", w.Code) } } func TestDocsView_NonMarkdown(t *testing.T) { srv := setupTestServer(t) req := httptest.NewRequest(http.MethodGet, "/docs/main.go", nil) w := httptest.NewRecorder() srv.Router.ServeHTTP(w, req) if w.Code != http.StatusForbidden { t.Fatalf("expected 403 for non-.md file, got %d", w.Code) } } func TestDocsView_NotFound(t *testing.T) { srv := setupTestServer(t) req := httptest.NewRequest(http.MethodGet, "/docs/nonexistent.md", nil) w := httptest.NewRecorder() srv.Router.ServeHTTP(w, req) if w.Code != http.StatusNotFound { t.Fatalf("expected 404, got %d", w.Code) } } func TestDocsView_HasBreadcrumbs(t *testing.T) { srv := setupTestServer(t) req := httptest.NewRequest(http.MethodGet, "/docs/agents/coder/CLAUDE.md", nil) w := httptest.NewRecorder() srv.Router.ServeHTTP(w, req) body := w.Body.String() if !containsStr(body, "Dokumenti") { t.Error("expected 'Dokumenti' in breadcrumbs") } if !containsStr(body, "coder") { t.Error("expected 'coder' in breadcrumbs") } } func TestDocsView_HasSidebarLayout(t *testing.T) { srv := setupTestServer(t) req := httptest.NewRequest(http.MethodGet, "/docs/CLAUDE.md", nil) w := httptest.NewRecorder() srv.Router.ServeHTTP(w, req) body := w.Body.String() if !containsStr(body, "docs-layout") { t.Error("expected docs-layout class for grid layout") } if !containsStr(body, "docs-sidebar") { t.Error("expected docs-sidebar class") } if !containsStr(body, "docs-main") { t.Error("expected docs-main class") } // Sidebar should list files if !containsStr(body, "README.md") { t.Error("expected file list in sidebar") } } func TestDocsView_HTMXReturnsFragment(t *testing.T) { srv := setupTestServer(t) req := httptest.NewRequest(http.MethodGet, "/docs/CLAUDE.md", nil) req.Header.Set("HX-Request", "true") w := httptest.NewRecorder() srv.Router.ServeHTTP(w, req) body := w.Body.String() // Should NOT have full page HTML if containsStr(body, "") { t.Error("HTMX request should return fragment, not full page") } // Should have breadcrumbs and content if !containsStr(body, "Dokumenti") { t.Error("expected breadcrumbs in fragment") } if !containsStr(body, "Glavni fajl") { t.Error("expected rendered content in fragment") } } func TestDocsList_HasSidebarLayout(t *testing.T) { srv := setupTestServer(t) req := httptest.NewRequest(http.MethodGet, "/docs", nil) w := httptest.NewRecorder() srv.Router.ServeHTTP(w, req) body := w.Body.String() if !containsStr(body, "docs-layout") { t.Error("expected docs-layout class on docs list page") } } func TestRewriteLinksSimple(t *testing.T) { input := `link and ext` result := rewriteLinksSimple(input, ".") if !containsStr(result, `/docs/README.md`) { t.Errorf("expected rewritten link, got: %s", result) } if !containsStr(result, `https://example.com`) { t.Error("external link should not be rewritten") } } func TestRewriteLinksSimple_NestedDir(t *testing.T) { input := `link` result := rewriteLinksSimple(input, "agents/coder") if !containsStr(result, `/docs/agents/coder/CLAUDE.md`) { t.Errorf("expected nested rewritten link, got: %s", result) } }