Пример #1
0
class UTF8HeaderPatchViewTest(UTF8PatchViewTest):
    fixtures = ['default_states', 'default_events']
    patch_filename = '0002-utf-8.patch'
    patch_encoding = 'utf-8'
    patch_author_name = u'P\xe4tch Author'

    def setUp(self):
        defaults.project.save()
        self.patch_author = Person(name=self.patch_author_name,
                                   email=defaults.patch_author_person.email)
        self.patch_author.save()
        self.patch_content = read_patch(self.patch_filename,
                                        encoding=self.patch_encoding)
        self.patch = Patch(project=defaults.project,
                           msgid='x',
                           name=defaults.patch_name,
                           submitter=self.patch_author,
                           content=self.patch_content)
        self.patch.save()
        self.client = Client()

    def tearDown(self):
        self.patch.delete()
        self.patch_author.delete()
        defaults.project.delete()
Пример #2
0
class UTF8PatchViewTest(TestCase):
    fixtures = ['default_states', 'default_events']
    patch_filename = '0002-utf-8.patch'
    patch_encoding = 'utf-8'

    def setUp(self):
        defaults.project.save()
        defaults.patch_author_person.save()
        self.patch_content = read_patch(self.patch_filename,
                                        encoding=self.patch_encoding)
        self.patch = Patch(project=defaults.project,
                           msgid='x',
                           name=defaults.patch_name,
                           submitter=defaults.patch_author_person,
                           content=self.patch_content)
        self.patch.save()
        self.client = Client()

    def testPatchView(self):
        response = self.client.get('/patch/%d/' % self.patch.id)
        self.assertContains(response, self.patch.name)

    def testMboxView(self):
        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(
            self.patch.content in response.content.decode(self.patch_encoding))

    def testRawView(self):
        response = self.client.get('/patch/%d/raw/' % self.patch.id)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content.decode(self.patch_encoding),
                         self.patch.content)

    def tearDown(self):
        self.patch.delete()
        defaults.patch_author_person.delete()
        defaults.project.delete()
Пример #3
0
class UTF8HeaderPatchViewTest(UTF8PatchViewTest):
    patch_filename = '0002-utf-8.patch'
    patch_encoding = 'utf-8'
    patch_author_name = u'P\xe4tch Author'

    def setUp(self):
        defaults.project.save()
        self.patch_author = Person(name = self.patch_author_name,
            email = defaults.patch_author_person.email)
        self.patch_author.save()
        self.patch_content = read_patch(self.patch_filename,
                encoding = self.patch_encoding)
        self.patch = Patch(project = defaults.project,
                           msgid = 'x', name = defaults.patch_name,
                           submitter = self.patch_author,
                           content = self.patch_content)
        self.patch.save()
        self.client = Client()

    def tearDown(self):
        self.patch.delete()
        self.patch_author.delete()
        defaults.project.delete()
Пример #4
0
class UTF8PatchViewTest(TestCase):
    fixtures = ['default_states', 'default_events']
    patch_filename = '0002-utf-8.patch'
    patch_encoding = 'utf-8'

    def setUp(self):
        defaults.project.save()
        defaults.patch_author_person.save()
        self.patch_content = read_patch(self.patch_filename,
                encoding = self.patch_encoding)
        self.patch = Patch(project = defaults.project,
                           msgid = 'x', name = defaults.patch_name,
                           submitter = defaults.patch_author_person,
                           content = self.patch_content)
        self.patch.save()
        self.client = Client()

    def testPatchView(self):
        response = self.client.get('/patch/%d/' % self.patch.id)
        self.assertContains(response, self.patch.name)

    def testMboxView(self):
        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertEquals(response.status_code, 200)
        self.assertTrue(self.patch.content in \
                response.content.decode(self.patch_encoding))

    def testRawView(self):
        response = self.client.get('/patch/%d/raw/' % self.patch.id)
        self.assertEquals(response.status_code, 200)
        self.assertEquals(response.content.decode(self.patch_encoding),
                self.patch.content)

    def tearDown(self):
        self.patch.delete()
        defaults.patch_author_person.delete()
        defaults.project.delete()
Пример #5
0
class PatchTagsTest(TransactionTestCase):
    ACK = 1
    REVIEW = 2
    TEST = 3
    fixtures = ['default_tags', 'default_states']

    def assertTagsEqual(self, patch, acks, reviews, tests):
        patch = Patch.objects.get(pk=patch.pk)

        def count(name):
            try:
                return patch.patchtag_set.get(tag__name=name).count
            except PatchTag.DoesNotExist:
                return 0

        counts = (
            count(name='Acked-by'),
            count(name='Reviewed-by'),
            count(name='Tested-by'),
        )

        self.assertEqual(counts, (acks, reviews, tests))

    def create_tag(self, tagtype = None):
        tags = {
            self.ACK: 'Acked',
            self.REVIEW: 'Reviewed',
            self.TEST: 'Tested'
        }
        if tagtype not in tags:
            return ''
        return '%s-by: %s\n' % (tags[tagtype], self.tagger)

    def create_tag_comment(self, patch, tagtype = None):
        comment = Comment(patch=patch, msgid=str(datetime.datetime.now()),
                submitter=defaults.patch_author_person,
                content=self.create_tag(tagtype))
        comment.save()
        return comment

    def setUp(self):
        settings.DEBUG = True
        project = Project(linkname='test-project', name='Test Project',
            use_tags=True)
        project.save()
        defaults.patch_author_person.save()
        self.patch = Patch(project=project,
                           msgid='x', name=defaults.patch_name,
                           submitter=defaults.patch_author_person,
                           content='')
        self.patch.save()
        self.tagger = 'Test Tagger <*****@*****.**>'

    def tearDown(self):
        self.patch.delete()

    def testNoComments(self):
        self.assertTagsEqual(self.patch, 0, 0, 0)

    def testNoTagComment(self):
        self.create_tag_comment(self.patch, None)
        self.assertTagsEqual(self.patch, 0, 0, 0)

    def testSingleComment(self):
        self.create_tag_comment(self.patch, self.ACK)
        self.assertTagsEqual(self.patch, 1, 0, 0)

    def testMultipleComments(self):
        self.create_tag_comment(self.patch, self.ACK)
        self.create_tag_comment(self.patch, self.ACK)
        self.assertTagsEqual(self.patch, 2, 0, 0)

    def testMultipleCommentTypes(self):
        self.create_tag_comment(self.patch, self.ACK)
        self.create_tag_comment(self.patch, self.REVIEW)
        self.create_tag_comment(self.patch, self.TEST)
        self.assertTagsEqual(self.patch, 1, 1, 1)

    def testCommentAdd(self):
        self.create_tag_comment(self.patch, self.ACK)
        self.assertTagsEqual(self.patch, 1, 0, 0)
        self.create_tag_comment(self.patch, self.ACK)
        self.assertTagsEqual(self.patch, 2, 0, 0)

    def testCommentUpdate(self):
        comment = self.create_tag_comment(self.patch, self.ACK)
        self.assertTagsEqual(self.patch, 1, 0, 0)

        comment.content += self.create_tag(self.ACK)
        comment.save()
        self.assertTagsEqual(self.patch, 2, 0, 0)

    def testCommentDelete(self):
        comment = self.create_tag_comment(self.patch, self.ACK)
        self.assertTagsEqual(self.patch, 1, 0, 0)
        comment.delete()
        self.assertTagsEqual(self.patch, 0, 0, 0)

    def testSingleCommentMultipleTags(self):
        comment = self.create_tag_comment(self.patch, self.ACK)
        comment.content += self.create_tag(self.REVIEW)
        comment.save()
        self.assertTagsEqual(self.patch, 1, 1, 0)

    def testMultipleCommentsMultipleTags(self):
        c1 = self.create_tag_comment(self.patch, self.ACK)
        c1.content += self.create_tag(self.REVIEW)
        c1.save()
        self.assertTagsEqual(self.patch, 1, 1, 0)
Пример #6
0
class PatchTagsTest(TransactionTestCase):
    ACK = 1
    REVIEW = 2
    TEST = 3
    fixtures = ['default_tags', 'default_states', 'default_events']

    def assertTagsEqual(self, patch, acks, reviews, tests):
        patch = Patch.objects.get(pk=patch.pk)

        def count(name):
            try:
                return patch.patchtag_set.get(tag__name=name).count
            except PatchTag.DoesNotExist:
                return 0

        counts = (
            count(name='Acked-by'),
            count(name='Reviewed-by'),
            count(name='Tested-by'),
        )

        self.assertEqual(counts, (acks, reviews, tests))

    def create_tag(self, tagtype=None):
        tags = {
            self.ACK: 'Acked',
            self.REVIEW: 'Reviewed',
            self.TEST: 'Tested'
        }
        if tagtype not in tags:
            return ''
        return '%s-by: %s\n' % (tags[tagtype], self.tagger)

    def create_tag_comment(self, patch, tagtype=None):
        comment = Comment(patch=patch,
                          msgid=str(datetime.datetime.now()),
                          submitter=defaults.patch_author_person,
                          content=self.create_tag(tagtype))
        comment.save()
        return comment

    def setUp(self):
        settings.DEBUG = True
        project = Project(linkname='test-project',
                          name='Test Project',
                          use_tags=True)
        project.save()
        defaults.patch_author_person.save()
        self.patch = Patch(project=project,
                           msgid='x',
                           name=defaults.patch_name,
                           submitter=defaults.patch_author_person,
                           content='')
        self.patch.save()
        self.tagger = 'Test Tagger <*****@*****.**>'

    def tearDown(self):
        self.patch.delete()

    def testNoComments(self):
        self.assertTagsEqual(self.patch, 0, 0, 0)

    def testNoTagComment(self):
        self.create_tag_comment(self.patch, None)
        self.assertTagsEqual(self.patch, 0, 0, 0)

    def testSingleComment(self):
        self.create_tag_comment(self.patch, self.ACK)
        self.assertTagsEqual(self.patch, 1, 0, 0)

    def testMultipleComments(self):
        self.create_tag_comment(self.patch, self.ACK)
        self.create_tag_comment(self.patch, self.ACK)
        self.assertTagsEqual(self.patch, 2, 0, 0)

    def testMultipleCommentTypes(self):
        self.create_tag_comment(self.patch, self.ACK)
        self.create_tag_comment(self.patch, self.REVIEW)
        self.create_tag_comment(self.patch, self.TEST)
        self.assertTagsEqual(self.patch, 1, 1, 1)

    def testCommentAdd(self):
        self.create_tag_comment(self.patch, self.ACK)
        self.assertTagsEqual(self.patch, 1, 0, 0)
        self.create_tag_comment(self.patch, self.ACK)
        self.assertTagsEqual(self.patch, 2, 0, 0)

    def testCommentUpdate(self):
        comment = self.create_tag_comment(self.patch, self.ACK)
        self.assertTagsEqual(self.patch, 1, 0, 0)

        comment.content += self.create_tag(self.ACK)
        comment.save()
        self.assertTagsEqual(self.patch, 2, 0, 0)

    def testCommentDelete(self):
        comment = self.create_tag_comment(self.patch, self.ACK)
        self.assertTagsEqual(self.patch, 1, 0, 0)
        comment.delete()
        self.assertTagsEqual(self.patch, 0, 0, 0)

    def testSingleCommentMultipleTags(self):
        comment = self.create_tag_comment(self.patch, self.ACK)
        comment.content += self.create_tag(self.REVIEW)
        comment.save()
        self.assertTagsEqual(self.patch, 1, 1, 0)

    def testMultipleCommentsMultipleTags(self):
        c1 = self.create_tag_comment(self.patch, self.ACK)
        c1.content += self.create_tag(self.REVIEW)
        c1.save()
        self.assertTagsEqual(self.patch, 1, 1, 0)
Пример #7
0
class PatchNotificationModelTest(TestCase):
    """Tests for the creation & update of the PatchChangeNotification model"""

    def setUp(self):
        self.project = defaults.project
        self.project.send_notifications = True
        self.project.save()
        self.submitter = defaults.patch_author_person
        self.submitter.save()
        self.patch = Patch(project = self.project, msgid = 'testpatch',
                        name = 'testpatch', content = '',
                        submitter = self.submitter)

    def tearDown(self):
        self.patch.delete()
        self.submitter.delete()
        self.project.delete()

    def testPatchCreation(self):
        """Ensure we don't get a notification on create"""
        self.patch.save()
        self.assertEqual(PatchChangeNotification.objects.count(), 0)

    def testPatchUninterestingChange(self):
        """Ensure we don't get a notification for "uninteresting" changes"""
        self.patch.save()
        self.patch.archived = True
        self.patch.save()
        self.assertEqual(PatchChangeNotification.objects.count(), 0)

    def testPatchChange(self):
        """Ensure we get a notification for interesting patch changes"""
        self.patch.save()
        oldstate = self.patch.state
        state = State.objects.exclude(pk = oldstate.pk)[0]

        self.patch.state = state
        self.patch.save()
        self.assertEqual(PatchChangeNotification.objects.count(), 1)
        notification = PatchChangeNotification.objects.all()[0]
        self.assertEqual(notification.patch, self.patch)
        self.assertEqual(notification.orig_state, oldstate)

    def testNotificationCancelled(self):
        """Ensure we cancel notifications that are no longer valid"""
        self.patch.save()
        oldstate = self.patch.state
        state = State.objects.exclude(pk = oldstate.pk)[0]

        self.patch.state = state
        self.patch.save()
        self.assertEqual(PatchChangeNotification.objects.count(), 1)

        self.patch.state = oldstate
        self.patch.save()
        self.assertEqual(PatchChangeNotification.objects.count(), 0)

    def testNotificationUpdated(self):
        """Ensure we update notifications when the patch has a second change,
           but keep the original patch details"""
        self.patch.save()
        oldstate = self.patch.state
        newstates = State.objects.exclude(pk = oldstate.pk)[:2]

        self.patch.state = newstates[0]
        self.patch.save()
        self.assertEqual(PatchChangeNotification.objects.count(), 1)
        notification = PatchChangeNotification.objects.all()[0]
        self.assertEqual(notification.orig_state, oldstate)
        orig_timestamp = notification.last_modified
                         
        self.patch.state = newstates[1]
        self.patch.save()
        self.assertEqual(PatchChangeNotification.objects.count(), 1)
        notification = PatchChangeNotification.objects.all()[0]
        self.assertEqual(notification.orig_state, oldstate)
        self.assertTrue(notification.last_modified > orig_timestamp)

    def testProjectNotificationsDisabled(self):
        """Ensure we don't see notifications created when a project is
           configured not to send them"""
        self.project.send_notifications = False
        self.project.save()

        self.patch.save()
        oldstate = self.patch.state
        state = State.objects.exclude(pk = oldstate.pk)[0]

        self.patch.state = state
        self.patch.save()
        self.assertEqual(PatchChangeNotification.objects.count(), 0)
Пример #8
0
class PatchNotificationEmailTest(TestCase):

    def setUp(self):
        self.project = defaults.project
        self.project.send_notifications = True
        self.project.save()
        self.submitter = defaults.patch_author_person
        self.submitter.save()
        self.patch = Patch(project = self.project, msgid = 'testpatch',
                        name = 'testpatch', content = '',
                        submitter = self.submitter)
        self.patch.save()

    def tearDown(self):
        self.patch.delete()
        self.submitter.delete()
        self.project.delete()

    def _expireNotifications(self, **kwargs):
        timestamp = datetime.datetime.now() - \
                    datetime.timedelta(minutes =
                            settings.NOTIFICATION_DELAY_MINUTES + 1)

        qs = PatchChangeNotification.objects.all()
        if kwargs:
            qs = qs.filter(**kwargs)

        qs.update(last_modified = timestamp)

    def testNoNotifications(self):
        self.assertEquals(send_notifications(), [])

    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 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 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('&quot;' in msg.body)

    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 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.assertEquals(PatchChangeNotification.objects.count(), len(patches))
        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 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)
Пример #9
0
class PatchNotificationModelTest(TestCase):
    fixtures = ['default_states', 'default_events']
    """Tests for the creation & update of the PatchChangeNotification model"""
    def setUp(self):
        self.project = defaults.project
        self.project.send_notifications = True
        self.project.save()
        self.submitter = defaults.patch_author_person
        self.submitter.save()
        self.patch = Patch(project=self.project,
                           msgid='testpatch',
                           name='testpatch',
                           content='',
                           submitter=self.submitter)

    def tearDown(self):
        self.patch.delete()
        self.submitter.delete()
        self.project.delete()

    def testPatchCreation(self):
        """Ensure we don't get a notification on create"""
        self.patch.save()
        self.assertEqual(PatchChangeNotification.objects.count(), 0)

    def testPatchUninterestingChange(self):
        """Ensure we don't get a notification for "uninteresting" changes"""
        self.patch.save()
        self.patch.archived = True
        self.patch.save()
        self.assertEqual(PatchChangeNotification.objects.count(), 0)

    def testPatchChange(self):
        """Ensure we get a notification for interesting patch changes"""
        self.patch.save()
        oldstate = self.patch.state
        state = State.objects.exclude(pk=oldstate.pk)[0]

        self.patch.state = state
        self.patch.save()
        self.assertEqual(PatchChangeNotification.objects.count(), 1)
        notification = PatchChangeNotification.objects.all()[0]
        self.assertEqual(notification.patch, self.patch)
        self.assertEqual(notification.orig_state, oldstate)

    def testNotificationCancelled(self):
        """Ensure we cancel notifications that are no longer valid"""
        self.patch.save()
        oldstate = self.patch.state
        state = State.objects.exclude(pk=oldstate.pk)[0]

        self.patch.state = state
        self.patch.save()
        self.assertEqual(PatchChangeNotification.objects.count(), 1)

        self.patch.state = oldstate
        self.patch.save()
        self.assertEqual(PatchChangeNotification.objects.count(), 0)

    def testNotificationUpdated(self):
        """Ensure we update notifications when the patch has a second change,
           but keep the original patch details"""
        self.patch.save()
        oldstate = self.patch.state
        newstates = State.objects.exclude(pk=oldstate.pk)[:2]

        self.patch.state = newstates[0]
        self.patch.save()
        self.assertEqual(PatchChangeNotification.objects.count(), 1)
        notification = PatchChangeNotification.objects.all()[0]
        self.assertEqual(notification.orig_state, oldstate)
        orig_timestamp = notification.last_modified

        self.patch.state = newstates[1]
        self.patch.save()
        self.assertEqual(PatchChangeNotification.objects.count(), 1)
        notification = PatchChangeNotification.objects.all()[0]
        self.assertEqual(notification.orig_state, oldstate)
        self.assertTrue(notification.last_modified >= orig_timestamp)

    def testProjectNotificationsDisabled(self):
        """Ensure we don't see notifications created when a project is
           configured not to send them"""
        self.project.send_notifications = False
        self.project.save()

        self.patch.save()
        oldstate = self.patch.state
        state = State.objects.exclude(pk=oldstate.pk)[0]

        self.patch.state = state
        self.patch.save()
        self.assertEqual(PatchChangeNotification.objects.count(), 0)
Пример #10
0
class PatchNotificationEmailTest(TestCase):
    fixtures = ['default_states', 'default_events']

    def setUp(self):
        self.project = defaults.project
        self.project.send_notifications = True
        self.project.save()
        self.submitter = defaults.patch_author_person
        self.submitter.save()
        self.patch = Patch(project=self.project,
                           msgid='testpatch',
                           name='testpatch',
                           content='',
                           submitter=self.submitter)
        self.patch.save()

    def tearDown(self):
        self.patch.delete()
        self.submitter.delete()
        self.project.delete()

    def _expireNotifications(self, **kwargs):
        timestamp = datetime.datetime.now() - \
                    datetime.timedelta(minutes =
                            settings.NOTIFICATION_DELAY_MINUTES + 1)

        qs = PatchChangeNotification.objects.all()
        if kwargs:
            qs = qs.filter(**kwargs)

        qs.update(last_modified=timestamp)

    def testNoNotifications(self):
        self.assertEquals(send_notifications(), [])

    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 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 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('&quot;' in msg.body)

    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 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.assertEquals(PatchChangeNotification.objects.count(),
                          len(patches))
        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 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)
Пример #11
0
class PatchChecksTest(TransactionTestCase):
    fixtures = ['default_tags', 'default_states']

    def setUp(self):
        project = defaults.project
        defaults.project.save()
        defaults.patch_author_person.save()
        self.patch = Patch(project=project,
                           msgid='x', name=defaults.patch_name,
                           submitter=defaults.patch_author_person,
                           diff='')
        self.patch.save()
        self.user = create_user()

    def create_check(self, **kwargs):
        check_values = {
            'patch': self.patch,
            'user': self.user,
            'date': dt.now(),
            'state': Check.STATE_SUCCESS,
            'target_url': 'http://example.com/',
            'description': '',
            'context': 'intel/jenkins-ci',
        }

        for key in check_values:
            if key in kwargs:
                check_values[key] = kwargs[key]

        check = Check(**check_values)
        check.save()
        return check

    def assertCheckEqual(self, patch, check_state):
        self.assertEqual(self.patch.combined_check_state, check_state)

    def assertChecksEqual(self, patch, checks=None):
        if not checks:
            checks = []

        self.assertEqual(len(self.patch.checks), len(checks))
        self.assertEqual(
            sorted(self.patch.checks, key=lambda check: check.id),
            sorted(checks, key=lambda check: check.id))

    def assertCheckCountEqual(self, patch, total, state_counts=None):
        if not state_counts:
            state_counts = {}

        counts = self.patch.check_count

        self.assertEqual(self.patch.check_set.count(), total)

        for state in state_counts:
            self.assertEqual(counts[state], state_counts[state])

        # also check the ones we didn't explicitly state
        for state, _ in Check.STATE_CHOICES:
            if state not in state_counts:
                self.assertEqual(counts[state], 0)

    def tearDown(self):
        self.patch.delete()

    def test_checks__no_checks(self):
        self.assertChecksEqual(self.patch, [])

    def test_checks__single_check(self):
        check = self.create_check()
        self.assertChecksEqual(self.patch, [check])

    def test_checks__multiple_checks(self):
        check_a = self.create_check()
        check_b = self.create_check(context='new-context/test1')
        self.assertChecksEqual(self.patch, [check_a, check_b])

    def test_checks__duplicate_checks(self):
        self.create_check(date=(dt.now() - timedelta(days=1)))
        check = self.create_check()
        # this isn't a realistic scenario (dates shouldn't be set by user so
        #   they will always increment), but it's useful to verify the removal
        #   of older duplicates by the function
        self.create_check(date=(dt.now() - timedelta(days=2)))
        self.assertChecksEqual(self.patch, [check])

    def test_check_count__no_checks(self):
        self.assertCheckCountEqual(self.patch, 0)

    def test_check_count__single_check(self):
        self.create_check()
        self.assertCheckCountEqual(self.patch, 1, {Check.STATE_SUCCESS: 1})

    def test_check_count__multiple_checks(self):
        self.create_check(date=(dt.now() - timedelta(days=1)))
        self.create_check(context='new/test1')
        self.assertCheckCountEqual(self.patch, 2, {Check.STATE_SUCCESS: 2})

    def test_check_count__duplicate_check_same_state(self):
        self.create_check(date=(dt.now() - timedelta(days=1)))
        self.assertCheckCountEqual(self.patch, 1, {Check.STATE_SUCCESS: 1})

        self.create_check()
        self.assertCheckCountEqual(self.patch, 2, {Check.STATE_SUCCESS: 1})

    def test_check_count__duplicate_check_new_state(self):
        self.create_check(date=(dt.now() - timedelta(days=1)))
        self.assertCheckCountEqual(self.patch, 1, {Check.STATE_SUCCESS: 1})

        self.create_check(state=Check.STATE_FAIL)
        self.assertCheckCountEqual(self.patch, 2, {Check.STATE_FAIL: 1})

    def test_check__no_checks(self):
        self.assertCheckEqual(self.patch, Check.STATE_PENDING)

    def test_check__single_check(self):
        self.create_check()
        self.assertCheckEqual(self.patch, Check.STATE_SUCCESS)

    def test_check__failure_check(self):
        self.create_check()
        self.create_check(context='new/test1', state=Check.STATE_FAIL)
        self.assertCheckEqual(self.patch, Check.STATE_FAIL)

    def test_check__warning_check(self):
        self.create_check()
        self.create_check(context='new/test1', state=Check.STATE_WARNING)
        self.assertCheckEqual(self.patch, Check.STATE_WARNING)

    def test_check__success_check(self):
        self.create_check()
        self.create_check(context='new/test1')
        self.assertCheckEqual(self.patch, Check.STATE_SUCCESS)