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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
module Feature.ConcurrentSpec where
|
||||
|
||||
import Control.Concurrent.Async (mapConcurrently)
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Control.Monad.Base
|
||||
import Control.Monad.Trans.Control
|
||||
@@ -16,10 +15,11 @@ import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.Internal
|
||||
import Test.Hspec.Wai.JSON
|
||||
|
||||
import Protolude hiding (get)
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $
|
||||
describe "Querying in parallel" $
|
||||
it "should not raise 'transaction in progress' error" $
|
||||
raceTest 10 $
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
module Feature.CorsSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Test.Hspec
|
||||
import Test.Hspec.Wai
|
||||
|
||||
import Protolude
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $
|
||||
describe "CORS" $ do
|
||||
it "replies naively and permissively to preflight request" $
|
||||
request methodOptions "/"
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
module Feature.ExtraSearchPathSpec where
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Network.Wai (Application)
|
||||
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 "extra search path" $ do
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig (baseCfg { configDbExtraSearchPath = ["public", "extensions", "EXTRA \"@/\\#~_-"] }) $ describe "extra search path" $ do
|
||||
|
||||
it "finds the ltree <@ operator on the public schema" $
|
||||
request methodGet "/ltree_sample?path=cd.Top.Science.Astronomy" [] ""
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
module Feature.NoSuperuserSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Test.Hspec
|
||||
import Test.Hspec.Wai
|
||||
|
||||
import Protolude
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $
|
||||
describe "No Superuser" $ do
|
||||
it "proves that the authenticator role is not a superuser" $ do
|
||||
request methodGet "/rpc/is_superuser"
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
module Feature.ObservabilitySpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
import Data.CaseInsensitive (mk)
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Test.Hspec
|
||||
import Test.Hspec.Wai
|
||||
|
||||
import Protolude
|
||||
import PostgREST.Config (AppConfig (..))
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
import Protolude
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig (baseCfg { configServerTraceHeader = Just $ mk "X-Request-Id" }) $
|
||||
describe "Observability" $ do
|
||||
it "includes the server trace header on the response" $ do
|
||||
request methodHead "/"
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
module Feature.OpenApi.DisabledOpenApiSpec where
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Test.Hspec
|
||||
import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.JSON
|
||||
|
||||
import Protolude
|
||||
import PostgREST.Config (AppConfig (..), OpenAPIMode (..))
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
import Protolude
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig (baseCfg { configOpenApiMode = OADisabled }) $
|
||||
describe "Disabled OpenApi" $ do
|
||||
it "responds with 404" $
|
||||
request methodGet "/"
|
||||
|
||||
@@ -4,19 +4,26 @@ import Control.Lens ((^?))
|
||||
|
||||
import Data.Aeson.Lens
|
||||
import Data.Aeson.QQ
|
||||
import Data.List.NonEmpty (fromList)
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Network.Wai (Application)
|
||||
import Network.Wai.Test (SResponse (..))
|
||||
|
||||
import Test.Hspec hiding (pendingWith)
|
||||
import Test.Hspec.Wai
|
||||
|
||||
import PostgREST.Config (AppConfig (..), OpenAPIMode (..))
|
||||
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec = describe "OpenAPI Ignore Privileges" $ do
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig (
|
||||
baseCfg {
|
||||
configOpenApiMode = OAIgnorePriv
|
||||
, configDbSchemas = fromList ["test", "v1"]
|
||||
}
|
||||
) $ describe "OpenAPI Ignore Privileges" $ do
|
||||
it "root path returns a valid openapi spec" $ do
|
||||
validateOpenApiResponse [("Accept", "application/openapi+json")]
|
||||
request methodHead "/"
|
||||
|
||||
@@ -2,7 +2,6 @@ module Feature.OpenApi.OpenApiSpec where
|
||||
|
||||
import Control.Lens ((^?))
|
||||
import Data.Aeson.Types (Value (..))
|
||||
import Network.Wai (Application)
|
||||
import Network.Wai.Test (SResponse (..))
|
||||
|
||||
import Data.Aeson.Lens
|
||||
@@ -15,8 +14,8 @@ import PostgREST.Version (docsVersion)
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec = describe "OpenAPI" $ do
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $ describe "OpenAPI" $ do
|
||||
it "root path returns a valid openapi spec" $ do
|
||||
validateOpenApiResponse [("Accept", "application/openapi+json")]
|
||||
request methodHead "/"
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
module Feature.OpenApi.ProxySpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
import Test.Hspec hiding (pendingWith)
|
||||
import Test.Hspec hiding (pendingWith)
|
||||
|
||||
import PostgREST.Config (AppConfig (..))
|
||||
|
||||
import Protolude
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig (baseCfg { configOpenApiServerProxyUri = Just "https://postgrest.com/openapi.json" }) $
|
||||
describe "GET / with proxy" $
|
||||
it "returns a valid openapi spec with proxy" $
|
||||
validateOpenApiResponse [("Accept", "application/openapi+json")]
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
module Feature.OpenApi.RootSpec where
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Test.Hspec hiding (pendingWith)
|
||||
import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.JSON
|
||||
|
||||
import Protolude hiding (get)
|
||||
import PostgREST.Config (AppConfig (..))
|
||||
import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier (..))
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig (baseCfg { configDbRootSpec = Just $ QualifiedIdentifier mempty "root" }) $
|
||||
describe "root spec function" $ do
|
||||
it "accepts application/openapi+json" $ do
|
||||
request methodGet "/"
|
||||
|
||||
@@ -5,16 +5,18 @@ import Control.Lens ((^?))
|
||||
import Data.Aeson.Lens
|
||||
import Data.Aeson.QQ
|
||||
|
||||
import Network.Wai (Application)
|
||||
import Network.Wai.Test (SResponse (..))
|
||||
|
||||
import Test.Hspec hiding (pendingWith)
|
||||
import Test.Hspec.Wai
|
||||
|
||||
import Protolude hiding (get)
|
||||
import PostgREST.Config (AppConfig (..))
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig (baseCfg { configOpenApiSecurityActive = True }) $
|
||||
describe "Security active" $
|
||||
it "includes security and security definitions" $ do
|
||||
r <- simpleBody <$> get "/"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
module Feature.OptionsSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
import Network.Wai.Test (SResponse (..))
|
||||
|
||||
import Network.HTTP.Types
|
||||
@@ -10,8 +9,8 @@ import Test.Hspec.Wai
|
||||
import Protolude
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec = describe "Allow header" $ do
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $ describe "Allow header" $ do
|
||||
context "a table" $ do
|
||||
it "includes read/write methods for writeable table" $ do
|
||||
r <- request methodOptions "/items" [] ""
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
module Feature.Query.AggregateFunctionsSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Test.Hspec hiding (pendingWith)
|
||||
import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.JSON
|
||||
|
||||
import PostgREST.Config (AppConfig (..))
|
||||
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
allowed :: SpecWith ((), Application)
|
||||
allowed =
|
||||
allowed :: SpecWithConfig
|
||||
allowed withConfig = withConfig (baseCfg { configDbAggregates = True }) $
|
||||
describe "aggregate functions" $ do
|
||||
context "performing a count without specifying a field" $ do
|
||||
it "returns the count of all rows when no other fields are selected" $
|
||||
@@ -306,8 +306,8 @@ allowed =
|
||||
{ matchStatus = 400
|
||||
, matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
disallowed :: SpecWith ((), Application)
|
||||
disallowed =
|
||||
disallowed :: SpecWithConfig
|
||||
disallowed withConfig = withConfig baseCfg $
|
||||
describe "attempting to use an aggregate when aggregate functions are disallowed" $ do
|
||||
it "prevents the use of aggregates" $
|
||||
get "/project_invoices?select=invoice_total.sum()" `shouldRespondWith`
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
module Feature.Query.AndOrParamsSpec 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 =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $
|
||||
describe "and/or params used for complex boolean logic" $ do
|
||||
context "used with GET" $ do
|
||||
context "or param" $ do
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
module Feature.Query.ComputedRelsSpec 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 "computed relationships" $ do
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $ describe "computed relationships" $ do
|
||||
it "can define a many-to-one relationship with SETOF and ROWS 1 and embed" $
|
||||
get "/videogames?select=name,designer:computed_designers(name)"
|
||||
`shouldRespondWith`
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
module Feature.Query.CustomMediaSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Network.Wai.Test (SResponse (simpleBody, simpleHeaders, simpleStatus))
|
||||
import Test.Hspec
|
||||
@@ -12,8 +10,8 @@ import Text.Heredoc (str)
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec = describe "custom media types" $ do
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $ describe "custom media types" $ do
|
||||
context "for tables with aggregate" $ do
|
||||
it "can query if there's an aggregate defined for the table" $ do
|
||||
r <- request methodGet "/lines" (acceptHdrs "application/vnd.twkb") ""
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
module Feature.Query.DeleteSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Test.Hspec hiding (pendingWith)
|
||||
import Test.Hspec.Wai
|
||||
@@ -10,8 +8,8 @@ import Test.Hspec.Wai.JSON
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $
|
||||
describe "Deleting" $ do
|
||||
context "existing record" $ do
|
||||
it "succeeds with 204 and deletion count" $
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
module Feature.Query.EmbedDisambiguationSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Test.Hspec hiding (pendingWith)
|
||||
import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.JSON
|
||||
@@ -9,8 +7,8 @@ import Test.Hspec.Wai.JSON
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $
|
||||
describe "resource embedding disambiguation" $ do
|
||||
context "ambiguous requests that give 300 Multiple Choices" $ do
|
||||
it "errs when there are o2m and m2m cardinalities to the target table" $
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
module Feature.Query.EmbedInnerJoinSpec where
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Test.Hspec
|
||||
import Test.Hspec.Wai
|
||||
@@ -10,8 +9,8 @@ import Test.Hspec.Wai.JSON
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $
|
||||
describe "Embedding with an inner join" $ do
|
||||
context "many-to-one relationships" $ do
|
||||
it "ignores null embeddings while the default left join doesn't" $ do
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
module Feature.Query.ErrorSpec 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
|
||||
|
||||
pgErrorCodeMapping :: SpecWith ((), Application)
|
||||
pgErrorCodeMapping = do
|
||||
pgErrorCodeMapping :: SpecWithConfig
|
||||
pgErrorCodeMapping withConfig = withConfig baseCfg $ do
|
||||
describe "PostreSQL error code mappings" $ do
|
||||
it "should return 500 for cardinality_violation" $
|
||||
get "/bad_subquery" `shouldRespondWith` 500
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
module Feature.Query.InsertSpec where
|
||||
|
||||
import Data.List (lookup)
|
||||
import Network.Wai (Application)
|
||||
import Network.Wai.Test (SResponse (simpleHeaders))
|
||||
import Test.Hspec hiding (pendingWith)
|
||||
import Test.Hspec.Wai.Matcher (bodyEquals)
|
||||
@@ -14,8 +13,8 @@ import Text.Heredoc
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec = do
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $ do
|
||||
describe "Posting new record" $ do
|
||||
context "disparate json types" $ do
|
||||
it "accepts disparate json types" $ do
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
module Feature.Query.JsonOperatorSpec 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 "json and jsonb operators" $ do
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $ describe "json and jsonb operators" $ do
|
||||
context "Shaping response with select parameter" $ do
|
||||
it "obtains a json subfield one level with casting" $
|
||||
get "/complex_items?id=eq.1&select=settings->>foo::json" `shouldRespondWith`
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
module Feature.Query.MultipleSchemaSpec where
|
||||
|
||||
import Control.Lens ((^?))
|
||||
import Control.Lens ((^?))
|
||||
import Data.Aeson.Lens
|
||||
import Data.Aeson.QQ
|
||||
import Data.List.NonEmpty (fromList)
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Network.Wai (Application)
|
||||
import Network.Wai.Test (SResponse (simpleHeaders), simpleBody)
|
||||
|
||||
import Test.Hspec
|
||||
import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.JSON
|
||||
|
||||
import PostgREST.Config (AppConfig (..))
|
||||
|
||||
import Protolude
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig (baseCfg { configDbSchemas = fromList ["v1", "v2", "SPECIAL \"@/\\#~_-"] }) $ describe "PostGIS features" $
|
||||
describe "multiple schemas in single instance" $ do
|
||||
context "Reading tables on different schemas" $ do
|
||||
it "succeeds in reading table from default schema v1 if no schema is selected via header" $
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
module Feature.Query.NullsStripSpec 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 =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $
|
||||
describe "Stripping null values from JSON response" $ do
|
||||
let arrayStrip = ("Accept", "application/vnd.pgrst.array+json;nulls=stripped")
|
||||
let singularStrip = ("Accept", "application/vnd.pgrst.object+json;nulls=stripped")
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
module Feature.Query.PgSafeUpdateSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Test.Hspec hiding (pendingWith)
|
||||
import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.JSON
|
||||
|
||||
import Protolude hiding (get, put)
|
||||
import PostgREST.Config (AppConfig (..))
|
||||
import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier (..))
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
import Protolude hiding (get, put)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig (baseCfg { configDbPreRequest = Just $ QualifiedIdentifier "test" "load_safeupdate" }) $
|
||||
describe "Enabling pg-safeupdate" $ do
|
||||
context "Full table update" $ do
|
||||
it "does not update and throws error if no condition is present" $
|
||||
@@ -48,8 +50,8 @@ spec =
|
||||
`shouldRespondWith`
|
||||
204
|
||||
|
||||
disabledSpec :: SpecWith ((), Application)
|
||||
disabledSpec =
|
||||
disabledSpec :: SpecWithConfig
|
||||
disabledSpec withConfig = withConfig baseCfg $
|
||||
describe "Disabling pg-safeupdate" $ do
|
||||
context "Full table update" $ do
|
||||
it "works if no condition is present" $
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
module Feature.Query.PlanSpec where
|
||||
|
||||
import Control.Lens ((^?))
|
||||
import Network.Wai (Application)
|
||||
import Network.Wai.Test (SResponse (..))
|
||||
|
||||
import Data.Aeson.Lens
|
||||
@@ -15,11 +14,13 @@ import Test.Hspec hiding (pendingWith)
|
||||
import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.JSON
|
||||
|
||||
import PostgREST.Config (AppConfig (..))
|
||||
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec = do
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig (baseCfg { configDbPlanEnabled = True }) $ do
|
||||
describe "read table/view plan" $ do
|
||||
it "outputs the total cost for a single filter on a table" $ do
|
||||
r <- request methodGet "/projects?id=in.(1,2,3)"
|
||||
@@ -529,8 +530,8 @@ spec = do
|
||||
totalCost `shouldSatisfy` (> 67.0)
|
||||
aggregateQty `shouldSatisfy` (> 1)
|
||||
|
||||
disabledSpec :: SpecWith ((), Application)
|
||||
disabledSpec =
|
||||
disabledSpec :: SpecWithConfig
|
||||
disabledSpec withConfig = withConfig baseCfg $
|
||||
it "doesn't work if db-plan-enabled=false(the default)" $ do
|
||||
request methodGet "/projects?id=in.(1,2,3)"
|
||||
(acceptHdrs "application/vnd.pgrst.plan") ""
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
module Feature.Query.PostGISSpec 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 "PostGIS features" $
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig (baseCfg { configDbExtraSearchPath = ["public", "extensions", "EXTRA \"@/\\#~_-"] }) $ describe "PostGIS features" $
|
||||
context "GeoJSON output" $ do
|
||||
it "works for a table that has a geometry column" $
|
||||
request methodGet "/shops"
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
module Feature.Query.Preferences.HandlingSpec 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 =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $
|
||||
describe "test Prefer: handling" $ do
|
||||
context "check behaviour of Prefer: handling=strict" $ do
|
||||
it "throws error when handling=strict and invalid prefs are given" $
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
module Feature.Query.Preferences.MaxAffectedSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Test.Hspec
|
||||
import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.JSON
|
||||
|
||||
import Protolude hiding (get)
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
describe "test Prefer: max-affected" $ do
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $ describe "test Prefer: max-affected" $ do
|
||||
context "test Prefer: max-affected with handling=strict" $ do
|
||||
it "should fail if items deleted more than 10" $
|
||||
request methodDelete "/items?id=lt.15"
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
module Feature.Query.Preferences.TimezoneSpec 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
|
||||
|
||||
enabledSpec :: SpecWith ((), Application)
|
||||
enabledSpec =
|
||||
describe "test Prefer: timezone with db-timezone-enabled is true" $ do
|
||||
enabledSpec :: SpecWithConfig
|
||||
enabledSpec withConfig = withConfig baseCfg $ describe "test Prefer: timezone with db-timezone-enabled is true" $ do
|
||||
context "test Prefer: timezone=America/Los_Angeles" $ do
|
||||
it "should change timezone with handling=strict" $
|
||||
request methodGet "/timestamps"
|
||||
@@ -62,8 +61,8 @@ enabledSpec =
|
||||
, "Preference-Applied" <:> "handling=lenient"]}
|
||||
|
||||
|
||||
disabledSpec :: SpecWith ((), Application)
|
||||
disabledSpec =
|
||||
disabledSpec :: SpecWithConfig
|
||||
disabledSpec withConfig = withConfig (baseCfg { configDbTimezoneEnabled = False }) $
|
||||
describe "test Prefer: timezone with db-timezone-enabled is false" $ do
|
||||
context "test Prefer: timezone=America/Los_Angeles when timezone is disabled" $ do
|
||||
it "should throw error with handling=strict" $
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
module Feature.Query.QueryLimitedSpec 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 =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig (baseCfg { configDbMaxRows = Just 2 }) $
|
||||
describe "Requesting many items with server limits(max-rows) enabled" $ do
|
||||
it "restricts results" $
|
||||
get "/items?order=id"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
module Feature.Query.QuerySpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
import Network.Wai.Test (SResponse (simpleHeaders))
|
||||
|
||||
import Network.HTTP.Types
|
||||
@@ -11,8 +10,8 @@ import Test.Hspec.Wai.JSON
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec = do
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $ do
|
||||
|
||||
describe "Querying a table with a column called count" $
|
||||
it "should not confuse count column with pg_catalog.count aggregate" $
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
module Feature.Query.RangeSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
import Network.Wai.Test (SResponse (simpleHeaders, simpleStatus))
|
||||
|
||||
import Network.HTTP.Types
|
||||
@@ -11,8 +10,8 @@ import Test.Hspec.Wai.JSON
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec = do
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $ do
|
||||
describe "GET /rpc/getitemrange" $ do
|
||||
context "without range headers" $ do
|
||||
context "with response under server size limit" $
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
module Feature.Query.RawOutputTypesSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Test.Hspec
|
||||
import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.JSON
|
||||
|
||||
import Protolude
|
||||
import SpecHelper (acceptHdrs)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec = describe "When raw-media-types config variable is missing or left empty" $ do
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $ describe "When raw-media-types config variable is missing or left empty" $ do
|
||||
let firefoxAcceptHdrs = acceptHdrs "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
||||
chromeAcceptHdrs = acceptHdrs "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3"
|
||||
it "responds json to a GET request with Firefox Accept headers" $
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
module Feature.Query.RelatedQueriesSpec 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 "related queries" $ do
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $ describe "related queries" $ do
|
||||
context "related orders" $ do
|
||||
it "works on a many-to-one relationship" $ do
|
||||
get "/projects?select=id,clients(name)&order=clients(name).nullsfirst" `shouldRespondWith`
|
||||
|
||||
@@ -2,7 +2,6 @@ module Feature.Query.RpcSpec where
|
||||
|
||||
import qualified Data.ByteString.Lazy as BL (empty)
|
||||
|
||||
import Network.Wai (Application)
|
||||
import Network.Wai.Test (SResponse (simpleBody, simpleHeaders, simpleStatus))
|
||||
|
||||
import Network.HTTP.Types
|
||||
@@ -16,8 +15,8 @@ import PostgREST.Config.PgVersion (PgVersion, pgVersion180)
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: PgVersion -> SpecWith ((), Application)
|
||||
spec actualPgVersion =
|
||||
spec :: PgVersion -> SpecWithConfig
|
||||
spec actualPgVersion withConfig = withConfig baseCfg $
|
||||
describe "remote procedure call" $ do
|
||||
context "a proc that returns a set" $ do
|
||||
context "returns paginated results" $ do
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
module Feature.Query.ServerTimingSpec 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 =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig (baseCfg { configDbPlanEnabled = True }) $
|
||||
describe "Show Duration on Server-Timing header" $ do
|
||||
|
||||
context "responds with Server-Timing header" $ do
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
module Feature.Query.SingularSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
import Network.Wai.Test (SResponse (..))
|
||||
|
||||
import Network.HTTP.Types
|
||||
@@ -11,8 +10,8 @@ import Test.Hspec.Wai.JSON
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $
|
||||
describe "Requesting singular json object" $ do
|
||||
let singular = ("Accept", "application/vnd.pgrst.object+json")
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
module Feature.Query.SpreadQueriesSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Test.Hspec
|
||||
import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.JSON
|
||||
@@ -9,8 +7,8 @@ import Test.Hspec.Wai.JSON
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $
|
||||
describe "spread embeds" $ do
|
||||
it "works on a many-to-one relationship" $ do
|
||||
get "/projects?select=id,...clients(client_name:name)" `shouldRespondWith`
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
module Feature.Query.UnicodeSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Data.List.NonEmpty (fromList)
|
||||
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 =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig (baseCfg { configDbSchemas = fromList ["تست"] }) $
|
||||
describe "Reading and writing to unicode schema and table names" $
|
||||
it "Can read and write values" $ do
|
||||
get "/%D9%85%D9%88%D8%A7%D8%B1%D8%AF"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
module Feature.Query.UpdateSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
import Test.Hspec hiding (pendingWith)
|
||||
import Test.Hspec hiding (pendingWith)
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Test.Hspec.Wai
|
||||
@@ -10,8 +9,8 @@ import Test.Hspec.Wai.JSON
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec = do
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $ do
|
||||
describe "Patching record" $ do
|
||||
context "to unknown uri" $
|
||||
it "indicates no table found by returning 404" $
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
-- - Upsert/IgnoreDuplicates.hs
|
||||
module Feature.Query.UpsertSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Test.Hspec
|
||||
import Test.Hspec.Wai
|
||||
@@ -13,8 +11,8 @@ import Test.Hspec.Wai.JSON
|
||||
import Protolude hiding (get, put)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig baseCfg $
|
||||
describe "UPSERT" $ do
|
||||
context "with POST" $ do
|
||||
context "when Prefer: resolution=merge-duplicates is specified" $ do
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
module Feature.RollbackSpec 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
|
||||
|
||||
@@ -211,8 +211,8 @@ shouldNotPersistMutations reqHeaders respHeaders = do
|
||||
`shouldRespondWith`
|
||||
[json|[{"id":1}]|]
|
||||
|
||||
allowed :: SpecWith ((), Application)
|
||||
allowed = describe "tx-allow-override = true" $ do
|
||||
allowed :: SpecWithConfig
|
||||
allowed withConfig = withConfig baseCfg $ describe "tx-allow-override = true" $ do
|
||||
describe "without Prefer tx" $ do
|
||||
preferDefault `shouldRespondToReads` withoutPreferenceApplied
|
||||
preferDefault `shouldNotPersistMutations` withoutPreferenceApplied
|
||||
@@ -232,8 +232,13 @@ allowed = describe "tx-allow-override = true" $ do
|
||||
-- because they return before the end of the transaction.
|
||||
preferRollback `shouldRaiseExceptions` withoutPreferenceApplied
|
||||
|
||||
disallowed :: SpecWith ((), Application)
|
||||
disallowed = describe "tx-rollback-all = false, tx-allow-override = false" $ do
|
||||
disallowed :: SpecWithConfig
|
||||
disallowed withConfig = withConfig (
|
||||
baseCfg {
|
||||
configDbTxAllowOverride = False
|
||||
, configDbTxRollbackAll = False
|
||||
}
|
||||
) $ describe "tx-rollback-all = false, tx-allow-override = false" $ do
|
||||
describe "without Prefer tx" $ do
|
||||
preferDefault `shouldRespondToReads` withoutPreferenceApplied
|
||||
preferDefault `shouldPersistMutations` withoutPreferenceApplied
|
||||
@@ -250,8 +255,13 @@ disallowed = describe "tx-rollback-all = false, tx-allow-override = false" $ do
|
||||
preferRollback `shouldRaiseExceptions` withoutPreferenceApplied
|
||||
|
||||
|
||||
forced :: SpecWith ((), Application)
|
||||
forced = describe "tx-rollback-all = true, tx-allow-override = false" $ do
|
||||
forced :: SpecWithConfig
|
||||
forced withConfig = withConfig (
|
||||
baseCfg {
|
||||
configDbTxAllowOverride = False
|
||||
, configDbTxRollbackAll = True
|
||||
}
|
||||
) $ describe "tx-rollback-all = true, tx-allow-override = false" $ do
|
||||
describe "without Prefer tx" $ do
|
||||
preferDefault `shouldRespondToReads` withoutPreferenceApplied
|
||||
preferDefault `shouldNotPersistMutations` withoutPreferenceApplied
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
module Feature.RpcPreRequestGucsSpec where
|
||||
|
||||
import Network.Wai (Application)
|
||||
|
||||
import Network.HTTP.Types
|
||||
import Test.Hspec hiding (pendingWith)
|
||||
import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.JSON
|
||||
|
||||
import PostgREST.Config (AppConfig (..))
|
||||
import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier (..))
|
||||
|
||||
import Protolude hiding (get, put)
|
||||
import SpecHelper
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
spec :: SpecWithConfig
|
||||
spec withConfig = withConfig (baseCfg { configDbPreRequest = Just $ QualifiedIdentifier mempty "custom_headers" }) $
|
||||
describe "GUC headers on all methods via pre-request" $ do
|
||||
it "succeeds setting the headers on POST" $
|
||||
post "/items"
|
||||
|
||||
+34
-130
@@ -79,15 +79,15 @@ main = do
|
||||
, P.acquisitionTimeout 10
|
||||
, P.agingTimeout 60
|
||||
, P.idlenessTimeout 60
|
||||
, P.staticConnectionSettings $ toConnectionSettings identity testCfg
|
||||
, P.staticConnectionSettings $ toConnectionSettings identity baseCfg
|
||||
]
|
||||
|
||||
actualPgVersion <- either (panic . show) id <$> P.use pool queryPgVersion
|
||||
|
||||
-- cached schema cache so most tests run fast
|
||||
baseSchemaCache <- loadSCache pool testCfg
|
||||
baseSchemaCache <- loadSCache pool baseCfg
|
||||
loggerState <- Logger.init
|
||||
metricsState <- Metrics.init (configDbPoolSize testCfg)
|
||||
metricsState <- Metrics.init (configDbPoolSize baseCfg)
|
||||
|
||||
let
|
||||
initApp sCache config = do
|
||||
@@ -104,42 +104,29 @@ main = do
|
||||
customSchemaCache <- loadSCache pool config
|
||||
initApp customSchemaCache config
|
||||
|
||||
let withApp = app testCfg
|
||||
maxRowsApp = app testMaxRowsCfg
|
||||
disabledOpenApi = app testDisabledOpenApiCfg
|
||||
securityOpenApi = app testSecurityOpenApiCfg
|
||||
proxyApp = app testProxyCfg
|
||||
noAnonApp = app testCfgNoAnon
|
||||
noJwtSecretApp = app testCfgNoJwtSecret
|
||||
binaryJwtApp = app testCfgBinaryJWT
|
||||
audJwtApp = app testCfgAudienceJWT
|
||||
asymJwkApp = app testCfgAsymJWK
|
||||
asymJwkSetApp = app testCfgAsymJWKSet
|
||||
rootSpecApp = app testCfgRootSpec
|
||||
responseHeadersApp = app testCfgResponseHeaders
|
||||
disallowRollbackApp = app testCfgDisallowRollback
|
||||
forceRollbackApp = app testCfgForceRollback
|
||||
planEnabledApp = app testPlanEnabledCfg
|
||||
pgSafeUpdateApp = app testPgSafeUpdateEnabledCfg
|
||||
obsApp = app testObservabilityCfg
|
||||
serverTiming = app testCfgServerTiming
|
||||
aggregatesEnabled = app testCfgAggregatesEnabled
|
||||
withConfig config = before (app config)
|
||||
withConfigDbs config = before (appDbs config)
|
||||
describeWithConfig label spec = describe label $ spec withConfig
|
||||
|
||||
extraSearchPathApp = appDbs testCfgExtraSearchPath
|
||||
unicodeApp = appDbs testUnicodeCfg
|
||||
multipleSchemaApp = appDbs testMultipleSchemaCfg
|
||||
ignorePrivOpenApi = appDbs testIgnorePrivOpenApiCfg
|
||||
timezoneDisabled = appDbs testCfgTimezoneDisabled
|
||||
|
||||
|
||||
let specs = uncurry describe <$> [
|
||||
("Feature.Auth.AudienceJwtSecretSpec" , Feature.Auth.AudienceJwtSecretSpec.disabledSpec)
|
||||
let specs = uncurry describeWithConfig <$> [
|
||||
("Feature.Auth.AsymmetricJwtSpec" , Feature.Auth.AsymmetricJwtSpec.spec)
|
||||
, ("Feature.Auth.AudienceJwtSecretSpec" , Feature.Auth.AudienceJwtSecretSpec.disabledSpec)
|
||||
, ("Feature.Auth.AudienceJwtSecretSpec" , Feature.Auth.AudienceJwtSecretSpec.spec)
|
||||
, ("Feature.Auth.AuthSpec" , Feature.Auth.AuthSpec.spec)
|
||||
, ("Feature.Auth.BinaryJwtSecretSpec" , Feature.Auth.BinaryJwtSecretSpec.spec)
|
||||
, ("Feature.Auth.NoAnonSpec" , Feature.Auth.NoAnonSpec.spec)
|
||||
, ("Feature.Auth.NoJwtSecretSpec" , Feature.Auth.NoJwtSecretSpec.spec)
|
||||
, ("Feature.ConcurrentSpec" , Feature.ConcurrentSpec.spec)
|
||||
, ("Feature.CorsSpec" , Feature.CorsSpec.spec)
|
||||
, ("Feature.NoSuperuserSpec" , Feature.NoSuperuserSpec.spec)
|
||||
, ("Feature.ObservabilitySpec" , Feature.ObservabilitySpec.spec)
|
||||
, ("Feature.OpenApi.DisabledOpenApiSpec" , Feature.OpenApi.DisabledOpenApiSpec.spec)
|
||||
, ("Feature.OpenApi.OpenApiSpec" , Feature.OpenApi.OpenApiSpec.spec)
|
||||
, ("Feature.OpenApi.ProxySpec" , Feature.OpenApi.ProxySpec.spec)
|
||||
, ("Feature.OpenApi.RootSpec" , Feature.OpenApi.RootSpec.spec)
|
||||
, ("Feature.OpenApi.SecurityOpenApiSpec" , Feature.OpenApi.SecurityOpenApiSpec.spec)
|
||||
, ("Feature.OptionsSpec" , Feature.OptionsSpec.spec)
|
||||
, ("Feature.Query.AggregateFunctionsSpec.allowed" , Feature.Query.AggregateFunctionsSpec.allowed)
|
||||
, ("Feature.Query.AggregateFunctionsSpec.disallowed" , Feature.Query.AggregateFunctionsSpec.disallowed)
|
||||
, ("Feature.Query.AndOrParamsSpec" , Feature.Query.AndOrParamsSpec.spec)
|
||||
, ("Feature.Query.ComputedRelsSpec" , Feature.Query.ComputedRelsSpec.spec)
|
||||
@@ -153,126 +140,43 @@ main = do
|
||||
, ("Feature.Query.NullsStripSpec" , Feature.Query.NullsStripSpec.spec)
|
||||
, ("Feature.Query.PgSafeUpdateSpec.disabledSpec" , Feature.Query.PgSafeUpdateSpec.disabledSpec)
|
||||
, ("Feature.Query.PlanSpec.disabledSpec" , Feature.Query.PlanSpec.disabledSpec)
|
||||
, ("Feature.Query.PlanSpec.spec" , Feature.Query.PlanSpec.spec)
|
||||
, ("Feature.Query.Preferences.HandlingSpec" , Feature.Query.Preferences.HandlingSpec.spec)
|
||||
, ("Feature.Query.Preferences.MaxAffectedSpec" , Feature.Query.Preferences.MaxAffectedSpec.spec)
|
||||
, ("Feature.Query.Preferences.TimezoneSpec.enabledSpec", Feature.Query.Preferences.TimezoneSpec.enabledSpec)
|
||||
, ("Feature.Query.QueryLimitedSpec" , Feature.Query.QueryLimitedSpec.spec)
|
||||
, ("Feature.Query.QuerySpec" , Feature.Query.QuerySpec.spec)
|
||||
, ("Feature.Query.RangeSpec" , Feature.Query.RangeSpec.spec)
|
||||
, ("Feature.Query.RawOutputTypesSpec" , Feature.Query.RawOutputTypesSpec.spec)
|
||||
, ("Feature.Query.RelatedQueriesSpec" , Feature.Query.RelatedQueriesSpec.spec)
|
||||
, ("Feature.Query.RpcSpec" , Feature.Query.RpcSpec.spec actualPgVersion)
|
||||
, ("Feature.Query.ServerTimingSpec" , Feature.Query.ServerTimingSpec.spec)
|
||||
, ("Feature.Query.SingularSpec" , Feature.Query.SingularSpec.spec)
|
||||
, ("Feature.Query.SpreadQueriesSpec" , Feature.Query.SpreadQueriesSpec.spec)
|
||||
, ("Feature.Query.UpdateSpec" , Feature.Query.UpdateSpec.spec)
|
||||
, ("Feature.Query.UpsertSpec" , Feature.Query.UpsertSpec.spec)
|
||||
, ("Feature.RpcPreRequestGucsSpec" , Feature.RpcPreRequestGucsSpec.spec)
|
||||
]
|
||||
|
||||
hspec $ do
|
||||
mapM_ (parallel . before withApp) specs
|
||||
|
||||
-- this test runs with a different server flag
|
||||
parallel $ before maxRowsApp $
|
||||
describe "Feature.Query.QueryLimitedSpec" Feature.Query.QueryLimitedSpec.spec
|
||||
|
||||
-- this test runs with a different schema
|
||||
parallel $ before unicodeApp $
|
||||
describe "Feature.Query.UnicodeSpec" Feature.Query.UnicodeSpec.spec
|
||||
|
||||
-- this test runs with openapi-mode set to disabled
|
||||
parallel $ before disabledOpenApi $
|
||||
describe "Feature.DisabledOpenApiSpec" Feature.OpenApi.DisabledOpenApiSpec.spec
|
||||
|
||||
-- this test runs with openapi-mode set to ignore-acl
|
||||
parallel $ before ignorePrivOpenApi $
|
||||
describe "Feature.OpenApi.IgnorePrivOpenApiSpec" Feature.OpenApi.IgnorePrivOpenApiSpec.spec
|
||||
|
||||
-- this test runs with a proxy
|
||||
parallel $ before proxyApp $
|
||||
describe "Feature.OpenApi.ProxySpec" Feature.OpenApi.ProxySpec.spec
|
||||
|
||||
-- this test runs with openapi-security-active set to true
|
||||
parallel $ before securityOpenApi $
|
||||
describe "Feature.OpenApi.SecurityOpenApiSpec" Feature.OpenApi.SecurityOpenApiSpec.spec
|
||||
|
||||
-- this test runs without an anonymous role
|
||||
parallel $ before noAnonApp $
|
||||
describe "Feature.Auth.NoAnonSpec" Feature.Auth.NoAnonSpec.spec
|
||||
|
||||
-- this test runs without a JWT secret
|
||||
parallel $ before noJwtSecretApp $
|
||||
describe "Feature.Auth.NoJwtSecretSpec" Feature.Auth.NoJwtSecretSpec.spec
|
||||
|
||||
-- this test runs with a binary JWT secret
|
||||
parallel $ before binaryJwtApp $
|
||||
describe "Feature.Auth.BinaryJwtSecretSpec" Feature.Auth.BinaryJwtSecretSpec.spec
|
||||
|
||||
-- this test runs with a binary JWT secret and an audience claim
|
||||
parallel $ before audJwtApp $
|
||||
describe "Feature.Auth.AudienceJwtSecretSpec" Feature.Auth.AudienceJwtSecretSpec.spec
|
||||
|
||||
-- this test runs with asymmetric JWK
|
||||
parallel $ before asymJwkApp $
|
||||
describe "Feature.Auth.AsymmetricJwtSpec" Feature.Auth.AsymmetricJwtSpec.spec
|
||||
|
||||
-- this test runs with asymmetric JWKSet
|
||||
parallel $ before asymJwkSetApp $
|
||||
describe "Feature.Auth.AsymmetricJwtSpec" Feature.Auth.AsymmetricJwtSpec.spec
|
||||
|
||||
-- this test runs with an extra search path
|
||||
parallel $ before extraSearchPathApp $ do
|
||||
describe "Feature.ExtraSearchPathSpec" Feature.ExtraSearchPathSpec.spec
|
||||
describe "Feature.Query.PostGISSpec" Feature.Query.PostGISSpec.spec
|
||||
|
||||
-- this test runs with a root spec function override
|
||||
parallel $ before rootSpecApp $
|
||||
describe "Feature.OpenApi.RootSpec" Feature.OpenApi.RootSpec.spec
|
||||
|
||||
-- this test runs with a pre request function override
|
||||
parallel $ before responseHeadersApp $
|
||||
describe "Feature.RpcPreRequestGucsSpec" Feature.RpcPreRequestGucsSpec.spec
|
||||
|
||||
-- this test runs with multiple schemas
|
||||
parallel $ before multipleSchemaApp $
|
||||
describe "Feature.Query.MultipleSchemaSpec" Feature.Query.MultipleSchemaSpec.spec
|
||||
|
||||
-- this test runs with db-plan-enabled = true
|
||||
parallel $ before planEnabledApp $
|
||||
describe "Feature.Query.PlanSpec.spec" Feature.Query.PlanSpec.spec
|
||||
|
||||
-- this test runs with server-trace-header set
|
||||
parallel $ before obsApp $
|
||||
describe "Feature.ObservabilitySpec.spec" Feature.ObservabilitySpec.spec
|
||||
|
||||
parallel $ before serverTiming $
|
||||
describe "Feature.Query.ServerTimingSpec.spec" Feature.Query.ServerTimingSpec.spec
|
||||
|
||||
parallel $ before aggregatesEnabled $
|
||||
describe "Feature.Query.AggregateFunctionsSpec" Feature.Query.AggregateFunctionsSpec.allowed
|
||||
|
||||
-- this test runs with db-timezone-enabled = false
|
||||
parallel $ before timezoneDisabled $
|
||||
describe "Feature.Query.Preferences.TimezoneSpec.disabledSpec" Feature.Query.Preferences.TimezoneSpec.disabledSpec
|
||||
mapM_ parallel specs
|
||||
|
||||
parallel $ describe "Feature.Query.UnicodeSpec" $ Feature.Query.UnicodeSpec.spec withConfigDbs
|
||||
parallel $ describe "Feature.OpenApi.IgnorePrivOpenApiSpec" $ Feature.OpenApi.IgnorePrivOpenApiSpec.spec withConfigDbs
|
||||
parallel $ describe "Feature.ExtraSearchPathSpec" $ Feature.ExtraSearchPathSpec.spec withConfigDbs
|
||||
parallel $ describe "Feature.Query.PostGISSpec" $ Feature.Query.PostGISSpec.spec withConfigDbs
|
||||
parallel $ describe "Feature.Query.MultipleSchemaSpec" $ Feature.Query.MultipleSchemaSpec.spec withConfigDbs
|
||||
parallel $ describe "Feature.Query.Preferences.TimezoneSpec.disabledSpec" $ Feature.Query.Preferences.TimezoneSpec.disabledSpec withConfigDbs
|
||||
|
||||
-- Note: the rollback tests can not run in parallel, because they test persistence and
|
||||
-- this results in race conditions
|
||||
|
||||
-- this test runs with tx-rollback-all = true and tx-allow-override = true
|
||||
before withApp $
|
||||
describe "Feature.RollbackAllowedSpec" Feature.RollbackSpec.allowed
|
||||
|
||||
-- this test runs with tx-rollback-all = false and tx-allow-override = false
|
||||
before disallowRollbackApp $
|
||||
describe "Feature.RollbackDisallowedSpec" Feature.RollbackSpec.disallowed
|
||||
|
||||
-- this test runs with tx-rollback-all = true and tx-allow-override = false
|
||||
before forceRollbackApp $
|
||||
describe "Feature.RollbackForcedSpec" Feature.RollbackSpec.forced
|
||||
describe "Feature.RollbackAllowedSpec" $ Feature.RollbackSpec.allowed withConfig
|
||||
describe "Feature.RollbackDisallowedSpec" $ Feature.RollbackSpec.disallowed withConfig
|
||||
describe "Feature.RollbackForcedSpec" $ Feature.RollbackSpec.forced withConfig
|
||||
|
||||
-- This test runs with a pre request to enable the pg-safeupdate library per-session.
|
||||
-- This needs to run last, because once pg safe update is loaded, it can't be unloaded again.
|
||||
before pgSafeUpdateApp $
|
||||
describe "Feature.Query.PgSafeUpdateSpec.spec" Feature.Query.PgSafeUpdateSpec.spec
|
||||
describe "Feature.Query.PgSafeUpdateSpec.spec" $ Feature.Query.PgSafeUpdateSpec.spec withConfig
|
||||
|
||||
where
|
||||
loadSCache pool conf =
|
||||
|
||||
+3
-96
@@ -14,9 +14,10 @@ import qualified Jose.Jws as JWT
|
||||
import qualified Jose.Jwt as JWT
|
||||
|
||||
import Data.Aeson ((.=))
|
||||
import Data.CaseInsensitive (CI (..), mk, original)
|
||||
import Data.CaseInsensitive (CI (..), original)
|
||||
import Data.List (lookup)
|
||||
import Data.List.NonEmpty (fromList)
|
||||
import Network.Wai (Application)
|
||||
import Network.Wai.Test (SResponse (simpleBody, simpleHeaders, simpleStatus))
|
||||
import System.IO.Unsafe (unsafePerformIO)
|
||||
import Text.Regex.TDFA ((=~))
|
||||
@@ -25,7 +26,6 @@ import Text.Regex.TDFA ((=~))
|
||||
import Network.HTTP.Types
|
||||
import Test.Hspec
|
||||
import Test.Hspec.Wai
|
||||
import Text.Heredoc
|
||||
|
||||
import Data.String (String)
|
||||
import PostgREST.Config (AppConfig (..),
|
||||
@@ -106,6 +106,7 @@ validateOpenApiResponse headers = do
|
||||
, matchHeaders = []
|
||||
}
|
||||
|
||||
type SpecWithConfig = (AppConfig -> SpecWith ((), Application) -> Spec) -> Spec
|
||||
|
||||
baseCfg :: AppConfig
|
||||
baseCfg = let secret = encodeUtf8 "reallyreallyreallyreallyverysafe" in
|
||||
@@ -161,100 +162,6 @@ baseCfg = let secret = encodeUtf8 "reallyreallyreallyreallyverysafe" in
|
||||
, configServerTimingEnabled = True
|
||||
}
|
||||
|
||||
testCfg :: AppConfig
|
||||
testCfg = baseCfg
|
||||
|
||||
testCfgDisallowRollback :: AppConfig
|
||||
testCfgDisallowRollback = baseCfg { configDbTxAllowOverride = False, configDbTxRollbackAll = False }
|
||||
|
||||
testCfgForceRollback :: AppConfig
|
||||
testCfgForceRollback = baseCfg { configDbTxAllowOverride = False, configDbTxRollbackAll = True }
|
||||
|
||||
testCfgNoAnon :: AppConfig
|
||||
testCfgNoAnon = baseCfg { configDbAnonRole = Nothing }
|
||||
|
||||
testCfgNoJwtSecret :: AppConfig
|
||||
testCfgNoJwtSecret = baseCfg { configJwtSecret = Nothing, configJWKS = Nothing }
|
||||
|
||||
testUnicodeCfg :: AppConfig
|
||||
testUnicodeCfg = baseCfg { configDbSchemas = fromList ["تست"] }
|
||||
|
||||
testMaxRowsCfg :: AppConfig
|
||||
testMaxRowsCfg = baseCfg { configDbMaxRows = Just 2 }
|
||||
|
||||
testDisabledOpenApiCfg :: AppConfig
|
||||
testDisabledOpenApiCfg = baseCfg { configOpenApiMode = OADisabled }
|
||||
|
||||
testIgnorePrivOpenApiCfg :: AppConfig
|
||||
testIgnorePrivOpenApiCfg = baseCfg { configOpenApiMode = OAIgnorePriv, configDbSchemas = fromList ["test", "v1"] }
|
||||
|
||||
testProxyCfg :: AppConfig
|
||||
testProxyCfg = baseCfg { configOpenApiServerProxyUri = Just "https://postgrest.com/openapi.json" }
|
||||
|
||||
testSecurityOpenApiCfg :: AppConfig
|
||||
testSecurityOpenApiCfg = baseCfg { configOpenApiSecurityActive = True }
|
||||
|
||||
testPlanEnabledCfg :: AppConfig
|
||||
testPlanEnabledCfg = baseCfg { configDbPlanEnabled = True }
|
||||
|
||||
testCfgBinaryJWT :: AppConfig
|
||||
testCfgBinaryJWT =
|
||||
baseCfg {
|
||||
configJwtSecret = Just generateSecret
|
||||
, configJWKS = rightToMaybe $ parseSecret generateSecret
|
||||
}
|
||||
|
||||
testCfgAudienceJWT :: AppConfig
|
||||
testCfgAudienceJWT =
|
||||
baseCfg {
|
||||
configJwtSecret = Just generateSecret
|
||||
, configJwtAudience = Just "youraudience"
|
||||
, configJWKS = rightToMaybe $ parseSecret generateSecret
|
||||
}
|
||||
|
||||
testCfgAsymJWK :: AppConfig
|
||||
testCfgAsymJWK =
|
||||
let secret = encodeUtf8 [str|{"alg":"RS256","e":"AQAB","key_ops":["verify"],"kty":"RSA","n":"0etQ2Tg187jb04MWfpuogYGV75IFrQQBxQaGH75eq_FpbkyoLcEpRUEWSbECP2eeFya2yZ9vIO5ScD-lPmovePk4Aa4SzZ8jdjhmAbNykleRPCxMg0481kz6PQhnHRUv3nF5WP479CnObJKqTVdEagVL66oxnX9VhZG9IZA7k0Th5PfKQwrKGyUeTGczpOjaPqbxlunP73j9AfnAt4XCS8epa-n3WGz1j-wfpr_ys57Aq-zBCfqP67UYzNpeI1AoXsJhD9xSDOzvJgFRvc3vm2wjAW4LEMwi48rCplamOpZToIHEPIaPzpveYQwDnB1HFTR1ove9bpKJsHmi-e2uzQ","use":"sig"}|]
|
||||
in baseCfg {
|
||||
configJwtSecret = Just secret
|
||||
, configJWKS = rightToMaybe $ parseSecret secret
|
||||
}
|
||||
|
||||
testCfgAsymJWKSet :: AppConfig
|
||||
testCfgAsymJWKSet =
|
||||
let secret = encodeUtf8 [str|{"keys": [{"alg":"RS256","e":"AQAB","key_ops":["verify"],"kty":"RSA","n":"0etQ2Tg187jb04MWfpuogYGV75IFrQQBxQaGH75eq_FpbkyoLcEpRUEWSbECP2eeFya2yZ9vIO5ScD-lPmovePk4Aa4SzZ8jdjhmAbNykleRPCxMg0481kz6PQhnHRUv3nF5WP479CnObJKqTVdEagVL66oxnX9VhZG9IZA7k0Th5PfKQwrKGyUeTGczpOjaPqbxlunP73j9AfnAt4XCS8epa-n3WGz1j-wfpr_ys57Aq-zBCfqP67UYzNpeI1AoXsJhD9xSDOzvJgFRvc3vm2wjAW4LEMwi48rCplamOpZToIHEPIaPzpveYQwDnB1HFTR1ove9bpKJsHmi-e2uzQ","use":"sig"}]}|]
|
||||
in baseCfg {
|
||||
configJwtSecret = Just secret
|
||||
, configJWKS = rightToMaybe $ parseSecret secret
|
||||
}
|
||||
|
||||
testCfgExtraSearchPath :: AppConfig
|
||||
testCfgExtraSearchPath = baseCfg { configDbExtraSearchPath = ["public", "extensions", "EXTRA \"@/\\#~_-"] }
|
||||
|
||||
testCfgRootSpec :: AppConfig
|
||||
testCfgRootSpec = baseCfg { configDbRootSpec = Just $ QualifiedIdentifier mempty "root"}
|
||||
|
||||
testCfgResponseHeaders :: AppConfig
|
||||
testCfgResponseHeaders = baseCfg { configDbPreRequest = Just $ QualifiedIdentifier mempty "custom_headers" }
|
||||
|
||||
testMultipleSchemaCfg :: AppConfig
|
||||
testMultipleSchemaCfg = baseCfg { configDbSchemas = fromList ["v1", "v2", "SPECIAL \"@/\\#~_-"] }
|
||||
|
||||
testPgSafeUpdateEnabledCfg :: AppConfig
|
||||
testPgSafeUpdateEnabledCfg = baseCfg { configDbPreRequest = Just $ QualifiedIdentifier "test" "load_safeupdate" }
|
||||
|
||||
testObservabilityCfg :: AppConfig
|
||||
testObservabilityCfg = baseCfg { configServerTraceHeader = Just $ mk "X-Request-Id" }
|
||||
|
||||
testCfgServerTiming :: AppConfig
|
||||
testCfgServerTiming = baseCfg { configDbPlanEnabled = True }
|
||||
|
||||
testCfgAggregatesEnabled :: AppConfig
|
||||
testCfgAggregatesEnabled = baseCfg { configDbAggregates = True }
|
||||
|
||||
testCfgTimezoneDisabled :: AppConfig
|
||||
testCfgTimezoneDisabled = baseCfg { configDbTimezoneEnabled = False }
|
||||
|
||||
rangeHdrs :: ByteRange -> [Header]
|
||||
rangeHdrs r = [rangeUnit, (hRange, renderByteRange r)]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user