summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei <mamoutkine@gmail.com>2011-04-07 22:52:53 -0400
committerAndrei <mamoutkine@gmail.com>2011-04-07 22:52:53 -0400
commit9caf98334054f85419a3fcceec3a0ccbc6f205d6 (patch)
tree19b5a09106b46d20377b7a80910c468f408e5c2d
parentcbd388912e6627e5eddc429752fea3e5509ff175 (diff)
downloadaskbot-9caf98334054f85419a3fcceec3a0ccbc6f205d6.tar.gz
askbot-9caf98334054f85419a3fcceec3a0ccbc6f205d6.tar.bz2
askbot-9caf98334054f85419a3fcceec3a0ccbc6f205d6.zip
fixed another correctness bug on tag subscriptions
-rw-r--r--askbot/models/content.py12
-rw-r--r--askbot/models/tag.py13
-rw-r--r--askbot/tests/db_api_tests.py1
-rw-r--r--askbot/tests/email_alert_tests.py70
-rw-r--r--askbot/tests/utils.py21
5 files changed, 106 insertions, 11 deletions
diff --git a/askbot/models/content.py b/askbot/models/content.py
index 02554a69..b320f541 100644
--- a/askbot/models/content.py
+++ b/askbot/models/content.py
@@ -6,7 +6,7 @@ from django.utils import html as html_utils
from askbot import const
from askbot.models.meta import Comment, Vote
from askbot.models.user import EmailFeedSetting
-from askbot.models.tag import Tag, MarkedTag
+from askbot.models.tag import Tag, MarkedTag, tags_match_some_wildcard
from askbot.conf import settings as askbot_settings
class Content(models.Model):
@@ -96,7 +96,6 @@ class Content(models.Model):
def get_global_tag_based_subscribers(
self,
- tags = None,
tag_mark_reason = None,
subscription_records = None
):
@@ -116,8 +115,9 @@ class Content(models.Model):
raise ValueError('Uknown value of tag mark reason %s' % tag_mark_reason)
#part 1 - find users who follow or not ignore the set of tags
+ tag_names = self.get_tag_names()
tag_selections = MarkedTag.objects.filter(
- tag__in = tags,
+ tag__name__in = tag_names,
reason = tag_mark_reason
)
subscribers = set(
@@ -159,7 +159,7 @@ class Content(models.Model):
wildcard_tags_attribute
).split(' ')
- if tags.tags_match_some_wildcard(wildcard_tags):
+ if tags_match_some_wildcard(tag_names, wildcard_tags):
update_subscribers(subscribers, potential_subscriber)
return subscribers
@@ -174,8 +174,6 @@ class Content(models.Model):
todo: retrieval of wildcard tag followers ignorers
won't scale at all
"""
- tags = self.tags.all()
-
subscriber_set = set()
global_subscriptions = EmailFeedSetting.objects.filter(
@@ -192,7 +190,6 @@ class Content(models.Model):
#segment of users who want emails on selected questions only
subscriber_set.update(
self.get_global_tag_based_subscribers(
- tags = tags,
subscription_records = global_subscriptions,
tag_mark_reason = 'good'
)
@@ -201,7 +198,6 @@ class Content(models.Model):
#segment of users who want to exclude ignored tags
subscriber_set.update(
self.get_global_tag_based_subscribers(
- tags = tags,
subscription_records = global_subscriptions,
tag_mark_reason = 'bad'
)
diff --git a/askbot/models/tag.py b/askbot/models/tag.py
index acfc9413..73aa328f 100644
--- a/askbot/models/tag.py
+++ b/askbot/models/tag.py
@@ -5,6 +5,17 @@ from django.utils.translation import ugettext as _
from askbot.models.base import DeletableContent
from askbot.models.base import BaseQuerySetManager
+def tags_match_some_wildcard(tag_names, wildcard_tags):
+ """Same as
+ :meth:`~askbot.models.tag.TagQuerySet.tags_match_some_wildcard`
+ except it works on tag name strings
+ """
+ for tag_name in tag_names:
+ for wildcard_tag in sorted(wildcard_tags):
+ if tag_name.startswith(wildcard_tag[:-1]):
+ return True
+ return False
+
class TagQuerySet(models.query.QuerySet):
UPDATE_USED_COUNTS_QUERY = """
UPDATE tag
@@ -35,6 +46,8 @@ class TagQuerySet(models.query.QuerySet):
matches a wildcard
:arg:`wildcard_tags` is an iterable of wildcard tag strings
+
+ todo: refactor to use :func:`tags_match_some_wildcard`
"""
for tag in self.all():
for wildcard_tag in sorted(wildcard_tags):
diff --git a/askbot/tests/db_api_tests.py b/askbot/tests/db_api_tests.py
index ac438f7c..66fb9f9d 100644
--- a/askbot/tests/db_api_tests.py
+++ b/askbot/tests/db_api_tests.py
@@ -260,7 +260,6 @@ class GlobalTagSubscriberGetterTests(AskbotTestCase):
frequency = 'i'
)
actual_subscribers = self.question.get_global_tag_based_subscribers(
- tags = self.question.tags.all(),
tag_mark_reason = reason,
subscription_records = subscriptions
)
diff --git a/askbot/tests/email_alert_tests.py b/askbot/tests/email_alert_tests.py
index 5ec598d7..de801967 100644
--- a/askbot/tests/email_alert_tests.py
+++ b/askbot/tests/email_alert_tests.py
@@ -1,6 +1,7 @@
import datetime
import functools
import copy
+import time
from django.conf import settings as django_settings
from django.core import management
import django.core.mail
@@ -11,9 +12,11 @@ from askbot.tests import utils
from askbot import models
from askbot.utils import mail
from askbot.conf import settings as askbot_settings
+from askbot import const
def email_alert_test(test_func):
- """decorator for test methods in EmailAlertTests
+ """decorator for test methods in
+ :class:`~askbot.tests.email_alert_tests.EmailAlertTests`
wraps tests with a generic sequence of testing
email alerts on updates to anything relating to
given question
@@ -732,3 +735,68 @@ class FeedbackTests(utils.AskbotTestCase):
mail.mail_moderators('subject', 'text')
self.assert_feedback_works()
+
+class TagFollowedInstantWholeForumEmailAlertTests(utils.AskbotTestCase):
+ def setUp(self):
+ self.create_user(
+ username = 'user1',
+ notification_schedule = {'q_all': 'i'},
+ status = 'm'
+ )
+ self.create_user(
+ username = 'user2',
+ status = 'm'
+ )
+
+ def test_wildcard_catches_new_tag(self):
+ """users asks a question with a brand new tag
+ and other user subscribes to it by wildcard
+ """
+ askbot_settings.update('USE_WILDCARD_TAGS', True)
+ self.user1.email_tag_filter_strategy = const.INCLUDE_INTERESTING
+ self.user1.save()
+ self.user1.mark_tags(
+ wildcards = ('some*',),
+ reason = 'good',
+ action = 'add'
+ )
+ self.user2.post_question(
+ title = 'some title',
+ body_text = 'some text for the question',
+ tags = 'something'
+ )
+ outbox = django.core.mail.outbox
+ self.assertEqual(len(outbox), 1)
+ self.assertEqual(len(outbox[0].recipients()), 1)
+ self.assertTrue(
+ self.user1.email in outbox[0].recipients()
+ )
+
+ def test_tag_based_subscription_on_new_question_works(self):
+ """someone subscribes for an pre-existing tag
+ then another user asks a question with that tag
+ and the subcriber receives an alert
+ """
+ models.Tag(
+ name = 'something',
+ created_by = self.user1
+ ).save()
+
+ self.user1.email_tag_filter_strategy = const.INCLUDE_INTERESTING
+ self.user1.save()
+ self.user1.mark_tags(
+ tagnames = ('something',),
+ reason = 'good',
+ action = 'add'
+ )
+ self.user2.post_question(
+ title = 'some title',
+ body_text = 'some text for the question',
+ tags = 'something'
+ )
+ outbox = django.core.mail.outbox
+ self.assertEqual(len(outbox), 1)
+ self.assertEqual(len(outbox[0].recipients()), 1)
+ self.assertTrue(
+ self.user1.email in outbox[0].recipients()
+ )
diff --git a/askbot/tests/utils.py b/askbot/tests/utils.py
index 85599682..0c18e661 100644
--- a/askbot/tests/utils.py
+++ b/askbot/tests/utils.py
@@ -12,7 +12,26 @@ def create_user(
reputation = 1
):
"""Creates a user and sets default update subscription
- settings"""
+ settings
+
+ ``notification_schedule`` is a dictionary with keys
+ the same as in keys in
+ :attr:`~askbot.models.EmailFeedSetting.FEED_TYPES`:
+
+ * 'q_ask' - questions that user asks
+ * 'q_all' - enture forum, tag filtered
+ * 'q_ans' - questions that user answers
+ * 'q_sel' - questions that user decides to follow
+ * 'm_and_c' - comments and mentions of user anywhere
+
+ and values as keys in
+ :attr:`~askbot.models.EmailFeedSetting.FEED_TYPES`:
+
+ * 'i' - instantly
+ * 'd' - daily
+ * 'w' - weekly
+ * 'n' - never
+ """
user = models.User.objects.create_user(username, email)
user.reputation = reputation
if date_joined is not None: