/tests/core/tests/indexes.py

https://github.com/fizx/django-haystack · Python · 350 lines · 278 code · 71 blank · 1 comment · 5 complexity · 3bd68b857bf15a4896d3884a8870eeea MD5 · raw file

  1. import datetime
  2. from django.test import TestCase
  3. from haystack.indexes import *
  4. from core.models import MockModel
  5. from core.tests.mocks import MockSearchBackend
  6. class BadSearchIndex1(SearchIndex):
  7. author = CharField(model_attr='author')
  8. pub_date = DateTimeField(model_attr='pub_date')
  9. class BadSearchIndex2(SearchIndex):
  10. content = CharField(document=True, use_template=True)
  11. content2 = CharField(document=True, use_template=True)
  12. author = CharField(model_attr='author')
  13. pub_date = DateTimeField(model_attr='pub_date')
  14. class GoodMockSearchIndex(SearchIndex):
  15. content = CharField(document=True, use_template=True)
  16. author = CharField(model_attr='author')
  17. pub_date = DateTimeField(model_attr='pub_date')
  18. extra = CharField(indexed=False, use_template=True)
  19. # For testing inheritance...
  20. class AltGoodMockSearchIndex(GoodMockSearchIndex):
  21. additional = CharField(model_attr='author')
  22. class GoodCustomMockSearchIndex(SearchIndex):
  23. content = CharField(document=True, use_template=True)
  24. author = CharField(model_attr='author', faceted=True)
  25. pub_date = DateTimeField(model_attr='pub_date', faceted=True)
  26. extra = CharField(indexed=False, use_template=True)
  27. hello = CharField(model_attr='hello')
  28. def prepare(self, obj):
  29. super(GoodCustomMockSearchIndex, self).prepare(obj)
  30. self.prepared_data['whee'] = 'Custom preparation.'
  31. return self.prepared_data
  32. def prepare_author(self, obj):
  33. return "Hi, I'm %s" % self.prepared_data['author']
  34. def load_all_queryset(self):
  35. return self.model._default_manager.filter(id__gt=1)
  36. class GoodNullableMockSearchIndex(SearchIndex):
  37. content = CharField(document=True, use_template=True)
  38. author = CharField(model_attr='author', null=True)
  39. class GoodOverriddenFieldNameMockSearchIndex(SearchIndex):
  40. content = CharField(document=True, use_template=True, index_fieldname='more_content')
  41. author = CharField(model_attr='author', index_fieldname='name_s')
  42. hello = CharField(model_attr='hello')
  43. class SearchIndexTestCase(TestCase):
  44. def setUp(self):
  45. super(SearchIndexTestCase, self).setUp()
  46. self.msb = MockSearchBackend()
  47. self.mi = GoodMockSearchIndex(MockModel, backend=self.msb)
  48. self.cmi = GoodCustomMockSearchIndex(MockModel, backend=self.msb)
  49. self.cnmi = GoodNullableMockSearchIndex(MockModel, backend=self.msb)
  50. self.sample_docs = {
  51. u'core.mockmodel.1': {
  52. 'content': u'Indexed!\n1',
  53. 'django_id': u'1',
  54. 'django_ct': u'core.mockmodel',
  55. 'extra': u'Stored!\n1',
  56. 'author': u'daniel1',
  57. 'pub_date': datetime.datetime(2009, 3, 17, 6, 0),
  58. 'id': u'core.mockmodel.1'
  59. },
  60. u'core.mockmodel.2': {
  61. 'content': u'Indexed!\n2',
  62. 'django_id': u'2',
  63. 'django_ct': u'core.mockmodel',
  64. 'extra': u'Stored!\n2',
  65. 'author': u'daniel2',
  66. 'pub_date': datetime.datetime(2009, 3, 17, 7, 0),
  67. 'id': u'core.mockmodel.2'
  68. },
  69. u'core.mockmodel.3': {
  70. 'content': u'Indexed!\n3',
  71. 'django_id': u'3',
  72. 'django_ct': u'core.mockmodel',
  73. 'extra': u'Stored!\n3',
  74. 'author': u'daniel3',
  75. 'pub_date': datetime.datetime(2009, 3, 17, 8, 0),
  76. 'id': u'core.mockmodel.3'
  77. }
  78. }
  79. def test_no_contentfield_present(self):
  80. self.assertRaises(SearchFieldError, BadSearchIndex1, MockModel, MockSearchBackend())
  81. def test_too_many_contentfields_present(self):
  82. self.assertRaises(SearchFieldError, BadSearchIndex2, MockModel, MockSearchBackend())
  83. def test_contentfield_present(self):
  84. try:
  85. mi = GoodMockSearchIndex(MockModel, backend=MockSearchBackend())
  86. except:
  87. self.fail()
  88. def test_proper_fields(self):
  89. self.assertEqual(len(self.mi.fields), 4)
  90. self.assert_('content' in self.mi.fields)
  91. self.assert_(isinstance(self.mi.fields['content'], CharField))
  92. self.assert_('author' in self.mi.fields)
  93. self.assert_(isinstance(self.mi.fields['author'], CharField))
  94. self.assert_('pub_date' in self.mi.fields)
  95. self.assert_(isinstance(self.mi.fields['pub_date'], DateTimeField))
  96. self.assert_('extra' in self.mi.fields)
  97. self.assert_(isinstance(self.mi.fields['extra'], CharField))
  98. def test_get_queryset(self):
  99. self.assertEqual(len(self.mi.get_queryset()), 3)
  100. def test_prepare(self):
  101. mock = MockModel()
  102. mock.pk = 20
  103. mock.author = 'daniel%s' % mock.id
  104. mock.pub_date = datetime.datetime(2009, 1, 31, 4, 19, 0)
  105. self.assertEqual(len(self.mi.prepare(mock)), 7)
  106. self.assertEqual(sorted(self.mi.prepare(mock).keys()), ['author', 'content', 'django_ct', 'django_id', 'extra', 'id', 'pub_date'])
  107. def test_custom_prepare(self):
  108. mock = MockModel()
  109. mock.pk = 20
  110. mock.author = 'daniel%s' % mock.id
  111. mock.pub_date = datetime.datetime(2009, 1, 31, 4, 19, 0)
  112. self.assertEqual(len(self.cmi.prepare(mock)), 9)
  113. self.assertEqual(sorted(self.cmi.prepare(mock).keys()), ['author', 'content', 'django_ct', 'django_id', 'extra', 'hello', 'id', 'pub_date', 'whee'])
  114. self.assertEqual(len(self.cmi.full_prepare(mock)), 11)
  115. self.assertEqual(sorted(self.cmi.full_prepare(mock).keys()), ['author', 'author_exact', 'content', 'django_ct', 'django_id', 'extra', 'hello', 'id', 'pub_date', 'pub_date_exact', 'whee'])
  116. def test_custom_prepare_author(self):
  117. mock = MockModel()
  118. mock.pk = 20
  119. mock.author = 'daniel%s' % mock.id
  120. mock.pub_date = datetime.datetime(2009, 1, 31, 4, 19, 0)
  121. self.assertEqual(len(self.cmi.prepare(mock)), 9)
  122. self.assertEqual(sorted(self.cmi.prepare(mock).keys()), ['author', 'content', 'django_ct', 'django_id', 'extra', 'hello', 'id', 'pub_date', 'whee'])
  123. self.assertEqual(len(self.cmi.full_prepare(mock)), 11)
  124. self.assertEqual(sorted(self.cmi.full_prepare(mock).keys()), ['author', 'author_exact', 'content', 'django_ct', 'django_id', 'extra', 'hello', 'id', 'pub_date', 'pub_date_exact', 'whee'])
  125. self.assertEqual(self.cmi.prepared_data['author'], "Hi, I'm daniel20")
  126. self.assertEqual(self.cmi.prepared_data['author_exact'], "Hi, I'm daniel20")
  127. def test_custom_model_attr(self):
  128. mock = MockModel()
  129. mock.pk = 20
  130. mock.author = 'daniel%s' % mock.id
  131. mock.pub_date = datetime.datetime(2009, 1, 31, 4, 19, 0)
  132. self.assertEqual(len(self.cmi.prepare(mock)), 9)
  133. self.assertEqual(sorted(self.cmi.prepare(mock).keys()), ['author', 'content', 'django_ct', 'django_id', 'extra', 'hello', 'id', 'pub_date', 'whee'])
  134. self.assertEqual(len(self.cmi.full_prepare(mock)), 11)
  135. self.assertEqual(sorted(self.cmi.full_prepare(mock).keys()), ['author', 'author_exact', 'content', 'django_ct', 'django_id', 'extra', 'hello', 'id', 'pub_date', 'pub_date_exact', 'whee'])
  136. self.assertEqual(self.cmi.prepared_data['hello'], u'World!')
  137. def test_custom_index_fieldname(self):
  138. mock = MockModel()
  139. mock.pk = 20
  140. mock.author = 'daniel%s' % mock.id
  141. mock.pub_date = datetime.datetime(2009, 1, 31, 4, 19, 0)
  142. cofnmi = GoodOverriddenFieldNameMockSearchIndex(MockModel, backend=self.msb)
  143. self.assertEqual(len(cofnmi.prepare(mock)), 6)
  144. self.assertEqual(sorted(cofnmi.prepare(mock).keys()), ['django_ct', 'django_id', 'hello', 'id', 'more_content', 'name_s'])
  145. self.assertEqual(cofnmi.prepared_data['name_s'], u'daniel20')
  146. self.assertEqual(cofnmi.get_content_field(), 'more_content')
  147. def test_get_content_field(self):
  148. self.assertEqual(self.mi.get_content_field(), 'content')
  149. def test_update(self):
  150. self.mi.update()
  151. self.assertEqual(self.msb.docs, self.sample_docs)
  152. self.msb.clear()
  153. def test_update_object(self):
  154. self.assertEqual(self.msb.docs, {})
  155. mock = MockModel()
  156. mock.pk = 20
  157. mock.author = 'daniel%s' % mock.id
  158. mock.pub_date = datetime.datetime(2009, 1, 31, 4, 19, 0)
  159. self.mi.update_object(mock)
  160. self.assertEqual(self.msb.docs, {'core.mockmodel.20': {'django_id': u'20', 'django_ct': u'core.mockmodel', 'author': u'daniel20', 'extra': u'Stored!\n20', 'content': u'Indexed!\n20', 'pub_date': datetime.datetime(2009, 1, 31, 4, 19), 'id': 'core.mockmodel.20'}})
  161. self.msb.clear()
  162. def test_remove_object(self):
  163. self.msb.docs = {'core.mockmodel.20': 'Indexed!\n20'}
  164. mock = MockModel()
  165. mock.pk = 20
  166. self.mi.remove_object(mock)
  167. self.assertEqual(self.msb.docs, {})
  168. self.msb.clear()
  169. def test_clear(self):
  170. self.msb.docs = {
  171. 'core.mockmodel.1': 'Indexed!\n1',
  172. 'core.mockmodel.2': 'Indexed!\n2',
  173. 'core.mockmodel.20': 'Indexed!\n20',
  174. }
  175. self.mi.clear()
  176. self.assertEqual(self.msb.docs, {})
  177. self.msb.clear()
  178. def test_reindex(self):
  179. self.msb.docs = {
  180. 'core.mockmodel.1': 'Indexed!\n1',
  181. 'core.mockmodel.2': 'Indexed!\n2',
  182. 'core.mockmodel.20': 'Indexed!\n20',
  183. }
  184. self.mi.reindex()
  185. self.assertEqual(self.msb.docs, self.sample_docs)
  186. self.msb.clear()
  187. def test_inheritance(self):
  188. try:
  189. agmi = AltGoodMockSearchIndex(MockModel, backend=self.msb)
  190. except:
  191. self.fail()
  192. self.assertEqual(len(agmi.fields), 5)
  193. self.assert_('content' in agmi.fields)
  194. self.assert_(isinstance(agmi.fields['content'], CharField))
  195. self.assert_('author' in agmi.fields)
  196. self.assert_(isinstance(agmi.fields['author'], CharField))
  197. self.assert_('pub_date' in agmi.fields)
  198. self.assert_(isinstance(agmi.fields['pub_date'], DateTimeField))
  199. self.assert_('extra' in agmi.fields)
  200. self.assert_(isinstance(agmi.fields['extra'], CharField))
  201. self.assert_('additional' in agmi.fields)
  202. self.assert_(isinstance(agmi.fields['additional'], CharField))
  203. def test_load_all_queryset(self):
  204. self.assertEqual([obj.id for obj in self.cmi.load_all_queryset()], [2, 3])
  205. def test_nullable(self):
  206. mock = MockModel()
  207. mock.pk = 20
  208. mock.author = None
  209. mock.pub_date = datetime.datetime(2009, 1, 31, 4, 19, 0)
  210. prepared_data = self.cnmi.prepare(mock)
  211. self.assertEqual(len(prepared_data), 4)
  212. self.assertEqual(sorted(prepared_data.keys()), ['content', 'django_ct', 'django_id', 'id'])
  213. class BasicModelSearchIndex(ModelSearchIndex):
  214. class Meta:
  215. pass
  216. class FieldsModelSearchIndex(ModelSearchIndex):
  217. class Meta:
  218. fields = ['author', 'pub_date']
  219. class ExcludesModelSearchIndex(ModelSearchIndex):
  220. class Meta:
  221. excludes = ['author', 'foo']
  222. class FieldsWithOverrideModelSearchIndex(ModelSearchIndex):
  223. foo = IntegerField(model_attr='foo')
  224. class Meta:
  225. fields = ['author', 'foo']
  226. def get_index_fieldname(self, f):
  227. if f.name == 'author':
  228. return 'author_bar'
  229. else:
  230. return f.name
  231. class ModelSearchIndexTestCase(TestCase):
  232. def setUp(self):
  233. super(ModelSearchIndexTestCase, self).setUp()
  234. self.msb = MockSearchBackend()
  235. self.bmsi = BasicModelSearchIndex(MockModel, backend=self.msb)
  236. self.fmsi = FieldsModelSearchIndex(MockModel, backend=self.msb)
  237. self.emsi = ExcludesModelSearchIndex(MockModel, backend=self.msb)
  238. self.fwomsi = FieldsWithOverrideModelSearchIndex(MockModel, backend=self.msb)
  239. def test_basic(self):
  240. self.assertEqual(len(self.bmsi.fields), 4)
  241. self.assert_('foo' in self.bmsi.fields)
  242. self.assert_(isinstance(self.bmsi.fields['foo'], CharField))
  243. self.assertEqual(self.bmsi.fields['foo'].null, False)
  244. self.assertEqual(self.bmsi.fields['foo'].index_fieldname, 'foo')
  245. self.assert_('author' in self.bmsi.fields)
  246. self.assert_(isinstance(self.bmsi.fields['author'], CharField))
  247. self.assertEqual(self.bmsi.fields['author'].null, False)
  248. self.assert_('pub_date' in self.bmsi.fields)
  249. self.assert_(isinstance(self.bmsi.fields['pub_date'], DateTimeField))
  250. self.assert_(isinstance(self.bmsi.fields['pub_date'].default, datetime.datetime))
  251. self.assert_('text' in self.bmsi.fields)
  252. self.assert_(isinstance(self.bmsi.fields['text'], CharField))
  253. self.assertEqual(self.bmsi.fields['text'].document, True)
  254. self.assertEqual(self.bmsi.fields['text'].use_template, True)
  255. def test_fields(self):
  256. self.assertEqual(len(self.fmsi.fields), 3)
  257. self.assert_('author' in self.fmsi.fields)
  258. self.assert_(isinstance(self.fmsi.fields['author'], CharField))
  259. self.assert_('pub_date' in self.fmsi.fields)
  260. self.assert_(isinstance(self.fmsi.fields['pub_date'], DateTimeField))
  261. self.assert_('text' in self.fmsi.fields)
  262. self.assert_(isinstance(self.fmsi.fields['text'], CharField))
  263. def test_excludes(self):
  264. self.assertEqual(len(self.emsi.fields), 2)
  265. self.assert_('pub_date' in self.emsi.fields)
  266. self.assert_(isinstance(self.emsi.fields['pub_date'], DateTimeField))
  267. self.assert_('text' in self.emsi.fields)
  268. self.assert_(isinstance(self.emsi.fields['text'], CharField))
  269. def test_fields_with_override(self):
  270. self.assertEqual(len(self.fwomsi.fields), 3)
  271. self.assert_('author' in self.fwomsi.fields)
  272. self.assert_(isinstance(self.fwomsi.fields['author'], CharField))
  273. self.assert_('foo' in self.fwomsi.fields)
  274. self.assert_(isinstance(self.fwomsi.fields['foo'], IntegerField))
  275. self.assert_('text' in self.fwomsi.fields)
  276. self.assert_(isinstance(self.fwomsi.fields['text'], CharField))
  277. def test_overriding_field_name_with_get_index_fieldname(self):
  278. self.assert_(self.fwomsi.fields['foo'].index_fieldname, 'foo')
  279. self.assert_(self.fwomsi.fields['author'].index_fieldname, 'author_bar')