Moved search test models into their own app

This commit is contained in:
Karl Hobley 2015-03-30 13:44:04 +01:00
parent 5c3b0b5da2
commit 1f8dc4bcfc
12 changed files with 156 additions and 81 deletions

View file

@ -0,0 +1 @@
default_app_config = 'wagtail.tests.search.apps.WagtailSearchTestsAppConfig'

View file

@ -0,0 +1,7 @@
from django.apps import AppConfig
class WagtailSearchTestsAppConfig(AppConfig):
name = 'wagtail.tests.search'
label = 'searchtests'
verbose_name = "Wagtail search tests"

View file

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import wagtail.wagtailsearch.index
class Migration(migrations.Migration):
dependencies = [
]
operations = [
migrations.CreateModel(
name='SearchTest',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
('title', models.CharField(max_length=255)),
('content', models.TextField()),
('live', models.BooleanField(default=False)),
('published_date', models.DateField(null=True)),
],
options={
},
bases=(models.Model, wagtail.wagtailsearch.index.Indexed),
),
migrations.CreateModel(
name='SearchTestChild',
fields=[
('searchtest_ptr', models.OneToOneField(primary_key=True, serialize=False, parent_link=True, to='searchtests.SearchTest', auto_created=True)),
('subtitle', models.CharField(null=True, max_length=255, blank=True)),
('extra_content', models.TextField()),
],
options={
},
bases=('searchtests.searchtest',),
),
]

View file

@ -0,0 +1,54 @@
from django.db import models
from wagtail.wagtailsearch import index
class SearchTest(models.Model, index.Indexed):
title = models.CharField(max_length=255)
content = models.TextField()
live = models.BooleanField(default=False)
published_date = models.DateField(null=True)
search_fields = [
index.SearchField('title', partial_match=True),
index.SearchField('content'),
index.SearchField('callable_indexed_field'),
index.FilterField('title'),
index.FilterField('live'),
index.FilterField('published_date'),
]
def callable_indexed_field(self):
return "Callable"
@classmethod
def get_indexed_objects(cls):
indexed_objects = super(SearchTest, cls).get_indexed_objects()
# Exclude SearchTests that have a SearchTestChild to stop update_index creating duplicates
if cls is SearchTest:
indexed_objects = indexed_objects.exclude(
id__in=SearchTestChild.objects.all().values_list('searchtest_ptr_id', flat=True)
)
# Exclude SearchTests that have the title "Don't index me!"
indexed_objects = indexed_objects.exclude(title="Don't index me!")
return indexed_objects
def get_indexed_instance(self):
# Check if there is a SearchTestChild that descends from this
child = SearchTestChild.objects.filter(searchtest_ptr_id=self.id).first()
# Return the child if there is one, otherwise return self
return child or self
class SearchTestChild(SearchTest):
subtitle = models.CharField(max_length=255, null=True, blank=True)
extra_content = models.TextField()
search_fields = SearchTest.search_fields + [
index.SearchField('subtitle', partial_match=True),
index.SearchField('extra_content'),
]

View file

@ -80,6 +80,7 @@ INSTALLED_APPS = (
'wagtail.tests.customuser',
'wagtail.tests.snippets',
'wagtail.tests.routablepage',
'wagtail.tests.search',
# Install wagtailredirects with its appconfig
# Theres nothing special about wagtailredirects, we just need to have one

View file

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('tests', '0013_auto_20150330_0717'),
]
operations = [
migrations.RemoveField(
model_name='searchtestchild',
name='searchtest_ptr',
),
migrations.DeleteModel(
name='SearchTestChild',
),
migrations.DeleteModel(
name='SearchTest',
),
]

View file

@ -361,56 +361,6 @@ class BusinessChild(Page):
parent_page_types = ['tests.BusinessIndex', BusinessSubIndex]
class SearchTest(models.Model, index.Indexed):
title = models.CharField(max_length=255)
content = models.TextField()
live = models.BooleanField(default=False)
published_date = models.DateField(null=True)
search_fields = [
index.SearchField('title', partial_match=True),
index.SearchField('content'),
index.SearchField('callable_indexed_field'),
index.FilterField('title'),
index.FilterField('live'),
index.FilterField('published_date'),
]
def callable_indexed_field(self):
return "Callable"
@classmethod
def get_indexed_objects(cls):
indexed_objects = super(SearchTest, cls).get_indexed_objects()
# Exclude SearchTests that have a SearchTestChild to stop update_index creating duplicates
if cls is SearchTest:
indexed_objects = indexed_objects.exclude(
id__in=SearchTestChild.objects.all().values_list('searchtest_ptr_id', flat=True)
)
# Exclude SearchTests that have the title "Don't index me!"
indexed_objects = indexed_objects.exclude(title="Don't index me!")
return indexed_objects
def get_indexed_instance(self):
# Check if there is a SearchTestChild that descends from this
child = SearchTestChild.objects.filter(searchtest_ptr_id=self.id).first()
# Return the child if there is one, otherwise return self
return child or self
class SearchTestChild(SearchTest):
subtitle = models.CharField(max_length=255, null=True, blank=True)
extra_content = models.TextField()
search_fields = SearchTest.search_fields + [
index.SearchField('subtitle', partial_match=True),
index.SearchField('extra_content'),
]
class TaggedPageTag(TaggedItemBase):
content_object = ParentalKey('tests.TaggedPage', related_name='tagged_items')

View file

@ -8,7 +8,7 @@ from django.conf import settings
from django.core import management
from wagtail.tests.utils import WagtailTestUtils
from wagtail.tests.testapp import models
from wagtail.tests.search import models
from wagtail.wagtailsearch.backends import get_search_backend, InvalidSearchBackendError
from wagtail.wagtailsearch.backends.db import DBSearch

View file

@ -8,7 +8,7 @@ import json
from django.test import TestCase
from django.db.models import Q
from wagtail.tests.testapp import models
from wagtail.tests.search import models
from .test_backends import BackendTests
@ -186,7 +186,7 @@ class TestElasticSearchQuery(TestCase):
query = self.ElasticSearchQuery(models.SearchTest.objects.all(), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'tests_searchtest'}}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.to_es(), expected_result)
def test_none_query_string(self):
@ -194,7 +194,7 @@ class TestElasticSearchQuery(TestCase):
query = self.ElasticSearchQuery(models.SearchTest.objects.all(), None)
# Check it
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'tests_searchtest'}}, 'query': {'match_all': {}}}}
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'match_all': {}}}}
self.assertDictEqual(query.to_es(), expected_result)
def test_filter(self):
@ -202,7 +202,7 @@ class TestElasticSearchQuery(TestCase):
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(title="Test"), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'term': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'term': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.to_es(), expected_result)
def test_and_filter(self):
@ -210,7 +210,7 @@ class TestElasticSearchQuery(TestCase):
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(title="Test", live=True), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'and': [{'term': {'live_filter': True}}, {'term': {'title_filter': 'Test'}}]}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'and': [{'term': {'live_filter': True}}, {'term': {'title_filter': 'Test'}}]}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
# Make sure field filters are sorted (as they can be in any order which may cause false positives)
query = query.to_es()
@ -229,7 +229,7 @@ class TestElasticSearchQuery(TestCase):
field_filters[:] = sorted(field_filters, key=lambda f: list(f['term'].keys())[0])
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'or': [{'term': {'live_filter': True}}, {'term': {'title_filter': 'Test'}}]}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'or': [{'term': {'live_filter': True}}, {'term': {'title_filter': 'Test'}}]}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query, expected_result)
def test_negated_filter(self):
@ -237,7 +237,7 @@ class TestElasticSearchQuery(TestCase):
query = self.ElasticSearchQuery(models.SearchTest.objects.exclude(live=True), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'not': {'term': {'live_filter': True}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'not': {'term': {'live_filter': True}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.to_es(), expected_result)
def test_fields(self):
@ -245,7 +245,7 @@ class TestElasticSearchQuery(TestCase):
query = self.ElasticSearchQuery(models.SearchTest.objects.all(), "Hello", fields=['title'])
# Check it
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'tests_searchtest'}}, 'query': {'match': {'title': 'Hello'}}}}
expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'match': {'title': 'Hello'}}}}
self.assertDictEqual(query.to_es(), expected_result)
def test_exact_lookup(self):
@ -253,7 +253,7 @@ class TestElasticSearchQuery(TestCase):
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(title__exact="Test"), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'term': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'term': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.to_es(), expected_result)
def test_none_lookup(self):
@ -261,7 +261,7 @@ class TestElasticSearchQuery(TestCase):
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(title=None), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'missing': {'field': 'title_filter'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'missing': {'field': 'title_filter'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.to_es(), expected_result)
def test_isnull_true_lookup(self):
@ -269,7 +269,7 @@ class TestElasticSearchQuery(TestCase):
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(title__isnull=True), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'missing': {'field': 'title_filter'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'missing': {'field': 'title_filter'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.to_es(), expected_result)
def test_isnull_false_lookup(self):
@ -277,7 +277,7 @@ class TestElasticSearchQuery(TestCase):
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(title__isnull=False), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'not': {'missing': {'field': 'title_filter'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'not': {'missing': {'field': 'title_filter'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.to_es(), expected_result)
def test_startswith_lookup(self):
@ -285,7 +285,7 @@ class TestElasticSearchQuery(TestCase):
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(title__startswith="Test"), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'prefix': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'prefix': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.to_es(), expected_result)
def test_gt_lookup(self):
@ -295,7 +295,7 @@ class TestElasticSearchQuery(TestCase):
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(published_date__gt=datetime.datetime(2014, 4, 29)), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'range': {'published_date_filter': {'gt': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'gt': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.to_es(), expected_result)
def test_lt_lookup(self):
@ -303,7 +303,7 @@ class TestElasticSearchQuery(TestCase):
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(published_date__lt=datetime.datetime(2014, 4, 29)), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'range': {'published_date_filter': {'lt': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'lt': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.to_es(), expected_result)
def test_gte_lookup(self):
@ -311,7 +311,7 @@ class TestElasticSearchQuery(TestCase):
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(published_date__gte=datetime.datetime(2014, 4, 29)), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'range': {'published_date_filter': {'gte': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'gte': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.to_es(), expected_result)
def test_lte_lookup(self):
@ -319,7 +319,7 @@ class TestElasticSearchQuery(TestCase):
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(published_date__lte=datetime.datetime(2014, 4, 29)), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'range': {'published_date_filter': {'lte': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'lte': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.to_es(), expected_result)
def test_range_lookup(self):
@ -330,7 +330,7 @@ class TestElasticSearchQuery(TestCase):
query = self.ElasticSearchQuery(models.SearchTest.objects.filter(published_date__range=(start_date, end_date)), "Hello")
# Check it
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'tests_searchtest'}}, {'range': {'published_date_filter': {'gte': '2014-04-29', 'lte': '2014-08-19'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'gte': '2014-04-29', 'lte': '2014-08-19'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
self.assertDictEqual(query.to_es(), expected_result)
@ -358,7 +358,7 @@ class TestElasticSearchMapping(TestCase):
self.obj.save()
def test_get_document_type(self):
self.assertEqual(self.es_mapping.get_document_type(), 'tests_searchtest')
self.assertEqual(self.es_mapping.get_document_type(), 'searchtests_searchtest')
def test_get_mapping(self):
# Build mapping
@ -366,7 +366,7 @@ class TestElasticSearchMapping(TestCase):
# Check
expected_result = {
'tests_searchtest': {
'searchtests_searchtest': {
'properties': {
'pk': {'index': 'not_analyzed', 'type': 'string', 'store': 'yes', 'include_in_all': False},
'content_type': {'index': 'not_analyzed', 'type': 'string', 'include_in_all': False},
@ -384,7 +384,7 @@ class TestElasticSearchMapping(TestCase):
self.assertDictEqual(mapping, expected_result)
def test_get_document_id(self):
self.assertEqual(self.es_mapping.get_document_id(self.obj), 'tests_searchtest:' + str(self.obj.pk))
self.assertEqual(self.es_mapping.get_document_id(self.obj), 'searchtests_searchtest:' + str(self.obj.pk))
def test_get_document(self):
# Get document
@ -393,7 +393,7 @@ class TestElasticSearchMapping(TestCase):
# Check
expected_result = {
'pk': str(self.obj.pk),
'content_type': 'tests_searchtest',
'content_type': 'searchtests_searchtest',
'_partials': ['Hello'],
'live_filter': False,
'published_date_filter': None,
@ -430,7 +430,7 @@ class TestElasticSearchMappingInheritance(TestCase):
self.obj.save()
def test_get_document_type(self):
self.assertEqual(self.es_mapping.get_document_type(), 'tests_searchtest_tests_searchtestchild')
self.assertEqual(self.es_mapping.get_document_type(), 'searchtests_searchtest_searchtests_searchtestchild')
def test_get_mapping(self):
# Build mapping
@ -438,7 +438,7 @@ class TestElasticSearchMappingInheritance(TestCase):
# Check
expected_result = {
'tests_searchtest_tests_searchtestchild': {
'searchtests_searchtest_searchtests_searchtestchild': {
'properties': {
# New
'extra_content': {'type': 'string', 'include_in_all': True},
@ -464,7 +464,7 @@ class TestElasticSearchMappingInheritance(TestCase):
# This must be tests_searchtest instead of 'tests_searchtest_tests_searchtestchild'
# as it uses the contents base content type name.
# This prevents the same object being accidentally indexed twice.
self.assertEqual(self.es_mapping.get_document_id(self.obj), 'tests_searchtest:' + str(self.obj.pk))
self.assertEqual(self.es_mapping.get_document_id(self.obj), 'searchtests_searchtest:' + str(self.obj.pk))
def test_get_document(self):
# Build document
@ -481,7 +481,7 @@ class TestElasticSearchMappingInheritance(TestCase):
'subtitle': 'World',
# Changed
'content_type': 'tests_searchtest_tests_searchtestchild',
'content_type': 'searchtests_searchtest_searchtests_searchtestchild',
# Inherited
'pk': str(self.obj.pk),

View file

@ -3,18 +3,18 @@ import warnings
from django.test import TestCase
from wagtail.wagtailsearch import index
from wagtail.tests.testapp import models
from wagtail.tests.search import models
from wagtail.tests.utils import WagtailTestUtils
class TestContentTypeNames(TestCase):
def test_base_content_type_name(self):
name = models.SearchTestChild.indexed_get_toplevel_content_type()
self.assertEqual(name, 'tests_searchtest')
self.assertEqual(name, 'searchtests_searchtest')
def test_qualified_content_type_name(self):
name = models.SearchTestChild.indexed_get_content_type()
self.assertEqual(name, 'tests_searchtest_tests_searchtestchild')
self.assertEqual(name, 'searchtests_searchtest_searchtests_searchtestchild')
class TestSearchFields(TestCase):

View file

@ -1,7 +1,7 @@
from django.test import TestCase
from wagtail.wagtailsearch import signal_handlers
from wagtail.tests.testapp import models
from wagtail.tests.search import models
class TestGetIndexedInstance(TestCase):