mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 02:25:56 +00:00
Test: improve frontend embedding coverage
Enhance tests for frontend embedding to cover filesystem overrides, dev proxy configuration, and SPA header handling.
This commit is contained in:
@@ -5,7 +5,6 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
@@ -17,81 +16,122 @@ func resetDevProxy() {
|
||||
devProxyErr = nil
|
||||
}
|
||||
|
||||
func writeFile(t *testing.T, dir, name, content string) {
|
||||
t.Helper()
|
||||
path := filepath.Join(dir, name)
|
||||
if err := os.WriteFile(path, []byte(content), 0644); err != nil {
|
||||
t.Fatalf("write file: %v", err)
|
||||
func TestGetFrontendDevProxy(t *testing.T) {
|
||||
resetDevProxy()
|
||||
t.Setenv("FRONTEND_DEV_SERVER", "http://localhost:1234")
|
||||
|
||||
proxy, err := getFrontendDevProxy()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if proxy == nil {
|
||||
t.Fatalf("expected proxy to be initialized")
|
||||
}
|
||||
|
||||
resetDevProxy()
|
||||
t.Setenv("FRONTEND_DEV_SERVER", "://bad-url")
|
||||
if _, err := getFrontendDevProxy(); err == nil {
|
||||
t.Fatalf("expected error for invalid URL")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFrontendFSOverride(t *testing.T) {
|
||||
resetDevProxy()
|
||||
dir := t.TempDir()
|
||||
writeFile(t, dir, "index.html", "<html>ok</html>")
|
||||
t.Setenv("PULSE_FRONTEND_DIR", dir)
|
||||
|
||||
fsys, err := getFrontendFS()
|
||||
if err != nil {
|
||||
t.Fatalf("getFrontendFS error: %v", err)
|
||||
func TestGetFrontendFS_Override(t *testing.T) {
|
||||
tmp := t.TempDir()
|
||||
indexPath := tmp + "/index.html"
|
||||
if err := os.WriteFile(indexPath, []byte("hello"), 0o644); err != nil {
|
||||
t.Fatalf("write index: %v", err)
|
||||
}
|
||||
|
||||
f, err := fsys.Open("index.html")
|
||||
t.Setenv("PULSE_FRONTEND_DIR", tmp)
|
||||
fs, err := getFrontendFS()
|
||||
if err != nil {
|
||||
t.Fatalf("getFrontendFS: %v", err)
|
||||
}
|
||||
|
||||
f, err := fs.Open("index.html")
|
||||
if err != nil {
|
||||
t.Fatalf("open index: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
data, err := io.ReadAll(f)
|
||||
content, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
t.Fatalf("read index: %v", err)
|
||||
}
|
||||
if string(data) != "<html>ok</html>" {
|
||||
t.Fatalf("unexpected content: %s", string(data))
|
||||
if string(content) != "hello" {
|
||||
t.Fatalf("unexpected content: %q", string(content))
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeFrontendHandler(t *testing.T) {
|
||||
func TestServeFrontendHandler_StaticAndSPA(t *testing.T) {
|
||||
resetDevProxy()
|
||||
dir := t.TempDir()
|
||||
writeFile(t, dir, "index.html", "<html>index</html>")
|
||||
writeFile(t, dir, "app-123.js", "console.log('ok');")
|
||||
t.Setenv("PULSE_FRONTEND_DIR", dir)
|
||||
t.Setenv("FRONTEND_DEV_SERVER", "")
|
||||
tmp := t.TempDir()
|
||||
if err := os.MkdirAll(tmp+"/assets", 0o755); err != nil {
|
||||
t.Fatalf("mkdir assets: %v", err)
|
||||
}
|
||||
if err := os.WriteFile(tmp+"/index.html", []byte("<html>ok</html>"), 0o644); err != nil {
|
||||
t.Fatalf("write index: %v", err)
|
||||
}
|
||||
if err := os.WriteFile(tmp+"/logo.svg", []byte("<svg></svg>"), 0o644); err != nil {
|
||||
t.Fatalf("write svg: %v", err)
|
||||
}
|
||||
if err := os.WriteFile(tmp+"/assets/index-abc123.css", []byte("body{}"), 0o644); err != nil {
|
||||
t.Fatalf("write css: %v", err)
|
||||
}
|
||||
t.Setenv("PULSE_FRONTEND_DIR", tmp)
|
||||
|
||||
handler := serveFrontendHandler()
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
||||
handler(rec, req)
|
||||
if rec.Code != http.StatusOK || !strings.Contains(rec.Body.String(), "index") {
|
||||
t.Fatalf("unexpected root response: %d %s", rec.Code, rec.Body.String())
|
||||
}
|
||||
if rec.Header().Get("Cache-Control") == "" {
|
||||
t.Fatal("expected cache headers for index")
|
||||
}
|
||||
|
||||
rec = httptest.NewRecorder()
|
||||
req = httptest.NewRequest(http.MethodGet, "/app-123.js", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
handler(rec, req)
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("unexpected asset response: %d", rec.Code)
|
||||
t.Fatalf("root status = %d", rec.Code)
|
||||
}
|
||||
if !strings.Contains(rec.Header().Get("Cache-Control"), "immutable") {
|
||||
t.Fatalf("expected immutable cache header, got %s", rec.Header().Get("Cache-Control"))
|
||||
if ct := rec.Header().Get("Content-Type"); !strings.Contains(ct, "text/html") {
|
||||
t.Fatalf("expected html content type, got %q", ct)
|
||||
}
|
||||
if cc := rec.Header().Get("Cache-Control"); cc == "" {
|
||||
t.Fatalf("expected cache control headers")
|
||||
}
|
||||
|
||||
req = httptest.NewRequest(http.MethodGet, "/assets/index-abc123.css", nil)
|
||||
rec = httptest.NewRecorder()
|
||||
req = httptest.NewRequest(http.MethodGet, "/missing", nil)
|
||||
handler(rec, req)
|
||||
if rec.Code != http.StatusOK || !strings.Contains(rec.Body.String(), "index") {
|
||||
t.Fatalf("expected SPA fallback, got %d %s", rec.Code, rec.Body.String())
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("hashed css status = %d", rec.Code)
|
||||
}
|
||||
if cc := rec.Header().Get("Cache-Control"); !strings.Contains(cc, "immutable") {
|
||||
t.Fatalf("expected immutable cache control, got %q", cc)
|
||||
}
|
||||
|
||||
req = httptest.NewRequest(http.MethodGet, "/logo.svg", nil)
|
||||
rec = httptest.NewRecorder()
|
||||
handler(rec, req)
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("svg status = %d", rec.Code)
|
||||
}
|
||||
if ct := rec.Header().Get("Content-Type"); ct != "image/svg+xml" {
|
||||
t.Fatalf("expected svg content type, got %q", ct)
|
||||
}
|
||||
if cc := rec.Header().Get("Cache-Control"); !strings.Contains(cc, "no-cache") {
|
||||
t.Fatalf("expected no-cache headers, got %q", cc)
|
||||
}
|
||||
|
||||
req = httptest.NewRequest(http.MethodGet, "/app/settings", nil)
|
||||
rec = httptest.NewRecorder()
|
||||
handler(rec, req)
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("spa route status = %d", rec.Code)
|
||||
}
|
||||
if ct := rec.Header().Get("Content-Type"); !strings.Contains(ct, "text/html") {
|
||||
t.Fatalf("expected html content type for spa, got %q", ct)
|
||||
}
|
||||
|
||||
req = httptest.NewRequest(http.MethodGet, "/api/unknown", nil)
|
||||
rec = httptest.NewRecorder()
|
||||
req = httptest.NewRequest(http.MethodGet, "/api/test", nil)
|
||||
handler(rec, req)
|
||||
if rec.Code != http.StatusNotFound {
|
||||
t.Fatalf("expected 404 for api path, got %d", rec.Code)
|
||||
t.Fatalf("api route status = %d", rec.Code)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user