package retentionapi import ( "net/http" "net/http/httptest" "testing" ) const testAllowedOrigin = "http://localhost:3099" func noopHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }) } // TestCORS_AllowedOriginGetsAccessControlHeader ist die geforderte // Pflichtprüfung: ein echter Browser-Fetch (simuliert über den Origin- // Header, den nur ein Browser automatisch setzt) erhält die nötigen // CORS-Header, die Same-Origin-Policy blockiert den Zugriff nicht mehr. func TestCORS_AllowedOriginGetsAccessControlHeader(t *testing.T) { handler := CORS(testAllowedOrigin, noopHandler()) server := httptest.NewServer(handler) defer server.Close() req, _ := http.NewRequest(http.MethodGet, server.URL, nil) req.Header.Set("Origin", testAllowedOrigin) resp, err := http.DefaultClient.Do(req) if err != nil { t.Fatalf("get: %v", err) } defer func() { _ = resp.Body.Close() }() if got := resp.Header.Get("Access-Control-Allow-Origin"); got != testAllowedOrigin { t.Fatalf("Access-Control-Allow-Origin = %q, want %q", got, testAllowedOrigin) } } // TestCORS_PreflightRequestForPostEndpoint ist die geforderte // Pflichtprüfung: OPTIONS-Preflight liefert korrekte CORS-Header für // POST /retention-classes. func TestCORS_PreflightRequestForPostEndpoint(t *testing.T) { handler := CORS(testAllowedOrigin, noopHandler()) server := httptest.NewServer(handler) defer server.Close() req, _ := http.NewRequest(http.MethodOptions, server.URL+"/retention-classes", nil) req.Header.Set("Origin", testAllowedOrigin) req.Header.Set("Access-Control-Request-Method", "POST") resp, err := http.DefaultClient.Do(req) if err != nil { t.Fatalf("options: %v", err) } defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusNoContent { t.Fatalf("preflight status = %d, want 204", resp.StatusCode) } if got := resp.Header.Get("Access-Control-Allow-Origin"); got != testAllowedOrigin { t.Fatalf("Access-Control-Allow-Origin = %q, want %q", got, testAllowedOrigin) } if got := resp.Header.Get("Access-Control-Allow-Methods"); got == "" { t.Fatal("Access-Control-Allow-Methods fehlt in der preflight-antwort") } } // TestCORS_UnconfiguredOriginGetsNoAccessControlHeader ist die geforderte // Pflichtprüfung: Fetch von einem NICHT konfigurierten Origin bleibt // blockiert — kein Wildcard-Leck. func TestCORS_UnconfiguredOriginGetsNoAccessControlHeader(t *testing.T) { handler := CORS(testAllowedOrigin, noopHandler()) server := httptest.NewServer(handler) defer server.Close() req, _ := http.NewRequest(http.MethodGet, server.URL, nil) req.Header.Set("Origin", "http://boesartige-seite.example") resp, err := http.DefaultClient.Do(req) if err != nil { t.Fatalf("get: %v", err) } defer func() { _ = resp.Body.Close() }() if got := resp.Header.Get("Access-Control-Allow-Origin"); got != "" { t.Fatalf("Access-Control-Allow-Origin haette bei fremdem origin leer sein muessen, war %q", got) } }