Example #1
0
class InstallUninstallTestBase(TestCase):
    @skipUnless(watson.get_backend().requires_installation,
                "search backend does not require installation")
    def testUninstallAndInstall(self):
        backend = watson.get_backend()
        call_command("uninstallwatson", verbosity=0)
        self.assertFalse(backend.is_installed())
        call_command("installwatson", verbosity=0)
        self.assertTrue(backend.is_installed())
Example #2
0
class RankingTest(SearchTestBase):
    def setUp(self):
        super(RankingTest, self).setUp()
        self.test11.title += " fooo baar fooo"
        self.test11.save()
        self.test12.content += " fooo baar"
        self.test12.save()

    def testRankingParamPresentOnSearch(self):
        self.assertGreater(watson.search("TITLE")[0].watson_rank, 0)

    def testRankingParamPresentOnFilter(self):
        self.assertGreater(
            watson.filter(WatsonTestModel1, "TITLE")[0].watson_rank, 0)

    def testRankingParamAbsentOnSearch(self):
        self.assertRaises(
            AttributeError,
            lambda: watson.search("TITLE", ranking=False)[0].watson_rank)

    def testRankingParamAbsentOnFilter(self):
        self.assertRaises(
            AttributeError, lambda: watson.filter(
                WatsonTestModel1, "TITLE", ranking=False)[0].watson_rank)

    @skipUnless(watson.get_backend().supports_ranking,
                "search backend does not support ranking")
    def testRankingWithSearch(self):
        self.assertEqual([entry.title for entry in watson.search("FOOO")], [
            "title model1 instance11 fooo baar fooo", "title model1 instance12"
        ])

    @skipUnless(watson.get_backend().supports_ranking,
                "search backend does not support ranking")
    def testRankingWithFilter(self):
        self.assertEqual(
            [entry.title for entry in watson.filter(WatsonTestModel1, "FOOO")],
            [
                "title model1 instance11 fooo baar fooo",
                "title model1 instance12"
            ])
Example #3
0
 def handle_noargs(self, **options):
     """Runs the management command."""
     verbosity = int(options.get("verbosity", 1))
     backend = get_backend()
     if not backend.requires_installation:
         if verbosity >= 2:
             self.stdout.write("Your search backend does not require installation.\n")
     elif backend.is_installed():
         backend.do_uninstall()
         if verbosity >= 2:
             self.stdout.write("django-watson has been successfully uninstalled.\n")
     else:
         if verbosity >= 2:
             self.stdout.write("django-watson is not installed.\n")
Example #4
0
 def handle_noargs(self, **options):
     """Runs the management command."""
     verbosity = int(options.get("verbosity", 1))
     backend = get_backend()
     if not backend.requires_installation:
         if verbosity >= 2:
             self.stdout.write("Your search backend does not require installation.\n")
     elif backend.is_installed():
         if verbosity >= 2:
             self.stdout.write("django-watson is already installed.\n")
     else:
         backend.do_install()
         if verbosity >= 2:
             self.stdout.write("django-watson has been successfully installed.\n")
Example #5
0
 def handle(self, *args, **options):
     """Runs the management command."""
     verbosity = int(options.get("verbosity", 1))
     backend = get_backend()
     schema_name = connection.tenant.schema_name
     if not backend.requires_installation:
         if verbosity >= 2:
             self.stdout.write(
                 "Your search backend does not require installation.\n")
     elif backend.is_installed(schema_name):
         backend.do_uninstall()
         if verbosity >= 2:
             self.stdout.write(
                 "django-watson has been successfully uninstalled.\n")
     else:
         if verbosity >= 2:
             self.stdout.write("django-watson is not installed.\n")
Example #6
0
 def testUninstallAndInstall(self):
     backend = watson.get_backend()
     call_command("uninstallwatson", verbosity=0)
     self.assertFalse(backend.is_installed())
     call_command("installwatson", verbosity=0)
     self.assertTrue(backend.is_installed())
Example #7
0
class SearchTest(SearchTestBase):
    def emptySearchTextGivesNoResults(self):
        self.assertEqual(watson.search("").count(), 0)
        self.assertEqual(watson.search(" ").count(), 0)

    def testMultiTableSearch(self):
        # Test a search that should get all models.
        self.assertEqual(watson.search("TITLE").count(), 4)
        self.assertEqual(watson.search("CONTENT").count(), 4)
        self.assertEqual(watson.search("DESCRIPTION").count(), 4)
        self.assertEqual(watson.search("TITLE CONTENT DESCRIPTION").count(), 4)
        # Test a search that should get two models.
        self.assertEqual(watson.search("MODEL1").count(), 2)
        self.assertEqual(watson.search("MODEL2").count(), 2)
        self.assertEqual(watson.search("TITLE MODEL1").count(), 2)
        self.assertEqual(watson.search("TITLE MODEL2").count(), 2)
        # Test a search that should get one model.
        self.assertEqual(watson.search("INSTANCE11").count(), 1)
        self.assertEqual(watson.search("INSTANCE21").count(), 1)
        self.assertEqual(watson.search("TITLE INSTANCE11").count(), 1)
        self.assertEqual(watson.search("TITLE INSTANCE21").count(), 1)
        # Test a search that should get zero models.
        self.assertEqual(watson.search("FOOO").count(), 0)
        self.assertEqual(watson.search("FOOO INSTANCE11").count(), 0)
        self.assertEqual(watson.search("MODEL2 INSTANCE11").count(), 0)

    def testSearchWithAccent(self):
        WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="content model1 instance13 café",
            description="description model1 instance13",
        )
        self.assertEqual(watson.search("café").count(), 1)

    def testSearchWithSpecialChars(self):
        WatsonTestModel1.objects.all().delete()

        x = WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="content model1 instance13 d'Argent",
            description="description model1 instance13",
        )
        self.assertEqual(watson.search("d'Argent").count(), 1)
        x.delete()

        x = WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="'content model1 instance13",
            description="description model1 instance13",
        )
        # Some database engines ignore leading apostrophes, some count them.
        self.assertTrue(watson.search("'content").exists())
        x.delete()

        x = WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="content model1 instance13 d'Argent",
            description="description abcd&efgh",
        )
        self.assertEqual(watson.search("abcd&efgh").count(), 1)
        x.delete()

        x = WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="content model1 instance13 d'Argent",
            description="description abcd.efgh",
        )
        self.assertEqual(watson.search("abcd.efgh").count(), 1)
        x.delete()

        x = WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="content model1 instance13 d'Argent",
            description="description abcd,efgh",
        )
        self.assertEqual(watson.search("abcd,efgh").count(), 1)
        x.delete()

        x = WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="content model1 instance13 d'Argent",
            description="description abcd@efgh",
        )
        self.assertEqual(watson.search("abcd@efgh").count(), 1)
        x.delete()

    @skipUnless(watson.get_backend().supports_prefix_matching,
                "Search backend does not support prefix matching.")
    def testMultiTablePrefixSearch(self):
        self.assertEqual(watson.search("DESCR").count(), 4)

    def testLimitedModelList(self):
        # Test a search that should get all models.
        self.assertEqual(
            watson.search("TITLE",
                          models=(WatsonTestModel1, WatsonTestModel2)).count(),
            4)
        # Test a search that should get two models.
        self.assertEqual(
            watson.search("MODEL1",
                          models=(WatsonTestModel1, WatsonTestModel2)).count(),
            2)
        self.assertEqual(
            watson.search("MODEL1", models=(WatsonTestModel1, )).count(), 2)
        self.assertEqual(
            watson.search("MODEL2",
                          models=(WatsonTestModel1, WatsonTestModel2)).count(),
            2)
        self.assertEqual(
            watson.search("MODEL2", models=(WatsonTestModel2, )).count(), 2)
        # Test a search that should get one model.
        self.assertEqual(
            watson.search("INSTANCE11",
                          models=(WatsonTestModel1, WatsonTestModel2)).count(),
            1)
        self.assertEqual(
            watson.search("INSTANCE11", models=(WatsonTestModel1, )).count(),
            1)
        self.assertEqual(
            watson.search("INSTANCE21",
                          models=(
                              WatsonTestModel1,
                              WatsonTestModel2,
                          )).count(), 1)
        self.assertEqual(
            watson.search("INSTANCE21", models=(WatsonTestModel2, )).count(),
            1)
        # Test a search that should get zero models.
        self.assertEqual(
            watson.search("MODEL1", models=(WatsonTestModel2, )).count(), 0)
        self.assertEqual(
            watson.search("MODEL2", models=(WatsonTestModel1, )).count(), 0)
        self.assertEqual(
            watson.search("INSTANCE21", models=(WatsonTestModel1, )).count(),
            0)
        self.assertEqual(
            watson.search("INSTANCE11", models=(WatsonTestModel2, )).count(),
            0)

    def testExcludedModelList(self):
        # Test a search that should get all models.
        self.assertEqual(watson.search("TITLE", exclude=()).count(), 4)
        # Test a search that should get two models.
        self.assertEqual(watson.search("MODEL1", exclude=()).count(), 2)
        self.assertEqual(
            watson.search("MODEL1", exclude=(WatsonTestModel2, )).count(), 2)
        self.assertEqual(watson.search("MODEL2", exclude=()).count(), 2)
        self.assertEqual(
            watson.search("MODEL2", exclude=(WatsonTestModel1, )).count(), 2)
        # Test a search that should get one model.
        self.assertEqual(watson.search("INSTANCE11", exclude=()).count(), 1)
        self.assertEqual(
            watson.search("INSTANCE11", exclude=(WatsonTestModel2, )).count(),
            1)
        self.assertEqual(watson.search("INSTANCE21", exclude=()).count(), 1)
        self.assertEqual(
            watson.search("INSTANCE21", exclude=(WatsonTestModel1, )).count(),
            1)
        # Test a search that should get zero models.
        self.assertEqual(
            watson.search("MODEL1", exclude=(WatsonTestModel1, )).count(), 0)
        self.assertEqual(
            watson.search("MODEL2", exclude=(WatsonTestModel2, )).count(), 0)
        self.assertEqual(
            watson.search("INSTANCE21", exclude=(WatsonTestModel2, )).count(),
            0)
        self.assertEqual(
            watson.search("INSTANCE11", exclude=(WatsonTestModel1, )).count(),
            0)

    def testLimitedModelQuerySet(self):
        # Test a search that should get all models.
        self.assertEqual(
            watson.search(
                "TITLE",
                models=(
                    WatsonTestModel1.objects.filter(title__icontains="TITLE"),
                    WatsonTestModel2.objects.filter(title__icontains="TITLE"),
                )).count(), 4)
        # Test a search that should get two models.
        self.assertEqual(
            watson.search("MODEL1",
                          models=(WatsonTestModel1.objects.filter(
                              title__icontains="MODEL1",
                              description__icontains="MODEL1",
                          ), )).count(), 2)
        self.assertEqual(
            watson.search("MODEL2",
                          models=(WatsonTestModel2.objects.filter(
                              title__icontains="MODEL2",
                              description__icontains="MODEL2",
                          ), )).count(), 2)
        # Test a search that should get one model.
        self.assertEqual(
            watson.search("INSTANCE11",
                          models=(WatsonTestModel1.objects.filter(
                              title__icontains="MODEL1", ), )).count(), 1)
        self.assertEqual(
            watson.search("INSTANCE21",
                          models=(WatsonTestModel2.objects.filter(
                              title__icontains="MODEL2", ), )).count(), 1)
        # Test a search that should get no models.
        self.assertEqual(
            watson.search("INSTANCE11",
                          models=(WatsonTestModel1.objects.filter(
                              title__icontains="MODEL2", ), )).count(), 0)
        self.assertEqual(
            watson.search("INSTANCE21",
                          models=(WatsonTestModel2.objects.filter(
                              title__icontains="MODEL1", ), )).count(), 0)

    def testExcludedModelQuerySet(self):
        # Test a search that should get all models.
        self.assertEqual(
            watson.search(
                "TITLE",
                exclude=(
                    WatsonTestModel1.objects.filter(title__icontains="FOOO"),
                    WatsonTestModel2.objects.filter(title__icontains="FOOO"),
                )).count(), 4)
        # Test a search that should get two models.
        self.assertEqual(
            watson.search("MODEL1",
                          exclude=(WatsonTestModel1.objects.filter(
                              title__icontains="INSTANCE21",
                              description__icontains="INSTANCE22",
                          ), )).count(), 2)
        self.assertEqual(
            watson.search("MODEL2",
                          exclude=(WatsonTestModel2.objects.filter(
                              title__icontains="INSTANCE11",
                              description__icontains="INSTANCE12",
                          ), )).count(), 2)
        # Test a search that should get one model.
        self.assertEqual(
            watson.search("INSTANCE11",
                          exclude=(WatsonTestModel1.objects.filter(
                              title__icontains="MODEL2", ), )).count(), 1)
        self.assertEqual(
            watson.search("INSTANCE21",
                          exclude=(WatsonTestModel2.objects.filter(
                              title__icontains="MODEL1", ), )).count(), 1)
        # Test a search that should get no models.
        self.assertEqual(
            watson.search("INSTANCE11",
                          exclude=(WatsonTestModel1.objects.filter(
                              title__icontains="MODEL1", ), )).count(), 0)
        self.assertEqual(
            watson.search("INSTANCE21",
                          exclude=(WatsonTestModel2.objects.filter(
                              title__icontains="MODEL2", ), )).count(), 0)

    def testKitchenSink(self):
        """For sanity, let's just test everything together in one giant search of doom!"""
        self.assertEqual(
            watson.search(
                "INSTANCE11",
                models=(
                    WatsonTestModel1.objects.filter(
                        title__icontains="INSTANCE11"),
                    WatsonTestModel2.objects.filter(title__icontains="TITLE"),
                ),
                exclude=(
                    WatsonTestModel1.objects.filter(title__icontains="MODEL2"),
                    WatsonTestModel2.objects.filter(title__icontains="MODEL1"),
                )).get().title, "title model1 instance11")
Example #8
0
class InternalsTest(SearchTestBase):
    def testSearchEntriesCreated(self):
        self.assertEqual(
            SearchEntry.objects.filter(engine_slug="default").count(), 4)

    def testBuildWatsonForModelCommand(self):
        # Hack a change into the model using a bulk update, which doesn't send signals.
        WatsonTestModel1.objects.filter(id=self.test11.id).update(
            title="fooo1_selective")
        WatsonTestModel2.objects.filter(id=self.test21.id).update(
            title="fooo2_selective")
        # Test that no update has happened.
        self.assertEqual(watson.search("fooo1_selective").count(), 0)
        self.assertEqual(watson.search("fooo2_selective").count(), 0)
        # Run the rebuild command.
        call_command("buildwatson",
                     "test_watson.WatsonTestModel1",
                     verbosity=0)
        # Test that the update is now applied to selected model.
        self.assertEqual(watson.search("fooo1_selective").count(), 1)
        self.assertEqual(watson.search("fooo2_selective").count(), 0)
        call_command("buildwatson",
                     "test_watson.WatsonTestModel1",
                     "test_watson.WatsonTestModel2",
                     verbosity=0)
        # Test that the update is now applied to multiple selected models.
        self.assertEqual(watson.search("fooo1_selective").count(), 1)
        self.assertEqual(watson.search("fooo2_selective").count(), 1)

    def testBuildWatsonCommand(self):
        # Hack a change into the model using a bulk update, which doesn't send signals.
        WatsonTestModel1.objects.filter(id=self.test11.id).update(
            title="fooo1")
        WatsonTestModel2.objects.filter(id=self.test21.id).update(
            title="fooo2")
        # Test that no update has happened.
        self.assertEqual(watson.search("fooo1").count(), 0)
        self.assertEqual(watson.search("fooo2").count(), 0)
        # Run the rebuild command.
        call_command("buildwatson", verbosity=0)
        # Test that the update is now applied.
        self.assertEqual(watson.search("fooo1").count(), 1)
        self.assertEqual(watson.search("fooo2").count(), 1)

    def testUpdateSearchIndex(self):
        # Update a model and make sure that the search results match.
        self.test11.title = "fooo"
        self.test11.save()
        # Test a search that should get one model.
        exact_search = watson.search("fooo")
        self.assertEqual(len(exact_search), 1)
        self.assertEqual(exact_search[0].title, "fooo")
        # Delete a model and make sure that the search results match.
        self.test11.delete()
        self.assertEqual(watson.search("fooo").count(), 0)

    def testSearchIndexUpdateDeferredByContext(self):
        with watson.update_index():
            self.test11.title = "fooo"
            self.test11.save()
            self.assertEqual(watson.search("fooo").count(), 0)
        self.assertEqual(watson.search("fooo").count(), 1)

    def testSearchIndexUpdateAbandonedOnError(self):
        try:
            with watson.update_index():
                self.test11.title = "fooo"
                self.test11.save()
                raise Exception("Foo")
        except:
            pass
        # Test a search that should get not model.
        self.assertEqual(watson.search("fooo").count(), 0)

    def testSkipSearchIndexUpdate(self):
        with watson.skip_index_update():
            self.test11.title = "fooo"
            self.test11.save()
        # Test a search that should get not model.
        self.assertEqual(watson.search("fooo").count(), 0)

    def testNestedSkipInUpdateContext(self):
        with watson.update_index():
            self.test21.title = "baar"
            self.test21.save()
            with watson.skip_index_update():
                self.test11.title = "fooo"
                self.test11.save()
        # We should get "baar", but not "fooo"
        self.assertEqual(watson.search("fooo").count(), 0)
        self.assertEqual(watson.search("baar").count(), 1)

    def testNestedUpdateInSkipContext(self):
        with watson.skip_index_update():
            self.test21.title = "baar"
            self.test21.save()
            with watson.update_index():
                self.test11.title = "fooo"
                self.test11.save()
        # We should get "fooo", but not "baar"
        self.assertEqual(watson.search("fooo").count(), 1)
        self.assertEqual(watson.search("baar").count(), 0)

    def testFixesDuplicateSearchEntries(self):
        search_entries = SearchEntry.objects.filter(engine_slug="default")
        # Duplicate a couple of search entries.
        for search_entry in search_entries.all()[:2]:
            search_entry.id = None
            search_entry.save()
        # Make sure that we have six (including duplicates).
        self.assertEqual(search_entries.all().count(), 6)
        # Run the rebuild command.
        call_command("buildwatson", verbosity=0)
        # Make sure that we have four again (including duplicates).
        self.assertEqual(search_entries.all().count(), 4)

    def testEmptyFilterGivesAllResults(self):
        for model in (WatsonTestModel1, WatsonTestModel2):
            self.assertEqual(watson.filter(model, "").count(), 2)
            self.assertEqual(watson.filter(model, " ").count(), 2)

    def testFilter(self):
        for model in (WatsonTestModel1, WatsonTestModel2):
            # Test can find all.
            self.assertEqual(watson.filter(model, "TITLE").count(), 2)
        # Test can find a specific one.
        obj = watson.filter(WatsonTestModel1, "INSTANCE12").get()
        self.assertTrue(isinstance(obj, WatsonTestModel1))
        self.assertEqual(obj.title, "title model1 instance12")
        # Test can do filter on a queryset.
        obj = watson.filter(
            WatsonTestModel1.objects.filter(title__icontains="TITLE"),
            "INSTANCE12").get()
        self.assertTrue(isinstance(obj, WatsonTestModel1))
        self.assertEqual(obj.title, "title model1 instance12")

    @skipUnless(watson.get_backend().supports_prefix_matching,
                "Search backend does not support prefix matching.")
    def testPrefixFilter(self):
        self.assertEqual(watson.filter(WatsonTestModel1, "INSTAN").count(), 2)
Example #9
0
class SearchTest(SearchTestBase):

    def testEscaping(self):
        # This must not crash the database with a syntax error.
        list(watson.search(string.printable))

    def emptySearchTextGivesNoResults(self):
        self.assertEqual(watson.search("").count(), 0)
        self.assertEqual(watson.search(" ").count(), 0)

    def testMultiTableSearch(self):
        # Test a search that should get all models.
        self.assertEqual(watson.search("TITLE").count(), 6)
        self.assertEqual(watson.search("CONTENT").count(), 6)
        self.assertEqual(watson.search("DESCRIPTION").count(), 6)
        self.assertEqual(watson.search("TITLE CONTENT DESCRIPTION").count(), 6)
        # Test a search that should get two models.
        self.assertEqual(watson.search("MODEL1").count(), 2)
        self.assertEqual(watson.search("MODEL2").count(), 2)
        self.assertEqual(watson.search("MODEL3").count(), 2)
        self.assertEqual(watson.search("TITLE MODEL1").count(), 2)
        self.assertEqual(watson.search("TITLE MODEL2").count(), 2)
        self.assertEqual(watson.search("TITLE MODEL3").count(), 2)
        # Test a search that should get one model.
        self.assertEqual(watson.search("INSTANCE11").count(), 1)
        self.assertEqual(watson.search("INSTANCE21").count(), 1)
        self.assertEqual(watson.search("INSTANCE31").count(), 1)
        self.assertEqual(watson.search("TITLE INSTANCE11").count(), 1)
        self.assertEqual(watson.search("TITLE INSTANCE21").count(), 1)
        self.assertEqual(watson.search("TITLE INSTANCE31").count(), 1)
        # Test a search that should get zero models.
        self.assertEqual(watson.search("FOOO").count(), 0)
        self.assertEqual(watson.search("FOOO INSTANCE11").count(), 0)
        self.assertEqual(watson.search("MODEL2 INSTANCE11").count(), 0)

    def testSearchWithAccent(self):
        WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="content model1 instance13 café",
            description="description model1 instance13",
        )
        self.assertEqual(watson.search("café").count(), 1)

    def testSearchWithSpecialChars(self):
        WatsonTestModel1.objects.all().delete()

        x = WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="content model1 instance13 d'Argent",
            description="description model1 instance13",
        )
        self.assertEqual(watson.search("d'Argent").count(), 1)
        x.delete()

        x = WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="'content model1 instance13",
            description="description model1 instance13",
        )
        # Some database engines ignore leading apostrophes, some count them.
        self.assertTrue(watson.search("'content").exists())
        x.delete()

        x = WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="content model1 instance13 d'Argent",
            description="description abcd&efgh",
        )
        self.assertEqual(watson.search("abcd&efgh").count(), 1)
        x.delete()

        x = WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="content model1 instance13 d'Argent",
            description="description abcd.efgh",
        )
        self.assertEqual(watson.search("abcd.efgh").count(), 1)
        x.delete()

        x = WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="content model1 instance13 d'Argent",
            description="description abcd,efgh",
        )
        self.assertEqual(watson.search("abcd,efgh").count(), 1)
        x.delete()

        x = WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="content model1 instance13 d'Argent",
            description="description abcd@efgh",
        )
        self.assertEqual(watson.search("abcd@efgh").count(), 1)
        x.delete()

    @skipUnless(
        watson.get_backend().supports_prefix_matching,
        "Search backend does not support prefix matching."
    )
    def testMultiTablePrefixSearch(self):
        self.assertEqual(watson.search("DESCR").count(), 6)

    def testLimitedModelList(self):
        # Test a search that should get all models.
        self.assertEqual(watson.search("TITLE", models=(WatsonTestModel1, WatsonTestModel2)).count(), 4)
        # Test a search that should get two models.
        self.assertEqual(watson.search("MODEL1", models=(WatsonTestModel1, WatsonTestModel2)).count(), 2)
        self.assertEqual(watson.search("MODEL1", models=(WatsonTestModel1,)).count(), 2)
        self.assertEqual(watson.search("MODEL2", models=(WatsonTestModel1, WatsonTestModel2)).count(), 2)
        self.assertEqual(watson.search("MODEL2", models=(WatsonTestModel2,)).count(), 2)
        self.assertEqual(watson.search("MODEL3", models=(WatsonTestModel2, WatsonTestModel3)).count(), 2)
        self.assertEqual(watson.search("MODEL3", models=(WatsonTestModel3,)).count(), 2)
        # Test a search that should get one model.
        self.assertEqual(watson.search("INSTANCE11", models=(WatsonTestModel1, WatsonTestModel2)).count(), 1)
        self.assertEqual(watson.search("INSTANCE11", models=(WatsonTestModel1,)).count(), 1)
        self.assertEqual(watson.search("INSTANCE21", models=(WatsonTestModel1, WatsonTestModel2,)).count(), 1)
        self.assertEqual(watson.search("INSTANCE21", models=(WatsonTestModel2,)).count(), 1)
        self.assertEqual(watson.search("INSTANCE31", models=(WatsonTestModel2, WatsonTestModel3,)).count(), 1)
        self.assertEqual(watson.search("INSTANCE31", models=(WatsonTestModel3,)).count(), 1)
        # Test a search that should get zero models.
        self.assertEqual(watson.search("MODEL1", models=(WatsonTestModel2,)).count(), 0)
        self.assertEqual(watson.search("MODEL2", models=(WatsonTestModel1,)).count(), 0)
        self.assertEqual(watson.search("INSTANCE21", models=(WatsonTestModel1,)).count(), 0)
        self.assertEqual(watson.search("INSTANCE11", models=(WatsonTestModel2,)).count(), 0)

    def testExcludedModelList(self):
        # Test a search that should get all models.
        self.assertEqual(watson.search("TITLE", exclude=()).count(), 6)
        # Test a search that should get two models.
        self.assertEqual(watson.search("MODEL1", exclude=()).count(), 2)
        self.assertEqual(watson.search("MODEL1", exclude=(WatsonTestModel2,)).count(), 2)
        self.assertEqual(watson.search("MODEL2", exclude=()).count(), 2)
        self.assertEqual(watson.search("MODEL2", exclude=(WatsonTestModel1,)).count(), 2)
        self.assertEqual(watson.search("MODEL3", exclude=()).count(), 2)
        self.assertEqual(watson.search("MODEL3", exclude=(WatsonTestModel1,)).count(), 2)
        # Test a search that should get one model.
        self.assertEqual(watson.search("INSTANCE11", exclude=()).count(), 1)
        self.assertEqual(watson.search("INSTANCE11", exclude=(WatsonTestModel2,)).count(), 1)
        self.assertEqual(watson.search("INSTANCE21", exclude=()).count(), 1)
        self.assertEqual(watson.search("INSTANCE21", exclude=(WatsonTestModel1,)).count(), 1)
        self.assertEqual(watson.search("INSTANCE31", exclude=()).count(), 1)
        self.assertEqual(watson.search("INSTANCE31", exclude=(WatsonTestModel1,)).count(), 1)
        # Test a search that should get zero models.
        self.assertEqual(watson.search("MODEL1", exclude=(WatsonTestModel1,)).count(), 0)
        self.assertEqual(watson.search("MODEL2", exclude=(WatsonTestModel2,)).count(), 0)
        self.assertEqual(watson.search("INSTANCE21", exclude=(WatsonTestModel2,)).count(), 0)
        self.assertEqual(watson.search("INSTANCE11", exclude=(WatsonTestModel1,)).count(), 0)

    def testLimitedModelQuerySet(self):
        # Test a search that should get all models.
        self.assertEqual(watson.search(
            "TITLE",
            models=(
                WatsonTestModel1.objects.filter(title__icontains="TITLE"),
                WatsonTestModel2.objects.filter(title__icontains="TITLE"),
            )
        ).count(), 4)
        # Test a search that should get two models.
        self.assertEqual(
            watson.search(
                "MODEL1",
                models=(WatsonTestModel1.objects.filter(
                    title__icontains="MODEL1",
                    description__icontains="MODEL1",
                ),)
            ).count(), 2)
        self.assertEqual(watson.search("MODEL2", models=(WatsonTestModel2.objects.filter(
            title__icontains="MODEL2",
            description__icontains="MODEL2",
        ),)).count(), 2)
        self.assertEqual(watson.search("MODEL3", models=(WatsonTestModel3.objects.filter(
            title__icontains="MODEL3",
            description__icontains="MODEL3",
        ),)).count(), 2)
        # Test a search that should get one model.
        self.assertEqual(watson.search("INSTANCE11", models=(WatsonTestModel1.objects.filter(
            title__icontains="MODEL1",
        ),)).count(), 1)
        self.assertEqual(watson.search("INSTANCE21", models=(WatsonTestModel2.objects.filter(
            title__icontains="MODEL2",
        ),)).count(), 1)
        self.assertEqual(watson.search("INSTANCE31", models=(WatsonTestModel3.objects.filter(
            title__icontains="MODEL3",
        ),)).count(), 1)
        # Test a search that should get no models.
        self.assertEqual(watson.search("INSTANCE11", models=(WatsonTestModel1.objects.filter(
            title__icontains="MODEL2",
        ),)).count(), 0)
        self.assertEqual(watson.search("INSTANCE21", models=(WatsonTestModel2.objects.filter(
            title__icontains="MODEL1",
        ),)).count(), 0)

    def testExcludedModelQuerySet(self):
        # Test a search that should get all models.
        self.assertEqual(
            watson.search(
                "TITLE",
                exclude=(
                    WatsonTestModel1.objects.filter(title__icontains="FOOO"),
                    WatsonTestModel2.objects.filter(title__icontains="FOOO"),)
            ).count(), 6)
        # Test a search that should get two models.
        self.assertEqual(watson.search("MODEL1", exclude=(WatsonTestModel1.objects.filter(
            title__icontains="INSTANCE21",
            description__icontains="INSTANCE22",
        ),)).count(), 2)
        self.assertEqual(watson.search("MODEL2", exclude=(WatsonTestModel2.objects.filter(
            title__icontains="INSTANCE11",
            description__icontains="INSTANCE12",
        ),)).count(), 2)
        self.assertEqual(watson.search("MODEL3", exclude=(WatsonTestModel3.objects.filter(
            title__icontains="INSTANCE11",
            description__icontains="INSTANCE12",
        ),)).count(), 2)
        # Test a search that should get one model.
        self.assertEqual(watson.search("INSTANCE11", exclude=(WatsonTestModel1.objects.filter(
            title__icontains="MODEL2",
        ),)).count(), 1)
        self.assertEqual(watson.search("INSTANCE21", exclude=(WatsonTestModel2.objects.filter(
            title__icontains="MODEL1",
        ),)).count(), 1)
        self.assertEqual(watson.search("INSTANCE21", exclude=(WatsonTestModel3.objects.filter(
            title__icontains="MODEL1",
        ),)).count(), 1)
        # Test a search that should get no models.
        self.assertEqual(watson.search("INSTANCE11", exclude=(WatsonTestModel1.objects.filter(
            title__icontains="MODEL1",
        ),)).count(), 0)
        self.assertEqual(watson.search("INSTANCE21", exclude=(WatsonTestModel2.objects.filter(
            title__icontains="MODEL2",
        ),)).count(), 0)

    def testKitchenSink(self):
        """For sanity, let's just test everything together in one giant search of doom!"""
        self.assertEqual(watson.search(
            "INSTANCE11",
            models=(
                WatsonTestModel1.objects.filter(title__icontains="INSTANCE11"),
                WatsonTestModel2.objects.filter(title__icontains="TITLE"),
            ),
            exclude=(
                WatsonTestModel1.objects.filter(title__icontains="MODEL2"),
                WatsonTestModel2.objects.filter(title__icontains="MODEL1"),
            )
        ).get().title, "title model1 instance11")

    def testReferencingWatsonRankInAnnotations(self):
        """We should be able to reference watson_rank from annotate expressions"""
        entries = watson.search("model1").annotate(
            relevant=Case(
                When(watson_rank__gt=1.0, then=Value(1)),
                default_value=Value(0),
                output_field=IntegerField()
            )
        )

        # watson_rank does not return the same value across backends, so we
        # can't hard code what those will be. In some cases (e.g. the regex
        # backend) all ranking is hard coded to 1.0. That doesn't matter - we
        # just want to make sure that Django is able to construct a valid query
        for entry in entries:
            if entry.watson_rank > 1.0:
                self.assertTrue(entry.relevant)
            else:
                self.assertFalse(entry.relevant)
Example #10
0
 def testUninstallAndInstall(self):
     backend = watson.get_backend()
     call_command("uninstallwatson", verbosity=0)
     self.assertFalse(backend.is_installed())
     call_command("installwatson", verbosity=0)
     self.assertTrue(backend.is_installed())