From cf0b20c0879ad1bb47a5b47163f6d67f56fadad1 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Sat, 27 Nov 2021 23:15:34 +0100 Subject: [PATCH] feat: drop support for pg 9.6 --- .github/workflows/ci.yaml | 2 +- CHANGELOG.md | 4 + default.nix | 1 - nix/README.md | 4 +- src/PostgREST/App.hs | 17 ++- src/PostgREST/CLI.hs | 2 - src/PostgREST/Config/PgVersion.hs | 6 +- src/PostgREST/DbStructure.hs | 26 ++-- src/PostgREST/Workers.hs | 3 +- test/Feature/OpenApiSpec.hs | 36 +++--- test/Feature/OptionsSpec.hs | 26 ++-- test/Feature/RpcSpec.hs | 200 +++++++++++------------------- test/Main.hs | 6 +- 13 files changed, 134 insertions(+), 199 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 286cacaf91e..966b759db0c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -61,7 +61,7 @@ jobs: strategy: fail-fast: false matrix: - pgVersion: [9.6, 10, 11, 12, 13, 14] + pgVersion: [10, 11, 12, 13, 14] name: Test PG ${{ matrix.pgVersion }} (Nix) runs-on: ubuntu-latest defaults: diff --git a/CHANGELOG.md b/CHANGELOG.md index d36a9c7c3cc..188d812aa34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +### Changed + + - #2052, Dropped support for PostgreSQL 9.6 - @wolfgangwalther + ## [9.0.0] - 2021-11-25 ### Added diff --git a/default.nix b/default.nix index a484819a67f..6705095727f 100644 --- a/default.nix +++ b/default.nix @@ -51,7 +51,6 @@ let { name = "postgresql-12"; postgresql = pkgs.postgresql_12; } { name = "postgresql-11"; postgresql = pkgs.postgresql_11; } { name = "postgresql-10"; postgresql = pkgs.postgresql_10; } - { name = "postgresql-9.6"; postgresql = pkgs.postgresql_9_6; } ]; patches = diff --git a/nix/README.md b/nix/README.md index 614ea04d44c..f797df52870 100644 --- a/nix/README.md +++ b/nix/README.md @@ -80,7 +80,7 @@ postgrest-coverage postgrest-with-postgresql-10 postgrest-lint postgrest-with-postgresql-11 postgrest-run postgrest-with-postgresql-12 postgrest-style postgrest-with-postgresql-13 -postgrest-style-check postgrest-with-postgresql-9.6 +postgrest-style-check postgrest-with-postgresql-14 postgrest-test-io ... @@ -104,7 +104,7 @@ postgrest-coverage postgrest-with-postgresql-10 postgrest-lint postgrest-with-postgresql-11 postgrest-run postgrest-with-postgresql-12 postgrest-style postgrest-with-postgresql-13 -postgrest-style-check postgrest-with-postgresql-9.6 +postgrest-style-check postgrest-with-postgresql-14 postgrest-test-io postgrest-test-memory ... diff --git a/src/PostgREST/App.hs b/src/PostgREST/App.hs index d70ac55efc1..da2b7cdfe9c 100644 --- a/src/PostgREST/App.hs +++ b/src/PostgREST/App.hs @@ -92,7 +92,6 @@ data RequestContext = RequestContext { ctxConfig :: AppConfig , ctxDbStructure :: DbStructure , ctxApiRequest :: ApiRequest - , ctxPgVersion :: PgVersion } type Handler = ExceptT Error @@ -194,7 +193,7 @@ postgrestResponse conf maybeDbStructure jsonDbS pgVer pool time req = do let handleReq apiReq = - handleRequest $ RequestContext conf dbStructure apiReq pgVer + handleRequest $ RequestContext conf dbStructure apiReq runDbHandler pool (txMode apiRequest) jwtClaims (configDbPreparedStatements conf) . Middleware.optionalRollback conf apiRequest $ @@ -213,7 +212,7 @@ runDbHandler pool mode jwtClaims prepared handler = do liftEither resp handleRequest :: RequestContext -> DbHandler Wai.Response -handleRequest context@(RequestContext _ _ ApiRequest{..} _) = +handleRequest context@(RequestContext _ _ ApiRequest{..}) = case (iAction, iTarget) of (ActionRead headersOnly, TargetIdent identifier) -> handleRead headersOnly identifier context @@ -331,7 +330,7 @@ handleCreate identifier@QualifiedIdentifier{..} context@RequestContext{..} = do response HTTP.status201 headers mempty handleUpdate :: QualifiedIdentifier -> RequestContext -> DbHandler Wai.Response -handleUpdate identifier context@(RequestContext _ _ ApiRequest{..} _) = do +handleUpdate identifier context@(RequestContext _ _ ApiRequest{..}) = do WriteQueryResult{..} <- writeQuery identifier False mempty context let @@ -353,7 +352,7 @@ handleUpdate identifier context@(RequestContext _ _ ApiRequest{..} _) = do response status [contentRangeHeader] mempty handleSingleUpsert :: QualifiedIdentifier -> RequestContext-> DbHandler Wai.Response -handleSingleUpsert identifier context@(RequestContext _ _ ApiRequest{..} _) = do +handleSingleUpsert identifier context@(RequestContext _ _ ApiRequest{..}) = do when (iTopLevelRange /= RangeQuery.allRange) $ throwError Error.PutRangeNotAllowedError @@ -377,7 +376,7 @@ handleSingleUpsert identifier context@(RequestContext _ _ ApiRequest{..} _) = do response HTTP.status204 (contentTypeHeaders context) mempty handleDelete :: QualifiedIdentifier -> RequestContext -> DbHandler Wai.Response -handleDelete identifier context@(RequestContext _ _ ApiRequest{..} _) = do +handleDelete identifier context@(RequestContext _ _ ApiRequest{..}) = do WriteQueryResult{..} <- writeQuery identifier False mempty context let @@ -460,12 +459,12 @@ handleInvoke invMethod proc context@RequestContext{..} = do (if invMethod == InvHead then mempty else LBS.fromStrict body) handleOpenApi :: Bool -> Schema -> RequestContext -> DbHandler Wai.Response -handleOpenApi headersOnly tSchema (RequestContext conf@AppConfig{..} dbStructure apiRequest ctxPgVersion) = do +handleOpenApi headersOnly tSchema (RequestContext conf@AppConfig{..} dbStructure apiRequest) = do body <- lift $ case configOpenApiMode of OAFollowPriv -> OpenAPI.encode conf dbStructure - <$> SQL.statement tSchema (DbStructure.accessibleTables ctxPgVersion configDbPreparedStatements) + <$> SQL.statement tSchema (DbStructure.accessibleTables configDbPreparedStatements) <*> SQL.statement tSchema (DbStructure.accessibleProcs configDbPreparedStatements) <*> SQL.statement tSchema (DbStructure.schemaDescription configDbPreparedStatements) OAIgnorePriv -> @@ -567,7 +566,7 @@ returnsScalar (TargetProc proc _) = Proc.procReturnsScalar proc returnsScalar _ = False readRequest :: Monad m => QualifiedIdentifier -> RequestContext -> Handler m ReadRequest -readRequest QualifiedIdentifier{..} (RequestContext AppConfig{..} dbStructure apiRequest _) = +readRequest QualifiedIdentifier{..} (RequestContext AppConfig{..} dbStructure apiRequest) = liftEither $ ReqBuilder.readRequest qiSchema qiName configDbMaxRows (dbRelationships dbStructure) diff --git a/src/PostgREST/CLI.hs b/src/PostgREST/CLI.hs index 6cd604dfc51..6fddad387bb 100644 --- a/src/PostgREST/CLI.hs +++ b/src/PostgREST/CLI.hs @@ -53,7 +53,6 @@ main installSignalHandlers runAppWithSocket CLI{cliCommand, cliPath} = do dumpSchema :: AppState -> IO LBS.ByteString dumpSchema appState = do AppConfig{..} <- AppState.getConfig appState - actualPgVersion <- AppState.getPgVersion appState result <- let transaction = if configDbPreparedStatements then SQL.transaction else SQL.unpreparedTransaction in SQL.use (AppState.getPool appState) $ @@ -61,7 +60,6 @@ dumpSchema appState = do queryDbStructure (toList configDbSchemas) configDbExtraSearchPath - actualPgVersion configDbPreparedStatements SQL.release $ AppState.getPool appState case result of diff --git a/src/PostgREST/Config/PgVersion.hs b/src/PostgREST/Config/PgVersion.hs index 8aa37275264..122b33181f7 100644 --- a/src/PostgREST/Config/PgVersion.hs +++ b/src/PostgREST/Config/PgVersion.hs @@ -3,7 +3,6 @@ module PostgREST.Config.PgVersion ( PgVersion(..) , minimumPgVersion - , pgVersion96 , pgVersion100 , pgVersion109 , pgVersion110 @@ -30,10 +29,7 @@ instance Ord PgVersion where -- | Tells the minimum PostgreSQL version required by this version of PostgREST minimumPgVersion :: PgVersion -minimumPgVersion = pgVersion96 - -pgVersion96 :: PgVersion -pgVersion96 = PgVersion 90600 "9.6" +minimumPgVersion = pgVersion100 pgVersion100 :: PgVersion pgVersion100 = PgVersion 100000 "10" diff --git a/src/PostgREST/DbStructure.hs b/src/PostgREST/DbStructure.hs index 87b48c8c433..14d2105f3e5 100644 --- a/src/PostgREST/DbStructure.hs +++ b/src/PostgREST/DbStructure.hs @@ -41,7 +41,6 @@ import Data.Set as S (fromList) import Data.Text (split) import Text.InterpolatedString.Perl6 (q) -import PostgREST.Config.PgVersion (PgVersion, pgVersion100) import PostgREST.DbStructure.Identifiers (QualifiedIdentifier (..), Schema, TableName) import PostgREST.DbStructure.Proc (PgType (..), @@ -83,10 +82,10 @@ type ViewColumn = Column -- | A SQL query that can be executed independently type SqlQuery = ByteString -queryDbStructure :: [Schema] -> [Schema] -> PgVersion -> Bool -> SQL.Transaction DbStructure -queryDbStructure schemas extraSearchPath pgVer prepared = do +queryDbStructure :: [Schema] -> [Schema] -> Bool -> SQL.Transaction DbStructure +queryDbStructure schemas extraSearchPath prepared = do SQL.sql "set local schema ''" -- This voids the search path. The following queries need this for getting the fully qualified name(schema.name) of every db object - tabs <- SQL.statement mempty $ allTables pgVer prepared + tabs <- SQL.statement mempty $ allTables prepared cols <- SQL.statement schemas $ allColumns tabs prepared srcCols <- SQL.statement (schemas, extraSearchPath) $ pfkSourceColumns cols prepared m2oRels <- SQL.statement mempty $ allM2ORels tabs cols prepared @@ -312,8 +311,8 @@ schemaDescription = where n.nspname = $1 |] -accessibleTables :: PgVersion -> Bool -> SQL.Statement Schema [Table] -accessibleTables pgVer = +accessibleTables :: Bool -> SQL.Statement Schema [Table] +accessibleTables = SQL.Statement sql (param HE.text) decodeTables where sql = [q| @@ -351,8 +350,8 @@ accessibleTables pgVer = left join pg_catalog.pg_description as d on d.objoid = c.oid and d.objsubid = 0 where c.relkind in ('v','r','m','f','p') - and n.nspname = $1 |] - <> relIsNotPartition pgVer <> [q| + and n.nspname = $1 + and not c.relispartition and ( pg_has_role(c.relowner, 'USAGE') or has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER') @@ -447,8 +446,8 @@ addViewPrimaryKeys srcCols = concatMap (\pk -> filter (\(col, _) -> colTable col == pkTable pk && colName col == pkName pk) srcCols in pk : viewPks) -allTables :: PgVersion -> Bool -> SQL.Statement () [Table] -allTables pgVer = +allTables :: Bool -> SQL.Statement () [Table] +allTables = SQL.Statement sql HE.noParams decodeTables where sql = [q| @@ -486,13 +485,10 @@ allTables pgVer = JOIN pg_namespace n ON n.oid = c.relnamespace LEFT JOIN pg_catalog.pg_description as d on d.objoid = c.oid and d.objsubid = 0 WHERE c.relkind IN ('v','r','m','f','p') - AND n.nspname NOT IN ('pg_catalog', 'information_schema') |] - <> relIsNotPartition pgVer <> [q| + AND n.nspname NOT IN ('pg_catalog', 'information_schema') + AND NOT c.relispartition ORDER BY table_schema, table_name |] -relIsNotPartition :: PgVersion -> SqlQuery -relIsNotPartition pgVer = if pgVer >= pgVersion100 then " AND not c.relispartition " else mempty - allColumns :: [Table] -> Bool -> SQL.Statement [Schema] [Column] allColumns tabs = SQL.Statement sql (arrayParam HE.text) (decodeColumns tabs) diff --git a/src/PostgREST/Workers.hs b/src/PostgREST/Workers.hs index 9f716e38290..0144ef54549 100644 --- a/src/PostgREST/Workers.hs +++ b/src/PostgREST/Workers.hs @@ -152,11 +152,10 @@ connectionStatus appState = loadSchemaCache :: AppState -> IO SCacheStatus loadSchemaCache appState = do AppConfig{..} <- AppState.getConfig appState - actualPgVersion <- AppState.getPgVersion appState result <- let transaction = if configDbPreparedStatements then SQL.transaction else SQL.unpreparedTransaction in SQL.use (AppState.getPool appState) . transaction SQL.ReadCommitted SQL.Read $ - queryDbStructure (toList configDbSchemas) configDbExtraSearchPath actualPgVersion configDbPreparedStatements + queryDbStructure (toList configDbSchemas) configDbExtraSearchPath configDbPreparedStatements case result of Left e -> do let diff --git a/test/Feature/OpenApiSpec.hs b/test/Feature/OpenApiSpec.hs index e594bb04e99..e4e2c39cf38 100644 --- a/test/Feature/OpenApiSpec.hs +++ b/test/Feature/OpenApiSpec.hs @@ -11,8 +11,7 @@ import Network.HTTP.Types import Test.Hspec hiding (pendingWith) import Test.Hspec.Wai -import PostgREST.Config.PgVersion (PgVersion, pgVersion100, - pgVersion110) +import PostgREST.Config.PgVersion (PgVersion, pgVersion110) import PostgREST.Version (docsVersion) import Protolude hiding (get) @@ -198,31 +197,30 @@ spec actualPgVersion = describe "OpenAPI" $ do ] |] - when (actualPgVersion >= pgVersion100) $ do - describe "Partitioned table" $ + describe "Partitioned table" $ - it "includes partitioned table properties" $ do - r <- simpleBody <$> get "/" + it "includes partitioned table properties" $ do + r <- simpleBody <$> get "/" - let method s = key "paths" . key "/car_models" . key s - getSummary = r ^? method "get" . key "summary" - getDescription = r ^? method "get" . key "description" - getParameterName = r ^? method "get" . key "parameters" . nth 0 . key "$ref" - getParameterYear = r ^? method "get" . key "parameters" . nth 1 . key "$ref" - getParameterRef = r ^? method "get" . key "parameters" . nth 2 . key "$ref" + let method s = key "paths" . key "/car_models" . key s + getSummary = r ^? method "get" . key "summary" + getDescription = r ^? method "get" . key "description" + getParameterName = r ^? method "get" . key "parameters" . nth 0 . key "$ref" + getParameterYear = r ^? method "get" . key "parameters" . nth 1 . key "$ref" + getParameterRef = r ^? method "get" . key "parameters" . nth 2 . key "$ref" - liftIO $ do + liftIO $ do - getSummary `shouldBe` Just "A partitioned table" + getSummary `shouldBe` Just "A partitioned table" - getDescription `shouldBe` Just "A test for partitioned tables" + getDescription `shouldBe` Just "A test for partitioned tables" - getParameterName `shouldBe` Just "#/parameters/rowFilter.car_models.name" + getParameterName `shouldBe` Just "#/parameters/rowFilter.car_models.name" - getParameterYear `shouldBe` Just "#/parameters/rowFilter.car_models.year" + getParameterYear `shouldBe` Just "#/parameters/rowFilter.car_models.year" - when (actualPgVersion >= pgVersion110) $ - getParameterRef `shouldBe` Just "#/parameters/rowFilter.car_models.car_brand_name" + when (actualPgVersion >= pgVersion110) $ + getParameterRef `shouldBe` Just "#/parameters/rowFilter.car_models.car_brand_name" describe "Materialized view" $ diff --git a/test/Feature/OptionsSpec.hs b/test/Feature/OptionsSpec.hs index e6bf9e35ff0..f2200ffc816 100644 --- a/test/Feature/OptionsSpec.hs +++ b/test/Feature/OptionsSpec.hs @@ -7,8 +7,7 @@ import Network.HTTP.Types import Test.Hspec import Test.Hspec.Wai -import PostgREST.Config.PgVersion (PgVersion, pgVersion100, - pgVersion110) +import PostgREST.Config.PgVersion (PgVersion, pgVersion110) import Protolude import SpecHelper @@ -22,18 +21,17 @@ spec actualPgVersion = describe "Allow header" $ do simpleHeaders r `shouldSatisfy` matchHeader "Allow" "OPTIONS,GET,HEAD,POST,PUT,PATCH,DELETE" - when (actualPgVersion >= pgVersion100) $ - context "a partitioned table" $ do - it "includes read/write verbs for writeable partitioned tables" $ do - r <- request methodOptions "/car_models" [] "" - liftIO $ - simpleHeaders r `shouldSatisfy` - matchHeader "Allow" ( - if actualPgVersion >= pgVersion110 then - "OPTIONS,GET,HEAD,POST,PUT,PATCH,DELETE" - else - "OPTIONS,GET,HEAD,POST,PATCH,DELETE" - ) + context "a partitioned table" $ do + it "includes read/write verbs for writeable partitioned tables" $ do + r <- request methodOptions "/car_models" [] "" + liftIO $ + simpleHeaders r `shouldSatisfy` + matchHeader "Allow" ( + if actualPgVersion >= pgVersion110 then + "OPTIONS,GET,HEAD,POST,PUT,PATCH,DELETE" + else + "OPTIONS,GET,HEAD,POST,PATCH,DELETE" + ) context "a view" $ do context "auto updatable" $ do diff --git a/test/Feature/RpcSpec.hs b/test/Feature/RpcSpec.hs index b0fc0f7aed6..b0dec76be96 100644 --- a/test/Feature/RpcSpec.hs +++ b/test/Feature/RpcSpec.hs @@ -12,10 +12,9 @@ import Test.Hspec.Wai import Test.Hspec.Wai.JSON import Text.Heredoc -import PostgREST.Config.PgVersion (PgVersion, pgVersion100, - pgVersion109, pgVersion110, - pgVersion112, pgVersion114, - pgVersion140) +import PostgREST.Config.PgVersion (PgVersion, pgVersion109, + pgVersion110, pgVersion112, + pgVersion114, pgVersion140) import Protolude hiding (get) import SpecHelper @@ -353,66 +352,34 @@ spec actualPgVersion = { matchHeaders = [matchContentTypeJson] } context "proc argument types" $ do - -- different syntax for array needed for pg<10 - when (actualPgVersion < pgVersion100) $ - it "accepts a variety of arguments (Postgres < 10)" $ - post "/rpc/varied_arguments" - [json| { - "double": 3.1, - "varchar": "hello", - "boolean": true, - "date": "20190101", - "money": 0, - "enum": "foo", - "arr": "{a,b,c}", - "integer": 43, - "json": {"some key": "some value"}, - "jsonb": {"another key": [1, 2, "3"]} - } |] - `shouldRespondWith` - [json| { - "double": 3.1, - "varchar": "hello", - "boolean": true, - "date": "2019-01-01", - "money": "$0.00", - "enum": "foo", - "arr": ["a", "b", "c"], - "integer": 43, - "json": {"some key": "some value"}, - "jsonb": {"another key": [1, 2, "3"]} - } |] - { matchHeaders = [matchContentTypeJson] } - - when (actualPgVersion >= pgVersion100) $ - it "accepts a variety of arguments (Postgres >= 10)" $ - post "/rpc/varied_arguments" - [json| { - "double": 3.1, - "varchar": "hello", - "boolean": true, - "date": "20190101", - "money": 0, - "enum": "foo", - "arr": ["a", "b", "c"], - "integer": 43, - "json": {"some key": "some value"}, - "jsonb": {"another key": [1, 2, "3"]} - } |] - `shouldRespondWith` - [json| { - "double": 3.1, - "varchar": "hello", - "boolean": true, - "date": "2019-01-01", - "money": "$0.00", - "enum": "foo", - "arr": ["a", "b", "c"], - "integer": 43, - "json": {"some key": "some value"}, - "jsonb": {"another key": [1, 2, "3"]} - } |] - { matchHeaders = [matchContentTypeJson] } + it "accepts a variety of arguments (Postgres >= 10)" $ + post "/rpc/varied_arguments" + [json| { + "double": 3.1, + "varchar": "hello", + "boolean": true, + "date": "20190101", + "money": 0, + "enum": "foo", + "arr": ["a", "b", "c"], + "integer": 43, + "json": {"some key": "some value"}, + "jsonb": {"another key": [1, 2, "3"]} + } |] + `shouldRespondWith` + [json| { + "double": 3.1, + "varchar": "hello", + "boolean": true, + "date": "2019-01-01", + "money": "$0.00", + "enum": "foo", + "arr": ["a", "b", "c"], + "integer": 43, + "json": {"some key": "some value"}, + "jsonb": {"another key": [1, 2, "3"]} + } |] + { matchHeaders = [matchContentTypeJson] } it "accepts a variety of arguments with GET" $ -- without JSON / JSONB here, because passing those via query string is useless - they just become a "json string" all the time @@ -458,14 +425,6 @@ spec actualPgVersion = [json|"object"|] { matchHeaders = [matchContentTypeJson] } - when (actualPgVersion < pgVersion100) $ - it "parses quoted JSON arguments as JSON (Postgres < 10)" $ - post "/rpc/json_argument" - [json| { "arg": "{ \"key\": 3 }" } |] - `shouldRespondWith` - [json|"object"|] - { matchHeaders = [matchContentTypeJson] } - when ((actualPgVersion >= pgVersion109 && actualPgVersion < pgVersion110) || actualPgVersion >= pgVersion114) $ it "parses quoted JSON arguments as JSON string (from Postgres 10.9, 11.4)" $ @@ -589,68 +548,59 @@ spec actualPgVersion = [json|[{"a": "A", "b": "B"}]|] context "procs with VARIADIC params" $ do - when (actualPgVersion < pgVersion100) $ - it "works with POST (Postgres < 10)" $ - post "/rpc/variadic_param" - [json| { "v": "{hi,hello,there}" } |] + it "works with POST (Postgres >= 10)" $ + post "/rpc/variadic_param" + [json| { "v": ["hi", "hello", "there"] } |] + `shouldRespondWith` + [json|["hi", "hello", "there"]|] + + context "works with GET and repeated params" $ do + it "n=0 (through DEFAULT)" $ + get "/rpc/variadic_param" + `shouldRespondWith` + [json|[]|] + + it "n=1" $ + get "/rpc/variadic_param?v=hi" `shouldRespondWith` - [json|["hi", "hello", "there"]|] + [json|["hi"]|] - when (actualPgVersion >= pgVersion100) $ do - it "works with POST (Postgres >= 10)" $ - post "/rpc/variadic_param" - [json| { "v": ["hi", "hello", "there"] } |] + it "n>1" $ + get "/rpc/variadic_param?v=hi&v=there" `shouldRespondWith` - [json|["hi", "hello", "there"]|] - - context "works with GET and repeated params" $ do - it "n=0 (through DEFAULT)" $ - get "/rpc/variadic_param" - `shouldRespondWith` - [json|[]|] - - it "n=1" $ - get "/rpc/variadic_param?v=hi" - `shouldRespondWith` - [json|["hi"]|] - - it "n>1" $ - get "/rpc/variadic_param?v=hi&v=there" - `shouldRespondWith` - [json|["hi", "there"]|] - - context "works with POST and repeated params from html form" $ do - it "n=0 (through DEFAULT)" $ - request methodPost "/rpc/variadic_param" - [("Content-Type", "application/x-www-form-urlencoded")] - "" - `shouldRespondWith` - [json|[]|] - - it "n=1" $ - request methodPost "/rpc/variadic_param" - [("Content-Type", "application/x-www-form-urlencoded")] - "v=hi" - `shouldRespondWith` - [json|["hi"]|] - - it "n>1" $ - request methodPost "/rpc/variadic_param" - [("Content-Type", "application/x-www-form-urlencoded")] - "v=hi&v=there" - `shouldRespondWith` - [json|["hi", "there"]|] + [json|["hi", "there"]|] + + context "works with POST and repeated params from html form" $ do + it "n=0 (through DEFAULT)" $ + request methodPost "/rpc/variadic_param" + [("Content-Type", "application/x-www-form-urlencoded")] + "" + `shouldRespondWith` + [json|[]|] + + it "n=1" $ + request methodPost "/rpc/variadic_param" + [("Content-Type", "application/x-www-form-urlencoded")] + "v=hi" + `shouldRespondWith` + [json|["hi"]|] + + it "n>1" $ + request methodPost "/rpc/variadic_param" + [("Content-Type", "application/x-www-form-urlencoded")] + "v=hi&v=there" + `shouldRespondWith` + [json|["hi", "there"]|] it "returns last value for repeated params without VARIADIC" $ get "/rpc/sayhello?name=ignored&name=world" `shouldRespondWith` [json|"Hello, world"|] - when (actualPgVersion >= pgVersion100) $ - it "returns last value for repeated non-variadic params in function with other VARIADIC arguments" $ - get "/rpc/sayhello_variadic?name=ignored&name=world&v=unused" - `shouldRespondWith` - [json|"Hello, world"|] + it "returns last value for repeated non-variadic params in function with other VARIADIC arguments" $ + get "/rpc/sayhello_variadic?name=ignored&name=world&v=unused" + `shouldRespondWith` + [json|"Hello, world"|] it "can handle procs with args that have a DEFAULT value" $ do get "/rpc/many_inout_params?num=1&str=two" diff --git a/test/Main.hs b/test/Main.hs index a292efd6a2e..9e1e09a4176 100644 --- a/test/Main.hs +++ b/test/Main.hs @@ -68,7 +68,6 @@ main = do loadDbStructure pool (configDbSchemas $ testCfg testDbConn) (configDbExtraSearchPath $ testCfg testDbConn) - actualPgVersion let -- For tests that run with the same refDbStructure @@ -88,7 +87,6 @@ main = do loadDbStructure pool (configDbSchemas config) (configDbExtraSearchPath config) - actualPgVersion appState <- AppState.initWithPool pool config AppState.putPgVersion appState actualPgVersion AppState.putDbStructure appState customDbStructure @@ -232,5 +230,5 @@ main = do describe "Feature.RollbackForcedSpec" Feature.RollbackSpec.forced where - loadDbStructure pool schemas extraSearchPath actualPgVersion = - either (panic.show) id <$> P.use pool (HT.transaction HT.ReadCommitted HT.Read $ queryDbStructure (toList schemas) extraSearchPath actualPgVersion True) + loadDbStructure pool schemas extraSearchPath = + either (panic.show) id <$> P.use pool (HT.transaction HT.ReadCommitted HT.Read $ queryDbStructure (toList schemas) extraSearchPath True)