KAOS/code/internal/server/docs_test.go
djuka 098ed13705 T22: Reorganizacija testova + logs handler + konzola fix
- Razbijen monolitni server_test.go na fokusirane test fajlove:
  api_test.go, dashboard_test.go, docs_test.go, search_test.go,
  submit_test.go, task_detail_test.go, console_test.go, sse_test.go,
  timestamp_test.go, ui_test.go, test_helpers_test.go
- Dodat logs.go handler (handleLogsTail) koji je nedostajao
- Dodat LogFile u config
- Fix konzola: prompt se šalje preko fajla umesto direktno u PTY
- 192 testova prolazi

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 04:45:50 +00:00

202 lines
5.2 KiB
Go

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, "<table>") || !containsStr(body, "<th>") {
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, "<!DOCTYPE html>") {
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 := `<a href="README.md">link</a> and <a href="https://example.com">ext</a>`
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 := `<a href="CLAUDE.md">link</a>`
result := rewriteLinksSimple(input, "agents/coder")
if !containsStr(result, `/docs/agents/coder/CLAUDE.md`) {
t.Errorf("expected nested rewritten link, got: %s", result)
}
}