summaryrefslogtreecommitdiff
path: root/test/elixir/test/all_docs_test.exs
diff options
context:
space:
mode:
Diffstat (limited to 'test/elixir/test/all_docs_test.exs')
-rw-r--r--test/elixir/test/all_docs_test.exs132
1 files changed, 132 insertions, 0 deletions
diff --git a/test/elixir/test/all_docs_test.exs b/test/elixir/test/all_docs_test.exs
new file mode 100644
index 000000000..2fd608dc6
--- /dev/null
+++ b/test/elixir/test/all_docs_test.exs
@@ -0,0 +1,132 @@
+defmodule AllDocsTest do
+ use CouchTestCase
+
+ @moduletag :all_docs
+
+ @moduledoc """
+ Test CouchDB _all_docs
+ This is a port of the all_docs.js suite
+ """
+
+ # TODO: do we need to bring this in?
+ # var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}, {w: 3});
+
+ @tag :with_db
+ test "All Docs tests", context do
+ db_name = context[:db_name]
+ resp1 = Couch.post("/#{db_name}", [body: %{:_id => "0", :a => 1, :b => 1}]).body
+ resp2 = Couch.post("/#{db_name}", [body: %{:_id => "3", :a => 4, :b => 16}]).body
+ resp3 = Couch.post("/#{db_name}", [body: %{:_id => "1", :a => 2, :b => 4}]).body
+ resp4 = Couch.post("/#{db_name}", [body: %{:_id => "2", :a => 3, :b => 9}]).body
+
+ assert resp1["ok"]
+ assert resp2["ok"]
+ assert resp3["ok"]
+ assert resp4["ok"]
+
+ revs = [resp1["rev"], resp2["rev"], resp3["rev"], resp4["rev"]]
+
+ # Check _all_docs
+ resp = Couch.get("/#{db_name}/_all_docs").body
+ rows = resp["rows"]
+ assert resp["total_rows"] == length(rows)
+ Enum.each(rows, fn row ->
+ assert row["id"] >= "0" && row["id"] <= "4"
+ end)
+
+ # Check _all_docs with descending=true
+ resp = Couch.get("/#{db_name}/_all_docs", query: %{:descending => true}).body
+ rows = resp["rows"]
+ assert resp["total_rows"] == length(rows)
+
+ # Check _all_docs offset
+ resp = Couch.get("/#{db_name}/_all_docs", query: %{:startkey => "\"2\""}).body
+ assert resp["offset"] == 2
+
+ # Confirm that queries may assume raw collation
+ resp = Couch.get("/#{db_name}/_all_docs", query: %{
+ :startkey => "\"org.couchdb.user:\"",
+ :endkey => "\"org.couchdb.user;\""
+ })
+ assert length(resp.body["rows"]) == 0
+
+ # Check that all docs show up in the changes feed; order can vary
+ resp = Couch.get("/#{db_name}/_changes").body
+ Enum.each(resp["results"], fn row ->
+ assert Enum.member?(revs, hd(row["changes"])["rev"]), "doc #{row["id"]} should be in changes"
+ end)
+
+ # Check that deletions also show up right
+ doc1 = Couch.get("/#{db_name}/1").body
+ assert Couch.delete("/#{db_name}/1", query: %{:rev => doc1["_rev"]}).body["ok"]
+ changes = Couch.get("/#{db_name}/_changes").body["results"]
+ assert length(changes) == 4
+ deleted = Enum.filter(changes, fn row -> row["deleted"] end)
+ assert length(deleted) == 1
+ assert hd(deleted)["id"] == "1"
+
+ # (remember old seq)
+ orig_doc = Enum.find(changes, fn row -> row["id"] == "3" end)
+ # Perform an update
+ doc3 = Couch.get("/#{db_name}/3").body
+ doc3 = Map.put(doc3, :updated, "totally")
+ assert Couch.put("/#{db_name}/3", body: doc3).body["ok"]
+
+ # The update should make doc id 3 have another seq num (not nec. higher or the last though)
+ changes = Couch.get("/#{db_name}/_changes").body["results"]
+ assert length(changes) == 4
+ updated_doc = Enum.find(changes, fn row -> row["id"] == "3" end)
+ assert orig_doc["seq"] != updated_doc["seq"], "seq num should be different"
+
+ # Ok, now let's see what happens with include docs
+ changes = Couch.get("/#{db_name}/_changes", query: %{:include_docs => true}).body["results"]
+ assert length(changes) == 4
+ updated_doc = Enum.find(changes, fn row -> row["id"] == doc3["_id"] end)
+ assert updated_doc["doc"]["updated"] == "totally"
+
+ deleted_doc = Enum.find(changes, fn row -> row["deleted"] end)
+ assert deleted_doc["doc"]["_deleted"]
+
+ # Test _all_docs with keys
+ rows = Couch.post("/#{db_name}/_all_docs", query: %{:include_docs => true}, body: %{:keys => ["1"]}).body["rows"]
+ row = hd(rows)
+ assert length(rows) == 1
+ assert row["key"] == "1"
+ assert row["id"] == "1"
+ assert row["value"]["deleted"]
+ assert row["doc"] == :null
+
+ # Add conflicts
+ conflicted_doc1 = %{:_id => "3", :_rev => "2-aa01552213fafa022e6167113ed01087", :value => "X"}
+ conflicted_doc2 = %{:_id => "3", :_rev => "2-ff01552213fafa022e6167113ed01087", :value => "Z"}
+ assert Couch.put("/#{db_name}/3", query: %{:new_edits => false}, body: conflicted_doc1).body["ok"]
+ assert Couch.put("/#{db_name}/3", query: %{:new_edits => false}, body: conflicted_doc2).body["ok"]
+
+ win_rev = Couch.get("/#{db_name}/3").body
+ changes = Couch.get("/#{db_name}/_changes", query: %{:include_docs => true, :conflicts => true, :style => "all_docs"}).body["results"]
+
+ doc3 = Enum.find(changes, fn row -> row["id"] == "3" end)
+ assert doc3["id"] == "3"
+ assert length(doc3["changes"]) == 3
+ assert win_rev["_rev"] == hd(doc3["changes"])["rev"]
+ assert is_list(doc3["doc"]["_conflicts"])
+ assert length(doc3["doc"]["_conflicts"]) == 2
+
+ rows = Couch.get("/#{db_name}/_all_docs", query: %{:include_docs => true, :conflicts => true}).body["rows"]
+ assert length(rows) == 3
+ change = hd(tl(tl(rows)))
+ assert change["key"] == "3"
+ assert change["id"] == "3"
+ assert change["value"]["rev"] == win_rev["_rev"]
+ assert change["doc"]["_rev"] == win_rev["_rev"]
+ assert change["doc"]["_id"] == "3"
+ assert is_list(change["doc"]["_conflicts"])
+ assert length(change["doc"]["_conflicts"]) == 2
+
+ # Test that _all_docs collates sanely
+ assert Couch.post("/#{db_name}", body: %{:_id => "Z", :foo => "Z"}).body["ok"]
+ assert Couch.post("/#{db_name}", body: %{:_id => "a", :foo => "a"}).body["ok"]
+ rows = Couch.get("/#{db_name}/_all_docs", query: %{:startkey => "\"Z\"", :endkey => "\"Z\""}).body["rows"]
+ assert length(rows) == 1
+ end
+end