Skip to content

Commit

Permalink
Refactor tests: replace str with json QuasiQuoter where appropriate
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfgangwalther committed Nov 18, 2020
1 parent 080ddbe commit 7944e76
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 138 deletions.
9 changes: 4 additions & 5 deletions test/Feature/AuthSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import Network.HTTP.Types
import Test.Hspec
import Test.Hspec.Wai
import Test.Hspec.Wai.JSON
import Text.Heredoc

import PostgREST.Types (PgVersion, pgVersion112)
import Protolude hiding (get)
Expand Down Expand Up @@ -85,7 +84,7 @@ spec actualPgVersion = describe "authorization" $ do
it "sql functions can read custom and standard claims variables" $ do
let auth = authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJmdW4iLCJqdGkiOiJmb28iLCJuYmYiOjEzMDA4MTkzODAsImV4cCI6OTk5OTk5OTk5OSwiaHR0cDovL3Bvc3RncmVzdC5jb20vZm9vIjp0cnVlLCJpc3MiOiJqb2UiLCJyb2xlIjoicG9zdGdyZXN0X3Rlc3RfYXV0aG9yIiwiaWF0IjoxMzAwODE5MzgwfQ.V5fEpXfpb7feqwVqlcDleFdKu86bdwU2cBRT4fcMhXg"
request methodPost "/rpc/reveal_big_jwt" [auth] "{}"
`shouldRespondWith` [str|[{"iss":"joe","sub":"fun","exp":9999999999,"nbf":1300819380,"iat":1300819380,"jti":"foo","http://postgrest.com/foo":true}]|]
`shouldRespondWith` [json|[{"iss":"joe","sub":"fun","exp":9999999999,"nbf":1300819380,"iat":1300819380,"jti":"foo","http://postgrest.com/foo":true}]|]

it "allows users with permissions to see their tables" $ do
let auth = authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXN0X3Rlc3RfYXV0aG9yIiwiaWQiOiJqZG9lIn0.B-lReuGNDwAlU1GOC476MlO0vAt9JNoHIlxg2vwMaO0"
Expand Down Expand Up @@ -148,7 +147,7 @@ spec actualPgVersion = describe "authorization" $ do
let auth = authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MX0.gKw7qI50i9hMrSJW8BlTpdMEVmMXJYxlAqueGqpa_mE" in
request methodPost "/rpc/get_current_user" [auth]
[json| {} |]
`shouldRespondWith` [str|"postgrest_test_author"|]
`shouldRespondWith` [json|"postgrest_test_author"|]
{ matchStatus = 200
, matchHeaders = []
}
Expand All @@ -157,7 +156,7 @@ spec actualPgVersion = describe "authorization" $ do
let auth = authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Mn0.nwzjMI0YLvVGJQTeoCPEBsK983b__gxdpLXisBNaO2A" in
request methodPost "/rpc/get_current_user" [auth]
[json| {} |]
`shouldRespondWith` [str|"postgrest_test_default_role"|]
`shouldRespondWith` [json|"postgrest_test_default_role"|]
{ matchStatus = 200
, matchHeaders = []
}
Expand All @@ -166,7 +165,7 @@ spec actualPgVersion = describe "authorization" $ do
let auth = authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6M30.OGxEJAf60NKZiTn-tIb2jy4rqKs_ZruLGWZ40TjrJsM" in
request methodPost "/rpc/get_current_user" [auth]
[json| {} |]
`shouldRespondWith` [str|{"hint":"Please contact administrator","details":null,"code":"P0001","message":"Disabled ID --> 3"}|]
`shouldRespondWith` [json|{"hint":"Please contact administrator","details":null,"code":"P0001","message":"Disabled ID --> 3"}|]
{ matchStatus = 400
, matchHeaders = []
}
Expand Down
11 changes: 5 additions & 6 deletions test/Feature/DeleteSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import Network.HTTP.Types
import Test.Hspec
import Test.Hspec.Wai
import Test.Hspec.Wai.JSON
import Text.Heredoc

import Protolude hiding (get)

Expand All @@ -23,7 +22,7 @@ spec =

it "returns the deleted item and count if requested" $
request methodDelete "/items?id=eq.2" [("Prefer", "return=representation"), ("Prefer", "count=exact")] ""
`shouldRespondWith` [str|[{"id":2}]|]
`shouldRespondWith` [json|[{"id":2}]|]
{ matchStatus = 200
, matchHeaders = ["Content-Range" <:> "*/1"]
}
Expand All @@ -42,26 +41,26 @@ spec =

it "returns the deleted item and shapes the response" $
request methodDelete "/complex_items?id=eq.2&select=id,name" [("Prefer", "return=representation")] ""
`shouldRespondWith` [str|[{"id":2,"name":"Two"}]|]
`shouldRespondWith` [json|[{"id":2,"name":"Two"}]|]
{ matchStatus = 200
, matchHeaders = ["Content-Range" <:> "*/*"]
}

it "can rename and cast the selected columns" $
request methodDelete "/complex_items?id=eq.3&select=ciId:id::text,ciName:name" [("Prefer", "return=representation")] ""
`shouldRespondWith` [str|[{"ciId":"3","ciName":"Three"}]|]
`shouldRespondWith` [json|[{"ciId":"3","ciName":"Three"}]|]

it "can embed (parent) entities" $
request methodDelete "/tasks?id=eq.8&select=id,name,project:projects(id)" [("Prefer", "return=representation")] ""
`shouldRespondWith` [str|[{"id":8,"name":"Code OSX","project":{"id":4}}]|]
`shouldRespondWith` [json|[{"id":8,"name":"Code OSX","project":{"id":4}}]|]
{ matchStatus = 200
, matchHeaders = ["Content-Range" <:> "*/*"]
}

it "actually clears items ouf the db" $ do
_ <- request methodDelete "/items?id=lt.15" [] ""
get "/items"
`shouldRespondWith` [str|[{"id":15}]|]
`shouldRespondWith` [json|[{"id":15}]|]
{ matchStatus = 200
, matchHeaders = ["Content-Range" <:> "0-0/*"]
}
Expand Down
5 changes: 2 additions & 3 deletions test/Feature/EmbedDisambiguationSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import Network.Wai (Application)
import Test.Hspec hiding (pendingWith)
import Test.Hspec.Wai
import Test.Hspec.Wai.JSON
import Text.Heredoc

import Protolude hiding (get)
import SpecHelper
Expand Down Expand Up @@ -154,7 +153,7 @@ spec =

it "can embed parent with view!fk and grandparent by using fk" $
get "/tasks?id=eq.1&select=id,name,projects_view!project(id,name,client(id,name))" `shouldRespondWith`
[str|[{"id":1,"name":"Design w7","projects_view":{"id":1,"name":"Windows 7","client":{"id":1,"name":"Microsoft"}}}]|]
[json|[{"id":1,"name":"Design w7","projects_view":{"id":1,"name":"Windows 7","client":{"id":1,"name":"Microsoft"}}}]|]

it "can embed by using a composite FK name" $
get "/unit_workdays?select=unit_id,day,fst_shift(car_id,schedule(name)),snd_shift(camera_id,schedule(name))" `shouldRespondWith`
Expand Down Expand Up @@ -230,7 +229,7 @@ spec =

it "can embed parent by using view!column and grandparent by using the column" $
get "/tasks?id=eq.1&select=id,name,project:projects_view!project_id(id,name,client:client_id(id,name))" `shouldRespondWith`
[str|[{"id":1,"name":"Design w7","project":{"id":1,"name":"Windows 7","client":{"id":1,"name":"Microsoft"}}}]|]
[json|[{"id":1,"name":"Design w7","project":{"id":1,"name":"Windows 7","client":{"id":1,"name":"Microsoft"}}}]|]

it "can specify table!column" $
get "/message?select=id,body,sender:person!sender(name),recipient:person!recipient(name)&id=lt.4" `shouldRespondWith`
Expand Down
59 changes: 29 additions & 30 deletions test/Feature/InsertSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ spec actualPgVersion = do
"integer": 14, "double": 3.14159, "varchar": "testing!"
, "boolean": false, "date": "1900-01-01", "money": "$3.99"
, "enum": "foo"
}] |] `shouldRespondWith` [str|[{"integer":14,"varchar":"testing!"}]|]
}] |] `shouldRespondWith` [json|[{"integer":14,"varchar":"testing!"}]|]
{ matchStatus = 201
, matchHeaders = [matchContentTypeJson]
}
Expand Down Expand Up @@ -86,7 +86,7 @@ spec actualPgVersion = do
it "includes related data after insert" $
request methodPost "/projects?select=id,name,clients(id,name)"
[("Prefer", "return=representation"), ("Prefer", "count=exact")]
[str|{"id":6,"name":"New Project","client_id":2}|] `shouldRespondWith` [str|[{"id":6,"name":"New Project","clients":{"id":2,"name":"Apple"}}]|]
[json|{"id":6,"name":"New Project","client_id":2}|] `shouldRespondWith` [json|[{"id":6,"name":"New Project","clients":{"id":2,"name":"Apple"}}]|]
{ matchStatus = 201
, matchHeaders = [ matchContentTypeJson
, "Location" <:> "/projects?id=eq.6"
Expand All @@ -96,8 +96,8 @@ spec actualPgVersion = do
it "can rename and cast the selected columns" $
request methodPost "/projects?select=pId:id::text,pName:name,cId:client_id::text"
[("Prefer", "return=representation")]
[str|{"id":7,"name":"New Project","client_id":2}|] `shouldRespondWith`
[str|[{"pId":"7","pName":"New Project","cId":"2"}]|]
[json|{"id":7,"name":"New Project","client_id":2}|] `shouldRespondWith`
[json|[{"pId":"7","pName":"New Project","cId":"2"}]|]
{ matchStatus = 201
, matchHeaders = [ matchContentTypeJson
, "Location" <:> "/projects?id=eq.7"
Expand All @@ -106,8 +106,8 @@ spec actualPgVersion = do

it "should not throw and return location header when selecting without PK" $
request methodPost "/projects?select=name,client_id" [("Prefer", "return=representation")]
[str|{"id":10,"name":"New Project","client_id":2}|] `shouldRespondWith`
[str|[{"name":"New Project","client_id":2}]|]
[json|{"id":10,"name":"New Project","client_id":2}|] `shouldRespondWith`
[json|[{"name":"New Project","client_id":2}]|]
{ matchStatus = 201
, matchHeaders = [ matchContentTypeJson
, "Location" <:> "/projects?id=eq.10"
Expand All @@ -117,7 +117,7 @@ spec actualPgVersion = do
context "requesting no representation" $
it "should not throw and return location header when selecting without PK" $
request methodPost "/projects?select=name,client_id" []
[str|{"id":11,"name":"New Project","client_id":2}|] `shouldRespondWith` ""
[json|{"id":11,"name":"New Project","client_id":2}|] `shouldRespondWith` ""
{ matchStatus = 201
, matchHeaders = [ "Location" <:> "/projects?id=eq.11"
, "Content-Range" <:> "*/*" ]
Expand Down Expand Up @@ -263,7 +263,7 @@ spec actualPgVersion = do
request methodPost "/json_table"
[("Prefer", "return=representation")]
inserted
`shouldRespondWith` [str|[{"data":{"foo":"bar"}}]|]
`shouldRespondWith` [json|[{"data":{"foo":"bar"}}]|]
{ matchStatus = 201
}

Expand All @@ -272,7 +272,7 @@ spec actualPgVersion = do
request methodPost "/json_table"
[("Prefer", "return=representation")]
inserted
`shouldRespondWith` [str|[{"data":[1,2,3]}]|]
`shouldRespondWith` [json|[{"data":[1,2,3]}]|]
{ matchStatus = 201
}

Expand Down Expand Up @@ -423,24 +423,23 @@ spec actualPgVersion = do

describe "Row level permission" $
it "set user_id when inserting rows" $ do
let auth = authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXN0X3Rlc3RfYXV0aG9yIiwiaWQiOiJqZG9lIn0.B-lReuGNDwAlU1GOC476MlO0vAt9JNoHIlxg2vwMaO0"
_ <- post "/postgrest/users" [json| { "id":"jdoe", "pass": "1234", "role": "postgrest_test_author" } |]
_ <- post "/postgrest/users" [json| { "id":"jroe", "pass": "1234", "role": "postgrest_test_author" } |]
post "/postgrest/users" [json| { "id":"jdoe", "pass": "1234", "role": "postgrest_test_author" } |]
post "/postgrest/users" [json| { "id":"jroe", "pass": "1234", "role": "postgrest_test_author" } |]

p1 <- request methodPost "/authors_only"
[ auth, ("Prefer", "return=representation") ]
[json| { "secret": "nyancat" } |]
liftIO $ do
simpleBody p1 `shouldBe` [str|[{"owner":"jdoe","secret":"nyancat"}]|]
simpleStatus p1 `shouldBe` created201
request methodPost "/authors_only"
[ authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXN0X3Rlc3RfYXV0aG9yIiwiaWQiOiJqZG9lIn0.B-lReuGNDwAlU1GOC476MlO0vAt9JNoHIlxg2vwMaO0", ("Prefer", "return=representation") ]
[json| { "secret": "nyancat" } |]
`shouldRespondWith`
[json|[{"owner":"jdoe","secret":"nyancat"}]|]
{ matchStatus = 201 }

p2 <- request methodPost "/authors_only"
-- jwt token for jroe
[ authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXN0X3Rlc3RfYXV0aG9yIiwiaWQiOiJqcm9lIn0.2e7mx0U4uDcInlbJVOBGlrRufwqWLINDIEDC1vS0nw8", ("Prefer", "return=representation") ]
[json| { "secret": "lolcat", "owner": "hacker" } |]
liftIO $ do
simpleBody p2 `shouldBe` [str|[{"owner":"jroe","secret":"lolcat"}]|]
simpleStatus p2 `shouldBe` created201
request methodPost "/authors_only"
-- jwt token for jroe
[ authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXN0X3Rlc3RfYXV0aG9yIiwiaWQiOiJqcm9lIn0.2e7mx0U4uDcInlbJVOBGlrRufwqWLINDIEDC1vS0nw8", ("Prefer", "return=representation") ]
[json| { "secret": "lolcat", "owner": "hacker" } |]
`shouldRespondWith`
[json|[{"owner":"jroe","secret":"lolcat"}]|]
{ matchStatus = 201 }

context "tables with self reference foreign keys" $ do
it "embeds parent after insert" $
Expand All @@ -456,7 +455,7 @@ spec actualPgVersion = do
context "table with limited privileges" $ do
it "succeeds inserting if correct select is applied" $
request methodPost "/limited_article_stars?select=article_id,user_id" [("Prefer", "return=representation")]
[json| {"article_id": 2, "user_id": 1} |] `shouldRespondWith` [str|[{"article_id":2,"user_id":1}]|]
[json| {"article_id": 2, "user_id": 1} |] `shouldRespondWith` [json|[{"article_id":2,"user_id":1}]|]
{ matchStatus = 201
, matchHeaders = []
}
Expand All @@ -465,9 +464,9 @@ spec actualPgVersion = do
request methodPost "/limited_article_stars?select=article_id,user_id,created_at" [("Prefer", "return=representation")]
[json| {"article_id": 2, "user_id": 2} |] `shouldRespondWith` (
if actualPgVersion >= pgVersion112 then
[str|{"hint":null,"details":null,"code":"42501","message":"permission denied for view limited_article_stars"}|]
[json|{"hint":null,"details":null,"code":"42501","message":"permission denied for view limited_article_stars"}|]
else
[str|{"hint":null,"details":null,"code":"42501","message":"permission denied for relation limited_article_stars"}|]
[json|{"hint":null,"details":null,"code":"42501","message":"permission denied for relation limited_article_stars"}|]
)
{ matchStatus = 401
, matchHeaders = []
Expand All @@ -477,9 +476,9 @@ spec actualPgVersion = do
request methodPost "/limited_article_stars" [("Prefer", "return=representation")]
[json| {"article_id": 3, "user_id": 1} |] `shouldRespondWith` (
if actualPgVersion >= pgVersion112 then
[str|{"hint":null,"details":null,"code":"42501","message":"permission denied for view limited_article_stars"}|]
[json|{"hint":null,"details":null,"code":"42501","message":"permission denied for view limited_article_stars"}|]
else
[str|{"hint":null,"details":null,"code":"42501","message":"permission denied for relation limited_article_stars"}|]
[json|{"hint":null,"details":null,"code":"42501","message":"permission denied for relation limited_article_stars"}|]
)
{ matchStatus = 401
, matchHeaders = []
Expand Down
22 changes: 10 additions & 12 deletions test/Feature/QuerySpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import Test.Hspec hiding (pendingWith)
import Test.Hspec.Wai
import Test.Hspec.Wai.JSON

import Text.Heredoc

import PostgREST.Types (PgVersion, pgVersion112, pgVersion121,
pgVersion96)
import Protolude hiding (get)
Expand Down Expand Up @@ -72,19 +70,19 @@ spec actualPgVersion = do
[json| [{"a": null, "b": null}] |]
{ matchHeaders = [matchContentTypeJson] }

get "/nullable_integer?a=is.null" `shouldRespondWith` [str|[{"a":null}]|]
get "/nullable_integer?a=is.null" `shouldRespondWith` [json|[{"a":null}]|]

it "matches with like" $ do
get "/simple_pk?k=like.*yx" `shouldRespondWith`
[str|[{"k":"xyyx","extra":"u"}]|]
[json|[{"k":"xyyx","extra":"u"}]|]
get "/simple_pk?k=like.xy*" `shouldRespondWith`
[str|[{"k":"xyyx","extra":"u"}]|]
[json|[{"k":"xyyx","extra":"u"}]|]
get "/simple_pk?k=like.*YY*" `shouldRespondWith`
[str|[{"k":"xYYx","extra":"v"}]|]
[json|[{"k":"xYYx","extra":"v"}]|]

it "matches with like using not operator" $
get "/simple_pk?k=not.like.*yx" `shouldRespondWith`
[str|[{"k":"xYYx","extra":"v"}]|]
[json|[{"k":"xYYx","extra":"v"}]|]

it "matches with ilike" $ do
get "/simple_pk?k=ilike.xy*&order=extra.asc" `shouldRespondWith`
Expand Down Expand Up @@ -251,11 +249,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`
[str|[{"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":1}]|]

it "dash `-` in column names is accepted" $
get "/complex_items?id=eq.3&select=id,field-with_sep" `shouldRespondWith`
[str|[{"id":3,"field-with_sep":1}]|]
[json|[{"id":3,"field-with_sep":1}]|]

it "one simple column" $
get "/complex_items?select=id" `shouldRespondWith`
Expand Down Expand Up @@ -320,7 +318,7 @@ spec actualPgVersion = do

it "requesting parents and filtering parent columns" $
get "/projects?id=eq.1&select=id, name, clients(id)" `shouldRespondWith`
[str|[{"id":1,"name":"Windows 7","clients":{"id":1}}]|]
[json|[{"id":1,"name":"Windows 7","clients":{"id":1}}]|]

it "rows with missing parents are included" $
get "/projects?id=in.(1,5)&select=id,clients(id)" `shouldRespondWith`
Expand All @@ -329,7 +327,7 @@ spec actualPgVersion = do

it "rows with no children return [] instead of null" $
get "/projects?id=in.(5)&select=id,tasks(id)" `shouldRespondWith`
[str|[{"id":5,"tasks":[]}]|]
[json|[{"id":5,"tasks":[]}]|]

it "requesting children 2 levels" $
get "/clients?id=eq.1&select=id,projects(id,tasks(id))" `shouldRespondWith`
Expand Down Expand Up @@ -660,7 +658,7 @@ spec actualPgVersion = do

it "ordering embeded parents does not break things" $
get "/projects?id=eq.1&select=id, name, clients(id, name)&clients.order=name.asc" `shouldRespondWith`
[str|[{"id":1,"name":"Windows 7","clients":{"id":1,"name":"Microsoft"}}]|]
[json|[{"id":1,"name":"Windows 7","clients":{"id":1,"name":"Microsoft"}}]|]

context "order syntax errors" $ do
it "gives meaningful error messages when asc/desc/nulls{first,last} are misspelled" $ do
Expand Down

0 comments on commit 7944e76

Please sign in to comment.