package test import ( "io" "net/http" "net/http/httptest" "os" "path/filepath" "strings" "testing" "github.com/evanreichard/markdown-editor/internal/api" "github.com/evanreichard/markdown-editor/internal/logging" "github.com/evanreichard/markdown-editor/internal/router" "github.com/evanreichard/markdown-editor/internal/storage" ) func TestStaticAssets(t *testing.T) { // Create temporary directories tmpDataDir, err := os.MkdirTemp("", "markdown-data-*") if err != nil { t.Fatalf("Failed to create temp data dir: %v", err) } defer os.RemoveAll(tmpDataDir) tmpStaticDir, err := os.MkdirTemp("", "markdown-static-*") if err != nil { t.Fatalf("Failed to create temp static dir: %v", err) } defer os.RemoveAll(tmpStaticDir) // Create a test static file testHTML := "Test" err = os.WriteFile(filepath.Join(tmpStaticDir, "index.html"), []byte(testHTML), 0644) if err != nil { t.Fatalf("Failed to create test file: %v", err) } // Initialize storage and handlers store, err := storage.New(tmpDataDir) if err != nil { t.Fatalf("Failed to create storage: %v", err) } handlers := api.New(store) // Create router with static directory mux := router.New(handlers, tmpStaticDir) // Create test server ts := httptest.NewServer(mux) defer ts.Close() // Test serving index.html resp, err := http.Get(ts.URL + "/") if err != nil { t.Fatalf("Failed to get index.html: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Errorf("Expected status 200, got %d", resp.StatusCode) } body, err := io.ReadAll(resp.Body) if err != nil { t.Fatalf("Failed to read response body: %v", err) } if strings.TrimSpace(string(body)) != strings.TrimSpace(testHTML) { t.Errorf("Response body mismatch") } t.Log("Static assets test passed") } func TestAPIRoutes(t *testing.T) { logging.Init() tmpDir, err := os.MkdirTemp("", "markdown-api-*") if err != nil { t.Fatalf("Failed to create temp dir: %v", err) } defer os.RemoveAll(tmpDir) store, err := storage.New(tmpDir) if err != nil { t.Fatalf("Failed to create storage: %v", err) } handlers := api.New(store) mux := router.New(handlers, "") ts := httptest.NewServer(mux) defer ts.Close() // Test GET /api/files (empty) resp, err := http.Get(ts.URL + "/api/files") if err != nil { t.Fatalf("Failed to get files: %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Errorf("Expected status 200 for empty list, got %d", resp.StatusCode) } // Test POST /api/files reqBody := `{"name":"test.md","content":"# Test"}` resp, err = http.Post(ts.URL+"/api/files", "application/json", strings.NewReader(reqBody)) if err != nil { t.Fatalf("Failed to create file: %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusCreated { t.Errorf("Expected status 201 for create, got %d", resp.StatusCode) } // Test GET /api/files (with file) resp, err = http.Get(ts.URL + "/api/files") if err != nil { t.Fatalf("Failed to get files: %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Errorf("Expected status 200 for list, got %d", resp.StatusCode) } // Test GET /api/files/test.md resp, err = http.Get(ts.URL + "/api/files/test.md") if err != nil { t.Fatalf("Failed to get file: %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Errorf("Expected status 200 for get, got %d", resp.StatusCode) } // Test PUT /api/files/test.md reqBody = `{"content":"# Updated"}` req, _ := http.NewRequest("PUT", ts.URL+"/api/files/test.md", strings.NewReader(reqBody)) req.Header.Set("Content-Type", "application/json") resp, err = http.DefaultClient.Do(req) if err != nil { t.Fatalf("Failed to update file: %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Errorf("Expected status 200 for update, got %d", resp.StatusCode) } // Test DELETE /api/files/test.md req, _ = http.NewRequest("DELETE", ts.URL+"/api/files/test.md", nil) resp, err = http.DefaultClient.Do(req) if err != nil { t.Fatalf("Failed to delete file: %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusNoContent { t.Errorf("Expected status 204 for delete, got %d", resp.StatusCode) } t.Log("API routes test passed") } func TestErrorResponses(t *testing.T) { tmpDir, err := os.MkdirTemp("", "markdown-error-*") if err != nil { t.Fatalf("Failed to create temp dir: %v", err) } defer os.RemoveAll(tmpDir) store, err := storage.New(tmpDir) if err != nil { t.Fatalf("Failed to create storage: %v", err) } handlers := api.New(store) mux := router.New(handlers, "") ts := httptest.NewServer(mux) defer ts.Close() // Test 404 for non-existent file resp, err := http.Get(ts.URL + "/api/files/nonexistent.md") if err != nil { t.Fatalf("Failed to get file: %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusNotFound { t.Errorf("Expected status 404, got %d", resp.StatusCode) } // Test 400 for invalid name resp, err = http.Get(ts.URL + "/api/files/invalid.txt") if err != nil { t.Fatalf("Failed to get file: %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusBadRequest { t.Errorf("Expected status 400, got %d", resp.StatusCode) } t.Log("Error responses test passed") }