Test json rpc arguments
In particular, check buggy behavior around embedded quoted JSON and Postgres versions, compare https://www.postgresql.org/message-id/D6921B37-BD8E-4664-8D5F-DB3525765DCD%40vllmrt.net This adds version-bounded tests for the handling of quoted JSON, and a pending test that documents the assumption that Postgres >=10 intends to parse quoted JSON as a string (similar to how jsonb works now).
This commit is contained in:
committed by
Steve Chávez
parent
1f69822fa3
commit
30d5a81156
+60
-2
@@ -6,12 +6,13 @@ import Network.Wai (Application)
|
|||||||
import Network.Wai.Test (SResponse (simpleBody, simpleStatus))
|
import Network.Wai.Test (SResponse (simpleBody, simpleStatus))
|
||||||
|
|
||||||
import Network.HTTP.Types
|
import Network.HTTP.Types
|
||||||
import Test.Hspec
|
import Test.Hspec hiding (pendingWith)
|
||||||
import Test.Hspec.Wai
|
import Test.Hspec.Wai
|
||||||
import Test.Hspec.Wai.JSON
|
import Test.Hspec.Wai.JSON
|
||||||
import Text.Heredoc
|
import Text.Heredoc
|
||||||
|
|
||||||
import PostgREST.Types (PgVersion, pgVersion95)
|
import PostgREST.Types (PgVersion, pgVersion100, pgVersion95,
|
||||||
|
pgVersion96)
|
||||||
import Protolude hiding (get)
|
import Protolude hiding (get)
|
||||||
import SpecHelper
|
import SpecHelper
|
||||||
|
|
||||||
@@ -230,6 +231,63 @@ spec actualPgVersion =
|
|||||||
[json|null|]
|
[json|null|]
|
||||||
{ matchHeaders = [matchContentTypeJson] }
|
{ 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
|
context "improper input" $ do
|
||||||
it "rejects unknown content type even if payload is good" $ do
|
it "rejects unknown content type even if payload is good" $ do
|
||||||
request methodPost "/rpc/sayhello"
|
request methodPost "/rpc/sayhello"
|
||||||
|
|||||||
@@ -426,6 +426,14 @@ spec = do
|
|||||||
"integer": {
|
"integer": {
|
||||||
"format": "integer",
|
"format": "integer",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"json": {
|
||||||
|
"format": "json",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"jsonb": {
|
||||||
|
"format": "jsonb",
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|||||||
Vendored
+12
-2
@@ -206,18 +206,28 @@ CREATE FUNCTION varied_arguments(
|
|||||||
date date,
|
date date,
|
||||||
money money,
|
money money,
|
||||||
enum enum_menagerie_type,
|
enum enum_menagerie_type,
|
||||||
"integer" integer default 42
|
"integer" integer default 42,
|
||||||
|
json json default '{}',
|
||||||
|
jsonb jsonb default '{}'
|
||||||
) RETURNS text
|
) RETURNS text
|
||||||
LANGUAGE sql
|
LANGUAGE sql
|
||||||
AS $_$
|
AS $_$
|
||||||
SELECT 'Hi'::text;
|
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
|
$_$An RPC function
|
||||||
|
|
||||||
Just a test for RPC function arguments$_$;
|
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: -
|
-- Name: jwt_test(); Type: FUNCTION; Schema: test; Owner: -
|
||||||
--
|
--
|
||||||
|
|||||||
Reference in New Issue
Block a user