def test_unexpired_notification_merge(self): """Test that when there are multiple pending notifications, with at least one within the notification delay, that other notifications are held""" patches = create_patches(2, project=self.project) for patch in patches: patch.save() PatchChangeNotification(patch=patch, orig_state=patch.state).save() state = create_state() self.assertEqual(PatchChangeNotification.objects.count(), len(patches)) self._expire_notifications() # update one notification, to bring it out of the notification delay patches[0].state = state patches[0].save() # the updated notification should prevent the other from being sent errors = send_notifications() self.assertEqual(errors, []) self.assertEqual(len(mail.outbox), 0) # expire the updated notification self._expire_notifications() errors = send_notifications() self.assertEqual(errors, []) self.assertEqual(len(mail.outbox), 1) msg = mail.outbox[0] for patch in patches: self.assertIn(patch.get_absolute_url(), msg.body)
def testNoReadyNotifications(self): """ We shouldn't see immediate notifications""" PatchChangeNotification(patch=self.patch, orig_state=self.patch.state).save() errors = send_notifications() self.assertEquals(errors, []) self.assertEquals(len(mail.outbox), 0)
def test_no_ready_notifications(self): """We shouldn't see immediate notifications.""" patch = create_patch(project=self.project) PatchChangeNotification(patch=patch, orig_state=patch.state).save() errors = send_notifications() self.assertEqual(errors, []) self.assertEqual(len(mail.outbox), 0)
def patch_change_callback(sender, instance, raw, **kwargs): # we only want notification of modified patches if raw or instance.pk is None: return if instance.project is None or not instance.project.send_notifications: return try: orig_patch = Patch.objects.get(pk=instance.pk) except Patch.DoesNotExist: return # If there's no interesting changes, abort without creating the # notification if orig_patch.state == instance.state: return notification = None try: notification = PatchChangeNotification.objects.get(patch=instance) except PatchChangeNotification.DoesNotExist: pass if notification is None: notification = PatchChangeNotification(patch=instance, orig_state=orig_patch.state) elif notification.orig_state == instance.state: # If we're back at the original state, there is no need to notify notification.delete() return notification.last_modified = dt.now() notification.save()
def testNotificationOptout(self): """ensure opt-out addresses don't get notifications""" PatchChangeNotification(patch=self.patch, orig_state=self.patch.state).save() self._expireNotifications() EmailOptout(email=self.submitter.email).save() errors = send_notifications() self.assertEquals(errors, []) self.assertEquals(len(mail.outbox), 0)
def testNotifications(self): PatchChangeNotification(patch=self.patch, orig_state=self.patch.state).save() self._expireNotifications() errors = send_notifications() self.assertEquals(errors, []) self.assertEquals(len(mail.outbox), 1) msg = mail.outbox[0] self.assertEquals(msg.to, [self.submitter.email]) self.assertTrue(self.patch.get_absolute_url() in msg.body)
def test_notification_optout(self): """Ensure opt-out addresses don't get notifications.""" patch = create_patch(project=self.project) PatchChangeNotification(patch=patch, orig_state=patch.state).save() self._expire_notifications() EmailOptout(email=patch.submitter.email).save() errors = send_notifications() self.assertEqual(errors, []) self.assertEqual(len(mail.outbox), 0)
def test_notifications(self): patch = create_patch(project=self.project) PatchChangeNotification(patch=patch, orig_state=patch.state).save() self._expire_notifications() errors = send_notifications() self.assertEqual(errors, []) self.assertEqual(len(mail.outbox), 1) msg = mail.outbox[0] self.assertEqual(msg.to, [patch.submitter.email]) self.assertIn(patch.get_absolute_url(), msg.body)
def patch_change_callback(sender, instance, raw, **kwargs): # we only want notification of modified patches if raw or instance.pk is None: return if instance.project is None or not instance.project.send_notifications: return try: orig_patch = Patch.objects.get(pk=instance.pk) except Patch.DoesNotExist: return # If there's no interesting changes, abort without creating the # notification if orig_patch.state == instance.state: return notification = None try: notification = PatchChangeNotification.objects.get(patch=instance) except PatchChangeNotification.DoesNotExist: pass if notification is None: notification = PatchChangeNotification(patch=instance, orig_state=orig_patch.state) elif notification.orig_state == instance.state: # If we're back at the original state, there is no need to notify notification.delete() return notification.last_modified = dt.utcnow() notification.save()
def test_notification_escaping(self): patch = create_patch(name='Patch name with " character', project=self.project) PatchChangeNotification(patch=patch, orig_state=patch.state).save() self._expire_notifications() errors = send_notifications() self.assertEqual(errors, []) self.assertEqual(len(mail.outbox), 1) msg = mail.outbox[0] self.assertEqual(msg.to, [patch.submitter.email]) self.assertNotIn('"', msg.body)
def testNotificationEscaping(self): self.patch.name = 'Patch name with " character' self.patch.save() PatchChangeNotification(patch=self.patch, orig_state=self.patch.state).save() self._expireNotifications() errors = send_notifications() self.assertEquals(errors, []) self.assertEquals(len(mail.outbox), 1) msg = mail.outbox[0] self.assertEquals(msg.to, [self.submitter.email]) self.assertFalse('"' in msg.body)
def test_notification_merge(self): """Ensure only one summary email is delivered to each user.""" patches = create_patches(2, project=self.project) for patch in patches: PatchChangeNotification(patch=patch, orig_state=patch.state).save() self.assertEqual(PatchChangeNotification.objects.count(), len(patches)) self._expire_notifications() errors = send_notifications() self.assertEqual(errors, []) self.assertEqual(len(mail.outbox), 1) msg = mail.outbox[0] for patch in patches: self.assertIn(patch.get_absolute_url(), msg.body)
def testUnexpiredNotificationMerge(self): """Test that when there are multiple pending notifications, with at least one within the notification delay, that other notifications are held""" patches = [ self.patch, Patch(project=self.project, msgid='testpatch-2', name='testpatch 2', content='', submitter=self.submitter) ] for patch in patches: patch.save() PatchChangeNotification(patch=patch, orig_state=patch.state).save() self.assertEquals(PatchChangeNotification.objects.count(), len(patches)) self._expireNotifications() # update one notification, to bring it out of the notification delay patches[0].state = State.objects.exclude(pk=patches[0].state.pk)[0] patches[0].save() # the updated notification should prevent the other from being sent errors = send_notifications() self.assertEquals(errors, []) self.assertEquals(len(mail.outbox), 0) # expire the updated notification self._expireNotifications() errors = send_notifications() self.assertEquals(errors, []) self.assertEquals(len(mail.outbox), 1) msg = mail.outbox[0] self.assertTrue(patches[0].get_absolute_url() in msg.body) self.assertTrue(patches[1].get_absolute_url() in msg.body)
def testNotificationMerge(self): patches = [ self.patch, Patch(project=self.project, msgid='testpatch-2', name='testpatch 2', content='', submitter=self.submitter) ] for patch in patches: patch.save() PatchChangeNotification(patch=patch, orig_state=patch.state).save() self.assertEqual(PatchChangeNotification.objects.count(), len(patches)) self._expireNotifications() errors = send_notifications() self.assertEqual(errors, []) self.assertEqual(len(mail.outbox), 1) msg = mail.outbox[0] self.assertIn(patches[0].get_absolute_url(), msg.body) self.assertIn(patches[1].get_absolute_url(), msg.body)