class TestFilter(filters.BaseSearchFilter):
    id = fields.IntegerSearchField("id", default=True)
    title = fields.SearchField("title", field_lookup="icontains")
    email = fields.SearchField("user__email",
                               default=True,
                               aliases="@",
                               validators=lambda x: not x.isdigit())
    contributor = fields.SearchField("contributors__display_name")
    def test_field_lookup__chained(self):
        field = fields.SearchField("pk", field_lookup="month__gte")
        self.assertEqual(field.field_lookup, "month__gte")

        field = fields.SearchField("pk", field_lookup="jazz__gte")
        self.assertEqual(field.field_lookup, "icontains")

        field = fields.SearchField("pk", field_lookup="hour__jazz")
        self.assertEqual(field.field_lookup, "icontains")
    def test_field_lookup(self):
        field = fields.SearchField("pk")
        self.assertEqual(field.field_lookup, "icontains")

        field = fields.SearchField("pk", field_lookup="regex")
        self.assertEqual(field.field_lookup, "regex")

        field = fields.SearchField("pk", field_lookup="jazz")
        self.assertEqual(field.field_lookup, "icontains")
    def test_base(self):
        """base test, no extra frills"""
        field = fields.SearchField("pk")
        self.assertEqual(field.field_name, "pk")
        self.assertEqual(field.field_lookup, "icontains")
        self.assertEqual(field.constructed, "pk__icontains")
        self.assertEqual(field.default, False)
        self.assertEqual(field._validators, [])

        field = fields.SearchField("pk",
                                   field_lookup="exact",
                                   default=True,
                                   validators=validators.validate_list)
        self.assertEqual(field.field_name, "pk")
        self.assertEqual(field.field_lookup, "exact")
        self.assertEqual(field.constructed, "pk__exact")
        self.assertEqual(field.default, True)
        self.assertEqual(field._validators, [validators.validate_list])
    def test_validators(self):
        # no validators
        field = fields.SearchField("pk")
        self.assertTrue(isinstance(field._validators, list))
        self.assertEqual(len(field._validators), 0)
        self.assertTrue(field.is_valid("this will always pass"))

        # if a validator returns a bad result
        field = fields.SearchField(
            "pk", validators=[lambda x: True, lambda x: False])
        self.assertTrue(isinstance(field._validators, list))
        self.assertEqual(len(field._validators), 2)
        self.assertFalse(field.is_valid("this will always fail"))

        # a test with a real validator
        field = fields.SearchField("pk",
                                   validators=validators.validate_numerical)
        self.assertTrue(isinstance(field._validators, list))
        self.assertEqual(len(field._validators), 1)
        self.assertTrue(field.is_valid("9780123456789"))
        self.assertFalse(field.is_valid("abcdef"))
    def test_constructed(self):
        field = fields.SearchField("pk")
        expected_constructed = "pk__icontains"
        self.assertEqual(field._constructed, None)
        self.assertEqual(field.constructed, expected_constructed)
        self.assertEqual(field._constructed, expected_constructed)

        # test if no field_lookup
        field = fields.SearchField("pk")
        expected_constructed = "pk"
        self.assertEqual(field._constructed, None)
        with patch.object(field, "field_lookup", new=None):
            self.assertEqual(field.constructed, expected_constructed)
        self.assertEqual(field._constructed, expected_constructed)

        # test if empty field lookup
        field = fields.SearchField("pk")
        expected_constructed = "pk"
        self.assertEqual(field._constructed, None)
        with patch.object(field, "field_lookup", new=""):
            self.assertEqual(field.constructed, expected_constructed)
        self.assertEqual(field._constructed, expected_constructed)
 def test_get_search_fields(self):
     attrs = [("field1", fields.SearchField("pk",
                                            field_lookup="istartswith")),
              ("field2",
               fields.ExactSearchField("name",
                                       match_case=False,
                                       default=True)),
              ("field3", fields.ExactSearchField("something"))]
     search_fields = filters.SearchFilterMetaclass._get_search_fields(
         (), dict(attrs))
     self.assertEqual(len(search_fields), 3)
     expected_fields = ["field2", "field3", "field1"]
     self.assertEqual(list(search_fields.keys()), expected_fields)
    def test_get_search_fields__with_aliases(self):
        test_fields = {
            "field1":
            fields.SearchField("pk", field_lookup="istartswith", aliases="f1"),
            "field2":
            fields.ExactSearchField("name", match_case=False, default=True),
            "field3":
            fields.ExactSearchField("something", aliases=["f3"])
        }

        attrs = [("field1", test_fields["field1"]),
                 ("field2", test_fields["field2"]),
                 ("field3", test_fields["field3"])]
        search_fields = filters.SearchFilterMetaclass._get_search_fields(
            (), dict(attrs))
        self.assertEqual(len(search_fields), 5)

        expected_fields = ["field2", "field3", "f3", "field1", "f1"]
        self.assertEqual(list(search_fields.keys()), expected_fields)
    def test_get_search_fields__with_bases__with_aliases(self):
        test_fields = {
            "fieldA":
            fields.IntegerSearchField("id", aliases="fa"),
            "fieldB":
            fields.RegexSearchField("title", aliases="fb"),
            "fieldZ":
            fields.BooleanSearchField("active"),
            "field1":
            fields.SearchField("pk", field_lookup="istartswith"),
            "field2":
            fields.ExactSearchField("name", match_case=False, default=True),
            "sharedfield":
            fields.ExactSearchField("something", aliases=["s"])
        }

        class Example(object):
            _search_fields = [("fieldA", test_fields["fieldA"]),
                              ("fieldB", test_fields["fieldB"]),
                              ("sharedfield", test_fields["sharedfield"])]

        class Example2(object):
            _search_fields = [("fieldZ", test_fields["fieldZ"]),
                              ("fieldB", test_fields["fieldB"]),
                              ("sharedfield", test_fields["sharedfield"])]

        bases = (Example, Example2)
        attrs = [("field1", test_fields["field1"]),
                 ("field2", test_fields["field2"]),
                 ("sharedfield", test_fields["sharedfield"])]
        search_fields = filters.SearchFilterMetaclass._get_search_fields(
            bases, dict(attrs))
        self.assertEqual(len(search_fields), 9)

        expected_fields = [
            "fieldA", "fa", "fieldZ", "fieldB", "fb", "field2", "field1",
            "sharedfield", "s"
        ]
        self.assertEqual(list(search_fields.keys()), expected_fields)