<commit_before>"""Tests for django-watson."""

from django.db import models
from django.test import TestCase
from django.core.management import call_command

from watson.registration import register, unregister, is_registered, get_registered_models, get_adapter, RegistrationError, SearchAdapter, search_context_manager, get_backend


class TestModelBase(models.Model):

    title = models.CharField(
        max_length = 200,
    )
    
    content = models.TextField(
        blank = True,
    )
    
    description = models.TextField(
        blank = True,
    )
    
    def __unicode__(self):
        return self.title

    class Meta:
        abstract = True
        app_label = "auth"  # Hack: Cannot use an app_label that is under South control, due to http://south.aeracode.org/ticket/520
        
        
class TestModel1(TestModelBase):

    pass


str_pk_gen = 0;

def get_str_pk():
    global str_pk_gen
    str_pk_gen += 1;
    return str(str_pk_gen)
    
    
class TestModel2(TestModelBase):

    id = models.CharField(
        primary_key = True,
        max_length = 100,
        default = get_str_pk
    )


class RegistrationText(TestCase):
    
    def testRegistration(self):
        # Register the model and test.
        register(TestModel1)
        self.assertTrue(is_registered(TestModel1))
        self.assertRaises(RegistrationError, lambda: register(TestModel1))
        self.assertEqual(get_registered_models(), [TestModel1])
        self.assertTrue(isinstance(get_adapter(TestModel1), SearchAdapter))
        # Unregister the model and text.
        unregister(TestModel1)
        self.assertFalse(is_registered(TestModel1))
        self.assertRaises(RegistrationError, lambda: unregister(TestModel1))
        self.assertEqual(get_registered_models(), [])
        self.assertRaises(RegistrationError, lambda: isinstance(get_adapter(TestModel1)))
        
        
class SearchTest(TestCase):
    
    search_adaptor = SearchAdapter
    
    @search_context_manager.update_index
    def setUp(self):
        register(TestModel1, self.search_adaptor)
        register(TestModel2, self.search_adaptor)
        # Create some test models.
        self.test11 = TestModel1.objects.create(
            title = "title model1 11",
            content = "content model1 11",
            description = "description model1 11",
        )
        self.test12 = TestModel1.objects.create(
            title = "title model1 12",
            content = "content model1 12",
            description = "description model1 12",
        )
        self.test21 = TestModel2.objects.create(
            title = "title model2 21",
            content = "content model2 21",
            description = "description model2 21",
        )
        self.test22 = TestModel2.objects.create(
            title = "title model2 22",
            content = "content model2 22",
            description = "description model2 22",
        )
    
    def testMultiTableSearch(self):
        backend = get_backend()
        # Test a search that should get all models.
        self.assertEqual(backend.search("tItle Content Description").count(), 4)
        # Test a search that should get two models.
        self.assertEqual(backend.search("mOdel1").count(), 2)
        # Test a search that should get one model.
        exact_search = backend.search("11")
        self.assertEqual(len(exact_search), 1)
        self.assertEqual(exact_search[0].meta["title"], "title model1 11")
    
    def testUpdateSearchIndex(self):
        backend = get_backend()
        # Update a model and make sure that the search results match.
        with search_context_manager.context():
            self.test11.title = "foo"
            self.test11.save()
        # Test a search that should get one model.
        exact_search = backend.search("foo")
        self.assertEqual(len(exact_search), 1)
        self.assertEqual(exact_search[0].meta["title"], "foo")
    
    def testLimitedModelList(self):
        backend = get_backend()
        # Test a search that should get all models.
        self.assertEqual(backend.search("tItle Content Description", models=(TestModel1,)).count(), 2)
        # Test a search that should get one model.
        exact_search = backend.search("11", models=(TestModel1,))
        self.assertEqual(len(exact_search), 1)
        self.assertEqual(exact_search[0].meta["title"], "title model1 11")
        # Test a search that should get no models.
        self.assertEqual(backend.search("11", models=(TestModel2,)).count(), 0)
        
    def testExcludedModelList(self):
        backend = get_backend()
        # Test a search that should get all models.
        self.assertEqual(backend.search("tItle Content Description", exclude=(TestModel2,)).count(), 2)
        # Test a search that should get one model.
        exact_search = backend.search("11", exclude=(TestModel2,))
        self.assertEqual(len(exact_search), 1)
        self.assertEqual(exact_search[0].meta["title"], "title model1 11")
        # Test a search that should get no models.
        self.assertEqual(backend.search("11", exclude=(TestModel1,)).count(), 0)
    
    def testRebuildWatsonCommand(self):
        backend = get_backend()
        # This update won't take affect, because no search context is active.
        self.test11.title = "foo"
        self.test11.save()
        # Test that no update has happened.
        self.assertEqual(backend.search("foo").count(), 0)
        # Run the rebuild command.
        call_command("rebuildwatson")
        # Test that the update is now applies.
        self.assertEqual(backend.search("foo").count(), 1)
        
    def tearDown(self):
        unregister(TestModel1)
        unregister(TestModel2)
        # Delete the test models.
        TestModel1.objects.all().delete()
        TestModel2.objects.all().delete()
        del self.test11
        del self.test12
        del self.test21
        del self.test22


class LiveFilterSearchAdapter(SearchAdapter):

    live_filter = True
        
        
class LiveFilterSearchTest(SearchTest):

    search_adaptor = LiveFilterSearchAdapter<commit_msg>Fixing error with test model primary key being included in search.<commit_after>"""Tests for django-watson."""

from django.db import models
from django.test import TestCase
from django.core.management import call_command

from watson.registration import register, unregister, is_registered, get_registered_models, get_adapter, RegistrationError, SearchAdapter, search_context_manager, get_backend
from watson.models import SearchEntry


class TestModelBase(models.Model):

    title = models.CharField(
        max_length = 200,
    )
    
    content = models.TextField(
        blank = True,
    )
    
    description = models.TextField(
        blank = True,
    )
    
    def __unicode__(self):
        return self.title

    class Meta:
        abstract = True
        app_label = "auth"  # Hack: Cannot use an app_label that is under South control, due to http://south.aeracode.org/ticket/520
        
        
class TestModel1(TestModelBase):

    pass


str_pk_gen = 0;

def get_str_pk():
    global str_pk_gen
    str_pk_gen += 1;
    return str(str_pk_gen)
    
    
class TestModel2(TestModelBase):

    id = models.CharField(
        primary_key = True,
        max_length = 100,
        default = get_str_pk
    )
    
    
class TestModel2SearchAdapter(SearchAdapter):

    exclude = ("id",)


class RegistrationText(TestCase):
    
    def testRegistration(self):
        # Register the model and test.
        register(TestModel1)
        self.assertTrue(is_registered(TestModel1))
        self.assertRaises(RegistrationError, lambda: register(TestModel1))
        self.assertEqual(get_registered_models(), [TestModel1])
        self.assertTrue(isinstance(get_adapter(TestModel1), SearchAdapter))
        # Unregister the model and text.
        unregister(TestModel1)
        self.assertFalse(is_registered(TestModel1))
        self.assertRaises(RegistrationError, lambda: unregister(TestModel1))
        self.assertEqual(get_registered_models(), [])
        self.assertRaises(RegistrationError, lambda: isinstance(get_adapter(TestModel1)))
        
        
class SearchTest(TestCase):
    
    search_adapter_1 = SearchAdapter
    
    search_adapter_2 = TestModel2SearchAdapter
    
    @search_context_manager.update_index
    def setUp(self):
        register(TestModel1, self.search_adapter_1)
        register(TestModel2, self.search_adapter_2)
        # Create some test models.
        self.test11 = TestModel1.objects.create(
            title = "title model1 11",
            content = "content model1 11",
            description = "description model1 11",
        )
        self.test12 = TestModel1.objects.create(
            title = "title model1 12",
            content = "content model1 12",
            description = "description model1 12",
        )
        self.test21 = TestModel2.objects.create(
            title = "title model2 21",
            content = "content model2 21",
            description = "description model2 21",
        )
        self.test22 = TestModel2.objects.create(
            title = "title model2 22",
            content = "content model2 22",
            description = "description model2 22",
        )
    
    def testMultiTableSearch(self):
        backend = get_backend()
        # Test a search that should get all models.
        self.assertEqual(backend.search("tItle Content Description").count(), 4)
        # Test a search that should get two models.
        self.assertEqual(backend.search("mOdel1").count(), 2)
        # Test a search that should get one model.
        exact_search = backend.search("11")
        self.assertEqual(len(exact_search), 1)
        self.assertEqual(exact_search[0].meta["title"], "title model1 11")
    
    def testUpdateSearchIndex(self):
        backend = get_backend()
        # Update a model and make sure that the search results match.
        with search_context_manager.context():
            self.test11.title = "foo"
            self.test11.save()
        # Test a search that should get one model.
        exact_search = backend.search("foo")
        self.assertEqual(len(exact_search), 1)
        self.assertEqual(exact_search[0].meta["title"], "foo")
    
    def testLimitedModelList(self):
        backend = get_backend()
        # Test a search that should get all models.
        self.assertEqual(backend.search("tItle Content Description", models=(TestModel1,)).count(), 2)
        # Test a search that should get one model.
        exact_search = backend.search("11", models=(TestModel1,))
        self.assertEqual(len(exact_search), 1)
        self.assertEqual(exact_search[0].meta["title"], "title model1 11")
        # Test a search that should get no models.
        self.assertEqual(backend.search("11", models=(TestModel2,)).count(), 0)
        
    def testExcludedModelList(self):
        backend = get_backend()
        # Test a search that should get all models.
        self.assertEqual(backend.search("tItle Content Description", exclude=(TestModel2,)).count(), 2)
        # Test a search that should get one model.
        exact_search = backend.search("11", exclude=(TestModel2,))
        self.assertEqual(len(exact_search), 1)
        self.assertEqual(exact_search[0].meta["title"], "title model1 11")
        # Test a search that should get no models.
        self.assertEqual(backend.search("11", exclude=(TestModel1,)).count(), 0)
            
    def testRebuildWatsonCommand(self):
        backend = get_backend()
        # This update won't take affect, because no search context is active.
        self.test11.title = "foo"
        self.test11.save()
        # Test that no update has happened.
        self.assertEqual(backend.search("foo").count(), 0)
        # Run the rebuild command.
        call_command("rebuildwatson")
        # Test that the update is now applies.
        self.assertEqual(backend.search("foo").count(), 1)
        
    def tearDown(self):
        unregister(TestModel1)
        unregister(TestModel2)
        # Delete the test models.
        TestModel1.objects.all().delete()
        TestModel2.objects.all().delete()
        del self.test11
        del self.test12
        del self.test21
        del self.test22
        # Delete the search index.
        SearchEntry.objects.all().delete()


class LiveFilterSearchAdapter(SearchAdapter):

    live_filter = True
    
    
class LiveFilterModel2SearchAdapter(TestModel2SearchAdapter):

    live_filter = True
        
        
class LiveFilterSearchTest(SearchTest):

    search_adapter_1 = LiveFilterSearchAdapter
    
    search_adapter_2 = LiveFilterModel2SearchAdapter
{'fraction_non_alphanumeric': 0.0963741955736933, 'fraction_numerical': 0.021896091665358657, 'mean_word_length': 2.592613476177051, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2806247', 'n_tokens_mistral': 3664, 'n_tokens_neox': 3445, 'n_words': 876}