Files
summercms/modules/surf/cors_test.go
Jakub Zych 5e50b166ef refactor(10.2-01): nest framework packages under modules
- Move remaining beach packages and embedded admin assets\n- Rewrite framework, example, build, and gate paths
2026-09-28 02:21:02 +02:00

123 lines
3.4 KiB
Go

package surf
import (
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
"git.golem15.com/golem15/summercms/modules/backpack"
"git.golem15.com/golem15/summercms/modules/compass"
"git.golem15.com/golem15/summercms/modules/party"
)
func TestCORSLaravelGlobMatchesNestedPaths(t *testing.T) {
re := compileLaravelGlob("api/*")
if re == nil || !re.MatchString("api/v1/acme/genres") {
t.Fatal("api/* must match api/v1/acme/genres (Laravel Str::is, not Go path.Match)")
}
if re.MatchString("_acme/api/v1/genres") {
t.Fatal("api/* must not match _acme/api/v1/genres")
}
mcp := compileLaravelGlob("oauth/mcp/*")
if mcp == nil || !mcp.MatchString("oauth/mcp/token") {
t.Fatal("oauth/mcp/* must match oauth/mcp/token")
}
}
func TestCORSPathScopedHeaders(t *testing.T) {
cfg := CORSConfig{
Paths: []string{"api/*", "oauth/mcp/*"},
AllowedMethods: []string{"*"},
AllowedOrigins: []string{"*"},
AllowedHeaders: []string{"*"},
}
mux := http.NewServeMux()
mux.HandleFunc("GET /api/v1/acme/genres", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
mux.HandleFunc("GET /_acme/api/v1/genres", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
h := pathScopedCORS(cfg, mux)
rec := httptest.NewRecorder()
h.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/api/v1/acme/genres", nil))
if rec.Header().Get("Access-Control-Allow-Origin") != "*" {
t.Fatalf("token group ACAO = %q", rec.Header().Get("Access-Control-Allow-Origin"))
}
rec = httptest.NewRecorder()
h.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/_acme/api/v1/genres", nil))
if got := rec.Header().Get("Access-Control-Allow-Origin"); got != "" {
t.Fatalf("JWT group ACAO = %q, want empty", got)
}
}
func TestCORSConfigLoadedFromHTTPSection(t *testing.T) {
cfg := writeHTTPConfig(t, `
cors:
paths: ["api/*"]
allowed_methods: ["*"]
allowed_origins: ["*"]
allowed_origins_patterns: []
allowed_headers: ["*"]
exposed_headers: []
max_age: 0
supports_credentials: false
`)
got, err := LoadCORSConfig(cfg)
if err != nil {
t.Fatal(err)
}
if len(got.Paths) != 1 || got.Paths[0] != "api/*" {
t.Fatalf("paths = %v", got.Paths)
}
if !containsStar(got.AllowedOrigins) {
t.Fatalf("origins = %v", got.AllowedOrigins)
}
}
func writeHTTPConfig(t *testing.T, httpYAML string) *compass.Config {
t.Helper()
dir := t.TempDir()
if err := os.WriteFile(filepath.Join(dir, "app.yaml"), []byte("name: cors-test\n"), 0o644); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(dir, "http.yaml"), []byte(httpYAML), 0o644); err != nil {
t.Fatal(err)
}
cfg, err := compass.Open(compass.Options{
Dir: dir,
Environ: []string{"SUMMER_ENV=development"},
})
if err != nil {
t.Fatal(err)
}
return cfg
}
func TestCORSAssembleUsesConfig(t *testing.T) {
cfg := writeHTTPConfig(t, `
body_limits:
default_bytes: 1048576
upload_bytes: 1048576
cors:
paths: ["api/*"]
allowed_methods: ["*"]
allowed_origins: ["*"]
allowed_headers: ["*"]
`)
p := assemblePlugin{id: "golem15.demo", path: "/genres"}
h, err := Assemble(backpack.New(cfg), []party.Plugin{p})
if err != nil {
t.Fatal(err)
}
rec := httptest.NewRecorder()
h.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/api/genres", nil))
if rec.Header().Get("Access-Control-Allow-Origin") != "*" {
t.Fatalf("ACAO = %q", rec.Header().Get("Access-Control-Allow-Origin"))
}
}