diff options
author | Andrei <mamoutkine@gmail.com> | 2011-04-07 22:52:53 -0400 |
---|---|---|
committer | Andrei <mamoutkine@gmail.com> | 2011-04-07 22:52:53 -0400 |
commit | 9caf98334054f85419a3fcceec3a0ccbc6f205d6 (patch) | |
tree | 19b5a09106b46d20377b7a80910c468f408e5c2d | |
parent | cbd388912e6627e5eddc429752fea3e5509ff175 (diff) | |
download | askbot-9caf98334054f85419a3fcceec3a0ccbc6f205d6.tar.gz askbot-9caf98334054f85419a3fcceec3a0ccbc6f205d6.tar.bz2 askbot-9caf98334054f85419a3fcceec3a0ccbc6f205d6.zip |
fixed another correctness bug on tag subscriptions
-rw-r--r-- | askbot/models/content.py | 12 | ||||
-rw-r--r-- | askbot/models/tag.py | 13 | ||||
-rw-r--r-- | askbot/tests/db_api_tests.py | 1 | ||||
-rw-r--r-- | askbot/tests/email_alert_tests.py | 70 | ||||
-rw-r--r-- | askbot/tests/utils.py | 21 |
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: |