package api import ( "html/template" "io" "log" "net/http" "net/http/httptest" "os" "path/filepath" "strings" "testing" "github.com/mathieu/personotes/internal/indexer" ) func newTestHandler(t *testing.T, notesDir string) *Handler { t.Helper() tpl, err := template.New("").Parse(` {{define "search-results.html"}} Query: {{.Query}}, Count: {{len .Results}} {{range .Results}} {{.Path}}|{{.Title}} {{end}} {{end}} {{define "editor.html"}} Filename: {{.Filename}}, Content: {{.Content}} {{end}} `) if err != nil { t.Fatalf("impossible d'analyser les templates de test: %v", err) } return NewHandler(notesDir, indexer.New(), tpl, log.New(io.Discard, "", 0)) } func TestHandler_Search(t *testing.T) { dir := t.TempDir() if err := os.WriteFile(filepath.Join(dir, "test.md"), []byte("---\ntags: [foo]\n---\ncorps"), 0o644); err != nil { t.Fatal(err) } handler := newTestHandler(t, dir) if err := handler.idx.Load(dir); err != nil { t.Fatal(err) } req := httptest.NewRequest(http.MethodGet, "/api/search?query=foo", nil) rec := httptest.NewRecorder() handler.ServeHTTP(rec, req) if rec.Code != http.StatusOK { t.Fatalf("code de statut attendu %d, obtenu %d", http.StatusOK, rec.Code) } body := strings.TrimSpace(rec.Body.String()) if !strings.Contains(body, "Query: foo, Count: 1") { t.Fatalf("corps de réponse inattendu: %s", body) } if !strings.Contains(body, "test.md|Test") { t.Fatalf("résultat de recherche manquant dans: %s", body) } } func TestHandler_GetNote(t *testing.T) { dir := t.TempDir() content := "hello world" if err := os.WriteFile(filepath.Join(dir, "test.md"), []byte(content), 0o644); err != nil { t.Fatal(err) } handler := newTestHandler(t, dir) req := httptest.NewRequest(http.MethodGet, "/api/notes/test.md", nil) rec := httptest.NewRecorder() handler.ServeHTTP(rec, req) if rec.Code != http.StatusOK { t.Fatalf("code de statut attendu %d, obtenu %d", http.StatusOK, rec.Code) } body := strings.TrimSpace(rec.Body.String()) expected := "Filename: test.md, Content: hello world" if body != expected { t.Fatalf("corps de réponse attendu '%s', obtenu '%s'", expected, body) } } func TestHandler_PostNote(t *testing.T) { dir := t.TempDir() handler := newTestHandler(t, dir) form := "content=new content" req := httptest.NewRequest(http.MethodPost, "/api/notes/new.md", strings.NewReader(form)) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") rec := httptest.NewRecorder() handler.ServeHTTP(rec, req) if rec.Code != http.StatusOK { t.Fatalf("code de statut attendu %d, obtenu %d", http.StatusOK, rec.Code) } body := rec.Body.String() if body != "Enregistré !" { t.Fatalf("corps de réponse attendu 'Enregistré !', obtenu '%s'", body) } savedContent, err := os.ReadFile(filepath.Join(dir, "new.md")) if err != nil { t.Fatalf("impossible de lire le fichier sauvegardé: %v", err) } if string(savedContent) != "new content" { t.Fatalf("contenu de fichier attendu 'new content', obtenu '%s'", string(savedContent)) } }