Files
fuj-management/go/internal/web/assets_test.go
Jan Novak d981392593
All checks were successful
Deploy to K8s / deploy (push) Successful in 8s
feat(go): M6.7 — single-binary embed verification
Add TestEmbedCompleteness and TestStaticAssetsServed in
go/internal/web/assets_test.go. The completeness guard walks the
on-disk templates/ and static/ directories and asserts every file is
present in the corresponding embed.FS, catching forgotten files on
future additions. The static mux test hits /static/css/app.css and all
JS files through the same http.FileServerFS wiring used in server.go,
confirming assets are served from the embedded FS with correct
Content-Type and a 404 for unknown paths.

Standalone binary smoke test passed manually: binary copied to /tmp
(no adjacent templates/ or static/), assets served correctly.

Closes M6.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 15:24:47 +02:00

94 lines
2.7 KiB
Go

package web
import (
"io/fs"
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"
)
// TestEmbedCompleteness guards against a new template or static file being
// added to disk but missing from the embedded FS (e.g. a new directory that
// the //go:embed glob does not match).
func TestEmbedCompleteness(t *testing.T) {
cases := []struct {
name string
diskDir string
embedFS fs.FS
embedRoot string
}{
{"templates", "templates", templateFS, "templates"},
{"static", "static", staticFS, "static"},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
diskFS := os.DirFS(tc.diskDir)
_ = fs.WalkDir(diskFS, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil || d.IsDir() {
return err
}
embPath := tc.embedRoot + "/" + path
if _, statErr := fs.Stat(tc.embedFS, embPath); statErr != nil {
t.Errorf("file %q exists on disk but is missing from embed.FS (%v)", embPath, statErr)
}
return nil
})
})
}
}
// TestStaticAssetsServed verifies that /static/* is served from the embedded
// FS through the same mux wiring used in server.go, so a standalone binary
// with no adjacent static/ directory still delivers assets.
func TestStaticAssetsServed(t *testing.T) {
subFS, err := fs.Sub(staticFS, "static")
if err != nil {
t.Fatalf("fs.Sub static: %v", err)
}
mux := http.NewServeMux()
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServerFS(subFS)))
cases := []struct {
path string
wantCT string
wantSnippet string
}{
{"/static/css/app.css", "text/css", "body {"},
{"/static/js/member-detail.js", "javascript", "Member-detail modal"},
{"/static/js/filters.js", "javascript", ""},
{"/static/js/payment-qr.js", "javascript", ""},
}
for _, tc := range cases {
t.Run(tc.path, func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, tc.path, nil)
w := httptest.NewRecorder()
mux.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("GET %s: status %d, want 200", tc.path, w.Code)
}
ct := w.Header().Get("Content-Type")
if !strings.Contains(ct, tc.wantCT) {
t.Errorf("GET %s: Content-Type %q, want it to contain %q", tc.path, ct, tc.wantCT)
}
if tc.wantSnippet != "" && !strings.Contains(w.Body.String(), tc.wantSnippet) {
t.Errorf("GET %s: body missing expected snippet %q", tc.path, tc.wantSnippet)
}
})
}
// Sanity: unknown path → 404 (file server doesn't fall through silently)
t.Run("missing-file", func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/static/css/nonexistent.css", nil)
w := httptest.NewRecorder()
mux.ServeHTTP(w, req)
if w.Code != http.StatusNotFound {
t.Errorf("unknown static path: status %d, want 404", w.Code)
}
})
}