This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb.git


The following commit(s) were added to refs/heads/main by this push:
     new 35b30385a Return a 400 response for a single new_edits=false doc 
update without revisions
35b30385a is described below

commit 35b30385abb0bcccfa008f67d0cf3c732e349600
Author: Nick Vatamaniuc <[email protected]>
AuthorDate: Wed Jul 20 18:02:12 2022 -0400

    Return a 400 response for a single new_edits=false doc update without 
revisions
    
    We are already doing that for _bulk_docs [1] but forgot to do it for 
individual
    doc updates.
    
    [1] https://github.com/apache/couchdb/issues/2242
    
    Fixes: https://github.com/apache/couchdb/issues/4121
---
 src/chttpd/src/chttpd_db.erl             |  4 +++
 src/chttpd/test/eunit/chttpd_db_test.erl | 56 ++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl
index 721da9a74..c41c82347 100644
--- a/src/chttpd/src/chttpd_db.erl
+++ b/src/chttpd/src/chttpd_db.erl
@@ -1205,6 +1205,8 @@ db_doc_req(#httpd{method = 'PUT', user_ctx = Ctx} = Req, 
Db, DocId) ->
                 fun() -> receive_request_data(Req) end
             ),
             Doc = couch_doc_from_req(Req, Db, DocId, Doc0),
+            validate_revs(Doc, UpdateType =:= ?INTERACTIVE_EDIT),
+
             try
                 {HttpCode, RespHeaders1, RespBody} = update_doc_req(
                     Req,
@@ -1227,6 +1229,7 @@ db_doc_req(#httpd{method = 'PUT', user_ctx = Ctx} = Req, 
Db, DocId) ->
                 "ok" ->
                     % batch
                     Doc = couch_doc_from_req(Req, Db, DocId, 
chttpd:json_body(Req)),
+                    validate_revs(Doc, UpdateType =:= ?INTERACTIVE_EDIT),
 
                     spawn(fun() ->
                         case catch (fabric:update_doc(Db, Doc, Options)) of
@@ -1253,6 +1256,7 @@ db_doc_req(#httpd{method = 'PUT', user_ctx = Ctx} = Req, 
Db, DocId) ->
                     % normal
                     Body = chttpd:json_body(Req),
                     Doc = couch_doc_from_req(Req, Db, DocId, Body),
+                    validate_revs(Doc, UpdateType =:= ?INTERACTIVE_EDIT),
                     send_updated_doc(Req, Db, DocId, Doc, RespHeaders, 
UpdateType)
             end
     end;
diff --git a/src/chttpd/test/eunit/chttpd_db_test.erl 
b/src/chttpd/test/eunit/chttpd_db_test.erl
index c76b31581..d6b980c07 100644
--- a/src/chttpd/test/eunit/chttpd_db_test.erl
+++ b/src/chttpd/test/eunit/chttpd_db_test.erl
@@ -69,6 +69,9 @@ all_test_() ->
                     fun should_return_ok_true_on_bulk_update/1,
                     fun 
should_return_201_new_edits_false_with_revs_on_bulk_update/1,
                     fun 
should_return_400_new_edits_false_no_revs_on_bulk_update/1,
+                    fun 
should_return_201_new_edits_false_with_rev_on_doc_update/1,
+                    fun 
should_return_201_new_edits_false_with_revisions_on_doc_update/1,
+                    fun 
should_return_400_new_edits_false_no_revs_on_doc_update/1,
                     fun should_return_ok_true_on_ensure_full_commit/1,
                     fun should_return_404_for_ensure_full_commit_on_no_db/1,
                     fun should_accept_live_as_an_alias_for_continuous/1,
@@ -161,6 +164,59 @@ 
should_return_400_new_edits_false_no_revs_on_bulk_update(Url) ->
             end
         )}.
 
+should_return_201_new_edits_false_with_rev_on_doc_update(Url) ->
+    {timeout, ?TIMEOUT,
+        ?_test(
+            begin
+                Url1 = Url ++ "/docrev2?new_edits=false",
+                Headers = [?CONTENT_JSON, ?AUTH],
+                Body = "{\"foo\": \"bar\", \"_rev\": \"1-abc\"}",
+                {ok, Status, _, ResultBody} = test_request:put(Url1, Headers, 
Body),
+                {Props} = ?JSON_DECODE(ResultBody),
+                ?assertEqual(201, Status),
+                Id = couch_util:get_value(<<"id">>, Props),
+                Rev = couch_util:get_value(<<"rev">>, Props),
+                ?assertEqual(<<"docrev2">>, Id),
+                ?assertEqual(<<"1-abc">>, Rev)
+            end
+        )}.
+
+should_return_201_new_edits_false_with_revisions_on_doc_update(Url) ->
+    {timeout, ?TIMEOUT,
+        ?_test(
+            begin
+                Url1 = Url ++ "/docrev3?new_edits=false",
+                Headers = [?CONTENT_JSON, ?AUTH],
+                Body =
+                    "{\"foo\": \"bar\", " ++
+                        "\"_revisions\": {" ++
+                        "\"ids\": [\"abc\", \"def\"], " ++
+                        "\"start\": 2}} ",
+                {ok, Status, _, ResultBody} = test_request:put(Url1, Headers, 
Body),
+                {Props} = ?JSON_DECODE(ResultBody),
+                Id = couch_util:get_value(<<"id">>, Props),
+                Rev = couch_util:get_value(<<"rev">>, Props),
+                ?assertEqual(201, Status),
+                ?assertEqual(<<"docrev3">>, Id),
+                ?assertEqual(<<"2-abc">>, Rev)
+            end
+        )}.
+
+should_return_400_new_edits_false_no_revs_on_doc_update(Url) ->
+    {timeout, ?TIMEOUT,
+        ?_test(
+            begin
+                Url1 = Url ++ "/docnorev4?new_edits=false",
+                Headers = [?CONTENT_JSON, ?AUTH],
+                Body = "{\"foo\": \"bar\"}",
+                {ok, Status, _, ResultBody} = test_request:put(Url1, Headers, 
Body),
+                {Props} = ?JSON_DECODE(ResultBody),
+                ?assertEqual(400, Status),
+                Error = couch_util:get_value(<<"error">>, Props),
+                ?assertEqual(<<"bad_request">>, Error)
+            end
+        )}.
+
 should_return_ok_true_on_ensure_full_commit(Url0) ->
     {timeout, ?TIMEOUT,
         ?_test(begin

Reply via email to