diff --git a/test/Feature/RpcSpec.hs b/test/Feature/RpcSpec.hs index c00c51b02..e944b675f 100644 --- a/test/Feature/RpcSpec.hs +++ b/test/Feature/RpcSpec.hs @@ -6,12 +6,13 @@ import Network.Wai (Application) import Network.Wai.Test (SResponse (simpleBody, simpleStatus)) import Network.HTTP.Types -import Test.Hspec +import Test.Hspec hiding (pendingWith) import Test.Hspec.Wai import Test.Hspec.Wai.JSON import Text.Heredoc -import PostgREST.Types (PgVersion, pgVersion95) +import PostgREST.Types (PgVersion, pgVersion100, pgVersion95, + pgVersion96) import Protolude hiding (get) import SpecHelper @@ -230,6 +231,63 @@ spec actualPgVersion = [json|null|] { matchHeaders = [matchContentTypeJson] } + context "proc argument types" $ do + it "accepts a variety of arguments" $ + post "/rpc/varied_arguments" + [json| { + "double": 3.1, + "varchar": "hello", + "boolean": true, + "date": "20190101", + "money": 0, + "enum": "foo", + "integer": 43, + "json": {"some key": "some value"}, + "jsonb": {"another key": [1, 2, "3"]} + } |] + `shouldRespondWith` + [json|"Hi"|] + { matchHeaders = [matchContentTypeJson] } + + it "parses embedded JSON arguments as JSON" $ + post "/rpc/json_argument" + [json| { "arg": { "key": 3 } } |] + `shouldRespondWith` + [json|"object"|] + { matchHeaders = [matchContentTypeJson] } + + when (actualPgVersion <= pgVersion96) $ + it "parses quoted JSON arguments as JSON (Postgres <= 9.6)" $ + post "/rpc/json_argument" + [json| { "arg": "{ \"key\": 3 }" } |] + `shouldRespondWith` + [json|"object"|] + { matchHeaders = [matchContentTypeJson] } + + when (actualPgVersion >= pgVersion100) $ do + it "parses quoted JSON arguments as JSON string (Postgres >= 10)" $ do + -- Postgres bug report: + -- https://www.postgresql.org/message-id/D6921B37-BD8E-4664-8D5F-DB3525765DCD%40vllmrt.net + -- * json_to_record fails (see following test) + -- * jsonb_to_record parses the embedded quoted JSON to a JSON string, + -- so that's probably the expected behavior for Postgres >= 10 + pendingWith "Postgres >= 10 fails to parse quoted embedded JSON" + post "/rpc/json_argument" + [json| { "arg": "{ \"key\": 3 }" } |] + `shouldRespondWith` + [json|"string"|] + { matchHeaders = [matchContentTypeJson] } + + it "fails to parse quoted JSON arguments (Postgres >= 10)" $ + -- Confirming buggy Postgres behavior (see previous test) + post "/rpc/json_argument" + [json| { "arg": "{ \"key\": 3 }" } |] + `shouldRespondWith` + [json|{"hint":null,"details":"Token \"key\" is invalid.","code":"22P02","message":"invalid input syntax for type json"}|] + { matchStatus = 400 + , matchHeaders = [matchContentTypeJson] + } + context "improper input" $ do it "rejects unknown content type even if payload is good" $ do request methodPost "/rpc/sayhello" diff --git a/test/Feature/StructureSpec.hs b/test/Feature/StructureSpec.hs index a140153b1..3bd7d7418 100644 --- a/test/Feature/StructureSpec.hs +++ b/test/Feature/StructureSpec.hs @@ -426,6 +426,14 @@ spec = do "integer": { "format": "integer", "type": "integer" + }, + "json": { + "format": "json", + "type": "string" + }, + "jsonb": { + "format": "jsonb", + "type": "string" } }, "type": "object", diff --git a/test/fixtures/schema.sql b/test/fixtures/schema.sql index 3d043c8f9..c8e35445b 100755 --- a/test/fixtures/schema.sql +++ b/test/fixtures/schema.sql @@ -206,18 +206,28 @@ CREATE FUNCTION varied_arguments( date date, money money, enum enum_menagerie_type, - "integer" integer default 42 + "integer" integer default 42, + json json default '{}', + jsonb jsonb default '{}' ) RETURNS text LANGUAGE sql AS $_$ SELECT 'Hi'::text; $_$; -COMMENT ON FUNCTION varied_arguments(double precision, character varying, boolean, date, money, enum_menagerie_type, integer) IS +COMMENT ON FUNCTION varied_arguments(double precision, character varying, boolean, date, money, enum_menagerie_type, integer, json, jsonb) IS $_$An RPC function Just a test for RPC function arguments$_$; + +CREATE FUNCTION json_argument(arg json) RETURNS text + +LANGUAGE sql +AS $_$ + SELECT json_typeof(arg); +$_$; + -- -- Name: jwt_test(); Type: FUNCTION; Schema: test; Owner: - --