test(spec): inline config into test suite

Previously, information about each test-suite was repeated in 3 separate
places:
- as a label and as implicit knowledge in the test-suite itself,
- as a comment in Main.hs, and
- as a configuration in SpecHelper.hs.

With this change, there will be a single source of truth in the test
suite itself. This will allow a single test-suite to easily test
multiple different configurations.
This commit is contained in:
Wolfgang Walther
2026-06-02 06:49:15 +00:00
parent 7803960cd1
commit 268ab00ed9
52 changed files with 280 additions and 439 deletions
+29 -9
View File
@@ -1,19 +1,39 @@
module Feature.Auth.AsymmetricJwtSpec where
import Network.Wai (Application)
import Network.HTTP.Types
import Test.Hspec
import Test.Hspec.Wai
import Text.Heredoc
import PostgREST.Config (AppConfig (..), parseSecret)
import Protolude
import SpecHelper
spec :: SpecWith ((), Application)
spec = describe "server started with asymmetric JWK" $
-- these tests will stop working 9999999999s after the UNIX EPOCH
spec :: SpecWithConfig
spec withConfig =
let
auth = authHeaderJWT "eyJhbGciOiJSUzI1NiJ9.eyJyb2xlIjogInBvc3RncmVzdF90ZXN0X2F1dGhvciJ9Cg.CBOYWDvqgAR0YYnZnyDGTQi6AJLc2Pds6_eV3YuBG6I36mj_h05eLhkEKNEDA5ZteMzCiY83P60rC_xtxVd7B6vo3BeF5uoanPS3rrbuHzKPwzsrgrD_CqvEuJ4n7Q9epkQiLsNkcexneENZDRqFjbwZx3DrXiCWwlK3Ytr5NAIGxmy0od-0xNpb2U1nXQyO_Q3mumWFViRt4tmFn_3goDHNKG3Ha_AzImfUNvHnWL78kAc4rbn15vLtWXD8PwtSnZaB4lY4V6RfsaW937srQsmRetvytM1i_bHBnjkjQLAqGbXPyItjtlXPs0uGNBadE8-wgkLtfmSCC4v2DjUthw"
jwk = encodeUtf8 [str|{"alg":"RS256","e":"AQAB","key_ops":["verify"],"kty":"RSA","n":"0etQ2Tg187jb04MWfpuogYGV75IFrQQBxQaGH75eq_FpbkyoLcEpRUEWSbECP2eeFya2yZ9vIO5ScD-lPmovePk4Aa4SzZ8jdjhmAbNykleRPCxMg0481kz6PQhnHRUv3nF5WP479CnObJKqTVdEagVL66oxnX9VhZG9IZA7k0Th5PfKQwrKGyUeTGczpOjaPqbxlunP73j9AfnAt4XCS8epa-n3WGz1j-wfpr_ys57Aq-zBCfqP67UYzNpeI1AoXsJhD9xSDOzvJgFRvc3vm2wjAW4LEMwi48rCplamOpZToIHEPIaPzpveYQwDnB1HFTR1ove9bpKJsHmi-e2uzQ","use":"sig"}|]
jwks = encodeUtf8 [str|{"keys": [{"alg":"RS256","e":"AQAB","key_ops":["verify"],"kty":"RSA","n":"0etQ2Tg187jb04MWfpuogYGV75IFrQQBxQaGH75eq_FpbkyoLcEpRUEWSbECP2eeFya2yZ9vIO5ScD-lPmovePk4Aa4SzZ8jdjhmAbNykleRPCxMg0481kz6PQhnHRUv3nF5WP479CnObJKqTVdEagVL66oxnX9VhZG9IZA7k0Th5PfKQwrKGyUeTGczpOjaPqbxlunP73j9AfnAt4XCS8epa-n3WGz1j-wfpr_ys57Aq-zBCfqP67UYzNpeI1AoXsJhD9xSDOzvJgFRvc3vm2wjAW4LEMwi48rCplamOpZToIHEPIaPzpveYQwDnB1HFTR1ove9bpKJsHmi-e2uzQ","use":"sig"}]}|]
in
describe "server started with asymmetric JWK" $ do
-- this test will stop working 9999999999s after the UNIX EPOCH
it "succeeds with jwt token signed with an asymmetric key" $ do
let auth = authHeaderJWT "eyJhbGciOiJSUzI1NiJ9.eyJyb2xlIjogInBvc3RncmVzdF90ZXN0X2F1dGhvciJ9Cg.CBOYWDvqgAR0YYnZnyDGTQi6AJLc2Pds6_eV3YuBG6I36mj_h05eLhkEKNEDA5ZteMzCiY83P60rC_xtxVd7B6vo3BeF5uoanPS3rrbuHzKPwzsrgrD_CqvEuJ4n7Q9epkQiLsNkcexneENZDRqFjbwZx3DrXiCWwlK3Ytr5NAIGxmy0od-0xNpb2U1nXQyO_Q3mumWFViRt4tmFn_3goDHNKG3Ha_AzImfUNvHnWL78kAc4rbn15vLtWXD8PwtSnZaB4lY4V6RfsaW937srQsmRetvytM1i_bHBnjkjQLAqGbXPyItjtlXPs0uGNBadE8-wgkLtfmSCC4v2DjUthw"
request methodGet "/authors_only" [auth] ""
`shouldRespondWith` 200
context "secret provided as JWK" $ withConfig (
baseCfg {
configJwtSecret = Just jwk
, configJWKS = rightToMaybe $ parseSecret jwk
}
) $ it "succeeds with jwt token signed with an asymmetric key" $
request methodGet "/authors_only" [auth] ""
`shouldRespondWith` 200
context "secret provided as JWKSet" $ withConfig (
baseCfg {
configJwtSecret = Just jwks
, configJWKS = rightToMaybe $ parseSecret jwks
}
) $ it "succeeds with jwt token signed with an asymmetric key" $
request methodGet "/authors_only" [auth] ""
`shouldRespondWith` 200
@@ -1,7 +1,5 @@
module Feature.Auth.AudienceJwtSecretSpec where
import Network.Wai (Application)
import Network.HTTP.Types
import Protolude hiding (get)
import SpecHelper
@@ -9,8 +7,16 @@ import Test.Hspec
import Test.Hspec.Wai
import Test.Hspec.Wai.JSON
spec :: SpecWith ((), Application)
spec = describe "test handling of aud claims in JWT when the jwt-aud config is set" $ do
import PostgREST.Config (AppConfig (..), parseSecret)
spec :: SpecWithConfig
spec withConfig = withConfig (
baseCfg {
configJwtSecret = Just generateSecret
, configJwtAudience = Just "youraudience"
, configJWKS = rightToMaybe $ parseSecret generateSecret
}
) $ describe "test handling of aud claims in JWT when the jwt-aud config is set" $ do
context "when the audience claim is a string" $ do
-- this test will stop working 9999999999s after the UNIX EPOCH
@@ -147,8 +153,8 @@ spec = describe "test handling of aud claims in JWT when the jwt-aud config is s
it "succeeds without a JWT" $
get "/has_count_column" `shouldRespondWith` 200
disabledSpec :: SpecWith ((), Application)
disabledSpec = describe "test handling of aud claims in JWT when the jwt-aud config is not set" $ do
disabledSpec :: SpecWithConfig
disabledSpec withConfig = withConfig baseCfg $ describe "test handling of aud claims in JWT when the jwt-aud config is not set" $ do
context "when the audience claim is a string" $ do
it "ignores the audience claim and suceeds" $ do
+2 -4
View File
@@ -1,7 +1,5 @@
module Feature.Auth.AuthSpec where
import Network.Wai (Application)
import Network.HTTP.Types
import Test.Hspec
import Test.Hspec.Wai
@@ -10,8 +8,8 @@ import Test.Hspec.Wai.JSON
import Protolude hiding (get)
import SpecHelper
spec :: SpecWith ((), Application)
spec = describe "authorization" $ do
spec :: SpecWithConfig
spec withConfig = withConfig baseCfg $ describe "authorization" $ do
let single = ("Accept","application/vnd.pgrst.object+json")
it "denies access to tables that anonymous does not own" $
@@ -1,16 +1,21 @@
module Feature.Auth.BinaryJwtSecretSpec where
import Network.Wai (Application)
import Network.HTTP.Types
import Test.Hspec
import Test.Hspec.Wai
import PostgREST.Config (AppConfig (..), parseSecret)
import Protolude
import SpecHelper
spec :: SpecWith ((), Application)
spec = describe "server started with binary JWT secret" $
spec :: SpecWithConfig
spec withConfig = withConfig (
baseCfg {
configJwtSecret = Just generateSecret
, configJWKS = rightToMaybe $ parseSecret generateSecret
}
) $ describe "server started with binary JWT secret" $
-- this test will stop working 9999999999s after the UNIX EPOCH
it "succeeds with jwt token encoded with a binary secret" $ do
+4 -4
View File
@@ -1,17 +1,17 @@
module Feature.Auth.NoAnonSpec where
import Network.Wai (Application)
import Network.HTTP.Types
import Test.Hspec
import Test.Hspec.Wai
import Test.Hspec.Wai.JSON
import PostgREST.Config (AppConfig (..))
import Protolude hiding (get)
import SpecHelper
spec :: SpecWith ((), Application)
spec = describe "server started without anonymous role" $ do
spec :: SpecWithConfig
spec withConfig = withConfig (baseCfg { configDbAnonRole = Nothing }) $ describe "server started without anonymous role" $ do
it "behaves normally on attempted auth" $ do
-- token body: { "role": "postgrest_test_author" }
let auth = authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXN0X3Rlc3RfYXV0aG9yIn0.Xod-F15qsGL0WhdOCr2j3DdKuTw9QJERVgoFD3vGaWA"
+9 -4
View File
@@ -1,17 +1,22 @@
module Feature.Auth.NoJwtSecretSpec where
import Network.Wai (Application)
import Network.HTTP.Types
import Test.Hspec
import Test.Hspec.Wai
import Test.Hspec.Wai.JSON
import PostgREST.Config (AppConfig (..))
import Protolude hiding (get)
import SpecHelper
spec :: SpecWith ((), Application)
spec = describe "server started without JWT secret" $ do
spec :: SpecWithConfig
spec withConfig = withConfig (
baseCfg {
configJwtSecret = Nothing
, configJWKS = Nothing
}
) $ describe "server started without JWT secret" $ do
it "responds with error on attempted auth" $ do
-- token body: { "role": "postgrest_test_author" }