Exemplo n.º 1
0
class MboxGeneratedHeaderTest(TestCase):
    fixtures = ['default_states', 'default_events']

    def setUp(self):
        defaults.project.save()
        self.person = defaults.patch_author_person
        self.person.save()

        self.user = create_user()

        self.patch = Patch(project=defaults.project,
                           msgid='p1',
                           name='testpatch',
                           submitter=self.person,
                           delegate=self.user,
                           content='')
        self.patch.save()

    def testPatchworkIdHeader(self):
        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response, 'X-Patchwork-Id: %d' % self.patch.id)

    def testPatchworkDelegateHeader(self):
        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response,
                            'X-Patchwork-Delegate: %s' % self.user.email)
Exemplo n.º 2
0
class MboxPassThroughHeaderTest(TestCase):
    """ Test that we see 'Cc' and 'To' headers passed through from original
        message to mbox view """

    def setUp(self):
        defaults.project.save()
        self.person = defaults.patch_author_person
        self.person.save()

        self.cc_header = 'Cc: CC Person <*****@*****.**>'
        self.to_header = 'To: To Person <*****@*****.**>'

        self.patch = Patch(project = defaults.project,
                           msgid = 'p1', name = 'testpatch',
                           submitter = self.person, content = '')

    def testCCHeader(self):
        self.patch.headers = self.cc_header + '\n'
        self.patch.save()

        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response, self.cc_header)

    def testToHeader(self):
        self.patch.headers = self.to_header + '\n'
        self.patch.save()

        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response, self.to_header)
Exemplo n.º 3
0
class MboxGeneratedHeaderTest(TestCase):
    fixtures = ['default_states']

    def setUp(self):
        defaults.project.save()
        self.person = defaults.patch_author_person
        self.person.save()

        self.user = create_user()

        self.patch = Patch(project=defaults.project,
                           msgid='p1',
                           name='testpatch',
                           submitter=self.person,
                           delegate=self.user,
                           content='')
        self.patch.save()

    def testPatchworkIdHeader(self):
        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response, 'X-Patchwork-Id: %d' % self.patch.id)

    def testPatchworkDelegateHeader(self):
        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response,
                            'X-Patchwork-Delegate: %s' % self.user.email)
Exemplo n.º 4
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()
Exemplo n.º 5
0
class MboxCommentPostcriptUnchangedTest(TestCase):
    fixtures = ['default_states', 'default_events']
    """ Test that the mbox view doesn't change the postscript part of a mail.
        There where always a missing blank right after the postscript
        delimiter '---' and an additional newline right before. """
    def setUp(self):
        defaults.project.save()

        self.person = defaults.patch_author_person
        self.person.save()

        self.patch = Patch(project=defaults.project,
                           msgid='p1',
                           name='testpatch',
                           submitter=self.person,
                           content='')
        self.patch.save()

        self.txt = 'some comment\n---\n some/file | 1 +\n'

        comment = Comment(patch=self.patch,
                          msgid='p1',
                          submitter=self.person,
                          content=self.txt)
        comment.save()

    def testCommentUnchanged(self):
        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response, self.txt)
        self.txt += "\n"
        self.assertNotContains(response, self.txt)
Exemplo n.º 6
0
 def _insert_patch(self):
     patch = Patch(project=defaults.project,
                   submitter=defaults.patch_author_person,
                   msgid=defaults.patch_name,
                   content=defaults.patch)
     patch.save()
     return patch
Exemplo n.º 7
0
class MboxPatchSplitResponseTest(TestCase):
    fixtures = ['default_states', 'default_events']
    """ Test that the mbox view appends the Acked-by from a patch comment,
        and places it before an '---' update line. """
    def setUp(self):
        defaults.project.save()

        self.person = defaults.patch_author_person
        self.person.save()

        self.patch = Patch(project=defaults.project,
                           msgid='p1',
                           name='testpatch',
                           submitter=self.person,
                           content='')
        self.patch.save()
        comment = Comment(patch=self.patch,
                          msgid='p1',
                          submitter=self.person,
                          content='comment 1 text\nAcked-by: 1\n---\nupdate\n')
        comment.save()

        comment = Comment(patch=self.patch,
                          msgid='p2',
                          submitter=self.person,
                          content='comment 2 text\nAcked-by: 2\n')
        comment.save()

    def testPatchResponse(self):
        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response, 'Acked-by: 1\nAcked-by: 2\n')
Exemplo n.º 8
0
class MboxPatchResponseTest(TestCase):
    fixtures = ['default_states']

    """ Test that the mbox view appends the Acked-by from a patch comment """

    def setUp(self):
        defaults.project.save()

        self.person = defaults.patch_author_person
        self.person.save()

        self.patch = Patch(project=defaults.project,
                           msgid='p1', name='testpatch',
                           submitter=self.person, diff='',
                           content='comment 1 text\nAcked-by: 1\n')
        self.patch.save()

        comment = Comment(submission=self.patch,
                          msgid='p2',
                          submitter=self.person,
                          content='comment 2 text\nAcked-by: 2\n')
        comment.save()

    def testPatchResponse(self):
        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response,
                            'Acked-by: 1\nAcked-by: 2\n')
Exemplo n.º 9
0
 def setUp(self):
     defaults.project.save()
     self.user = create_maintainer(defaults.project)
     self.client.login(username=self.user.username,
                       password=self.user.username)
     self.properties_form_id = 'patchform-properties'
     self.url = reverse('patchwork.views.patch.list',
                        args=[defaults.project.linkname])
     self.base_data = {
         'action': 'Update',
         'project': str(defaults.project.id),
         'form': 'patchlistform',
         'archived': '*',
         'delegate': '*',
         'state': '*'
     }
     self.patches = []
     for name in ['patch one', 'patch two', 'patch three']:
         patch = Patch(project=defaults.project,
                       msgid=name,
                       name=name,
                       content='',
                       submitter=Person.objects.get(user=self.user))
         patch.save()
         self.patches.append(patch)
Exemplo n.º 10
0
class MboxCommentPostcriptUnchangedTest(TestCase):
    """ Test that the mbox view doesn't change the postscript part of a mail.
        There where always a missing blank right after the postscript
        delimiter '---' and an additional newline right before. """
    def setUp(self):
        defaults.project.save()

        self.person = defaults.patch_author_person
        self.person.save()

        self.patch = Patch(project = defaults.project,
                           msgid = 'p1', name = 'testpatch',
                           submitter = self.person, content = '')
        self.patch.save()

        self.txt = 'some comment\n---\n some/file | 1 +\n'

        comment = Comment(patch = self.patch, msgid = 'p1',
                submitter = self.person,
                content = self.txt)
        comment.save()

    def testCommentUnchanged(self):
        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response, self.txt)
        self.txt += "\n"
        self.assertNotContains(response, self.txt)
Exemplo n.º 11
0
 def _insert_patch(self):
     patch = Patch(project=defaults.project,
                   submitter=defaults.patch_author_person,
                   msgid=defaults.patch_name,
                   content=defaults.patch)
     patch.save()
     return patch
Exemplo n.º 12
0
class MboxDateHeaderTest(TestCase):
    """ Test that the date provided in the patch mail view is correct """

    def setUp(self):
        defaults.project.save()
        self.person = defaults.patch_author_person
        self.person.save()

        self.patch = Patch(project = defaults.project,
                           msgid = 'p1', name = 'testpatch',
                           submitter = self.person, content = '')
        self.patch.save()

    def testDateHeader(self):
        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        mail = email.message_from_string(response.content)
        mail_date = dateutil.parser.parse(mail['Date'])
        # patch dates are all in UTC
        patch_date = self.patch.date.replace(tzinfo=dateutil.tz.tzutc(),
                                            microsecond=0)
        self.assertEqual(mail_date, patch_date)

    def testSuppliedDateHeader(self):
        hour_offset = 3
        tz = dateutil.tz.tzoffset(None, hour_offset * 60 * 60)
        date = datetime.datetime.utcnow() - datetime.timedelta(days = 1)
        date = date.replace(tzinfo=tz, microsecond=0)

        self.patch.headers = 'Date: %s\n' % date.strftime("%a, %d %b %Y %T %z")
        self.patch.save()

        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        mail = email.message_from_string(response.content)
        mail_date = dateutil.parser.parse(mail['Date'])
        self.assertEqual(mail_date, date)
Exemplo n.º 13
0
class MboxPatchSplitResponseTest(TestCase):
    """ Test that the mbox view appends the Acked-by from a patch comment,
        and places it before an '---' update line. """
    def setUp(self):
        defaults.project.save()

        self.person = defaults.patch_author_person
        self.person.save()

        self.patch = Patch(project = defaults.project,
                           msgid = 'p1', name = 'testpatch',
                           submitter = self.person, content = '')
        self.patch.save()
        comment = Comment(patch = self.patch, msgid = 'p1',
                submitter = self.person,
                content = 'comment 1 text\nAcked-by: 1\n---\nupdate\n')
        comment.save()

        comment = Comment(patch = self.patch, msgid = 'p2',
                submitter = self.person,
                content = 'comment 2 text\nAcked-by: 2\n')
        comment.save()

    def testPatchResponse(self):
        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response,
                'Acked-by: 1\nAcked-by: 2\n')
Exemplo n.º 14
0
 def _insert_patch(self):
     patch = Patch(project=defaults.project,
                   submitter=defaults.patch_author_person,
                   msgid=make_msgid(),
                   content=defaults.patch,
                   date=self.last_patch_ts)
     self.last_patch_ts += datetime.timedelta(0, 1)
     patch.save()
     return patch
Exemplo n.º 15
0
    def setUp(self):
        defaults.project.save()

        for (name, email, date) in self.patchmeta:
            patch_name = 'testpatch' + name
            person = Person(name = name, email = email)
            person.save()
            patch = Patch(project = defaults.project, msgid = patch_name,
                        submitter = person, content = '', date = date)
            patch.save()
Exemplo n.º 16
0
    def setUp(self):
        defaults.project.save()
        self.person = defaults.patch_author_person
        self.person.save()

        self.patch = Patch(project=defaults.project,
                           msgid='p1',
                           name='testpatch',
                           submitter=self.person,
                           content='')
        self.patch.save()
Exemplo n.º 17
0
 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)
Exemplo n.º 18
0
 def setUp(self):
     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 <*****@*****.**>'
Exemplo n.º 19
0
    def testList(self):
        defaults.project.save()
        defaults.patch_author_person.save()
        patch = Patch(project=defaults.project,
                      submitter=defaults.patch_author_person,
                      msgid=defaults.patch_name,
                      content=defaults.patch)
        patch.save()

        patches = self.rpc.patch_list()
        self.assertEqual(len(patches), 1)
        self.assertEqual(patches[0]['id'], patch.id)
Exemplo n.º 20
0
    def testList(self):
        defaults.project.save()
        defaults.patch_author_person.save()
        patch = Patch(project = defaults.project,
                submitter = defaults.patch_author_person,
                msgid = defaults.patch_name,
                content = defaults.patch)
        patch.save()

        patches = self.rpc.patch_list()
        self.assertEqual(len(patches), 1)
        self.assertEqual(patches[0]['id'], patch.id)
Exemplo n.º 21
0
 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()
Exemplo n.º 22
0
    def setUp(self):
        defaults.project.save()

        for (name, email, date) in self.patchmeta:
            patch_name = 'testpatch' + name
            person = Person(name=name, email=email)
            person.save()
            patch = Patch(project=defaults.project,
                          msgid=patch_name,
                          submitter=person,
                          content='',
                          date=date)
            patch.save()
Exemplo n.º 23
0
    def testWithChangedPersonName(self):
        self.patch = Patch(project=defaults.project,
                           msgid='p1',
                           name='testpatch',
                           submitter=self.person,
                           content='',
                           headers='From: {}'.format(self.original_author))
        self.patch.save()

        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response, 'From: {}'.format(self.original_author))
        self.assertNotContains(response, self.person.name)
        self.assertNotContains(response, self.person.email)
Exemplo n.º 24
0
    def testWithoutTheHeaderFallback(self):
        """ this should fallback to the Person """
        self.patch = Patch(project=defaults.project,
                           msgid='p1',
                           name='testpatch',
                           submitter=self.person,
                           content='',
                           headers='')
        self.patch.save()

        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(
            response, 'From: {} <{}>'.format(self.person.name,
                                             self.person.email))
Exemplo n.º 25
0
    def setUp(self):
        defaults.project.save()
        self.person = defaults.patch_author_person
        self.person.save()

        self.cc_header = 'Cc: CC Person <*****@*****.**>'
        self.to_header = 'To: To Person <*****@*****.**>'
        self.date_header = 'Date: Fri, 7 Jun 2013 15:42:54 +1000'

        self.patch = Patch(project=defaults.project,
                           msgid='p1',
                           name='testpatch',
                           submitter=self.person,
                           content='')
Exemplo n.º 26
0
def create_patches(count=1):
    """Create 'count' unique patches."""
    defaults.project.save()
    defaults.patch_author_person.save()

    patches = []

    for i in range(0, count):
        patch = Patch(project=defaults.project,
                      submitter=defaults.patch_author_person,
                      msgid=make_msgid(),
                      name='testpatch%d' % (i + 1),
                      diff=defaults.patch)
        patch.save()
        patches.append(patch)

    return patches
Exemplo n.º 27
0
    def testPatchSubmitterExpiry(self):
        defaults.project.save()
        defaults.patch_author_person.save()

        # someone submits a patch...
        patch = Patch(project=defaults.project,
                      msgid='*****@*****.**',
                      name='test patch',
                      submitter=defaults.patch_author_person,
                      content=defaults.patch)
        patch.save()

        # ... then starts registration...
        date = ((datetime.datetime.now() - EmailConfirmation.validity) -
                datetime.timedelta(hours=1))
        userid = 'test-user'
        user = User.objects.create_user(userid,
                                        defaults.patch_author_person.email,
                                        userid)
        user.is_active = False
        user.date_joined = user.last_login = date
        user.save()

        self.assertEqual(user.email, patch.submitter.email)

        conf = EmailConfirmation(type='registration',
                                 user=user,
                                 email=user.email)
        conf.date = date
        conf.save()

        # ... which expires
        do_expiry()

        # we should see no matching user
        self.assertFalse(
            User.objects.filter(email=patch.submitter.email).exists())
        # but the patch and person should still be present
        self.assertTrue(
            Person.objects.filter(pk=defaults.patch_author_person.pk).exists())
        self.assertTrue(Patch.objects.filter(pk=patch.pk).exists())

        # and there should be no user associated with the person
        self.assertEqual(
            Person.objects.get(pk=defaults.patch_author_person.pk).user, None)
Exemplo n.º 28
0
    def setUp(self, patch_count=3):
        patch_names = ['testpatch%d' % (i) for i in range(1, patch_count+1)]
        self.user = create_user()
        self.client.login(username = self.user.username,
                password = self.user.username)
        defaults.project.save()
        self.bundle = Bundle(owner = self.user, project = defaults.project,
                name = 'testbundle')
        self.bundle.save()
        self.patches = []

        for patch_name in patch_names:
            patch = Patch(project = defaults.project,
                               msgid = patch_name, name = patch_name,
                               submitter = Person.objects.get(user = self.user),
                               content = '')
            patch.save()
            self.patches.append(patch)
Exemplo n.º 29
0
 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)
Exemplo n.º 30
0
    def setUp(self):
        defaults.project.save()
        self.person = defaults.patch_author_person
        self.person.save()

        self.patch = Patch(project = defaults.project,
                           msgid = 'p1', name = 'testpatch',
                           submitter = self.person, content = '')
        self.patch.save()
Exemplo n.º 31
0
 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()
Exemplo n.º 32
0
 def assertTagsEqual(self, str, acks, reviews, tests):  # noqa
     counts = Patch.extract_tags(str, Tag.objects.all())
     self.assertEqual(
         (acks, reviews, tests),
         (
             counts[Tag.objects.get(name='Acked-by')],
             counts[Tag.objects.get(name='Reviewed-by')],
             counts[Tag.objects.get(name='Tested-by')],
         ),
     )
Exemplo n.º 33
0
    def testPatchSubmitterExpiry(self):
        defaults.project.save()
        defaults.patch_author_person.save()

        # someone submits a patch...
        patch = Patch(project=defaults.project,
                      msgid='*****@*****.**', name='test patch',
                      submitter=defaults.patch_author_person,
                      content=defaults.patch)
        patch.save()

        # ... then starts registration...
        date = ((datetime.datetime.now() - EmailConfirmation.validity) -
                datetime.timedelta(hours=1))
        userid = 'test-user'
        user = User.objects.create_user(
            userid,
            defaults.patch_author_person.email, userid)
        user.is_active = False
        user.date_joined = user.last_login = date
        user.save()

        self.assertEqual(user.email, patch.submitter.email)

        conf = EmailConfirmation(type='registration', user=user,
                                 email=user.email)
        conf.date = date
        conf.save()

        # ... which expires
        do_expiry()

        # we should see no matching user
        self.assertFalse(User.objects.filter(email=patch.submitter.email)
                         .exists())
        # but the patch and person should still be present
        self.assertTrue(Person.objects.filter(
            pk=defaults.patch_author_person.pk).exists())
        self.assertTrue(Patch.objects.filter(pk=patch.pk).exists())

        # and there should be no user associated with the person
        self.assertEqual(Person.objects.get(
            pk=defaults.patch_author_person.pk).user, None)
Exemplo n.º 34
0
 def setUp(self):
     defaults.project.save()
     self.user = create_maintainer(defaults.project)
     self.client.login(username = self.user.username,
             password = self.user.username)
     self.properties_form_id = 'patchform-properties'
     self.url = reverse(
         'patchwork.views.patch.list', args = [defaults.project.linkname])
     self.base_data = {
         'action': 'Update', 'project': str(defaults.project.id),
         'form': 'patchlistform', 'archived': '*', 'delegate': '*',
         'state': '*'}
     self.patches = []
     for name in ['patch one', 'patch two', 'patch three']:
         patch = Patch(project = defaults.project, msgid = name,
                         name = name, content = '',
                         submitter = Person.objects.get(user = self.user))
         patch.save()
         self.patches.append(patch)
Exemplo n.º 35
0
 def setUp(self):
     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 <*****@*****.**>'
Exemplo n.º 36
0
def create_patch(**kwargs):
    """Create 'Patch' object."""
    num = Patch.objects.count()

    values = {
        'submitter': create_person(),
        'delegate': None,
        'project': create_project(),
        'msgid': make_msgid(),
        'name': 'testpatch%d' % num,
        'headers': '',
        'content': '',
        'diff': SAMPLE_DIFF,
    }
    values.update(kwargs)

    patch = Patch(**values)
    patch.save()

    return patch
Exemplo n.º 37
0
 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()
Exemplo n.º 38
0
    def testPullRequestEvent(self):
        submitter = Person()
        submitter.save()

        patch = Patch(project=self.project,
                      pull_url="git://foo.bar master",
                      submitter=submitter)
        patch.save()

        # n events for n series, +1 for the pull request above
        events = self.get_json('/projects/%(project_id)s/events/')
        self.assertEqual(events['count'], self.n_series + 1)

        prs = filter(lambda r: r['name'] == 'pull-request-new',
                     events['results'])
        prs = list(prs)
        self.assertEqual(len(prs), 1)

        self.assertEqual(prs[0]['patch'], patch.id)
        self.assertEqual(prs[0]['parameters']['pull_url'], patch.pull_url)
Exemplo n.º 39
0
    def setUp(self):
        defaults.project.save()

        self.person = defaults.patch_author_person
        self.person.save()

        self.patch = Patch(project=defaults.project,
                           msgid='p1',
                           name='testpatch',
                           submitter=self.person,
                           content='')
        self.patch.save()

        self.txt = 'some comment\n---\n some/file | 1 +\n'

        comment = Comment(patch=self.patch,
                          msgid='p1',
                          submitter=self.person,
                          content=self.txt)
        comment.save()
Exemplo n.º 40
0
    def setUp(self):
        defaults.project.save()
        self.person = defaults.patch_author_person
        self.person.save()

        self.cc_header = 'Cc: CC Person <*****@*****.**>'
        self.to_header = 'To: To Person <*****@*****.**>'

        self.patch = Patch(project = defaults.project,
                           msgid = 'p1', name = 'testpatch',
                           submitter = self.person, content = '')
Exemplo n.º 41
0
class MboxAuthorship(TestCase):
    fixtures = ['default_states', 'default_events']
    """ Test that the From in mbox is the same as in the original header """
    def setUp(self):
        defaults.project.save()

        self.original_author = "Orignal Author <*****@*****.**>"

        self.person = defaults.patch_author_person
        self.person.name = "Changed Name"
        self.person.email = "*****@*****.**"
        self.person.save()

    def testWithChangedPersonName(self):
        self.patch = Patch(project=defaults.project,
                           msgid='p1',
                           name='testpatch',
                           submitter=self.person,
                           content='',
                           headers='From: {}'.format(self.original_author))
        self.patch.save()

        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response, 'From: {}'.format(self.original_author))
        self.assertNotContains(response, self.person.name)
        self.assertNotContains(response, self.person.email)

    def testWithoutTheHeaderFallback(self):
        """ this should fallback to the Person """
        self.patch = Patch(project=defaults.project,
                           msgid='p1',
                           name='testpatch',
                           submitter=self.person,
                           content='',
                           headers='')
        self.patch.save()

        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(
            response, 'From: {} <{}>'.format(self.person.name,
                                             self.person.email))
Exemplo n.º 42
0
    def setUp(self):
        defaults.project.save()

        self.person = defaults.patch_author_person
        self.person.save()

        self.txt = 'some comment\n---\n some/file | 1 +\n'

        self.patch = Patch(project=defaults.project,
                           msgid='p1', name='testpatch',
                           submitter=self.person, diff='',
                           content=self.txt)
        self.patch.save()
Exemplo n.º 43
0
class MboxBrokenFromHeaderTest(TestCase):
    """ Test that a person with characters outside ASCII in his name do
        produce correct From header. As RFC 2822 state we must retain the
        <*****@*****.**> format for the mail while the name part may be coded
        in some ways. """

    def setUp(self):
        defaults.project.save()
        self.person = defaults.patch_author_person
        self.person.name = u'©ool guŷ'
        self.person.save()

        self.patch = Patch(project = defaults.project,
                msgid = 'p1', name = 'testpatch',
                submitter = self.person, content = '')

    def testFromHeader(self):
        self.patch.save()
        from_email = '<' + self.person.email + '>'

        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response, from_email)
Exemplo n.º 44
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()
Exemplo n.º 45
0
class MboxPatchworkLink(TestCase):
    fixtures = ['default_states', 'default_events']

    """ Test that the mbox view appends the patch link """

    def setUp(self):
        defaults.project.save()

        self.person = defaults.patch_author_person
        self.person.save()

        self.patch = Patch(project=defaults.project,
                           msgid='p1', name='testpatch',
                           submitter=self.person, content='')
        self.patch.save()

    def testPatchResponse(self):
        response = self.client.get('/patch/%d/mbox/' % self.patch.id,
                                   {'link': 'Patchwork'})

        m = re.search(r'^Patchwork:.*/%d/$' % self.patch.pk, response.content,
                      re.M)
        self.assertTrue(m)
Exemplo n.º 46
0
class MboxPatchworkLink(TestCase):
    fixtures = ['default_states', 'default_events']
    """ Test that the mbox view appends the patch link """
    def setUp(self):
        defaults.project.save()

        self.person = defaults.patch_author_person
        self.person.save()

        self.patch = Patch(project=defaults.project,
                           msgid='p1',
                           name='testpatch',
                           submitter=self.person,
                           content='')
        self.patch.save()

    def testPatchResponse(self):
        response = self.client.get('/patch/%d/mbox/' % self.patch.id,
                                   {'link': 'Patchwork'})

        m = re.search(r'^Patchwork:.*/%d/$' % self.patch.pk, response.content,
                      re.M)
        self.assertTrue(m)
Exemplo n.º 47
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()
Exemplo n.º 48
0
    def setUp(self):
        defaults.project.save()

        self.person = defaults.patch_author_person
        self.person.save()

        self.patch = Patch(project=defaults.project,
                           msgid='p1',
                           name='testpatch',
                           submitter=self.person,
                           content='')
        self.patch.save()
        comment = Comment(patch=self.patch,
                          msgid='p1',
                          submitter=self.person,
                          content='comment 1 text\nAcked-by: 1\n---\nupdate\n')
        comment.save()

        comment = Comment(patch=self.patch,
                          msgid='p2',
                          submitter=self.person,
                          content='comment 2 text\nAcked-by: 2\n')
        comment.save()
Exemplo n.º 49
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()
Exemplo n.º 50
0
class MboxDateHeaderTest(TestCase):
    fixtures = ['default_states', 'default_events']
    """ Test that the date provided in the patch mail view is correct """
    def setUp(self):
        defaults.project.save()
        self.person = defaults.patch_author_person
        self.person.save()

        self.patch = Patch(project=defaults.project,
                           msgid='p1',
                           name='testpatch',
                           submitter=self.person,
                           content='')
        self.patch.save()

    def testDateHeader(self):
        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        mail = email.message_from_string(response.content)
        mail_date = dateutil.parser.parse(mail['Date'])
        # patch dates are all in UTC
        patch_date = self.patch.date.replace(tzinfo=dateutil.tz.tzutc(),
                                             microsecond=0)
        self.assertEqual(mail_date, patch_date)

    def testSuppliedDateHeader(self):
        hour_offset = 3
        tz = dateutil.tz.tzoffset(None, hour_offset * 60 * 60)
        date = datetime.datetime.utcnow() - datetime.timedelta(days=1)
        date = date.replace(tzinfo=tz, microsecond=0)

        self.patch.headers = 'Date: %s\n' % date.strftime("%a, %d %b %Y %T %z")
        self.patch.save()

        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        mail = email.message_from_string(response.content)
        mail_date = dateutil.parser.parse(mail['Date'])
        self.assertEqual(mail_date, date)
Exemplo n.º 51
0
class MboxBrokenFromHeaderTest(TestCase):
    fixtures = ['default_states', 'default_events']
    """ Test that a person with characters outside ASCII in his name do
        produce correct From header. As RFC 2822 state we must retain the
        <*****@*****.**> format for the mail while the name part may be coded
        in some ways. """
    def setUp(self):
        defaults.project.save()
        self.person = defaults.patch_author_person
        self.person.name = u'©ool guŷ'
        self.person.save()

        self.patch = Patch(project=defaults.project,
                           msgid='p1',
                           name='testpatch',
                           submitter=self.person,
                           content='')

    def testFromHeader(self):
        self.patch.save()
        from_email = '<' + self.person.email + '>'

        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response, from_email)
Exemplo n.º 52
0
    def setUp(self):
        defaults.project.save()

        self.person = defaults.patch_author_person
        self.person.save()

        self.patch = Patch(project=defaults.project,
                           msgid='p1', name='testpatch',
                           submitter=self.person, diff='',
                           content='comment 1 text\nAcked-by: 1\n')
        self.patch.save()

        comment = Comment(submission=self.patch,
                          msgid='p2',
                          submitter=self.person,
                          content='comment 2 text\nAcked-by: 2\n')
        comment.save()
Exemplo n.º 53
0
    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)
Exemplo n.º 54
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.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)
Exemplo n.º 55
0
class MboxPassThroughHeaderTest(TestCase):
    fixtures = ['default_states', 'default_events']
    """ Test that we see 'Cc' and 'To' headers passed through from original
        message to mbox view """
    def setUp(self):
        defaults.project.save()
        self.person = defaults.patch_author_person
        self.person.save()

        self.cc_header = 'Cc: CC Person <*****@*****.**>'
        self.to_header = 'To: To Person <*****@*****.**>'
        self.date_header = 'Date: Fri, 7 Jun 2013 15:42:54 +1000'

        self.patch = Patch(project=defaults.project,
                           msgid='p1',
                           name='testpatch',
                           submitter=self.person,
                           content='')

    def testCCHeader(self):
        self.patch.headers = self.cc_header + '\n'
        self.patch.save()

        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response, self.cc_header)

    def testToHeader(self):
        self.patch.headers = self.to_header + '\n'
        self.patch.save()

        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response, self.to_header)

    def testDateHeader(self):
        self.patch.headers = self.date_header + '\n'
        self.patch.save()

        response = self.client.get('/patch/%d/mbox/' % self.patch.id)
        self.assertContains(response, self.date_header)
Exemplo n.º 56
0
def parse_mail(mail, list_id=None):
    """Parse a mail and add to the database.

    Args:
        mail (`mbox.Mail`): Mail to parse and add.
        list_id (str): Mailing list ID

    Returns:
        None
    """
    # some basic sanity checks
    if 'From' not in mail:
        raise ValueError("Missing 'From' header")

    if 'Subject' not in mail:
        raise ValueError("Missing 'Subject' header")

    if 'Message-Id' not in mail:
        raise ValueError("Missing 'Message-Id' header")

    hint = clean_header(mail.get('X-Patchwork-Hint', ''))
    if hint and hint.lower() == 'ignore':
        logger.debug("Ignoring email due to 'ignore' hint")
        return

    if list_id:
        project = find_project_by_id(list_id)
    else:
        project = find_project_by_header(mail)

    if project is None:
        logger.error('Failed to find a project for email')
        return

    # parse metadata

    msgid = clean_header(mail.get('Message-Id'))
    if not msgid:
        raise ValueError("Broken 'Message-Id' header")
    msgid = msgid[:255]

    author = find_author(mail)
    subject = mail.get('Subject')
    name, prefixes = clean_subject(subject, [project.linkname])
    is_comment = subject_check(subject)
    x, n = parse_series_marker(prefixes)
    version = parse_version(name, prefixes)
    refs = find_references(mail)
    date = find_date(mail)
    headers = find_headers(mail)

    # parse content

    if not is_comment:
        diff, message = find_patch_content(mail)
    else:
        diff, message = find_comment_content(mail)

    if not (diff or message):
        return  # nothing to work with

    pull_url = parse_pull_request(message)

    # build objects

    if not is_comment and (diff or pull_url):  # patches or pull requests
        # we delay the saving until we know we have a patch.
        author.save()

        delegate = find_delegate_by_header(mail)
        if not delegate and diff:
            filenames = find_filenames(diff)
            delegate = find_delegate_by_filename(project, filenames)

        # if we don't have a series marker, we will never have an existing
        # series to match against.
        series = None
        if n:
            series = find_series(project, mail)
        else:
            x = n = 1

        # We will create a new series if:
        # - there is no existing series to assign this patch to, or
        # - there is an existing series, but it already has a patch with this
        #   number in it
        if not series or (
                SeriesPatch.objects.filter(series=series, number=x).count()):
            series = Series(project=project,
                            date=date,
                            submitter=author,
                            version=version,
                            total=n)
            series.save()

            # NOTE(stephenfin) We must save references for series. We
            # do this to handle the case where a later patch is
            # received first. Without storing references, it would not
            # be possible to identify the relationship between patches
            # as the earlier patch does not reference the later one.
            for ref in refs + [msgid]:
                ref = ref[:255]
                # we don't want duplicates
                try:
                    # we could have a ref to a previous series. (For
                    # example, a series sent in reply to another
                    # series.) That should not create a series ref
                    # for this series, so check for the msg-id only,
                    # not the msg-id/series pair.
                    SeriesReference.objects.get(msgid=ref,
                                                series__project=project)
                except SeriesReference.DoesNotExist:
                    SeriesReference.objects.create(series=series, msgid=ref)

        patch = Patch(
            msgid=msgid,
            project=project,
            name=name[:255],
            date=date,
            headers=headers,
            submitter=author,
            content=message,
            diff=diff,
            pull_url=pull_url,
            delegate=delegate,
            state=find_state(mail))
        patch.save()
        logger.debug('Patch saved')

        # add to a series if we have found one, and we have a numbered
        # patch. Don't add unnumbered patches (for example diffs sent
        # in reply, or just messages with random refs/in-reply-tos)
        if series and x:
            series.add_patch(patch, x)

        return patch
    elif x == 0:  # (potential) cover letters
        # if refs are empty, it's implicitly a cover letter. If not,
        # however, we need to see if a match already exists and, if
        # not, assume that it is indeed a new cover letter
        is_cover_letter = False
        if not is_comment:
            if not refs == []:
                try:
                    CoverLetter.objects.all().get(name=name)
                except CoverLetter.DoesNotExist:
                    # if no match, this is a new cover letter
                    is_cover_letter = True
                except CoverLetter.MultipleObjectsReturned:
                    # if multiple cover letters are found, just ignore
                    pass
            else:
                is_cover_letter = True

        if is_cover_letter:
            author.save()

            # we don't use 'find_series' here as a cover letter will
            # always be the first item in a thread, thus the references
            # could only point to a different series or unrelated
            # message
            try:
                series = SeriesReference.objects.get(
                    msgid=msgid, series__project=project).series
            except SeriesReference.DoesNotExist:
                series = None

            if not series:
                series = Series(project=project,
                                date=date,
                                submitter=author,
                                version=version,
                                total=n)
                series.save()

                # we don't save the in-reply-to or references fields
                # for a cover letter, as they can't refer to the same
                # series
                SeriesReference.objects.get_or_create(series=series,
                                                      msgid=msgid)

            cover_letter = CoverLetter(
                msgid=msgid,
                project=project,
                name=name[:255],
                date=date,
                headers=headers,
                submitter=author,
                content=message)
            cover_letter.save()
            logger.debug('Cover letter saved')

            series.add_cover_letter(cover_letter)

            return cover_letter

    # comments

    # we only save comments if we have the parent email
    submission = find_submission_for_comment(project, refs)
    if not submission:
        return

    author.save()

    comment = Comment(
        submission=submission,
        msgid=msgid,
        date=date,
        headers=headers,
        submitter=author,
        content=message)
    comment.save()
    logger.debug('Comment saved')

    return comment
Exemplo n.º 57
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)
Exemplo n.º 58
0
 def assertTagsEqual(self, str, acks, reviews, tests):
     counts = Patch.extract_tags(str, Tag.objects.all())
     self.assertEqual((acks, reviews, tests),
                      (counts[Tag.objects.get(name='Acked-by')],
                       counts[Tag.objects.get(name='Reviewed-by')],
                       counts[Tag.objects.get(name='Tested-by')]))