feat: drop support for pg 9.5
This commit is contained in:
committed by
Wolfgang Walther
parent
7ed8b10776
commit
a65ac9b0f6
@@ -15,10 +15,8 @@ import Test.Hspec.Wai.JSON
|
||||
import Protolude
|
||||
import SpecHelper
|
||||
|
||||
import PostgREST.Config.PgVersion (PgVersion, pgVersion96)
|
||||
|
||||
spec :: PgVersion -> SpecWith ((), Application)
|
||||
spec actualPgVersion =
|
||||
spec :: SpecWith ((), Application)
|
||||
spec =
|
||||
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" $
|
||||
@@ -191,16 +189,15 @@ spec actualPgVersion =
|
||||
[json|[{"id": 1, "name": "child v2-3", "parent_id": 3}]|]
|
||||
{ matchHeaders = ["Content-Profile" <:> "v2"] }
|
||||
|
||||
when (actualPgVersion >= pgVersion96) $
|
||||
it "succeeds on PUT on the v2 schema" $
|
||||
request methodPut "/children?id=eq.111" [("Content-Profile", "v2"), ("Prefer", "return=representation")]
|
||||
[json| [ { "id": 111, "name": "child v2-111", "parent_id": null } ]|]
|
||||
`shouldRespondWith`
|
||||
[json|[{ "id": 111, "name": "child v2-111", "parent_id": null }]|]
|
||||
{
|
||||
matchStatus = 200
|
||||
, matchHeaders = [matchContentTypeJson, "Content-Profile" <:> "v2"]
|
||||
}
|
||||
it "succeeds on PUT on the v2 schema" $
|
||||
request methodPut "/children?id=eq.111" [("Content-Profile", "v2"), ("Prefer", "return=representation")]
|
||||
[json| [ { "id": 111, "name": "child v2-111", "parent_id": null } ]|]
|
||||
`shouldRespondWith`
|
||||
[json|[{ "id": 111, "name": "child v2-111", "parent_id": null }]|]
|
||||
{
|
||||
matchStatus = 200
|
||||
, matchHeaders = [matchContentTypeJson, "Content-Profile" <:> "v2"]
|
||||
}
|
||||
|
||||
context "OpenAPI output" $ do
|
||||
it "succeeds in reading table definition from default schema v1 if no schema is selected via header" $ do
|
||||
|
||||
+25
-27
@@ -9,8 +9,7 @@ import Test.Hspec.Wai
|
||||
import Test.Hspec.Wai.JSON
|
||||
|
||||
import PostgREST.Config.PgVersion (PgVersion, pgVersion110,
|
||||
pgVersion112, pgVersion121,
|
||||
pgVersion96)
|
||||
pgVersion112, pgVersion121)
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
@@ -200,34 +199,33 @@ spec actualPgVersion = do
|
||||
{"text_search_vector": "'art':4 'spass':5 'unmog':7"}]|]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
when (actualPgVersion >= pgVersion96) $
|
||||
context "Use of the phraseto_tsquery function" $ do
|
||||
it "finds matches" $
|
||||
get "/tsearch?text_search_vector=phfts.The%20Fat%20Cats" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'ate':3 'cat':2 'fat':1 'rat':4" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
context "Use of the phraseto_tsquery function" $ do
|
||||
it "finds matches" $
|
||||
get "/tsearch?text_search_vector=phfts.The%20Fat%20Cats" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'ate':3 'cat':2 'fat':1 'rat':4" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
it "finds matches with different dictionaries" $
|
||||
get "/tsearch?text_search_vector=phfts(german).Art%20Spass" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'art':4 'spass':5 'unmog':7" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
it "finds matches with different dictionaries" $
|
||||
get "/tsearch?text_search_vector=phfts(german).Art%20Spass" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'art':4 'spass':5 'unmog':7" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
it "can be negated with not operator" $
|
||||
get "/tsearch?text_search_vector=not.phfts(english).The%20Fat%20Cats" `shouldRespondWith`
|
||||
[json| [
|
||||
{"text_search_vector": "'fun':5 'imposs':9 'kind':3"},
|
||||
{"text_search_vector": "'also':2 'fun':3 'possibl':8"},
|
||||
{"text_search_vector": "'amus':5 'fair':7 'impossibl':9 'peu':4"},
|
||||
{"text_search_vector": "'art':4 'spass':5 'unmog':7"}]|]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
it "can be negated with not operator" $
|
||||
get "/tsearch?text_search_vector=not.phfts(english).The%20Fat%20Cats" `shouldRespondWith`
|
||||
[json| [
|
||||
{"text_search_vector": "'fun':5 'imposs':9 'kind':3"},
|
||||
{"text_search_vector": "'also':2 'fun':3 'possibl':8"},
|
||||
{"text_search_vector": "'amus':5 'fair':7 'impossibl':9 'peu':4"},
|
||||
{"text_search_vector": "'art':4 'spass':5 'unmog':7"}]|]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
it "can be used with or query param" $
|
||||
get "/tsearch?or=(text_search_vector.phfts(german).Art%20Spass, text_search_vector.phfts(french).amusant, text_search_vector.fts(english).impossible)" `shouldRespondWith`
|
||||
[json|[
|
||||
{"text_search_vector": "'fun':5 'imposs':9 'kind':3" },
|
||||
{"text_search_vector": "'amus':5 'fair':7 'impossibl':9 'peu':4" },
|
||||
{"text_search_vector": "'art':4 'spass':5 'unmog':7"}
|
||||
]|] { matchHeaders = [matchContentTypeJson] }
|
||||
it "can be used with or query param" $
|
||||
get "/tsearch?or=(text_search_vector.phfts(german).Art%20Spass, text_search_vector.phfts(french).amusant, text_search_vector.fts(english).impossible)" `shouldRespondWith`
|
||||
[json|[
|
||||
{"text_search_vector": "'fun':5 'imposs':9 'kind':3" },
|
||||
{"text_search_vector": "'amus':5 'fair':7 'impossibl':9 'peu':4" },
|
||||
{"text_search_vector": "'art':4 'spass':5 'unmog':7"}
|
||||
]|] { matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
it "matches with computed column" $
|
||||
get "/items?always_true=eq.true&order=id.asc" `shouldRespondWith`
|
||||
|
||||
+57
-59
@@ -15,7 +15,7 @@ import Text.Heredoc
|
||||
import PostgREST.Config.PgVersion (PgVersion, pgVersion100,
|
||||
pgVersion109, pgVersion110,
|
||||
pgVersion112, pgVersion114,
|
||||
pgVersion140, pgVersion96)
|
||||
pgVersion140)
|
||||
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
@@ -1005,72 +1005,70 @@ spec actualPgVersion =
|
||||
[json|[{"text_search_vector":"'fun':5 'imposs':9 'kind':3"}]|]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
when (actualPgVersion >= pgVersion96) $
|
||||
it "should work with the phraseto_tsquery function" $
|
||||
get "/rpc/get_tsearch?text_search_vector=phfts(english).impossible" `shouldRespondWith`
|
||||
[json|[{"text_search_vector":"'fun':5 'imposs':9 'kind':3"}]|]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
it "should work with the phraseto_tsquery function" $
|
||||
get "/rpc/get_tsearch?text_search_vector=phfts(english).impossible" `shouldRespondWith`
|
||||
[json|[{"text_search_vector":"'fun':5 'imposs':9 'kind':3"}]|]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
it "should work with an argument of custom type in public schema" $
|
||||
get "/rpc/test_arg?my_arg=something" `shouldRespondWith`
|
||||
[json|"foobar"|]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
when (actualPgVersion >= pgVersion96) $ do
|
||||
context "GUC headers on function calls" $ do
|
||||
it "succeeds setting the headers" $ do
|
||||
get "/rpc/get_projects_and_guc_headers?id=eq.2&select=id"
|
||||
`shouldRespondWith` [json|[{"id": 2}]|]
|
||||
{matchHeaders = [
|
||||
matchContentTypeJson,
|
||||
"X-Test" <:> "key1=val1; someValue; key2=val2",
|
||||
"X-Test-2" <:> "key1=val1"]}
|
||||
get "/rpc/get_int_and_guc_headers?num=1"
|
||||
`shouldRespondWith` [json|1|]
|
||||
{matchHeaders = [
|
||||
matchContentTypeJson,
|
||||
"X-Test" <:> "key1=val1; someValue; key2=val2",
|
||||
"X-Test-2" <:> "key1=val1"]}
|
||||
post "/rpc/get_int_and_guc_headers" [json|{"num": 1}|]
|
||||
`shouldRespondWith` [json|1|]
|
||||
{matchHeaders = [
|
||||
matchContentTypeJson,
|
||||
"X-Test" <:> "key1=val1; someValue; key2=val2",
|
||||
"X-Test-2" <:> "key1=val1"]}
|
||||
context "GUC headers on function calls" $ do
|
||||
it "succeeds setting the headers" $ do
|
||||
get "/rpc/get_projects_and_guc_headers?id=eq.2&select=id"
|
||||
`shouldRespondWith` [json|[{"id": 2}]|]
|
||||
{matchHeaders = [
|
||||
matchContentTypeJson,
|
||||
"X-Test" <:> "key1=val1; someValue; key2=val2",
|
||||
"X-Test-2" <:> "key1=val1"]}
|
||||
get "/rpc/get_int_and_guc_headers?num=1"
|
||||
`shouldRespondWith` [json|1|]
|
||||
{matchHeaders = [
|
||||
matchContentTypeJson,
|
||||
"X-Test" <:> "key1=val1; someValue; key2=val2",
|
||||
"X-Test-2" <:> "key1=val1"]}
|
||||
post "/rpc/get_int_and_guc_headers" [json|{"num": 1}|]
|
||||
`shouldRespondWith` [json|1|]
|
||||
{matchHeaders = [
|
||||
matchContentTypeJson,
|
||||
"X-Test" <:> "key1=val1; someValue; key2=val2",
|
||||
"X-Test-2" <:> "key1=val1"]}
|
||||
|
||||
it "fails when setting headers with wrong json structure" $ do
|
||||
get "/rpc/bad_guc_headers_1"
|
||||
`shouldRespondWith`
|
||||
[json|{"message":"response.headers guc must be a JSON array composed of objects with a single key and a string value"}|]
|
||||
{ matchStatus = 500
|
||||
, matchHeaders = [ matchContentTypeJson ]
|
||||
}
|
||||
get "/rpc/bad_guc_headers_2"
|
||||
`shouldRespondWith`
|
||||
[json|{"message":"response.headers guc must be a JSON array composed of objects with a single key and a string value"}|]
|
||||
{ matchStatus = 500
|
||||
, matchHeaders = [ matchContentTypeJson ]
|
||||
}
|
||||
get "/rpc/bad_guc_headers_3"
|
||||
`shouldRespondWith`
|
||||
[json|{"message":"response.headers guc must be a JSON array composed of objects with a single key and a string value"}|]
|
||||
{ matchStatus = 500
|
||||
, matchHeaders = [ matchContentTypeJson ]
|
||||
}
|
||||
post "/rpc/bad_guc_headers_1" [json|{}|]
|
||||
`shouldRespondWith`
|
||||
[json|{"message":"response.headers guc must be a JSON array composed of objects with a single key and a string value"}|]
|
||||
{ matchStatus = 500
|
||||
, matchHeaders = [ matchContentTypeJson ]
|
||||
}
|
||||
it "fails when setting headers with wrong json structure" $ do
|
||||
get "/rpc/bad_guc_headers_1"
|
||||
`shouldRespondWith`
|
||||
[json|{"message":"response.headers guc must be a JSON array composed of objects with a single key and a string value"}|]
|
||||
{ matchStatus = 500
|
||||
, matchHeaders = [ matchContentTypeJson ]
|
||||
}
|
||||
get "/rpc/bad_guc_headers_2"
|
||||
`shouldRespondWith`
|
||||
[json|{"message":"response.headers guc must be a JSON array composed of objects with a single key and a string value"}|]
|
||||
{ matchStatus = 500
|
||||
, matchHeaders = [ matchContentTypeJson ]
|
||||
}
|
||||
get "/rpc/bad_guc_headers_3"
|
||||
`shouldRespondWith`
|
||||
[json|{"message":"response.headers guc must be a JSON array composed of objects with a single key and a string value"}|]
|
||||
{ matchStatus = 500
|
||||
, matchHeaders = [ matchContentTypeJson ]
|
||||
}
|
||||
post "/rpc/bad_guc_headers_1" [json|{}|]
|
||||
`shouldRespondWith`
|
||||
[json|{"message":"response.headers guc must be a JSON array composed of objects with a single key and a string value"}|]
|
||||
{ matchStatus = 500
|
||||
, matchHeaders = [ matchContentTypeJson ]
|
||||
}
|
||||
|
||||
it "can set the same http header twice" $
|
||||
get "/rpc/set_cookie_twice"
|
||||
`shouldRespondWith`
|
||||
"null"
|
||||
{ matchHeaders = [ matchContentTypeJson
|
||||
, "Set-Cookie" <:> "sessionid=38afes7a8; HttpOnly; Path=/"
|
||||
, "Set-Cookie" <:> "id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly" ]}
|
||||
it "can set the same http header twice" $
|
||||
get "/rpc/set_cookie_twice"
|
||||
`shouldRespondWith`
|
||||
"null"
|
||||
{ matchHeaders = [ matchContentTypeJson
|
||||
, "Set-Cookie" <:> "sessionid=38afes7a8; HttpOnly; Path=/"
|
||||
, "Set-Cookie" <:> "id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly" ]}
|
||||
|
||||
it "can override the Location header on a trigger" $
|
||||
post "/stuff"
|
||||
|
||||
+12
-14
@@ -9,13 +9,12 @@ import Data.List.NonEmpty (toList)
|
||||
|
||||
import Test.Hspec
|
||||
|
||||
import PostgREST.App (postgrest)
|
||||
import PostgREST.Config (AppConfig (..), LogLevel (..))
|
||||
import PostgREST.Config.Database (queryPgVersion)
|
||||
import PostgREST.Config.PgVersion (pgVersion96)
|
||||
import PostgREST.DbStructure (queryDbStructure)
|
||||
import Protolude hiding (toList, toS)
|
||||
import Protolude.Conv (toS)
|
||||
import PostgREST.App (postgrest)
|
||||
import PostgREST.Config (AppConfig (..), LogLevel (..))
|
||||
import PostgREST.Config.Database (queryPgVersion)
|
||||
import PostgREST.DbStructure (queryDbStructure)
|
||||
import Protolude hiding (toList, toS)
|
||||
import Protolude.Conv (toS)
|
||||
import SpecHelper
|
||||
|
||||
import qualified PostgREST.AppState as AppState
|
||||
@@ -203,16 +202,15 @@ main = do
|
||||
parallel $ before extraSearchPathApp $
|
||||
describe "Feature.ExtraSearchPathSpec" Feature.ExtraSearchPathSpec.spec
|
||||
|
||||
when (actualPgVersion >= pgVersion96) $ do
|
||||
-- this test runs with a root spec function override
|
||||
parallel $ before rootSpecApp $
|
||||
describe "Feature.RootSpec" Feature.RootSpec.spec
|
||||
parallel $ before responseHeadersApp $
|
||||
describe "Feature.RpcPreRequestGucsSpec" Feature.RpcPreRequestGucsSpec.spec
|
||||
-- this test runs with a root spec function override
|
||||
parallel $ before rootSpecApp $
|
||||
describe "Feature.RootSpec" Feature.RootSpec.spec
|
||||
parallel $ before responseHeadersApp $
|
||||
describe "Feature.RpcPreRequestGucsSpec" Feature.RpcPreRequestGucsSpec.spec
|
||||
|
||||
-- this test runs with multiple schemas
|
||||
parallel $ before multipleSchemaApp $
|
||||
describe "Feature.MultipleSchemaSpec" $ Feature.MultipleSchemaSpec.spec actualPgVersion
|
||||
describe "Feature.MultipleSchemaSpec" Feature.MultipleSchemaSpec.spec
|
||||
|
||||
-- this test runs with db-uses-legacy-gucs = false
|
||||
parallel $ before testCfgLegacyGucsApp $
|
||||
|
||||
Reference in New Issue
Block a user