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