feat(api): add file listing endpoint

- Add GET /api endpoint to list all markdown files
- Filter to only include .md files
- Return JSON response with files array
- Add comprehensive tests for file listing functionality
This commit is contained in:
2026-02-06 21:23:59 -05:00
parent 2a9e793971
commit a074f5a854
4 changed files with 224 additions and 193 deletions

View File

@@ -0,0 +1,141 @@
package main
import (
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
"github.com/evanreichard/markdown-editor/internal/api"
"github.com/evanreichard/markdown-editor/internal/logger"
"github.com/gorilla/mux"
"github.com/stretchr/testify/assert"
)
func TestFileListing(t *testing.T) {
dataDir, err := setupTestDir()
if err != nil {
t.Fatalf("Failed to create test dir: %v", err)
}
defer cleanupTestDir(dataDir)
// Create some test files
testFiles := []string{
"file1.md",
"file2.md",
"file3.md",
}
for _, filename := range testFiles {
filepath := filepath.Join(dataDir, filename)
content := "# " + filename + "\n\nContent of " + filename
if err := os.WriteFile(filepath, []byte(content), 0644); err != nil {
t.Fatalf("Failed to create test file %s: %v", filename, err)
}
}
log := logger.NewLogger()
handler := api.NewAPIHandler(dataDir, log)
router := mux.NewRouter()
router.Handle("/api", handler).Methods("GET")
router.Handle("/api/{filename:.+\\.md}", handler)
// Test GET /api (list files)
req := httptest.NewRequest("GET", "/api", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var response struct {
Files []string `json:"files"`
}
body, _ := io.ReadAll(w.Body)
assert.NoError(t, json.Unmarshal(body, &response))
// Verify all test files are returned
assert.Len(t, response.Files, 3)
assert.Contains(t, response.Files, "file1.md")
assert.Contains(t, response.Files, "file2.md")
assert.Contains(t, response.Files, "file3.md")
}
func TestFileListingWithNonMarkdownFiles(t *testing.T) {
dataDir, err := setupTestDir()
if err != nil {
t.Fatalf("Failed to create test dir: %v", err)
}
defer cleanupTestDir(dataDir)
// Create test files including non-markdown files
testFiles := []string{
"file1.md",
"file2.txt",
"file3.md",
"file4.log",
}
for _, filename := range testFiles {
filepath := filepath.Join(dataDir, filename)
content := "Content of " + filename
if err := os.WriteFile(filepath, []byte(content), 0644); err != nil {
t.Fatalf("Failed to create test file %s: %v", filename, err)
}
}
log := logger.NewLogger()
handler := api.NewAPIHandler(dataDir, log)
router := mux.NewRouter()
router.Handle("/api", handler).Methods("GET")
router.Handle("/api/{filename:.+\\.md}", handler)
// Test GET /api (list files)
req := httptest.NewRequest("GET", "/api", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var response struct {
Files []string `json:"files"`
}
body, _ := io.ReadAll(w.Body)
assert.NoError(t, json.Unmarshal(body, &response))
// Verify only markdown files are returned
assert.Len(t, response.Files, 2)
assert.Contains(t, response.Files, "file1.md")
assert.Contains(t, response.Files, "file3.md")
assert.NotContains(t, response.Files, "file2.txt")
assert.NotContains(t, response.Files, "file4.log")
}
func TestFileListingEmptyDirectory(t *testing.T) {
dataDir, err := setupTestDir()
if err != nil {
t.Fatalf("Failed to create test dir: %v", err)
}
defer cleanupTestDir(dataDir)
log := logger.NewLogger()
handler := api.NewAPIHandler(dataDir, log)
router := mux.NewRouter()
router.Handle("/api", handler).Methods("GET")
router.Handle("/api/{filename:.+\\.md}", handler)
// Test GET /api (list files in empty directory)
req := httptest.NewRequest("GET", "/api", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
var response struct {
Files []string `json:"files"`
}
body, _ := io.ReadAll(w.Body)
assert.NoError(t, json.Unmarshal(body, &response))
// Verify empty array is returned
assert.Len(t, response.Files, 0)
}