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(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(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"] )
class InstallUninstallTestBase(TestCase): @skipUnless(get_backend().requires_installation, "search backend does not require installation") def testUninstallAndInstall(self): backend = get_backend() call_command("uninstallwatson", verbosity=0) self.assertFalse(backend.is_installed()) call_command("installwatson", verbosity=0) self.assertTrue(backend.is_installed())
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")
class InstallUninstallTestBase(TestCase): def testUninstallAndInstall(self): # Not too much to test here, as some backends don't require installation. # Just make sure the commands don't error. call_command("uninstallwatson", verbosity=0) call_command("installwatson", verbosity=0) @skipUnless(get_backend().requires_installation, "search backend does not require installation") def testRealInstallAndUninstall(self): backend = get_backend() call_command("uninstallwatson", verbosity=0) self.assertFalse(backend.is_installed()) call_command("installwatson", verbosity=0) self.assertTrue(backend.is_installed())
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 testUninstallAndInstall(self): backend = 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) @skipUnless(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 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="fooo") # Test that no update has happened. self.assertEqual(watson.search("fooo").count(), 0) # Run the rebuild command. call_command("buildwatson", verbosity=0) # Test that the update is now applies. self.assertEqual(watson.search("fooo").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 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(get_backend().supports_prefix_matching, "Search backend does not support prefix matching.") def testPrefixFilter(self): self.assertEqual(watson.filter(WatsonTestModel1, "INSTAN").count(), 2)
def testRealInstallAndUninstall(self): backend = 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 testSearchWithApostrophe(self): 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) def testSearchWithLeadingApostrophe(self): WatsonTestModel1.objects.create( title="title model1 instance12", content="'content model1 instance13", description="description model1 instance13", ) self.assertTrue( watson.search("'content").exists() ) # Some database engines ignore leading apostrophes, some count them. @skipUnless(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")