def test_two_overrides_dont_collide_with_eachother(self): with override_service('metrics', FakeMetrics): Services.metrics.view.record("1") self.assertEqual([("1", {})], Services.metrics.view.records) with override_service('metrics', FakeMetrics): Services.metrics.view.record("2") self.assertEqual([("2", {})], Services.metrics.view.records)
def test_delivering_email_records_email_sent_metric(self): with override_service('experiment_placer', FakeExperimentPlacer, kwargs={'email_notifications': 'experimental'}): user = create_user(email="*****@*****.**") comment = create_comment() comment2 = create_comment(author=user, replied_comment=comment) pn = Actions.replied(user, comment2) notification = Notification.from_pending_notification(pn, user, "EmailChannel") channel = EmailChannel() with override_service('metrics', FakeMetrics): channel.deliver(notification) self.assertEqual(1, len(Services.metrics.email_sent.records))
def test_today(self): with override_service('time', FakeTimeProvider): today = datetime.datetime.today() today = datetime.datetime(*today.timetuple()[:6]) now = time.mktime(today.timetuple()) Services.time.t = now self.assertEqual(Services.time.today(), today)
def _test_rate_limit(self, user, allowed): with override_service('time', FakeTimeProvider, kwargs={'t': 1333333333.}): client = self.get_client(user=user) flag_count = min( freq for freq, timespan in knobs.FLAG_RATE_LIMITS.itervalues()) + 1 cmts = [ self.post_comment(reply_content=create_content().id) for _ in xrange(flag_count) ] msg = None for cmt in cmts: resp = self.api_post('/api/comment/flag', {'comment_id': cmt.id}, client=client) if not resp['success']: msg = resp['reason'] break getattr(self, { True: 'assertEqual', False: 'assertNotEqual' }[allowed])(msg, None) if not allowed: self.assertTrue('limit' in msg)
def test_with_html(self): with override_service('time', FakeTimeProvider): timestamp = Services.time.time() - 60*60*24*365*9001 html = jinja_tags.relative_timestamp(timestamp) self.assertTrue('9001 years' in html) self.assertTrue('rel-timestamp' in html) self.assertTrue(str(timestamp) in html)
def test_send_email_happens_once_per_recipient(self): with override_service('time', FakeTimeProvider): user = create_staff() Services.time.step(60*60*24) (recipient,) = send_24h_email.recipients() self.assertEqual(recipient, user) with override_service('metrics', FakeMetrics): def send(): for user in send_24h_email.recipients(): send_24h_email.send_welcome_email(user) self.assertEqual(0, len(Services.metrics.email_sent.records)) send() self.assertEqual(1, len(Services.metrics.email_sent.records), "The digest email wasn't sent.") send() self.assertEqual(1, len(Services.metrics.email_sent.records), "The email was sent twice.")
def test_really_old_users_dont_get_it(self): with override_service('time', FakeTimeProvider): user = create_user() Services.time.step(60*60*24) self.assertTrue(user in send_24h_email.recipients()) Services.time.step(60*60*24*30) # a month later. self.assertFalse(user in send_24h_email.recipients())
def after_setUp(self): self.user = create_user() self.COMMENT_COUNT = 7 self.GROUP = create_group(name=Config['featured_groups'][0]) self.TODAY = datetime.datetime(year=2011, month=2, day=3) with override_service('time', FakeTimeProvider): #TODO refactor into tests_helpers and consolidate w/ other tests that do this (email_channel, models) Services.time.t = time.mktime(self.TODAY.timetuple()) self.comments = [ self.post_comment(reply_content=create_content().id, category=self.GROUP.name) for _ in xrange(self.COMMENT_COUNT - 1) ] self.comments.append( self.post_comment(reply_content=create_content().id, category=self.GROUP.name, parent_comment=self.comments[-1].id)) Services.time.step(60 * 60) for cmt in self.comments: self.api_post('/api/sticker/comment', { 'type_id': '1', 'comment_id': cmt.id }, user=create_user()) Services.time.step() Services.time.step(60 * 60) cmt.update_score()
def test_with_html(self): with override_service('time', FakeTimeProvider): timestamp = Services.time.time() - 60 * 60 * 24 * 365 * 9001 html = jinja_tags.relative_timestamp(timestamp) self.assertTrue('9001 years' in html) self.assertTrue('rel-timestamp' in html) self.assertTrue(str(timestamp) in html)
def test_really_old_users_dont_get_it(self): with override_service('time', FakeTimeProvider): user = create_user() Services.time.step(60 * 60 * 24) self.assertTrue(user in send_24h_email.recipients()) Services.time.step(60 * 60 * 24 * 30) # a month later. self.assertFalse(user in send_24h_email.recipients())
def test_streak_rewards(self): user = create_user() with override_service('time', FakeTimeProvider): def post(): quest = create_current_quest() def rewards(): resp = self.api_post('/api/quest_comments/rewards_for_posting', {'quest_id': quest.id}, user=user) self.assertAPISuccess(resp) print resp return resp['rewards'] before = rewards() self._post(user=user, quest=quest) after = rewards() Services.time.t += 60*60*24 return (before, after,) current_streak = 0 streaks = [3, 10, 100] for _ in xrange(4): #TODO should be higher but this is just too slow. before, after = post() for streak in streaks: msg = 'After posting this, the current streak would be: {}'.format(current_streak + 1) if (current_streak + 1) == streak: self.assertTrue('streak_' + str(streak) in before, msg) self.assertFalse('streak_' + str(streak) in after, msg) else: self.assertFalse('streak_' + str(streak) in before, msg) current_streak += 1
def test_trigger_rate_limit(self): knobs.PUBLIC_API_RATE_LIMIT = 2 with override_service('time', FakeTimeProvider): def inner(): for x in range(knobs.PUBLIC_API_RATE_LIMIT + 5): result = self.get('/public_api/') self.assertAPISuccess(result) self.assertRaises(AssertionError, inner)
def test_can_force_user_into_control(self): user = create_user() with override_service('experiment_placer', FakeExperimentPlacer, kwargs={'null_hypothesis': 'control'}): self.assertEqual( 'control', user.redis.experiments.get(Experiments.null_hypothesis).name)
def test_rate_limit_restarts_after_time(self): with override_service('time', FakeTimeProvider): self.assertTrue(self.rl.allowed()) self.assertTrue(self.rl.allowed()) Services.time.step(100) self.assertTrue(self.rl.allowed()) self.assertTrue(self.rl.allowed()) self.assertFalse(self.rl.allowed())
def test_logged_out_best_everything_returns_enough_comments(self): with override_service('time', FakeTimeProvider): Services.time.t = time.mktime(self.TODAY.timetuple()) for category in [Category.ALL] + list(Category.objects.all()): category.merge_top_scores() cmts = get_front_comments(AnonymousUser(), Navigation(sort='best', offset=0, year=2011, category=Category.ALL)) self.assertEqual(len(cmts), self.COMMENT_COUNT)
def test_send_notification(self): with override_service('metrics', FakeMetrics): user = create_staff() pn = self.api_post('/api/staff/send_notification_email', { 'action': 'digest', 'username': user.username, }, user=create_staff()) self.assertAPISuccess(pn) self.assertEqual(1, len(Services.metrics.email_sent.records))
def test_details_replies_one_reply(self): with override_service('time', FakeTimeProvider): cmt = create_comment() Services.time.step() child = create_comment(parent_comment=cmt) d = cmt.details() self.assertEqual(d.reply_count, 1) self.assertEqual(d.last_reply_id, child.id) self.assertAlmostEqual(d.last_reply_time, child.timestamp, places=4)
def test_send_email_happens_once_per_recipient(self): with override_service('time', FakeTimeProvider): user = create_staff() Services.time.step(60 * 60 * 24) (recipient, ) = send_24h_email.recipients() self.assertEqual(recipient, user) with override_service('metrics', FakeMetrics): def send(): for user in send_24h_email.recipients(): send_24h_email.send_welcome_email(user) self.assertEqual(0, len(Services.metrics.email_sent.records)) send() self.assertEqual(1, len(Services.metrics.email_sent.records), "The digest email wasn't sent.") send() self.assertEqual(1, len(Services.metrics.email_sent.records), "The email was sent twice.")
def test_logged_out_best_everything_returns_enough_comments(self): with override_service('time', FakeTimeProvider): Services.time.t = time.mktime(self.TODAY.timetuple()) for category in [Category.ALL] + list(Category.objects.all()): category.merge_top_scores() cmts = get_front_comments( AnonymousUser(), Navigation(sort='best', offset=0, year=2011, category=Category.ALL)) self.assertEqual(len(cmts), self.COMMENT_COUNT)
def test_threshold_doubles_appropriately(self): mt = ThresholdMetric(str(random()), 5, 1) with override_service('time', FakeTimeProvider): self.assertFalse(mt.is_okay()) mt.increment() mt.increment() Services.time.step(30) mt.increment() mt.increment() Services.time.step(50) mt.increment() mt.increment() self.assertFalse(mt.is_okay()) self.assertTrue(mt.is_okay(True))
def test_already_received(self): with override_service('time', FakeTimeProvider): # Create dummy first, so count of users and count of recipients is unequal. create_user() Services.time.step(60*60*48) user = create_user() self.assertFalse(user in send_24h_email.recipients()) Services.time.step(60*60*48) WelcomeEmailRecipient.objects.create(recipient=user) recipients = send_24h_email.recipients() self.assertFalse(user in recipients) self.assertFalse(recipients)
def _test_rate_limit(self, user, allowed): with override_service('time', FakeTimeProvider, kwargs={'t': 1333333333.}): client = self.get_client(user=user) flag_count = min(freq for freq,timespan in knobs.FLAG_RATE_LIMITS.itervalues()) + 1 cmts = [self.post_comment(reply_content=create_content().id) for _ in xrange(flag_count)] msg = None for cmt in cmts: resp = self.api_post('/api/comment/flag', {'comment_id': cmt.id}, client=client) if not resp['success']: msg = resp['reason'] break getattr(self, {True: 'assertEqual', False: 'assertNotEqual'}[allowed])(msg, None) if not allowed: self.assertTrue('limit' in msg)
def test_already_received(self): with override_service('time', FakeTimeProvider): # Create dummy first, so count of users and count of recipients is unequal. create_user() Services.time.step(60 * 60 * 48) user = create_user() self.assertFalse(user in send_24h_email.recipients()) Services.time.step(60 * 60 * 48) WelcomeEmailRecipient.objects.create(recipient=user) recipients = send_24h_email.recipients() self.assertFalse(user in recipients) self.assertFalse(recipients)
def test_time_only(self): with override_service('time', FakeTimeProvider): for t, s in ((1, 'a moment'), (59, 'a moment'), (60, '1 minute'), (60*5, '5 minutes'), (60*60*24, '1 day'), (60*60*23, '23 hours'), (60*60*23.9, '23 hours'), (60*60*23.999, '23 hours'), (60*60*24*365*1.2, '1 year'), (60*60*24*365*1.9, '1 year'), (60*60*24*365*9001, '9001 years'),): then = Services.time.time() - t self.assertEqual(jinja_tags._relative_timestamp(then), s + ' ago')
def test_negative_threshold_returns_to_success(self): mt = ThresholdMetric(str(random()), -5, 1) with override_service('time', FakeTimeProvider): self.assertTrue(mt.is_okay()) mt.increment() Services.time.step(30) mt.increment() mt.increment() mt.increment() mt.increment() self.assertFalse(mt.is_okay()) Services.time.step(50) self.assertTrue(mt.is_okay()) mt.increment() self.assertFalse(mt.is_okay())
def test_24h_digest_email_has_top_comments(self): COMMENT_COUNT = knobs.TWENTYFOUR_HOUR_EMAIL_COMMENT_COUNT GROUP = create_group(name=Config["featured_groups"][0]) TODAY = datetime.datetime(year=2011, month=2, day=3) with override_service("time", FakeTimeProvider): # TODO refactor into tests_helpers and consolidate w/ other tests that do this (email_channel, models) # Make posts to show up in 'best'. Services.time.t = time.mktime(TODAY.timetuple()) comments = [ self.post_comment(reply_content=create_content().id, category=GROUP.name) for _ in xrange(COMMENT_COUNT) ] Services.time.step(60 * 60) # Sticker them. for cmt in comments: self.api_post("/api/sticker/comment", {"type_id": "1", "comment_id": cmt.id}, user=create_user()) Services.time.step(60 * 60) cmt.update_score() def merge_scores(): for category in [Category.ALL] + list(Category.objects.all()): category.merge_top_scores() merge_scores() def get_email_message(): user = create_user() pn = Actions.digest(user) notification = Notification.from_pending_notification(pn, user, "EmailChannel") return EmailChannel().make_message(notification, force=True) email_message = get_email_message() for cmt in comments: self.assertTrue(cmt.get_absolute_url() in email_message.body_html) # Wait a couple months, and make sure the comments disappear (so we're only showing top of the month, # not top of the year). Services.time.step(60 * 60 * 24 * 30 * 2) for cmt in comments: cmt.update_score() merge_scores() email_message = get_email_message() for cmt in comments: self.assertFalse(cmt.get_absolute_url() in email_message.body_html)
def test_users_over_one_day_old(self): with override_service('time', FakeTimeProvider): beginning_count = User.users_over_one_day_old().count() def assert_count(count, cutoff=None): self.assertEqual(beginning_count + count, User.users_over_one_day_old(cutoff=cutoff).count()) assert_count(0) [create_user() for _ in xrange(2)] assert_count(0) Services.time.step(60*60*48) assert_count(2) create_user() assert_count(2) Services.time.step(60*60) assert_count(2) assert_count(0, cutoff=(Services.time.today() - datetime.timedelta(days=1)))
def test_time_only(self): with override_service('time', FakeTimeProvider): for t, s in ( (1, 'a moment'), (59, 'a moment'), (60, '1 minute'), (60 * 5, '5 minutes'), (60 * 60 * 24, '1 day'), (60 * 60 * 23, '23 hours'), (60 * 60 * 23.9, '23 hours'), (60 * 60 * 23.999, '23 hours'), (60 * 60 * 24 * 365 * 1.2, '1 year'), (60 * 60 * 24 * 365 * 1.9, '1 year'), (60 * 60 * 24 * 365 * 9001, '9001 years'), ): then = Services.time.time() - t self.assertEqual(jinja_tags._relative_timestamp(then), s + ' ago')
def test_24h_digest_email_has_top_comments(self): COMMENT_COUNT = knobs.TWENTYFOUR_HOUR_EMAIL_COMMENT_COUNT GROUP = create_group(name=Config['featured_groups'][0]) TODAY = datetime.datetime(year=2011, month=2, day=3) with override_service('time', FakeTimeProvider): #TODO refactor into tests_helpers and consolidate w/ other tests that do this (email_channel, models) # Make posts to show up in 'best'. Services.time.t = time.mktime(TODAY.timetuple()) comments = [self.post_comment(reply_content=create_content().id, category=GROUP.name) for _ in xrange(COMMENT_COUNT)] Services.time.step(60*60) # Sticker them. for cmt in comments: self.api_post('/api/sticker/comment', {'type_id': '1', 'comment_id': cmt.id}, user=create_user()) Services.time.step(60*60) cmt.update_score() def merge_scores(): for category in [Category.ALL] + list(Category.objects.all()): category.merge_top_scores() merge_scores() def get_email_message(): user = create_user() pn = Actions.digest(user) notification = Notification.from_pending_notification(pn, user, "EmailChannel") return EmailChannel().make_message(notification, force=True) email_message = get_email_message() for cmt in comments: self.assertTrue(cmt.get_absolute_url() in email_message.body_html) # Wait a couple months, and make sure the comments disappear (so we're only showing top of the month, # not top of the year). Services.time.step(60*60*24*30*2) for cmt in comments: cmt.update_score() merge_scores() email_message = get_email_message() for cmt in comments: self.assertFalse(cmt.get_absolute_url() in email_message.body_html)
def test_streak_rewards(self): user = create_user() with override_service('time', FakeTimeProvider): def post(): quest = create_current_quest() def rewards(): resp = self.api_post( '/api/quest_comments/rewards_for_posting', {'quest_id': quest.id}, user=user) self.assertAPISuccess(resp) print resp return resp['rewards'] before = rewards() self._post(user=user, quest=quest) after = rewards() Services.time.t += 60 * 60 * 24 return ( before, after, ) current_streak = 0 streaks = [3, 10, 100] for _ in xrange( 4): #TODO should be higher but this is just too slow. before, after = post() for streak in streaks: msg = 'After posting this, the current streak would be: {}'.format( current_streak + 1) if (current_streak + 1) == streak: self.assertTrue('streak_' + str(streak) in before, msg) self.assertFalse('streak_' + str(streak) in after, msg) else: self.assertFalse('streak_' + str(streak) in before, msg) current_streak += 1
def after_setUp(self): self.user = create_user() self.COMMENT_COUNT = 7 self.GROUP = create_group(name=Config['featured_groups'][0]) self.TODAY = datetime.datetime(year=2011, month=2, day=3) with override_service('time', FakeTimeProvider): #TODO refactor into tests_helpers and consolidate w/ other tests that do this (email_channel, models) Services.time.t = time.mktime(self.TODAY.timetuple()) self.comments = [self.post_comment(reply_content=create_content().id, category=self.GROUP.name) for _ in xrange(self.COMMENT_COUNT - 1)] self.comments.append(self.post_comment(reply_content=create_content().id, category=self.GROUP.name, parent_comment=self.comments[-1].id)) Services.time.step(60*60) for cmt in self.comments: self.api_post('/api/sticker/comment', {'type_id': '1', 'comment_id': cmt.id}, user=create_user()) Services.time.step() Services.time.step(60*60) cmt.update_score()
def test_not_yet_receieved(self): with override_service('time', FakeTimeProvider): user = create_user() Services.time.step(60 * 60 * 24) recipients = send_24h_email.recipients() self.assertTrue(user in recipients)
def test_not_yet_receieved(self): with override_service('time', FakeTimeProvider): user = create_user() Services.time.step(60*60*24) recipients = send_24h_email.recipients() self.assertTrue(user in recipients)
def test_threshold_initial_failure(self): mt = ThresholdMetric(str(random()), 5, 1) with override_service('time', FakeTimeProvider): self.assertFalse(mt.is_okay())
def test_context_overrides(self): self.assertFalse(isinstance(Services.time, FakeTimeProvider)) with override_service('time', FakeTimeProvider): self.assertTrue(isinstance(Services.time, FakeTimeProvider))
def test_can_force_user_into_control(self): user = create_user() with override_service('experiment_placer', FakeExperimentPlacer, kwargs={'null_hypothesis': 'control'}): self.assertEqual('control', user.redis.experiments.get(Experiments.null_hypothesis).name)