From 8bde0ad4748a697b26b1385642fa6b174b2ce18b Mon Sep 17 00:00:00 2001 From: Taimoor Zaeem Date: Tue, 9 Jun 2026 13:49:42 +0500 Subject: [PATCH] test: move cors related tests from io tests to spec tests Towards #4946. Signed-off-by: Taimoor Zaeem --- test/io/test_io.py | 80 ----------------------------------- test/spec/Feature/CorsSpec.hs | 62 ++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 82 deletions(-) diff --git a/test/io/test_io.py b/test/io/test_io.py index ed618c6f3..63d7ebc67 100644 --- a/test/io/test_io.py +++ b/test/io/test_io.py @@ -1618,86 +1618,6 @@ def test_fail_with_automatic_recovery_disabled_and_terminated_using_query(defaul assert exitCode == 1 -def test_preflight_request_with_cors_allowed_origin_config(defaultenv): - "OPTIONS preflight request should return Access-Control-Allow-Origin equal to origin" - - env = { - **defaultenv, - "PGRST_SERVER_CORS_ALLOWED_ORIGINS": "http://example.com, http://example2.com", - } - - headers = { - "Accept": "*/*", - "Origin": "http://example.com", - "Access-Control-Request-Method": "POST", - "Access-Control-Request-Headers": "Content-Type", - } - - with run(env=env) as postgrest: - response = postgrest.session.options("/items", headers=headers) - assert ( - response.headers["Access-Control-Allow-Origin"] == "http://example.com" - and response.headers["Access-Control-Allow-Credentials"] == "true" - ) - - -def test_preflight_request_with_empty_cors_allowed_origin_config(defaultenv): - "OPTIONS preflight request should allow all origins when config is not set or empty" - - env = { - **defaultenv, - "PGRST_SERVER_CORS_ALLOWED_ORIGINS": "", - } - - headers = { - "Accept": "*/*", - "Origin": "http://anyorigin.com", - "Access-Control-Request-Method": "POST", - "Access-Control-Request-Headers": "Content-Type", - } - - with run(env=env) as postgrest: - response = postgrest.session.options("/items", headers=headers) - assert response.headers["Access-Control-Allow-Origin"] == "*" - assert "POST" in response.headers["Access-Control-Allow-Methods"] - - -def test_no_preflight_request_with_CORS_config_should_return_header(defaultenv): - "GET no preflight request should return Access-Control-Allow-Origin equal to origin" - - env = { - **defaultenv, - "PGRST_SERVER_CORS_ALLOWED_ORIGINS": "http://example.com, http://example2.com", - } - - headers = { - "Accept": "*/*", - "Origin": "http://example.com", - } - - with run(env=env) as postgrest: - response = postgrest.session.get("/items", headers=headers) - assert response.headers["Access-Control-Allow-Origin"] == "http://example.com" - - -def test_no_preflight_request_with_CORS_config_should_not_return_header(defaultenv): - "GET no preflight request should not return Access-Control-Allow-Origin" - - env = { - **defaultenv, - "PGRST_SERVER_CORS_ALLOWED_ORIGINS": "http://example.com, http://example2.com", - } - - headers = { - "Accept": "*/*", - "Origin": "http://invalid.com", - } - - with run(env=env) as postgrest: - response = postgrest.session.get("/items", headers=headers) - assert "Access-Control-Allow-Origin" not in response.headers - - @pytest.mark.parametrize("level", ["crit", "error", "warn", "info", "debug"]) def test_db_error_logging_to_stderr(level, defaultenv, metapostgrest): "verify that DB errors are logged to stderr" diff --git a/test/spec/Feature/CorsSpec.hs b/test/spec/Feature/CorsSpec.hs index 27e00b8a3..ef2e4b562 100644 --- a/test/spec/Feature/CorsSpec.hs +++ b/test/spec/Feature/CorsSpec.hs @@ -4,12 +4,14 @@ import Network.HTTP.Types import Test.Hspec import Test.Hspec.Wai +import PostgREST.Config (AppConfig (..)) + import Protolude import SpecHelper spec :: SpecWithConfig -spec withConfig = withConfig baseCfg $ - describe "CORS" $ do +spec withConfig = do + withConfig baseCfg $ describe "CORS" $ do it "replies naively and permissively to preflight request" $ request methodOptions "/" [ ("Accept", "*/*") @@ -66,3 +68,59 @@ spec withConfig = withConfig baseCfg $ `shouldRespondWith` "" { matchHeaders = [ "Access-Control-Allow-Origin" <:> "*" ] } + + withConfig baseCfg { configServerCorsAllowedOrigins = ["http://example.com", "http://example2.com"] } $ + describe "test preflight/non-preflight request and cors server allowed config" $ do + it "OPTIONS preflight request should return Access-Control-Allow-Origin equal to origin" $ + request methodOptions "/items" + [ ("Accept", "*/*") + , ("Origin", "http://example.com") + , ("Access-Control-Request-Method", "POST") + , ("Access-Control-Request-Headers", "Content-Type") ] + "" + `shouldRespondWith` + ResponseMatcher + { matchStatus = 200 + , matchBody = MatchBody (\_ _ -> Nothing) -- match any body + , matchHeaders = [ "Access-Control-Allow-Origin" <:> "http://example.com" + , "Access-Control-Allow-Credentials" <:> "true" ] + } + + it "GET no preflight request should return Access-Control-Allow-Origin equal to origin" $ + request methodGet "/items" + [ ("Accept", "*/*") + , ("Origin", "http://example.com") ] + "" + `shouldRespondWith` + ResponseMatcher + { matchStatus = 200 + , matchBody = MatchBody (\_ _ -> Nothing) -- match any body + , matchHeaders = [ "Access-Control-Allow-Origin" <:> "http://example.com" ] } + + it "GET no preflight request should not return Access-Control-Allow-Origin" $ + request methodGet "/items" + [ ("Accept", "*/*") + , ("Origin", "http://invalid.com") ] + "" + `shouldRespondWith` + ResponseMatcher + { matchStatus = 200 + , matchBody = MatchBody (\_ _ -> Nothing) -- match any body + , matchHeaders = [ matchHeaderAbsent "Access-Control-Allow-Origin" ] } + + withConfig baseCfg { configServerCorsAllowedOrigins = [] } $ + describe "test preflight request with empty cors allowed origin config" $ + it "OPTIONS preflight request should allow all origins when config is not set or empty" $ + request methodOptions "/items" + [ ("Accept", "*/*") + , ("Origin", "http://anyorigin.com") + , ("Access-Control-Request-Method", "POST") + , ("Access-Control-Request-Headers", "Content-Type") ] + "" + `shouldRespondWith` + ResponseMatcher + { matchStatus = 200 + , matchBody = MatchBody (\_ _ -> Nothing) -- match any body + , matchHeaders = [ "Access-Control-Allow-Origin" <:> "*" + , matchHeaderValuePresent "Access-Control-Allow-Methods" "POST" ] + }