blob: 1c2ab57315b023474545fb59d9f5c3f995558a34 [file] [log] [blame]
defmodule ViewIncludeDocsTest do
use CouchTestCase
@moduletag :view_include_docs
@moduletag kind: :single_node
@ddoc %{
_id: "_design/test",
language: "javascript",
views: %{
all_docs: %{
map: "function(doc) { emit(doc.integer, doc.string) }"
},
with_prev: %{
map:
"function(doc){if(doc.prev) emit(doc._id,{'_rev':doc.prev}); else emit(doc._id,{'_rev':doc._rev});}"
},
with_id: %{
map:
"function(doc) {if(doc.link_id) { var value = {'_id':doc.link_id}; if (doc.link_rev) {value._rev = doc.link_rev}; emit(doc._id, value);}};"
},
summate: %{
map:
"function (doc) { if (typeof doc.integer === 'number') {emit(doc.integer, doc.integer)};}",
reduce: "function (keys, values) { return sum(values); };"
}
}
}
setup_all do
db_name = random_db_name()
{:ok, _} = create_db(db_name)
on_exit(fn -> delete_db(db_name) end)
bulk_save(db_name, make_docs(0..99))
create_doc(db_name, @ddoc)
{:ok, [db_name: db_name]}
end
test "include docs in view", context do
db_name = context[:db_name]
resp = view(db_name, "test/all_docs", %{include_docs: true, limit: 2})
assert length(resp.body["rows"]) == 2
row0 = Enum.at(resp.body["rows"], 0)
assert row0["id"] == "0"
assert row0["doc"]["_id"] == "0"
row1 = Enum.at(resp.body["rows"], 1)
assert row1["id"] == "1"
assert row1["doc"]["_id"] == "1"
resp = view(db_name, "test/all_docs", %{include_docs: true}, [29, 74])
assert length(resp.body["rows"]) == 2
row0 = Enum.at(resp.body["rows"], 0)
assert row0["doc"]["_id"] == "29"
row1 = Enum.at(resp.body["rows"], 1)
assert row1["doc"]["integer"] == 74
end
test "include docs in all_docs", context do
db_name = context[:db_name]
resp =
Couch.get("/#{db_name}/_all_docs",
query: [limit: 2, skip: 1, include_docs: true]
)
assert length(resp.body["rows"]) == 2
row0 = Enum.at(resp.body["rows"], 0)
row1 = Enum.at(resp.body["rows"], 1)
assert row0["doc"]["integer"] == 1
assert row1["doc"]["integer"] == 10
resp =
Couch.post("/#{db_name}/_all_docs",
query: [include_docs: true],
headers: ["Content-Type": "application/json"],
body: %{"keys" => ["not_a_doc"]}
)
assert length(resp.body["rows"]) == 1
row0 = Enum.at(resp.body["rows"], 0)
assert not Map.has_key?(row0, "doc")
resp =
Couch.post("/#{db_name}/_all_docs",
query: [include_docs: true],
headers: ["Content-Type": "application/json"],
body: %{"keys" => ["1", "foo"]}
)
assert length(resp.body["rows"]) == 2
row0 = Enum.at(resp.body["rows"], 0)
row1 = Enum.at(resp.body["rows"], 1)
assert row0["doc"]["integer"] == 1
assert not Map.has_key?(row1, "doc")
resp =
Couch.get("/#{db_name}/_all_docs",
query: [limit: 0, include_docs: true]
)
assert Enum.empty?(resp.body["rows"])
end
test "no reduce support", context do
db_name = context[:db_name]
resp =
Couch.get("/#{db_name}/_design/test/_view/summate", query: [include_docs: true])
assert resp.status_code == 400
assert resp.body["error"] == "query_parse_error"
end
test "Reduce support when reduce=false", context do
db_name = context[:db_name]
resp =
Couch.get("/#{db_name}/_design/test/_view/summate",
query: [reduce: false, include_docs: true]
)
assert length(resp.body["rows"]) == 100
end
test "Not an error with include_docs=false&reduce=true", context do
db_name = context[:db_name]
resp =
Couch.get("/#{db_name}/_design/test/_view/summate",
query: [reduce: true, include_docs: false]
)
assert length(resp.body["rows"]) == 1
row0 = Enum.at(resp.body["rows"], 0)
assert row0["value"] == 4950
end
@tag :with_db
test "link to another doc from a value", context do
db_name = context[:db_name]
bulk_save(db_name, make_docs(0..99))
create_doc(db_name, @ddoc)
doc_link = %{
_id: "link-to-10",
link_id: "10"
}
{:ok, _} = create_doc(db_name, doc_link)
resp = view(db_name, "test/with_id", %{key: ~s("link-to-10")})
assert length(resp.body["rows"]) == 1
row0 = Enum.at(resp.body["rows"], 0)
assert row0["key"] == "link-to-10"
assert row0["value"]["_id"] == "10"
resp = view(db_name, "test/with_id", %{key: ~s("link-to-10"), include_docs: true})
assert length(resp.body["rows"]) == 1
row0 = Enum.at(resp.body["rows"], 0)
assert row0["value"]["_id"] == "10"
assert row0["doc"]["_id"] == "10"
end
@tag :with_db
test "emitted _rev controls things", context do
db_name = context[:db_name]
bulk_save(db_name, make_docs(0..99))
create_doc(db_name, @ddoc)
resp =
Couch.post("/#{db_name}/_all_docs",
query: [include_docs: true],
headers: ["Content-Type": "application/json"],
body: %{"keys" => ["0"]}
)
doc_before = Enum.at(resp.body["rows"], 0)["doc"]
resp = Couch.get("/#{db_name}/0")
assert resp.status_code == 200
prev = resp.body["_rev"]
doc_after =
resp.body
|> Map.put("integer", 100)
|> Map.put("prev", prev)
saved_doc = save(db_name, doc_after)
resp = Couch.get("/#{db_name}/0")
assert resp.status_code == 200
doc_after = resp.body
assert doc_after["_rev"] == saved_doc["_rev"]
assert doc_after["_rev"] != doc_after["prev"]
assert doc_after["integer"] == 100
resp = view(db_name, "test/with_prev", %{include_docs: true}, ["0"])
row0 = Enum.at(resp.body["rows"], 0)["doc"]
assert row0["_id"] == "0"
assert row0["_rev"] == doc_before["_rev"]
assert not Map.has_key?(row0, "prev")
assert assert row0["integer"] == 0
end
test "COUCHDB-549 - include_docs=true with conflicts=true" do
db_name_a = random_db_name()
db_name_b = random_db_name()
create_db(db_name_a)
create_db(db_name_b)
on_exit(fn -> delete_db(db_name_a) end)
on_exit(fn -> delete_db(db_name_b) end)
ddoc = %{
_id: "_design/mydesign",
language: "javascript",
views: %{
myview: %{
map: """
function(doc) {
emit(doc.value, 1);
}
"""
}
}
}
{:ok, _} = create_doc(db_name_a, ddoc)
doc1a = %{_id: "foo", value: 1, str: "1"}
{:ok, _} = create_doc(db_name_a, doc1a)
doc1b = %{_id: "foo", value: 1, str: "666"}
{:ok, _} = create_doc(db_name_b, doc1b)
doc2 = %{_id: "bar", value: 2, str: "2"}
{:ok, _} = create_doc(db_name_a, doc2)
replicate(db_name_a, db_name_b)
resp = Couch.get("/#{db_name_b}/foo", query: [conflicts: true])
assert resp.status_code == 200
doc1b = resp.body
assert Map.has_key?(doc1b, "_conflicts")
assert length(doc1b["_conflicts"]) == 1
conflict_rev = Enum.at(doc1b["_conflicts"], 0)
resp = Couch.get("/#{db_name_b}/bar", query: [conflicts: true])
assert resp.status_code == 200
doc2 = resp.body
assert not Map.has_key?(doc2, "_conflicts")
resp = view(db_name_b, "mydesign/myview", %{include_docs: true, conflicts: true})
assert length(resp.body["rows"]) == 2
row0 = Enum.at(resp.body["rows"], 0)["doc"]
assert length(row0["_conflicts"]) == 1
assert Enum.at(row0["_conflicts"], 0) == conflict_rev
row1 = Enum.at(resp.body["rows"], 1)["doc"]
assert not Map.has_key?(row1, "_conflicts")
end
end