feat: undefined json keys as defaults w/ Prefer:undefined-keys

This commit is contained in:
Steve Chavez
2023-03-22 02:44:14 -05:00
committed by GitHub
parent e731241b97
commit 439a96c578
16 changed files with 232 additions and 38 deletions
+61 -10
View File
@@ -11,8 +11,9 @@ import Test.Hspec.Wai
import Test.Hspec.Wai.JSON
import Text.Heredoc
import PostgREST.Config.PgVersion (PgVersion, pgVersion110,
pgVersion112, pgVersion130)
import PostgREST.Config.PgVersion (PgVersion, pgVersion100,
pgVersion110, pgVersion112,
pgVersion130)
import Protolude hiding (get)
import SpecHelper
@@ -448,14 +449,64 @@ spec actualPgVersion = do
{"id": 204, "body": "yyy"},
333,
"asdf",
{"id": 205, "body": "zzz"}]|] `shouldRespondWith`
[json|{
"code": "22023",
"details": null,
"hint": null,
"message": "argument of json_to_recordset must be an array of objects"}|]
{ matchStatus = 400
, matchHeaders = []
{"id": 205, "body": "zzz"}]|] `shouldRespondWith` 400
context "apply defaults on undefined keys" $ do
-- inserting the array fails on pg 9.6, but the feature should work normally
when (actualPgVersion >= pgVersion100) $
it "inserts table default values(field-with_sep) when json keys are undefined" $
request methodPost "/complex_items?columns=id,name,field-with_sep,arr_data" [("Prefer", "return=representation"), ("Prefer", "undefined-keys=apply-defaults")]
[json|[
{"id": 4, "name": "Vier"},
{"id": 5, "name": "Funf", "arr_data": null},
{"id": 6, "name": "Sechs", "field-with_sep": 6, "arr_data": "{1,2,3}"}
]|]
`shouldRespondWith`
[json|[
{"id": 4, "name": "Vier", "field-with_sep": 1, "settings":null,"arr_data":null},
{"id": 5, "name": "Funf", "field-with_sep": 1, "settings":null,"arr_data":null},
{"id": 6, "name": "Sechs", "field-with_sep": 6, "settings":null,"arr_data":[1,2,3]}
]|]
{ matchStatus = 201
, matchHeaders = ["Preference-Applied" <:> "undefined-keys=apply-defaults"]
}
it "inserts view default values(field-with_sep) when json keys are undefined" $
request methodPost "/complex_items_view?columns=id,name" [("Prefer", "return=representation"), ("Prefer", "undefined-keys=apply-defaults")]
[json|[
{"id": 7, "name": "Sieben"},
{"id": 8}
]|]
`shouldRespondWith`
[json|[
{"id": 7, "name": "Sieben", "field-with_sep": 1, "settings":null,"arr_data":null},
{"id": 8, "name": "Default", "field-with_sep": 1, "settings":null,"arr_data":null}
]|]
{ matchStatus = 201
, matchHeaders = ["Preference-Applied" <:> "undefined-keys=apply-defaults"]
}
it "doesn't insert json duplicate keys(since it uses jsonb)" $
request methodPost "/tbl_w_json?columns=id,data" [("Prefer", "return=representation"), ("Prefer", "undefined-keys=apply-defaults")]
[json| { "data": { "a": 1, "a": 2 }, "id": 3 } |]
`shouldRespondWith`
[json| [ { "data": { "a": 2 }, "id": 3 } ] |]
{ matchStatus = 201
, matchHeaders = ["Preference-Applied" <:> "undefined-keys=apply-defaults"]
}
it "inserts json that has duplicate keys" $ do
request methodPost "/tbl_w_json" [("Prefer", "return=representation")]
[json| { "data": { "a": 1, "a": 2 }, "id": 3 } |]
`shouldRespondWith`
[json| [ { "data": { "a": 1, "a": 2 }, "id": 3 } ] |]
{ matchStatus = 201
}
request methodPost "/tbl_w_json?columns=id,data" [("Prefer", "return=representation")]
[json| { "data": { "a": 1, "a": 2 }, "id": 3 } |]
`shouldRespondWith`
[json| [ { "data": { "a": 1, "a": 2 }, "id": 3 } ] |]
{ matchStatus = 201
}
context "with unicode values" $ do
+2 -2
View File
@@ -327,11 +327,11 @@ spec actualPgVersion = do
describe "Shaping response with select parameter" $ do
it "selectStar works in absense of parameter" $
get "/complex_items?id=eq.3" `shouldRespondWith`
[json|[{"id":3,"name":"Three","settings":{"foo":{"int":1,"bar":"baz"}},"arr_data":[1,2,3],"field-with_sep":1}]|]
[json|[{"id":3,"name":"Three","settings":{"foo":{"int":1,"bar":"baz"}},"arr_data":[1,2,3],"field-with_sep":3}]|]
it "dash `-` in column names is accepted" $
get "/complex_items?id=eq.3&select=id,field-with_sep" `shouldRespondWith`
[json|[{"id":3,"field-with_sep":1}]|]
[json|[{"id":3,"field-with_sep":3}]|]
it "one simple column" $
get "/complex_items?select=id" `shouldRespondWith`
+51
View File
@@ -330,6 +330,57 @@ spec = do
, matchHeaders = []
}
context "apply defaults on undefined keys" $ do
it "updates table using default values(field-with_sep) when json keys are undefined" $ do
request methodPatch "/complex_items?id=eq.3&columns=name,field-with_sep"
[("Prefer", "return=representation"), ("Prefer", "undefined-keys=apply-defaults")]
[json|{"name": "Tres"}|]
`shouldRespondWith`
[json|[
{"id":3,"name":"Tres","settings":{"foo":{"int":1,"bar":"baz"}},"arr_data":[1,2,3],"field-with_sep":1}
]|]
{ matchStatus = 200
, matchHeaders = ["Preference-Applied" <:> "undefined-keys=apply-defaults"]
}
it "updates with limit/offset using table default values(field-with_sep) when json keys are undefined" $ do
request methodPatch "/complex_items?select=id,name&columns=name,field-with_sep&limit=1&offset=2&order=id"
[("Prefer", "return=representation"), ("Prefer", "undefined-keys=apply-defaults")]
[json|{"name": "Tres"}|]
`shouldRespondWith`
[json|[
{"id":3,"name":"Tres"}
]|]
{ matchStatus = 200
, matchHeaders = ["Preference-Applied" <:> "undefined-keys=apply-defaults"]
}
it "updates table default values(field-with_sep) when json keys are undefined" $ do
request methodPatch "/complex_items?id=eq.3&columns=name,field-with_sep"
[("Prefer", "return=representation"), ("Prefer", "undefined-keys=apply-defaults")]
[json|{"name": "Tres"}|]
`shouldRespondWith`
[json|[
{"id":3,"name":"Tres","settings":{"foo":{"int":1,"bar":"baz"}},"arr_data":[1,2,3],"field-with_sep":1}
]|]
{ matchStatus = 200
, matchHeaders = ["Preference-Applied" <:> "undefined-keys=apply-defaults"]
}
it "updates view default values(field-with_sep) when json keys are undefined" $
request methodPatch "/complex_items_view?id=eq.3&columns=arr_data,name"
[("Prefer", "return=representation"), ("Prefer", "undefined-keys=apply-defaults")]
[json|
{"arr_data":null}
|]
`shouldRespondWith`
[json|[
{"id":3,"name":"Default","settings":{"foo":{"int":1,"bar":"baz"}},"arr_data":null,"field-with_sep":3}
]|]
{ matchStatus = 200
, matchHeaders = ["Preference-Applied" <:> "undefined-keys=apply-defaults"]
}
context "tables with self reference foreign keys" $ do
it "embeds children after update" $
request methodPatch "/web_content?id=eq.0&select=id,name,web_content(name)"