diff --git a/src/PostgREST/ApiRequest/QueryParams.hs b/src/PostgREST/ApiRequest/QueryParams.hs index 738427b49..95e69907c 100644 --- a/src/PostgREST/ApiRequest/QueryParams.hs +++ b/src/PostgREST/ApiRequest/QueryParams.hs @@ -669,6 +669,46 @@ pDelimiter = char '.' "delimiter (.)" -- -- >>> P.parse pOrder "" "name,clients(name),id" -- Right [OrderTerm {otTerm = ("name",[]), otDirection = Nothing, otNullOrder = Nothing},OrderRelationTerm {otRelation = "clients", otRelTerm = ("name",[]), otDirection = Nothing, otNullOrder = Nothing},OrderTerm {otTerm = ("id",[]), otDirection = Nothing, otNullOrder = Nothing}] +-- +-- >>> P.parse pOrder "" "id.ac" +-- Left (line 1, column 4): +-- unexpected "c" +-- expecting "asc", "desc", "nullsfirst" or "nullslast" +-- +-- >>> P.parse pOrder "" "id.descc" +-- Left (line 1, column 8): +-- unexpected 'c' +-- expecting delimiter (.), "," or end of input +-- +-- >>> P.parse pOrder "" "id.nulsfist" +-- Left (line 1, column 4): +-- unexpected "n" +-- expecting "asc", "desc", "nullsfirst" or "nullslast" +-- +-- >>> P.parse pOrder "" "id.nullslasttt" +-- Left (line 1, column 13): +-- unexpected 't' +-- expecting "," or end of input +-- +-- >>> P.parse pOrder "" "id.smth34" +-- Left (line 1, column 4): +-- unexpected "s" +-- expecting "asc", "desc", "nullsfirst" or "nullslast" +-- +-- >>> P.parse pOrder "" "id.asc.nlsfst" +-- Left (line 1, column 8): +-- unexpected "l" +-- expecting "nullsfirst" or "nullslast" +-- +-- >>> P.parse pOrder "" "id.asc.nullslasttt" +-- Left (line 1, column 17): +-- unexpected 't' +-- expecting "," or end of input +-- +-- >>> P.parse pOrder "" "id.asc.smth34" +-- Left (line 1, column 8): +-- unexpected "s" +-- expecting "nullsfirst" or "nullslast" pOrder :: Parser [OrderTerm] pOrder = lexeme (try pOrderRelationTerm <|> pOrderTerm) `sepBy1` char ',' where diff --git a/test/spec/Feature/Query/QuerySpec.hs b/test/spec/Feature/Query/QuerySpec.hs index 7b0afac71..c076f11ee 100644 --- a/test/spec/Feature/Query/QuerySpec.hs +++ b/test/spec/Feature/Query/QuerySpec.hs @@ -921,50 +921,12 @@ spec actualPgVersion = do get "/projects?id=eq.1&select=id, name, clients(id, name)&clients.order=name.asc" `shouldRespondWith` [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 - get "/items?order=id.ac" `shouldRespondWith` - [json|{"details":"unexpected \"c\" expecting \"asc\", \"desc\", \"nullsfirst\" or \"nullslast\"","message":"\"failed to parse order (id.ac)\" (line 1, column 4)","code":"PGRST100","hint":null}|] - { matchStatus = 400 - , matchHeaders = [matchContentTypeJson] - } - get "/items?order=id.descc" `shouldRespondWith` - [json|{"details":"unexpected 'c' expecting delimiter (.), \",\" or end of input","message":"\"failed to parse order (id.descc)\" (line 1, column 8)","code":"PGRST100","hint":null}|] - { matchStatus = 400 - , matchHeaders = [matchContentTypeJson] - } - get "/items?order=id.nulsfist" `shouldRespondWith` - [json|{"details":"unexpected \"n\" expecting \"asc\", \"desc\", \"nullsfirst\" or \"nullslast\"","message":"\"failed to parse order (id.nulsfist)\" (line 1, column 4)","code":"PGRST100","hint":null}|] - { matchStatus = 400 - , matchHeaders = [matchContentTypeJson] - } - get "/items?order=id.nullslasttt" `shouldRespondWith` - [json|{"details":"unexpected 't' expecting \",\" or end of input","message":"\"failed to parse order (id.nullslasttt)\" (line 1, column 13)","code":"PGRST100","hint":null}|] - { matchStatus = 400 - , matchHeaders = [matchContentTypeJson] - } - get "/items?order=id.smth34" `shouldRespondWith` - [json|{"details":"unexpected \"s\" expecting \"asc\", \"desc\", \"nullsfirst\" or \"nullslast\"","message":"\"failed to parse order (id.smth34)\" (line 1, column 4)","code":"PGRST100","hint":null}|] - { matchStatus = 400 - , matchHeaders = [matchContentTypeJson] - } - - it "gives meaningful error messages when nulls{first,last} are misspelled after asc/desc" $ do - get "/items?order=id.asc.nlsfst" `shouldRespondWith` - [json|{"details":"unexpected \"l\" expecting \"nullsfirst\" or \"nullslast\"","message":"\"failed to parse order (id.asc.nlsfst)\" (line 1, column 8)","code":"PGRST100","hint":null}|] - { matchStatus = 400 - , matchHeaders = [matchContentTypeJson] - } - get "/items?order=id.asc.nullslasttt" `shouldRespondWith` - [json|{"details":"unexpected 't' expecting \",\" or end of input","message":"\"failed to parse order (id.asc.nullslasttt)\" (line 1, column 17)","code":"PGRST100","hint":null}|] - { matchStatus = 400 - , matchHeaders = [matchContentTypeJson] - } - get "/items?order=id.asc.smth34" `shouldRespondWith` - [json|{"details":"unexpected \"s\" expecting \"nullsfirst\" or \"nullslast\"","message":"\"failed to parse order (id.asc.smth34)\" (line 1, column 8)","code":"PGRST100","hint":null}|] - { matchStatus = 400 - , matchHeaders = [matchContentTypeJson] - } + it "gives meaningful error message on bad syntax" $ do + get "/items?order=id.asc.nullslasttt" `shouldRespondWith` + [json|{"details":"unexpected 't' expecting \",\" or end of input","message":"\"failed to parse order (id.asc.nullslasttt)\" (line 1, column 17)","code":"PGRST100","hint":null}|] + { matchStatus = 400 + , matchHeaders = [matchContentTypeJson] + } describe "Accept headers" $ do it "should respond an unknown accept type with 415" $