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