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())
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" ])
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")
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")
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")
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())
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")
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)
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)