]> git.ozlabs.org Git - patchwork/blobdiff - apps/patchwork/tests/patchparser.py
tests: Add tests for explicit delegate and state requests
[patchwork] / apps / patchwork / tests / patchparser.py
index 0fad67b2eecf7c6875a30cd7e6d3948fe4135bb3..8e1a8250da7546300aac554ca338a34db8d28858 100644 (file)
 import unittest
 import os
 from email import message_from_string
-from patchwork.models import Project, Person, Patch, Comment
-from patchwork.tests.utils import read_patch, create_email, defaults
+from patchwork.models import Project, Person, Patch, Comment, State, \
+         get_default_initial_patch_state
+from patchwork.tests.utils import read_patch, read_mail, create_email, \
+         defaults, create_user
 
 try:
     from email.mime.text import MIMEText
@@ -34,7 +36,8 @@ class PatchTest(unittest.TestCase):
     default_subject = defaults.subject
     project = defaults.project
 
-from patchwork.bin.parsemail import find_content, find_author, parse_mail
+from patchwork.bin.parsemail import find_content, find_author, find_project, \
+                                    parse_mail
 
 class InlinePatchTest(PatchTest):
     patch_filename = '0001-add-line.patch'
@@ -120,6 +123,11 @@ class ListFooterTest(InlinePatchTest):
         (self.patch, self.comment) = find_content(self.project, email)
 
 
+class DiffWordInCommentTest(InlinePatchTest):
+    test_comment = 'Lines can start with words beginning in "diff"\n' + \
+                   'difficult\nDifferent'
+
+
 class UpdateCommentTest(InlinePatchTest):
     """ Test for '---\nUpdate: v2' style comments to patches. """
     patch_filename = '0001-add-line.patch'
@@ -172,6 +180,29 @@ class SenderUTF8QPSplitEncodingTest(SenderEncodingTest):
 class SenderUTF8B64EncodingTest(SenderUTF8QPEncodingTest):
     from_header = '=?utf-8?B?w6l4YW1wbGUgdXNlcg==?= <user@example.com>'
 
+class SubjectEncodingTest(PatchTest):
+    sender = 'example user <user@example.com>'
+    subject = 'test subject'
+    subject_header = 'test subject'
+
+    def setUp(self):
+        mail = 'From: %s\n' % self.sender + \
+               'Subject: %s\n\n' % self.subject_header + \
+               'test\n\n' + defaults.patch
+        self.projects = defaults.project
+        self.email = message_from_string(mail)
+
+    def testSubjectEncoding(self):
+        (patch, comment) = find_content(self.project, self.email)
+        self.assertEquals(patch.name, self.subject)
+
+class SubjectUTF8QPEncodingTest(SubjectEncodingTest):
+    subject = u'test s\xfcbject'
+    subject_header = '=?utf-8?q?test=20s=c3=bcbject?='
+
+class SubjectUTF8QPMultipleEncodingTest(SubjectEncodingTest):
+    subject = u'test s\xfcbject'
+    subject_header = 'test =?utf-8?q?s=c3=bcbject?='
 
 class SenderCorrelationTest(unittest.TestCase):
     existing_sender = 'Existing Sender <existing@example.com>'
@@ -275,3 +306,199 @@ class MultipleProjectPatchCommentTest(MultipleProjectPatchTest):
             # and the one we parsed in setUp()
             self.assertEquals(Comment.objects.filter(patch = patch).count(), 2)
 
+class ListIdHeaderTest(unittest.TestCase):
+    """ Test that we parse List-Id headers from mails correctly """
+    def setUp(self):
+        self.project = Project(linkname = 'test-project-1', name = 'Project 1',
+                listid = '1.example.com', listemail='1@example.com')
+        self.project.save()
+
+    def testNoListId(self):
+        email = MIMEText('')
+        project = find_project(email)
+        self.assertEquals(project, None)
+
+    def testBlankListId(self):
+        email = MIMEText('')
+        email['List-Id'] = ''
+        project = find_project(email)
+        self.assertEquals(project, None)
+
+    def testWhitespaceListId(self):
+        email = MIMEText('')
+        email['List-Id'] = ' '
+        project = find_project(email)
+        self.assertEquals(project, None)
+
+    def testSubstringListId(self):
+        email = MIMEText('')
+        email['List-Id'] = 'example.com'
+        project = find_project(email)
+        self.assertEquals(project, None)
+
+    def testShortListId(self):
+        """ Some mailing lists have List-Id headers in short formats, where it
+            is only the list ID itself (without enclosing angle-brackets). """
+        email = MIMEText('')
+        email['List-Id'] = self.project.listid
+        project = find_project(email)
+        self.assertEquals(project, self.project)
+
+    def testLongListId(self):
+        email = MIMEText('')
+        email['List-Id'] = 'Test text <%s>' % self.project.listid
+        project = find_project(email)
+        self.assertEquals(project, self.project)
+
+    def tearDown(self):
+        self.project.delete()
+
+class MBoxPatchTest(PatchTest):
+    def setUp(self):
+        self.mail = read_mail(self.mail_file, project = self.project)
+
+class GitPullTest(MBoxPatchTest):
+    mail_file = '0001-git-pull-request.mbox'
+
+    def testGitPullRequest(self):
+        (patch, comment) = find_content(self.project, self.mail)
+        self.assertTrue(patch is not None)
+        self.assertTrue(patch.pull_url is not None)
+        self.assertTrue(patch.content is None)
+        self.assertTrue(comment is not None)
+
+class GitPullWrappedTest(GitPullTest):
+    mail_file = '0002-git-pull-request-wrapped.mbox'
+
+class GitPullWithDiffTest(MBoxPatchTest):
+    mail_file = '0003-git-pull-request-with-diff.mbox'
+
+    def testGitPullWithDiff(self):
+        (patch, comment) = find_content(self.project, self.mail)
+        self.assertTrue(patch is not None)
+        self.assertEqual('git://git.kernel.org/pub/scm/linux/kernel/git/tip/' +
+             'linux-2.6-tip.git x86-fixes-for-linus', patch.pull_url)
+        self.assertTrue(
+            patch.content.startswith('diff --git a/arch/x86/include/asm/smp.h'),
+            patch.content)
+        self.assertTrue(comment is not None)
+
+class GitPullGitSSHUrlTest(GitPullTest):
+    mail_file = '0004-git-pull-request-git+ssh.mbox'
+
+class GitPullSSHUrlTest(GitPullTest):
+    mail_file = '0005-git-pull-request-ssh.mbox'
+
+class GitPullHTTPUrlTest(GitPullTest):
+    mail_file = '0006-git-pull-request-http.mbox'
+
+class CVSFormatPatchTest(MBoxPatchTest):
+    mail_file = '0007-cvs-format-diff.mbox'
+
+    def testPatch(self):
+        (patch, comment) = find_content(self.project, self.mail)
+        self.assertTrue(patch is not None)
+        self.assertTrue(comment is not None)
+        self.assertTrue(patch.content.startswith('Index'))
+
+class DelegateRequestTest(unittest.TestCase):
+    patch_filename = '0001-add-line.patch'
+    msgid = '<1@example.com>'
+    invalid_delegate_email = "nobody"
+
+    def setUp(self):
+        self.patch = read_patch(self.patch_filename)
+        self.user = create_user()
+        self.p1 = Project(linkname = 'test-project-1', name = 'Project 1',
+                listid = '1.example.com', listemail='1@example.com')
+        self.p1.save()
+
+    def get_email(self):
+        email = create_email(self.patch)
+        del email['List-ID']
+        email['List-ID'] = '<' + self.p1.listid + '>'
+        email['Message-Id'] = self.msgid
+        return email
+
+    def testDelegate(self):
+        email = self.get_email()
+        email['X-Patchwork-Delegate'] = self.user.email
+        parse_mail(email)
+        self.assertEquals(Patch.objects.filter(project=self.p1).count(), 1)
+        self.assertEquals(Patch.objects.get(pk=1).delegate, self.user)
+
+    def testNoDelegate(self):
+        email = self.get_email()
+        parse_mail(email)
+        self.assertEquals(Patch.objects.filter(project=self.p1).count(), 1)
+        self.assertEquals(Patch.objects.get(pk=1).delegate, None)
+
+    def testInvalidDelegateFallsBackToNoDelegate(self):
+        email = self.get_email()
+        email['X-Patchwork-Delegate'] = self.invalid_delegate_email
+        parse_mail(email)
+        self.assertEquals(Patch.objects.filter(project=self.p1).count(), 1)
+        self.assertEquals(Patch.objects.get(pk=1).delegate, None)
+
+    def tearDown(self):
+        self.p1.delete()
+        self.user.delete()
+
+class InitialPatchStateTest(unittest.TestCase):
+    patch_filename = '0001-add-line.patch'
+    msgid = '<1@example.com>'
+    invalid_state_name = "Nonexistent Test State"
+
+    def setUp(self):
+        self.patch = read_patch(self.patch_filename)
+        self.user = create_user()
+        self.p1 = Project(linkname = 'test-project-1', name = 'Project 1',
+                listid = '1.example.com', listemail='1@example.com')
+        self.p1.save()
+        self.default_state = get_default_initial_patch_state()
+        self.nondefault_state = State.objects.get(name="Accepted")
+
+    def get_email(self):
+        email = create_email(self.patch)
+        del email['List-ID']
+        email['List-ID'] = '<' + self.p1.listid + '>'
+        email['Message-Id'] = self.msgid
+        return email
+
+    def testNonDefaultStateIsActuallyNotTheDefaultState(self):
+        self.assertNotEqual(self.default_state, self.nondefault_state)
+
+    def testExplicitNonDefaultStateRequest(self):
+        email = self.get_email()
+        email['X-Patchwork-State'] = self.nondefault_state.name
+        parse_mail(email)
+        self.assertEquals(Patch.objects.filter(project=self.p1).count(), 1)
+        self.assertEquals(Patch.objects.get(pk=1).state, self.nondefault_state)
+
+    def testExplicitDefaultStateRequest(self):
+        email = self.get_email()
+        email['X-Patchwork-State'] = self.default_state.name
+        parse_mail(email)
+        self.assertEquals(Patch.objects.filter(project=self.p1).count(), 1)
+        self.assertEquals(Patch.objects.get(pk=1).state, self.default_state)
+
+    def testImplicitDefaultStateRequest(self):
+        email = self.get_email()
+        parse_mail(email)
+        self.assertEquals(Patch.objects.filter(project=self.p1).count(), 1)
+        self.assertEquals(Patch.objects.get(pk=1).state, self.default_state)
+
+    def testInvalidTestStateDoesNotExist(self):
+        with self.assertRaises(State.DoesNotExist):
+            State.objects.get(name=self.invalid_state_name)
+
+    def testInvalidStateRequestFallsBackToDefaultState(self):
+        email = self.get_email()
+        email['X-Patchwork-State'] = self.invalid_state_name
+        parse_mail(email)
+        self.assertEquals(Patch.objects.filter(project=self.p1).count(), 1)
+        self.assertEquals(Patch.objects.get(pk=1).state, self.default_state)
+
+    def tearDown(self):
+        self.p1.delete()
+        self.user.delete()