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:
Robert Vollmert
2019-06-02 01:26:52 -05:00
committed by Steve Chávez
parent 1f69822fa3
commit 30d5a81156
3 changed files with 80 additions and 4 deletions
+60 -2
View File
@@ -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"
+8
View File
@@ -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",
+12 -2
View File
@@ -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: -
-- --