claude-web-chat/files_test.go
djuka 3283888738
All checks were successful
Tests / unit-tests (push) Successful in 51s
Inicijalna implementacija Claude Web Chat (Faza 1 - CLI mod)
- Login sa session cookie autentifikacijom
- Lista projekata iz filesystem-a
- Chat sa Claude CLI preko WebSocket-a
- Streaming NDJSON parsiranje iz CLI stdout-a
- Sesija zivi nezavisno od browsera (reconnect replay)
- Sidebar sa .md fajlovima i markdown renderovanjem
- Dark tema, htmx + Go templates
- 47 unit testova

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 05:03:40 +00:00

126 lines
3.1 KiB
Go

package main
import (
"os"
"path/filepath"
"strings"
"testing"
)
func TestListMarkdownFiles(t *testing.T) {
dir := t.TempDir()
// Create test files
os.WriteFile(filepath.Join(dir, "README.md"), []byte("# Hello"), 0644)
os.WriteFile(filepath.Join(dir, "SPEC.md"), []byte("# Spec"), 0644)
os.WriteFile(filepath.Join(dir, "main.go"), []byte("package main"), 0644)
// Create docs subdirectory
os.MkdirAll(filepath.Join(dir, "docs"), 0755)
os.WriteFile(filepath.Join(dir, "docs", "ARCHITECTURE.md"), []byte("# Arch"), 0644)
os.WriteFile(filepath.Join(dir, "docs", "notes.txt"), []byte("not md"), 0644)
t.Run("lists only .md files", func(t *testing.T) {
files, err := ListMarkdownFiles(dir)
if err != nil {
t.Fatalf("ListMarkdownFiles: %v", err)
}
if len(files) != 3 {
t.Fatalf("got %d files, want 3", len(files))
}
})
t.Run("includes docs subdir", func(t *testing.T) {
files, err := ListMarkdownFiles(dir)
if err != nil {
t.Fatalf("ListMarkdownFiles: %v", err)
}
found := false
for _, f := range files {
if f.Name == "docs/ARCHITECTURE.md" {
found = true
break
}
}
if !found {
t.Error("should include docs/ARCHITECTURE.md")
}
})
t.Run("sorted", func(t *testing.T) {
files, err := ListMarkdownFiles(dir)
if err != nil {
t.Fatalf("ListMarkdownFiles: %v", err)
}
for i := 1; i < len(files); i++ {
if files[i].Name < files[i-1].Name {
t.Errorf("not sorted: %q before %q", files[i-1].Name, files[i].Name)
}
}
})
t.Run("nonexistent dir", func(t *testing.T) {
_, err := ListMarkdownFiles("/nonexistent")
if err == nil {
t.Fatal("expected error")
}
})
}
func TestReadFileContent(t *testing.T) {
dir := t.TempDir()
os.WriteFile(filepath.Join(dir, "test.md"), []byte("hello world"), 0644)
t.Run("reads file", func(t *testing.T) {
content, err := ReadFileContent(dir, "test.md")
if err != nil {
t.Fatalf("ReadFileContent: %v", err)
}
if content != "hello world" {
t.Errorf("content = %q", content)
}
})
t.Run("path traversal blocked", func(t *testing.T) {
_, err := ReadFileContent(dir, "../../etc/passwd")
if err == nil {
t.Fatal("expected error for path traversal")
}
if !strings.Contains(err.Error(), "path traversal") {
t.Errorf("error = %v, want path traversal error", err)
}
})
t.Run("file not found", func(t *testing.T) {
_, err := ReadFileContent(dir, "nonexistent.md")
if err == nil {
t.Fatal("expected error for nonexistent file")
}
})
}
func TestRenderMarkdownFile(t *testing.T) {
dir := t.TempDir()
os.WriteFile(filepath.Join(dir, "test.md"), []byte("# Hello\n\nWorld"), 0644)
t.Run("renders markdown", func(t *testing.T) {
html, err := RenderMarkdownFile(dir, "test.md")
if err != nil {
t.Fatalf("RenderMarkdownFile: %v", err)
}
if !strings.Contains(html, "<h1>Hello</h1>") {
t.Errorf("missing h1, got: %s", html)
}
if !strings.Contains(html, "<p>World</p>") {
t.Errorf("missing p, got: %s", html)
}
})
t.Run("path traversal blocked", func(t *testing.T) {
_, err := RenderMarkdownFile(dir, "../../../etc/passwd")
if err == nil {
t.Fatal("expected error for path traversal")
}
})
}