test(19.3-06): unit tests for the review fixes

- TestCORSCredentialedOriginRules, TestCORSAnchoredPatternNoSuffixMatch (D-04)
- TestAPIDocsCSPNoHostSource (D-17)
- TestLoadCookieConfigProductionInferredSecure, TestZeroCookieConfigDefaults (D-03)
- TestSiteCachePurgeWaitAndClose, TestSiteCacheBulkCommitCoalesced (D-10)
This commit is contained in:
Jakub Zych
2026-10-15 22:45:16 +02:00
parent 4d4e37932c
commit 8d80580083
4 changed files with 409 additions and 0 deletions

View File

@@ -442,3 +442,89 @@ func TestCookieHandlerOptionsValidated(t *testing.T) {
t.Fatalf("valid logout options: %v", err)
}
}
func TestLoadCookieConfigProductionInferredSecure(t *testing.T) {
for _, tc := range []struct {
name string
env string
values map[string]any
wantErr bool
secure bool
}{
{"production, http app.url", "production", map[string]any{"app.url": "http://api.example.com"}, true, false},
{"production, unset app.url", "production", map[string]any{}, true, false},
{"production, malformed app.url", "production", map[string]any{"app.url": "://not a url"}, true, false},
{"production, https app.url", "production", map[string]any{"app.url": "https://api.example.com"}, false, true},
{"production, http app.url and secure true", "production", map[string]any{"app.url": "http://api.example.com", "auth.cookie.secure": true}, false, true},
{"development, http app.url", "development", map[string]any{"app.url": "http://localhost:8000"}, false, false},
} {
t.Run(tc.name, func(t *testing.T) {
cfg, err := LoadCookieConfig(cookieSource{values: tc.values, env: tc.env})
if tc.wantErr {
if err == nil {
t.Fatalf("config = %+v, want an error", cfg)
}
for _, key := range []string{"auth.cookie.secure", "app.url"} {
if !strings.Contains(err.Error(), key) {
t.Errorf("error %q does not name %s", err, key)
}
}
return
}
if err != nil {
t.Fatal(err)
}
if cfg.Secure != tc.secure {
t.Fatalf("Secure = %t, want %t", cfg.Secure, tc.secure)
}
})
}
}
func TestZeroCookieConfigDefaults(t *testing.T) {
var zero CookieConfig
for name, c := range map[string]*http.Cookie{
"TokenCookie": zero.TokenCookie("tok", time.Hour),
"ForgetTokenCookie": zero.ForgetTokenCookie(),
} {
if c.Name != DefaultCookieName || c.Path != "/" || c.Domain != "" || !c.HttpOnly || c.SameSite != http.SameSiteLaxMode || !c.Secure {
t.Errorf("%s of the zero config = %+v, want token on / with HttpOnly, SameSite=Lax and Secure", name, c)
}
}
partial := CookieConfig{Name: "sid"}.TokenCookie("tok", time.Hour)
if partial.SameSite != http.SameSiteLaxMode || partial.Secure {
t.Errorf("{Name: sid} cookie SameSite %v Secure %t, want Lax and not Secure", partial.SameSite, partial.Secure)
}
write := func(w http.ResponseWriter, _ *http.Request, res CookieResult) { w.WriteHeader(res.Status) }
refresh, err := CookieRefreshHandler(CookieRefreshOptions{
RefreshTTL: time.Hour,
Refresh: func(context.Context, string) (string, error) { return "rotated", nil },
Write: write,
})
if err != nil {
t.Fatal(err)
}
logout, err := CookieLogoutHandler(CookieLogoutOptions{
Revoke: func(context.Context, string) error { return nil },
Write: write,
})
if err != nil {
t.Fatal(err)
}
for name, h := range map[string]http.Handler{"refresh": refresh, "logout": logout} {
req := httptest.NewRequest(http.MethodPost, "/auth/"+name, nil)
req.AddCookie(&http.Cookie{Name: DefaultCookieName, Value: "old"})
rec := httptest.NewRecorder()
h.ServeHTTP(rec, req)
set := rec.Header().Get("Set-Cookie")
if set == "" {
t.Fatalf("%s: no Set-Cookie (status %d)", name, rec.Code)
}
for _, want := range []string{DefaultCookieName + "=", "Path=/", "HttpOnly", "SameSite=Lax", "Secure"} {
if !strings.Contains(set, want) {
t.Errorf("%s: Set-Cookie %q lacks %s", name, set, want)
}
}
}
}