module Feature.Query.NullsStripSpec where import Network.Wai (Application) import Network.HTTP.Types import Test.Hspec import Test.Hspec.Wai import Test.Hspec.Wai.JSON import Protolude hiding (get) import SpecHelper spec :: SpecWith ((), Application) spec = describe "Stripping null values from JSON response" $ do let arrayStrip = ("Accept", "application/vnd.pgrst.array+json;nulls=stripped") let singularStrip = ("Accept", "application/vnd.pgrst.object+json;nulls=stripped") context "strip nulls from response" $ do it "strips nulls when Accept: application/vnd.pgrst.array+json;nulls=stripped" $ do request methodGet "/organizations?select=*" [arrayStrip] "" `shouldRespondWith` [json|[{"id":1,"name":"Referee Org","manager_id":1},{"id":2,"name":"Auditor Org","manager_id":2},{"id":3,"name":"Acme","referee":1,"auditor":2,"manager_id":3},{"id":4,"name":"Umbrella","referee":1,"auditor":2,"manager_id":4},{"id":5,"name":"Cyberdyne","referee":3,"auditor":4,"manager_id":5},{"id":6,"name":"Oscorp","referee":3,"auditor":4,"manager_id":6}]|] { matchStatus = 200 , matchHeaders = [matchCTArrayStrip] } request methodPost "/organizations?select=*" [arrayStrip,("Prefer","return=representation")] [json|{"id":7,"name":"John","referee":null,"auditor":null,"manager_id":6}|] `shouldRespondWith` [json|[{"id":7,"name":"John","manager_id":6}]|] { matchStatus = 201 , matchHeaders = [matchCTArrayStrip] } request methodPatch "/organizations?id=eq.3&select=*" [arrayStrip, ("Prefer","return=representation")] [json|{"name":"John","referee":null}|] `shouldRespondWith` [json|[{"id":3,"name":"John","auditor":2,"manager_id":3}]|] { matchStatus = 200 , matchHeaders = [matchCTArrayStrip] } it "strips nulls when Accept: application/vnd.pgrst.array;nulls=stripped" $ request methodGet "/organizations?select=*" [("Accept","application/vnd.pgrst.array;nulls=stripped")] "" `shouldRespondWith` [json|[{"id":1,"name":"Referee Org","manager_id":1},{"id":2,"name":"Auditor Org","manager_id":2},{"id":3,"name":"Acme","referee":1,"auditor":2,"manager_id":3},{"id":4,"name":"Umbrella","referee":1,"auditor":2,"manager_id":4},{"id":5,"name":"Cyberdyne","referee":3,"auditor":4,"manager_id":5},{"id":6,"name":"Oscorp","referee":3,"auditor":4,"manager_id":6}]|] { matchStatus = 200 , matchHeaders = [matchCTArrayStrip] } it "strips nulls when Accept: application/vnd.pgrst.object+json;nulls=stripped" $ request methodGet "/organizations?limit=1" [singularStrip] "" `shouldRespondWith` [json|{"id":1,"name":"Referee Org","manager_id":1}|] { matchStatus = 200 , matchHeaders = [matchCTSingularStrip] } it "throws error when Accept: application/vnd.pgrst.object+json;nulls=stripped and result not singular" $ request methodGet "/organizations?select=*" [singularStrip] "" `shouldRespondWith` [json|{"details":"The result contains 6 rows","message":"JSON object requested, multiple (or no) rows returned","code":"PGRST116","hint":null}|] { matchStatus = 406 , matchHeaders = [matchContentTypeJson] } context "strip nulls from response even if explicitly selected" $ do it "strips nulls when Accept: application/vnd.pgrst.array+json;nulls=stripped" $ do request methodGet "/organizations?select=id,referee,auditor" [arrayStrip] "" `shouldRespondWith` [json|[{"id":1},{"id":2},{"id":3,"referee":1,"auditor":2},{"id":4,"referee":1,"auditor":2},{"id":5,"referee":3,"auditor":4},{"id":6,"referee":3,"auditor":4}]|] { matchStatus = 200 , matchHeaders = [matchCTArrayStrip] } request methodPost "/organizations?select=id,referee,auditor" [arrayStrip,("Prefer","return=representation")] [json|{"id":7,"name":"John","referee":null,"auditor":null,"manager_id":6}|] `shouldRespondWith` [json|[{"id":7}]|] { matchStatus = 201 , matchHeaders = [matchCTArrayStrip] } request methodPatch "/organizations?id=eq.3&select=id,name,referee,auditor" [arrayStrip, ("Prefer","return=representation")] [json|{"name":"John","referee":null}|] `shouldRespondWith` [json|[{"id":3,"name":"John","auditor":2}]|] { matchStatus = 200 , matchHeaders = [matchCTArrayStrip] } it "strips nulls when Accept: application/vnd.pgrst.object+json;nulls=stripped" $ request methodGet "/organizations?select=id,referee,auditor&limit=1" [singularStrip] "" `shouldRespondWith` [json|{"id":1}|] { matchStatus = 200 , matchHeaders = [matchCTSingularStrip] } context "doesn't strip nulls" $ do it "doesn't strips nulls when Accept: application/vnd.pgrst.array+json" $ request methodGet "/organizations?select=id,referee,auditor" [("Accept", "application/vnd.pgrst.array+json")] "" `shouldRespondWith` [json|[{"id":1,"referee":null,"auditor":null},{"id":2,"referee":null,"auditor":null},{"id":3,"referee":1,"auditor":2},{"id":4,"referee":1,"auditor":2},{"id":5,"referee":3,"auditor":4},{"id":6,"referee":3,"auditor":4}]|] { matchStatus = 200 , matchHeaders = [matchContentTypeJson] }