From 8557ee55f598ab5cb58ae2fbaa8b4ecd49a08c90 Mon Sep 17 00:00:00 2001 From: Marios Koulakis Date: Fri, 7 Apr 2017 23:21:50 -0400 Subject: [PATCH] Update with empty json (#852) --- CHANGELOG.md | 2 +- src/PostgREST/App.hs | 10 ++++++---- test/Feature/InsertSpec.hs | 24 ++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b93645ec..cae35f7a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added - Allow requesting binary output on GET - @steve-chavez - Accept clients requesting `Content-Type: application/json` from / - @feynmanliang +- #493, Updating with empty JSON object makes zero updates @koulakis ### Fixed - - #827, Avoid Warp reaper, extend socket timeout to 1 hour - @majorcode - #791, malformed nested JSON error - @diogob - Resource embedding in views referencing tables in public schema - @fab1an diff --git a/src/PostgREST/App.hs b/src/PostgREST/App.hs index c60335699..b2ef314eb 100644 --- a/src/PostgREST/App.hs +++ b/src/PostgREST/App.hs @@ -165,10 +165,12 @@ app dbStructure conf apiRequest = if iPreferRepresentation apiRequest == Full then toS body else "" - (ActionUpdate, TargetIdent _, Just payload) -> - case mutateSqlParts of - Left errorResponse -> return errorResponse - Right (sq, mq) -> do + (ActionUpdate, TargetIdent _, Just payload@(PayloadJSON rows)) -> + case (mutateSqlParts, null <$> rows V.!? 0, iPreferRepresentation apiRequest == Full) of + (Left errorResponse, _, _) -> return errorResponse + (_, Just True, True) -> return $ responseLBS status200 [contentRangeH 1 0 Nothing] "[]" + (_, Just True, False) -> return $ responseLBS status204 [contentRangeH 1 0 Nothing] "" + (Right (sq, mq), _, _) -> do let stm = createWriteStatement sq mq (contentType == CTSingularJSON) False (contentType == CTTextCSV) (iPreferRepresentation apiRequest) [] diff --git a/test/Feature/InsertSpec.hs b/test/Feature/InsertSpec.hs index a8c69ec9b..60b770465 100644 --- a/test/Feature/InsertSpec.hs +++ b/test/Feature/InsertSpec.hs @@ -413,6 +413,30 @@ spec = do [json| { id: 99 } |] `shouldRespondWith` [json| [{id:99}] |] { matchHeaders = [matchContentTypeJson] } + -- put value back for other tests + void $ request methodPatch "/items?id=eq.99" [] [json| { "id":1 } |] + + it "makes no updates and returns 204, when patching with an empty json object" $ do + request methodPatch "/items" [] [json| {} |] + `shouldRespondWith` "" + { + matchStatus = 204, + matchHeaders = ["Content-Range" <:> "*/*"] + } + + g <- get "/items" + liftIO $ simpleBody g `shouldBe` [json| [{"id":3},{"id":4},{"id":5},{"id":6},{"id":7},{"id":8},{"id":9},{"id":10},{"id":11},{"id":12},{"id":13},{"id":14},{"id":15},{id:16},{"id":2},{"id":1}] |] + + it "makes no updates and and returns 200, when patching with an empty json object and return=rep" $ do + request methodPatch "/items" [("Prefer", "return=representation")] [json| {} |] + `shouldRespondWith` "[]" + { + matchStatus = 200, + matchHeaders = ["Content-Range" <:> "*/*"] + } + + g <- get "/items" + liftIO $ simpleBody g `shouldBe` [json| [{"id":3},{"id":4},{"id":5},{"id":6},{"id":7},{"id":8},{"id":9},{"id":10},{"id":11},{"id":12},{"id":13},{"id":14},{"id":15},{id:16},{"id":2},{"id":1}] |] context "with unicode values" $ it "succeeds and returns values intact" $ do