summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--askbot/search/haystack/__init__.py83
-rw-r--r--askbot/tests/__init__.py1
-rw-r--r--askbot/tests/form_tests.py12
-rw-r--r--askbot/tests/haystack_search_tests.py95
-rw-r--r--askbot/tests/utils.py18
5 files changed, 153 insertions, 56 deletions
diff --git a/askbot/search/haystack/__init__.py b/askbot/search/haystack/__init__.py
index 7927aa87..71f04d00 100644
--- a/askbot/search/haystack/__init__.py
+++ b/askbot/search/haystack/__init__.py
@@ -1,58 +1,59 @@
try:
from haystack import indexes, site
from haystack.query import SearchQuerySet
-except ImportError:
- pass
+ from askbot.models import Post, Thread, User
-from askbot.models import Post, Thread, User
-class ThreadIndex(indexes.SearchIndex):
- text = indexes.CharField(document=True, use_template=True)
- title = indexes.CharField(model_attr='title')
- post_text = indexes.CharField(model_attr='posts__text__search')
+ class ThreadIndex(indexes.SearchIndex):
+ text = indexes.CharField(document=True, use_template=True)
+ title = indexes.CharField(model_attr='title')
+ post_text = indexes.CharField(model_attr='posts__text__search')
- def index_queryset(self):
- return Thread.objects.filter(posts__deleted=False)
+ def index_queryset(self):
+ return Thread.objects.filter(posts__deleted=False)
- def prepare(self, obj):
- self.prepared_data = super(ThreadIndex, self).prepare(object)
+ def prepare(self, obj):
+ self.prepared_data = super(ThreadIndex, self).prepare(object)
- self.prepared_data['tags'] = [tag.name for tag in objects.tags.all()]
+ self.prepared_data['tags'] = [tag.name for tag in objects.tags.all()]
-class PostIndex(indexes.SearchIndex):
- text = indexes.CharField(document=True, use_template=True)
- post_text = indexes.CharField(model_attr='text')
- author = indexes.CharField(model_attr='user')
- thread_id = indexes.CharField(model_attr='thread')
+ class PostIndex(indexes.SearchIndex):
+ text = indexes.CharField(document=True, use_template=True)
+ post_text = indexes.CharField(model_attr='text')
+ author = indexes.CharField(model_attr='user')
+ thread_id = indexes.CharField(model_attr='thread')
- def index_queryset(self):
- return Post.objects.filter(deleted=False)
+ def index_queryset(self):
+ return Post.objects.filter(deleted=False)
-class UserIndex(indexes.SearchIndex):
- text = indexes.CharField(document=True, use_template=True)
+ class UserIndex(indexes.SearchIndex):
+ text = indexes.CharField(document=True, use_template=True)
- def index_queryset(self):
- return User.objects.all()
+ def index_queryset(self):
+ return User.objects.all()
-site.register(Post, PostIndex)
-site.register(Thread, ThreadIndex)
-site.register(User, UserIndex)
+ site.register(Post, PostIndex)
+ site.register(Thread, ThreadIndex)
+ site.register(User, UserIndex)
-class AskbotSearchQuerySet(SearchQuerySet):
+ class AskbotSearchQuerySet(SearchQuerySet):
- def get_django_queryset(self, model_klass=Thread):
- '''dirty hack because models() method from the
- SearchQuerySet does not work </3'''
- id_list = []
- for r in self:
- if r.model_name in ['thread','post'] \
- and model_klass._meta.object_name.lower() == 'thread':
- if getattr(r, 'thread_id'):
- id_list.append(r.thread_id)
- else:
+ def get_django_queryset(self, model_klass=Thread):
+ '''dirty hack because models() method from the
+ SearchQuerySet does not work </3'''
+ id_list = []
+ for r in self:
+ if r.model_name in ['thread','post'] \
+ and model_klass._meta.object_name.lower() == 'thread':
+ if getattr(r, 'thread_id'):
+ id_list.append(r.thread_id)
+ else:
+ id_list.append(r.pk)
+ elif r.model_name == model_klass._meta.object_name.lower():
+ #FIXME: add a highlight here?
id_list.append(r.pk)
- elif r.model_name == model_klass._meta.object_name.lower():
- #FIXME: add a highlight here?
- id_list.append(r.pk)
- return model_klass.objects.filter(id__in=set(id_list))
+ return model_klass.objects.filter(id__in=set(id_list))
+
+except:
+ pass
diff --git a/askbot/tests/__init__.py b/askbot/tests/__init__.py
index 1b25e064..1b8b703a 100644
--- a/askbot/tests/__init__.py
+++ b/askbot/tests/__init__.py
@@ -15,3 +15,4 @@ from askbot.tests.markup_test import *
from askbot.tests.misc_tests import *
from askbot.tests.post_model_tests import *
from askbot.tests.reply_by_email_tests import *
+from askbot.tests.haystack_search_tests import *
diff --git a/askbot/tests/form_tests.py b/askbot/tests/form_tests.py
index 654272b3..5bca5eac 100644
--- a/askbot/tests/form_tests.py
+++ b/askbot/tests/form_tests.py
@@ -72,8 +72,8 @@ class AskByEmailFormTests(AskbotTestCase):
askbot_settings.update('TAGS_ARE_REQUIRED', setting_backup)
def test_email(self):
- """loops through variants of the from field
- in the emails and tests the email address
+ """loops through variants of the from field
+ in the emails and tests the email address
extractor"""
for test_case in EMAIL_CASES:
self.data['sender'] = test_case[0]
@@ -178,7 +178,7 @@ class EditQuestionAnonymouslyFormTests(AskbotTestCase):
def setup_data(self, is_anon, can_be_anon, is_owner, box_checked):
"""sets up data in the same order as shown in the
truth table above
-
+
the four positional arguments are in the same order
"""
askbot_settings.update('ALLOW_ASK_ANONYMOUSLY', can_be_anon)
@@ -264,7 +264,7 @@ class UserStatusFormTest(AskbotTestCase):
self.moderator.set_status('m')
self.subject = self.create_user('normal_user')
self.subject.set_status('a')
- self.form = forms.ChangeUserStatusForm(data, moderator = self.moderator,
+ self.form = forms.ChangeUserStatusForm(data, moderator = self.moderator,
subject = self.subject)
def test_moderator_can_suspend_user(self):
self.setup_data('s')
@@ -292,7 +292,7 @@ class UserNameFieldTest(AskbotTestCase):
self.username_field.skip_clean = True
self.assertEquals(self.username_field.clean('bar'), 'bar')#will pass anything
- self.username_field.skip_clean = False
+ self.username_field.skip_clean = False
#will not pass b/c instance is not User model
self.username_field.user_instance = dict(foo=1)
@@ -328,7 +328,7 @@ class AnswerEditorFieldTests(AskbotTestCase):
self.field.clean,
'a'
)
-
+
def test_pass_long_body(self):
self.assertEquals(
self.field.clean(10*'a'),
diff --git a/askbot/tests/haystack_search_tests.py b/askbot/tests/haystack_search_tests.py
new file mode 100644
index 00000000..853f4683
--- /dev/null
+++ b/askbot/tests/haystack_search_tests.py
@@ -0,0 +1,95 @@
+"""Tests haystack indexes and queries"""
+from django.core import exceptions
+from django.conf import settings
+from django.contrib.auth.models import User
+from askbot.tests.utils import AskbotTestCase, skipIf
+from askbot.search.haystack import AskbotSearchQuerySet
+from askbot import models
+import datetime
+
+class HaystackSearchTests(AskbotTestCase):
+ """tests methods on User object,
+ that were added for askbot
+ """
+ def setUp(self):
+ self.user = self.create_user(username='gepeto')
+ self.other_user = self.create_user(username = 'pinocho')
+ self.other_user.location = 'Managua'
+ self.other_user.about = "I'm made of wood, gepeto made me"
+ self.other_user.save()
+ body_1 = '''Lorem turpis purus? Amet mattis eu et sociis phasellus
+ montes elementum proin ut urna enim, velit, tincidunt quis ut,
+ et integer mus? Nunc! Vut sed? Ac tincidunt egestas adipiscing,
+ magna et pulvinar mid est urna ultricies, turpis tristique nisi,
+ cum. Urna. Purus elit porttitor nisi porttitor ridiculus tincidunt
+ amet duis, gepeto'''
+ #from Baldy of Nome by Esther Birdsall Darling
+ body_2 = ''' With unseeing eyes and dragging steps, the boy trudged along the snowy
+ trail, dreading the arrival at Golconda Camp. For there was the House of
+ Judgment, where all of the unfortunate events of that most unhappy day
+ would be reviewed sternly, lorem'''
+ self.question1 = self.post_question(
+ user=self.user,
+ body_text=body_1,
+ title='Test title 1'
+ )
+ self.question2 = self.post_question(
+ user=self.other_user,
+ body_text=body_2,
+ title='Test title 2, Baldy of Nome'
+ )
+ self.answer1 = self.post_answer(
+ user=self.user,
+ question = self.question1,
+ body_text="This is a answer for question 1"
+ )
+ self.answer1 = self.post_answer(
+ user=self.other_user,
+ question = self.question2,
+ body_text="Just a random text to fill the space"
+ )
+
+ @skipIf('haystack' not in settings.INSTALLED_APPS,
+ 'Haystack not setup')
+ def test_title_search(self):
+ #title search
+ title_search_qs = models.Thread.objects.get_for_query('title')
+ self.assertEquals(title_search_qs.count(), 2)
+ title_search_qs_2 = models.Thread.objects.get_for_query('Nome')
+ self.assertEquals(title_search_qs_2.count(), 1)
+
+ @skipIf('haystack' not in settings.INSTALLED_APPS,
+ 'Haystack not setup')
+ def test_body_search(self):
+
+ #bodysearch
+ body_search_qs = models.Thread.objects.get_for_query('Lorem')
+ self.assertEquals(body_search_qs.count(), 2)
+ body_search_qs_2 = models.Thread.objects.get_for_query('steps')
+ self.assertEquals(body_search_qs_2.count(), 1)
+
+ @skipIf('haystack' not in settings.INSTALLED_APPS,
+ 'Haystack not setup')
+ def test_user_profile_search(self):
+ #must return pinocho
+ user_profile_qs = models.get_users_by_text_query('wood')
+ self.assertEquals(user_profile_qs.count(), 1)
+
+ #returns both gepeto and pinocho because gepeto nickname
+ #and gepeto name in pinocho's profile
+ user_profile_qs = models.get_users_by_text_query('gepeto')
+ self.assertEquals(user_profile_qs.count(), 2)
+
+ @skipIf('haystack' not in settings.INSTALLED_APPS,
+ 'Haystack not setup')
+ def test_get_django_queryset(self):
+ '''makes a query that can return multiple models and test
+ get_django_queryset() method from AskbotSearchQuerySet'''
+ #gepeto is present in profile and in question
+ qs = AskbotSearchQuerySet().filter(content='gepeto').get_django_queryset(User)
+ for instance in qs:
+ self.assertTrue(isinstance(instance, User))
+
+ qs = AskbotSearchQuerySet().filter(content='gepeto').get_django_queryset(models.Thread)
+ for instance in qs:
+ self.assertTrue(isinstance(instance, models.Thread))
diff --git a/askbot/tests/utils.py b/askbot/tests/utils.py
index 4bc69ac4..b672da1c 100644
--- a/askbot/tests/utils.py
+++ b/askbot/tests/utils.py
@@ -5,8 +5,8 @@ from functools import wraps
from askbot import models
def create_user(
- username = None,
- email = None,
+ username = None,
+ email = None,
notification_schedule = None,
date_joined = None,
status = 'a',
@@ -25,13 +25,13 @@ def create_user(
* 'q_sel' - questions that user decides to follow
* 'm_and_c' - comments and mentions of user anywhere
- and values as keys in
+ and values as keys in
:attr:`~askbot.models.EmailFeedSetting.FEED_TYPES`:
* 'i' - instantly
* 'd' - daily
* 'w' - weekly
- * 'n' - never
+ * 'n' - never
"""
user = models.User.objects.create_user(username, email)
@@ -42,7 +42,7 @@ def create_user(
user.set_status(status)
if notification_schedule == None:
notification_schedule = models.EmailFeedSetting.NO_EMAIL_SCHEDULE
-
+
#a hack, we need to delete these, that will be created automatically
#because just below we will be replacing them with the new values
user.notification_subscriptions.all().delete()
@@ -110,7 +110,7 @@ class AskbotTestCase(TestCase):
def post_question(
- self,
+ self,
user = None,
title = 'test question title',
body_text = 'test question body text',
@@ -151,7 +151,7 @@ class AskbotTestCase(TestCase):
"""reloads model object from the database
"""
return obj.__class__.objects.get(id = obj.id)
-
+
def post_answer(
self,
user = None,
@@ -194,8 +194,8 @@ class AskbotTestCase(TestCase):
by_email = False,
timestamp = None
):
- """posts and returns a comment to parent post, uses
- now timestamp if not given, dummy body_text
+ """posts and returns a comment to parent post, uses
+ now timestamp if not given, dummy body_text
author is required
"""
if user is None: