garrensmith closed pull request #1487: Port conflicts.js
URL: https://github.com/apache/couchdb/pull/1487
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git a/test/elixir/test/conflicts_test.exs
b/test/elixir/test/conflicts_test.exs
new file mode 100644
index 0000000000..d744cf7954
--- /dev/null
+++ b/test/elixir/test/conflicts_test.exs
@@ -0,0 +1,108 @@
+defmodule RevisionTest do
+ use CouchTestCase
+
+ @moduletag :conflicts
+
+ @moduledoc """
+ Test CouchDB conflicts
+ This is a port of conflicts.js
+ (but is arguably more focused on revisions than conflicts)
+ """
+
+ setup context do
+ # Generate a doc with _rev field for each test
+ doc = %{_id: "doc-1", a: 1, b: 1}
+ doc = rev(doc, put(context[:db_name], doc))
+ %{doc: doc}
+ end
+
+ @tag :with_db
+ test "multiple updates with same _rev raise conflict errors", context do
+ db = context[:db_name]
+ doc = context[:doc]
+ doc2 = %{doc | a: 2, b: 2} # doc and doc2 have same _rev
+ _doc = rev(doc, put(db, doc)) # doc updated with new _rev
+ assert_conflict Couch.put("/#{db}/#{doc2._id}", [body: doc2])
+
+ resp = Couch.get("/#{db}/_changes")
+ assert length(resp.body["results"]) == 1
+
+ doc2 = Map.delete(doc2, :_rev)
+ assert_conflict(Couch.put("/#{db}/#{doc2._id}", [body: doc2]))
+ end
+
+ @tag :with_db
+ test "mismatched rev in body and query string returns error", context do
+ db = context[:db_name]
+ doc = context[:doc]
+ resp = Couch.put("/#{db}/#{doc._id}?rev=1-foobar", [body: doc])
+ expected_reason = "Document rev from request body and query string " <>
+ "have different values"
+ assert_bad_request(resp, expected_reason)
+ end
+
+ @tag :with_db
+ test "mismatched rev in body and etag returns error", context do
+ opts = [body: context[:doc], headers: [{:"If-Match", "1-foobar"}]]
+ resp = Couch.put("/#{context[:db_name]}/foobar", opts)
+ expected_reason = "Document rev and etag have different values"
+ assert_bad_request(resp, expected_reason)
+ end
+
+ @tag :with_db
+ test "`new_edits: false` prevents bulk updates (COUCHDB-1178)", context do
+ db = context[:db_name]
+
+ ddoc = %{_id: "_design/couchdb-1178", validate_doc_update: "function(){}"}
+ assert put(db, ddoc)["ok"] == true
+
+ r0 = %{_id: "doc", val: "r0"}
+ r1 = %{_id: "doc", val: "r1", _rev: "1-47f3268e7546965196b57572099f4372"}
+ r2 = %{_id: "doc", val: "r2", _rev: "2-1d8171ab3a91475cfece749291e6f897"}
+ r3 = %{_id: "doc", val: "r3", _rev: "3-3fb0a342d2ce092fdcc77856dbe8a2ef"}
+ assert put(db, r0)["ok"] == true
+ assert put(db, r1)["ok"] == true
+ assert put(db, r2)["ok"] == true
+ # N.b. that we *do not* put r3
+
+ expected = %{
+ "_id" => "doc",
+ "_rev" => r3._rev,
+ "_revisions" => %{
+ "ids" => (for r <- [r3._rev, r2._rev, r1._rev], do: suffix(r)),
+ "start" => 3},
+ "val" => r2.val}
+ assert Couch.get("/#{db}/doc?revs=true").body == expected
+
+ opts = [body: %{docs: [r3, r2, r1], new_edits: false}]
+ assert Couch.post("/#{db}/_bulk_docs", opts).body == []
+ end
+
+
+ defp put(db, doc) do
+ Couch.put("/#{db}/#{doc._id}", [body: doc]).body
+ end
+
+ # Update doc's _rev entry with request result
+ @spec rev(map(), map()) :: map()
+ defp rev(doc = %{_id: id}, %{"id" => id, "rev" => rev}) do
+ Map.put(doc, :_rev, rev)
+ end
+
+ defp suffix(rev) do
+ hd(tl(String.split(rev, "-")))
+ end
+
+ defp assert_conflict(resp) do
+ assert resp.status_code == 409
+ assert resp.body["error"] == "conflict"
+ assert resp.body["reason"] == "Document update conflict."
+ end
+
+ defp assert_bad_request(resp, reason) do
+ assert resp.status_code == 400
+ assert resp.body["error"] == "bad_request"
+ assert resp.body["reason"] == reason
+ end
+
+end
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services