blob: 8514111c45b3283b18c7967cf4e239f8bf5a6505 [file] [log] [blame]
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
import mango
import unittest
import user_docs
@unittest.skipUnless(mango.has_text_service(), "requires text service")
class CustomFieldsTest(mango.UserDocsTextTests):
FIELDS = [
{"name": "favorites.[]", "type": "string"},
{"name": "manager", "type": "boolean"},
{"name": "age", "type": "number"},
# These two are to test the default analyzer for
# each field.
{"name": "location.state", "type": "string"},
{"name": "location.address.street", "type": "string"},
{"name": "name\\.first", "type": "string"},
]
def test_basic(self):
docs = self.db.find({"age": 22})
assert len(docs) == 1
assert docs[0]["user_id"] == 9
def test_multi_field(self):
docs = self.db.find({"age": 22, "manager": True})
assert len(docs) == 1
assert docs[0]["user_id"] == 9
docs = self.db.find({"age": 22, "manager": False})
assert len(docs) == 0
def test_element_acess(self):
docs = self.db.find({"favorites.0": "Ruby"})
assert len(docs) == 3
for d in docs:
assert "Ruby" in d["favorites"]
# This should throw an exception because we only index the array
# favorites.[], and not the string field favorites
def test_index_selection(self):
try:
self.db.find(
{"selector": {"$or": [{"favorites": "Ruby"}, {"favorites.0": "Ruby"}]}}
)
except Exception as e:
assert e.response.status_code == 400
def test_in_with_array(self):
vals = ["Lisp", "Python"]
docs = self.db.find({"favorites": {"$in": vals}})
assert len(docs) == 10
def test_in_with_array_not_explicit(self):
agelist = [22, 51]
statelist = ["New Hampshire"]
docs = self.db.find({"age": {"$in": agelist}})
docs2 = self.db.find({"location.state": {"$in": statelist}})
docs3 = self.db.find({"age": {"$in": statelist}})
assert len(docs) == 2
assert len(docs2) == 1
assert len(docs3) == 0
# This should also throw an error because we only indexed
# favorites.[] of type string. For the following query to work, the
# user has to index favorites.[] of type number, and also
# favorites.[].Versions.Alpha of type string.
def test_in_different_types(self):
vals = ["Random Garbage", 52, {"Versions": {"Alpha": "Beta"}}]
try:
self.db.find({"favorites": {"$in": vals}})
except Exception as e:
assert e.response.status_code == 400
def test_nin_with_array(self):
vals = ["Lisp", "Python"]
docs = self.db.find({"favorites": {"$nin": vals}})
assert len(docs) == 5
def test_missing(self):
self.db.find({"location.state": "Nevada"})
def test_missing_type(self):
# Raises an exception
try:
self.db.find({"age": "foo"})
raise Exception("Should have thrown an HTTPError")
except:
return
def test_field_analyzer_is_keyword(self):
docs = self.db.find({"location.state": "New"})
assert len(docs) == 0
docs = self.db.find({"location.state": "New Hampshire"})
assert len(docs) == 1
assert docs[0]["user_id"] == 10
# Since our FIELDS list only includes "name\\.first", we should
# get an error when we try to search for "name.first", since the index
# for that field does not exist.
def test_escaped_field(self):
docs = self.db.find({"name\\.first": "name dot first"})
assert len(docs) == 1
assert docs[0]["name.first"] == "name dot first"
try:
self.db.find({"name.first": "name dot first"})
raise Exception("Should have thrown an HTTPError")
except:
return
def test_filtered_search_fields(self):
docs = self.db.find({"age": 22}, fields=["age", "location.state"])
assert len(docs) == 1
assert docs == [{"age": 22, "location": {"state": "Missouri"}}]
docs = self.db.find({"age": 22}, fields=["age", "Random Garbage"])
assert len(docs) == 1
assert docs == [{"age": 22}]
docs = self.db.find({"age": 22}, fields=["favorites"])
assert len(docs) == 1
assert docs == [{"favorites": ["Lisp", "Erlang", "Python"]}]
docs = self.db.find({"age": 22}, fields=["favorites.[]"])
assert len(docs) == 1
assert docs == [{}]
docs = self.db.find({"age": 22}, fields=["all_fields"])
assert len(docs) == 1
assert docs == [{}]
def test_two_or(self):
docs = self.db.find(
{
"$or": [
{"location.state": "New Hampshire"},
{"location.state": "Don't Exist"},
]
}
)
assert len(docs) == 1
assert docs[0]["user_id"] == 10
def test_all_match(self):
docs = self.db.find({"favorites": {"$allMatch": {"$eq": "Erlang"}}})
assert len(docs) == 1
assert docs[0]["user_id"] == 10
@unittest.skipUnless(mango.has_text_service(), "requires text service")
class CustomFieldsExistsTest(mango.UserDocsTextTests):
FIELDS = [
{"name": "exists_field", "type": "string"},
{"name": "exists_array.[]", "type": "string"},
{"name": "exists_object.should", "type": "string"},
{"name": "twitter", "type": "string"},
]
def test_exists_field(self):
docs = self.db.find({"exists_field": {"$exists": True}})
self.assertEqual(len(docs), 2)
for d in docs:
self.assertIn(d["user_id"], (7, 8))
docs = self.db.find({"exists_field": {"$exists": False}})
self.assertEqual(len(docs), len(user_docs.DOCS) - 2)
for d in docs:
self.assertNotIn(d["user_id"], (7, 8))
def test_exists_array(self):
docs = self.db.find({"exists_array": {"$exists": True}})
self.assertEqual(len(docs), 2)
for d in docs:
self.assertIn(d["user_id"], (9, 10))
docs = self.db.find({"exists_array": {"$exists": False}})
self.assertEqual(len(docs), len(user_docs.DOCS) - 2)
for d in docs:
self.assertNotIn(d["user_id"], (9, 10))
def test_exists_object_member(self):
docs = self.db.find({"exists_object.should": {"$exists": True}})
self.assertEqual(len(docs), 1)
self.assertEqual(docs[0]["user_id"], 11)
docs = self.db.find({"exists_object.should": {"$exists": False}})
self.assertEqual(len(docs), len(user_docs.DOCS) - 1)
for d in docs:
self.assertNotEqual(d["user_id"], 11)
def test_exists_false_same_as_views(self):
docs = self.db.find({"twitter": {"$exists": False}})
for d in docs:
self.assertNotIn(d["user_id"], (0, 1, 4, 13))