package movementtest import ( "net/http" "net/http/httptest" "regexp" "strings" "testing" movement "amadan.net/carlos/movement/internal/movement" ) // hashedStylesheet is the fingerprinted URL shape the index page // links: /static/tokens.<16 hex>.css. var hashedStylesheet = regexp.MustCompile(`/static/tokens\.[0-9a-f]{16}\.css`) func TestIndexRenders(t *testing.T) { rec := get(t, newApp(t), "/") if rec.Code != http.StatusOK { t.Fatalf("GET /: status %d, want 200", rec.Code) } // The heading comes from the copy table, not from the template, so this // asserts the wiring rather than the words. When copy review replaces // the placeholder, this test does not need to change — which is the // point of holding copy separately. if !strings.Contains(rec.Body.String(), movement.T("index.headline")) { t.Errorf("GET /: page is missing its heading:\n%s", rec.Body.String()) } } func TestIndexLinksFingerprintedStylesheet(t *testing.T) { h := newApp(t) href := hashedStylesheet.FindString(get(t, h, "/").Body.String()) if href == "" { t.Fatal("index page links no fingerprinted stylesheet") } rec := get(t, h, href) if rec.Code != http.StatusOK { t.Fatalf("GET %s: status %d, want 200", href, rec.Code) } if got := rec.Header().Get("Cache-Control"); got != "public, max-age=31536000, immutable" { t.Errorf("GET %s: Cache-Control = %q, want immutable year", href, got) } } // The bare name keeps working, just never long-cached — so a changed // file always shows on an ordinary reload. func TestBareAssetNameStaysFresh(t *testing.T) { rec := get(t, newApp(t), "/static/tokens.css") if rec.Code != http.StatusOK { t.Fatalf("GET /static/tokens.css: status %d, want 200", rec.Code) } if got := rec.Header().Get("Cache-Control"); got != "no-cache" { t.Errorf("Cache-Control = %q, want no-cache", got) } } // ErrorPage is what main.go points Options.ErrorPage at (and the seam // to wire into Ctx.ErrorPage as handlers grow); called directly, it // pins that a panic's page is the framework's error-page partial, not // a stray net/http default. func TestErrorPageRendersFrameworkPartial(t *testing.T) { rec := httptest.NewRecorder() movement.ErrorPage(rec, httptest.NewRequest(http.MethodGet, "/", nil), http.StatusInternalServerError, "abc123") if rec.Code != http.StatusInternalServerError { t.Fatalf("ErrorPage: status %d, want %d", rec.Code, http.StatusInternalServerError) } body := rec.Body.String() if !strings.Contains(body, "Something went wrong on our side") { t.Errorf("ErrorPage body missing the 500 title:\n%s", body) } if !strings.Contains(body, "abc123") { t.Errorf("ErrorPage body missing the ref:\n%s", body) } }