blob: 829b3395fc4fa8836a5915c0db7a92233a72ebb6 [file] [log] [blame]
defmodule SearchTest do
use CouchTestCase
@moduletag :search
@moduledoc """
Test search
"""
def create_search_docs(db_name) do
resp = Couch.post("/#{db_name}/_bulk_docs",
headers: ["Content-Type": "application/json"],
body: %{:docs => [
%{"item" => "apple", "place" => "kitchen", "state" => "new"},
%{"item" => "banana", "place" => "kitchen", "state" => "new"},
%{"item" => "carrot", "place" => "kitchen", "state" => "old"},
%{"item" => "date", "place" => "lobby", "state" => "unknown"},
]}
)
assert resp.status_code in [201, 202]
end
def create_ddoc(db_name, opts \\ %{}) do
default_ddoc = %{
indexes: %{
fruits: %{
analyzer: %{name: "standard"},
index: "function (doc) {\n index(\"item\", doc.item, {facet: true});\n index(\"place\", doc.place, {facet: true});\n index(\"state\", doc.state, {facet: true});\n}"
}
}
}
ddoc = Enum.into(opts, default_ddoc)
resp = Couch.put("/#{db_name}/_design/inventory", body: ddoc)
assert resp.status_code in [201, 202]
assert Map.has_key?(resp.body, "ok") == true
end
def create_invalid_ddoc(db_name, opts \\ %{}) do
invalid_ddoc = %{
:indexes => [
%{"name" => "foo", "ddoc" => "bar", "type" => "text"},
]
}
ddoc = Enum.into(opts, invalid_ddoc)
resp = Couch.put("/#{db_name}/_design/search", body: ddoc)
assert resp.status_code in [201, 202]
assert Map.has_key?(resp.body, "ok") == true
end
def get_items (resp) do
%{:body => %{"rows" => rows}} = resp
Enum.map(rows, fn row -> row["doc"]["item"] end)
end
@tag :with_db
test "search returns all items for GET", context do
db_name = context[:db_name]
create_search_docs(db_name)
create_ddoc(db_name)
url = "/#{db_name}/_design/inventory/_search/fruits"
resp = Couch.get(url, query: %{q: "*:*", include_docs: true})
assert resp.status_code == 200
ids = get_items(resp)
assert Enum.sort(ids) == Enum.sort(["apple", "banana", "carrot", "date"])
end
@tag :with_db
test "drilldown single key single value for GET", context do
db_name = context[:db_name]
create_search_docs(db_name)
create_ddoc(db_name)
url = "/#{db_name}/_design/inventory/_search/fruits"
resp = Couch.get(url, query: %{q: "*:*", drilldown: :jiffy.encode(["place", "kitchen"]), include_docs: true})
assert resp.status_code == 200
ids = get_items(resp)
assert Enum.sort(ids) == Enum.sort(["apple", "banana", "carrot"])
end
@tag :with_db
test "drilldown single key multiple values for GET", context do
db_name = context[:db_name]
create_search_docs(db_name)
create_ddoc(db_name)
url = "/#{db_name}/_design/inventory/_search/fruits"
resp = Couch.get(url, query: %{q: "*:*", drilldown: :jiffy.encode(["state", "new", "unknown"]), include_docs: true})
assert resp.status_code == 200
ids = get_items(resp)
assert Enum.sort(ids) == Enum.sort(["apple", "banana", "date"])
end
@tag :with_db
test "drilldown multiple keys single values for GET", context do
db_name = context[:db_name]
create_search_docs(db_name)
create_ddoc(db_name)
url = "/#{db_name}/_design/inventory/_search/fruits"
resp = Couch.get(url, query: %{q: "*:*", drilldown: :jiffy.encode([["state", "old"], ["item", "apple"]]), include_docs: true})
assert resp.status_code == 200
ids = get_items(resp)
assert Enum.sort(ids) == []
end
@tag :with_db
test "drilldown multiple query definitions for GET", context do
db_name = context[:db_name]
create_search_docs(db_name)
create_ddoc(db_name)
url = "/#{db_name}/_design/inventory/_search/fruits?q=*:*&drilldown=[\"state\",\"old\"]&drilldown=[\"item\",\"apple\"]&include_docs=true"
resp = Couch.get(url)
assert resp.status_code == 200
ids = get_items(resp)
assert Enum.sort(ids) == []
end
@tag :with_db
test "search returns all items for POST", context do
db_name = context[:db_name]
create_search_docs(db_name)
create_ddoc(db_name)
url = "/#{db_name}/_design/inventory/_search/fruits"
resp = Couch.post(url, body: %{q: "*:*", include_docs: true})
assert resp.status_code == 200
ids = get_items(resp)
assert Enum.sort(ids) == Enum.sort(["apple", "banana", "carrot", "date"])
end
@tag :with_db
test "drilldown single key single value for POST", context do
db_name = context[:db_name]
create_search_docs(db_name)
create_ddoc(db_name)
url = "/#{db_name}/_design/inventory/_search/fruits"
resp = Couch.post(url, body: %{query: "*:*", drilldown: ["place", "kitchen"], include_docs: true})
assert resp.status_code == 200
ids = get_items(resp)
assert Enum.sort(ids) == Enum.sort(["apple", "banana", "carrot"])
end
@tag :with_db
test "drilldown single key multiple values for POST", context do
db_name = context[:db_name]
create_search_docs(db_name)
create_ddoc(db_name)
url = "/#{db_name}/_design/inventory/_search/fruits"
resp = Couch.post(url, body: %{query: "*:*", drilldown: ["state", "new", "unknown"], include_docs: true})
assert resp.status_code == 200
ids = get_items(resp)
assert Enum.sort(ids) == Enum.sort(["apple", "banana", "date"])
end
@tag :with_db
test "drilldown multiple keys single values for POST", context do
db_name = context[:db_name]
create_search_docs(db_name)
create_ddoc(db_name)
url = "/#{db_name}/_design/inventory/_search/fruits"
resp = Couch.post(url, body: %{q: "*:*", drilldown: [["state", "old"], ["item", "apple"]], include_docs: true})
assert resp.status_code == 200
ids = get_items(resp)
assert Enum.sort(ids) == []
end
@tag :with_db
test "drilldown three keys single values for POST", context do
db_name = context[:db_name]
create_search_docs(db_name)
create_ddoc(db_name)
url = "/#{db_name}/_design/inventory/_search/fruits"
resp = Couch.post(url, body: %{q: "*:*", drilldown: [["place", "kitchen"], ["state", "new"], ["item", "apple"]], include_docs: true})
assert resp.status_code == 200
ids = get_items(resp)
assert Enum.sort(ids) == ["apple"]
end
@tag :with_db
test "drilldown multiple keys multiple values for POST", context do
db_name = context[:db_name]
create_search_docs(db_name)
create_ddoc(db_name)
url = "/#{db_name}/_design/inventory/_search/fruits"
resp = Couch.post(url, body: %{q: "*:*", drilldown: [["state", "old", "new"], ["item", "apple"]], include_docs: true})
assert resp.status_code == 200
ids = get_items(resp)
assert Enum.sort(ids) == ["apple"]
end
@tag :with_db
test "drilldown multiple query definitions for POST", context do
db_name = context[:db_name]
create_search_docs(db_name)
create_ddoc(db_name)
url = "/#{db_name}/_design/inventory/_search/fruits"
resp = Couch.post(url, body: "{\"include_docs\": true, \"q\": \"*:*\", \"drilldown\": [\"state\", \"old\"], \"drilldown\": [\"item\", \"apple\"]}")
assert resp.status_code == 200
ids = get_items(resp)
assert Enum.sort(ids) == ["apple"]
end
@tag :with_db
test "clean up search index with invalid design document", context do
db_name = context[:db_name]
create_search_docs(db_name)
create_ddoc(db_name)
create_invalid_ddoc(db_name)
resp = Couch.post("/#{db_name}/_search_cleanup")
assert resp.status_code in [201, 202]
end
end