Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1786)

Unified Diff: appengine/monorail/features/test/inboundemail_test.py

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: appengine/monorail/features/test/inboundemail_test.py
diff --git a/appengine/monorail/features/test/inboundemail_test.py b/appengine/monorail/features/test/inboundemail_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..60b4e522a1d3680dc89f24b71fd85e59baaf8465
--- /dev/null
+++ b/appengine/monorail/features/test/inboundemail_test.py
@@ -0,0 +1,280 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is govered by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""Unittests for monorail.feature.inboundemail."""
+
+import unittest
+
+import mox
+
+from features import commitlogcommands
+from features import inboundemail
+from framework import emailfmt
+from framework import monorailrequest
+from framework import permissions
+from proto import project_pb2
+from proto import tracker_pb2
+from proto import user_pb2
+from services import service_manager
+from testing import fake
+from testing import testing_helpers
+
+
+class InboundEmailTest(unittest.TestCase):
+
+ def setUp(self):
+ self.cnxn = 'fake cnxn'
+ self.services = service_manager.Services(
+ issue=fake.IssueService(),
+ user=fake.UserService(),
+ project=fake.ProjectService())
+ self.project = self.services.project.TestAddProject(
+ 'proj', project_id=987, process_inbound_email=True)
+ self.project_addr = 'proj@monorail.example.com'
+
+ self.issue = tracker_pb2.Issue()
+ self.issue.project_id = 987
+ self.issue.local_id = 100
+ self.services.issue.TestAddIssue(self.issue)
+
+ self.msg = testing_helpers.MakeMessage(
+ testing_helpers.HEADER_LINES, 'awesome!')
+
+ request, _ = testing_helpers.GetRequestObjects()
+ self.inbound = inboundemail.InboundEmail(request, None, self.services)
+ self.mox = mox.Mox()
+
+ def tearDown(self):
+ self.mox.UnsetStubs()
+ self.mox.ResetAll()
+
+ def testTemplates(self):
+ for name, template_path in self.inbound._templates.iteritems():
+ assert(name in inboundemail.MSG_TEMPLATES)
+ assert(
+ template_path.GetTemplatePath().endswith(
+ inboundemail.MSG_TEMPLATES[name]))
+
+ def testProcessMail_MsgTooBig(self):
+ self.mox.StubOutWithMock(emailfmt, 'IsBodyTooBigToParse')
+ emailfmt.IsBodyTooBigToParse(mox.IgnoreArg()).AndReturn(True)
+ self.mox.ReplayAll()
+
+ email_tasks = self.inbound.ProcessMail(self.msg, self.project_addr)
+ self.mox.VerifyAll()
+ self.assertEquals(1, len(email_tasks))
+ email_task = email_tasks[0]
+ self.assertEquals('user@example.com', email_task['to'])
+ self.assertEquals('Email body too long', email_task['subject'])
+
+ def testProcessMail_NoProjectOnToLine(self):
+ self.mox.StubOutWithMock(emailfmt, 'IsProjectAddressOnToLine')
+ emailfmt.IsProjectAddressOnToLine(
+ self.project_addr, [self.project_addr]).AndReturn(False)
+ self.mox.ReplayAll()
+
+ ret = self.inbound.ProcessMail(self.msg, self.project_addr)
+ self.mox.VerifyAll()
+ self.assertIsNone(ret)
+
+ def testProcessMail_ProjectUnidentified(self):
+ self.mox.StubOutWithMock(emailfmt, 'IdentifyProjectAndIssue')
+ emailfmt.IdentifyProjectAndIssue(
+ self.project_addr, mox.IgnoreArg()).AndReturn((None, None))
+ self.mox.ReplayAll()
+
+ ret = self.inbound.ProcessMail(self.msg, self.project_addr)
+ self.mox.VerifyAll()
+ self.assertIsNone(ret)
+
+ def testProcessMail_ProjectNotLive(self):
+ self.project.state = project_pb2.ProjectState.DELETABLE
+ email_tasks = self.inbound.ProcessMail(self.msg, self.project_addr)
+ email_task = email_tasks[0]
+ self.assertEquals('user@example.com', email_task['to'])
+ self.assertEquals('Project not found', email_task['subject'])
+
+ def testProcessMail_ProjectInboundEmailDisabled(self):
+ self.project.process_inbound_email = False
+ email_tasks = self.inbound.ProcessMail(self.msg, self.project_addr)
+ email_task = email_tasks[0]
+ self.assertEquals('user@example.com', email_task['to'])
+ self.assertEquals('Email replies are not enabled in project proj',
+ email_task['subject'])
+
+ def testProcessMail_NoRefHeader(self):
+ self.mox.StubOutWithMock(emailfmt, 'ValidateReferencesHeader')
+ emailfmt.ValidateReferencesHeader(
+ mox.IgnoreArg(), self.project, mox.IgnoreArg(),
+ mox.IgnoreArg()).AndReturn(False)
+ self.mox.ReplayAll()
+
+ email_tasks = self.inbound.ProcessMail(self.msg, self.project_addr)
+ self.mox.VerifyAll()
+ self.assertEquals(1, len(email_tasks))
+ email_task = email_tasks[0]
+ self.assertEquals('user@example.com', email_task['to'])
+ self.assertEquals('Your message is not a reply to a notification email',
+ email_task['subject'])
+
+ def testProcessMail_NoAccount(self):
+ self.mox.StubOutWithMock(emailfmt, 'ValidateReferencesHeader')
+ emailfmt.ValidateReferencesHeader(
+ mox.IgnoreArg(), self.project, mox.IgnoreArg(),
+ mox.IgnoreArg()).AndReturn(True)
+ self.mox.ReplayAll()
+
+ email_tasks = self.inbound.ProcessMail(self.msg, self.project_addr)
+ self.mox.VerifyAll()
+ self.assertEquals(1, len(email_tasks))
+ email_task = email_tasks[0]
+ self.assertEquals('user@example.com', email_task['to'])
+ self.assertEquals('Could not determine account of sender',
+ email_task['subject'])
+
+ def testProcessMail_BannedAccount(self):
+ self.services.user.TestAddUser('user@example.com', 111L)
+ class MockAuthData:
+ def __init__(self):
+ self.user_pb = user_pb2.MakeUser()
+ self.effective_ids = set([1, 2, 3])
+ self.user_id = 111L
+ mock_auth_data = MockAuthData()
+ mock_auth_data.user_pb.banned = 'banned'
+
+ self.mox.StubOutWithMock(emailfmt, 'ValidateReferencesHeader')
+ emailfmt.ValidateReferencesHeader(
+ mox.IgnoreArg(), self.project, mox.IgnoreArg(),
+ mox.IgnoreArg()).AndReturn(True)
+ self.mox.StubOutWithMock(monorailrequest.AuthData, 'FromEmail')
+ monorailrequest.AuthData.FromEmail(
+ mox.IgnoreArg(), 'user@example.com', self.services).AndReturn(
+ mock_auth_data)
+ self.mox.ReplayAll()
+
+ email_tasks = self.inbound.ProcessMail(self.msg, self.project_addr)
+ self.mox.VerifyAll()
+ self.assertEquals(1, len(email_tasks))
+ email_task = email_tasks[0]
+ self.assertEquals('user@example.com', email_task['to'])
+ self.assertEquals('You are banned from using this issue tracker',
+ email_task['subject'])
+
+ def testProcessMail_Success(self):
+ self.services.user.TestAddUser('user@example.com', 111L)
+ class MockAuthData:
+ def __init__(self):
+ self.user_pb = user_pb2.MakeUser()
+ self.effective_ids = set([1, 2, 3])
+ self.user_id = 111L
+ mock_auth_data = MockAuthData()
+
+ self.mox.StubOutWithMock(emailfmt, 'ValidateReferencesHeader')
+ emailfmt.ValidateReferencesHeader(
+ mox.IgnoreArg(), self.project, mox.IgnoreArg(),
+ mox.IgnoreArg()).AndReturn(True)
+
+ self.mox.StubOutWithMock(monorailrequest.AuthData, 'FromEmail')
+ monorailrequest.AuthData.FromEmail(
+ mox.IgnoreArg(), 'user@example.com', self.services).AndReturn(
+ mock_auth_data)
+
+ self.mox.StubOutWithMock(permissions, 'GetPermissions')
+ permissions.GetPermissions(
+ mock_auth_data.user_pb, mock_auth_data.effective_ids,
+ self.project).AndReturn('test permissions')
+
+ self.mox.StubOutWithMock(self.inbound, 'ProcessIssueReply')
+ self.inbound.ProcessIssueReply(
+ mox.IgnoreArg(), self.project, 123, self.project_addr,
+ 'user@example.com', 111L, mock_auth_data.effective_ids,
+ 'test permissions', 'awesome!')
+
+ self.mox.ReplayAll()
+
+ ret = self.inbound.ProcessMail(self.msg, self.project_addr)
+ self.mox.VerifyAll()
+ self.assertIsNone(ret)
+
+ def testProcessIssueReply_NoIssue(self):
+ nonexistant_local_id = 200
+ email_tasks = self.inbound.ProcessIssueReply(
+ self.cnxn, self.project, nonexistant_local_id, self.project_addr,
+ 'user@example.com', 111L, [1, 2, 3], permissions.USER_PERMISSIONSET,
+ 'awesome!')
+ self.assertEquals(1, len(email_tasks))
+ email_task = email_tasks[0]
+ self.assertEquals('user@example.com', email_task['to'])
+ self.assertEquals('Could not find issue %d in project %s' % (
+ nonexistant_local_id, self.project.project_name),
+ email_task['subject'])
+
+ def testProcessIssueReply_DeletedIssue(self):
+ self.issue.deleted = True
+ email_tasks = self.inbound.ProcessIssueReply(
+ self.cnxn, self.project, self.issue.local_id, self.project_addr,
+ 'user@example.com', 111L, [1, 2, 3], permissions.USER_PERMISSIONSET,
+ 'awesome!')
+ self.assertEquals(1, len(email_tasks))
+ email_task = email_tasks[0]
+ self.assertEquals('user@example.com', email_task['to'])
+ self.assertEquals('Could not find issue %d in project %s' % (
+ self.issue.local_id, self.project.project_name),
+ email_task['subject'])
+
+ def testProcessIssueReply_NoAddIssuePerm(self):
+ perms = permissions.READ_ONLY_PERMISSIONSET
+ email_tasks = self.inbound.ProcessIssueReply(
+ self.cnxn, self.project, self.issue.local_id, self.project_addr,
+ 'user@example.com', 111L, [1, 2, 3], perms, 'awesome!')
+ self.assertEquals(1, len(email_tasks))
+ email_task = email_tasks[0]
+ self.assertEquals('user@example.com', email_task['to'])
+ self.assertEquals('User does not have permission to add a comment',
+ email_task['subject'])
+
+ def testProcessIssueReply_NoEditIssuePerm(self):
+ perms = permissions.USER_PERMISSIONSET
+ mock_uia = commitlogcommands.UpdateIssueAction(self.issue.local_id)
+
+ self.mox.StubOutWithMock(commitlogcommands, 'UpdateIssueAction')
+ commitlogcommands.UpdateIssueAction(self.issue.local_id).AndReturn(mock_uia)
+
+ self.mox.StubOutWithMock(mock_uia, 'Parse')
+ mock_uia.Parse(
+ self.cnxn, self.project.project_name, 111L, ['awesome!'], self.services,
+ strip_quoted_lines=True)
+ self.mox.StubOutWithMock(mock_uia, 'Run')
+ # Allow edit is false here because the permission set does not contain
+ # EDIT_ISSUE.
+ mock_uia.Run(self.cnxn, self.services, allow_edit=False)
+
+ self.mox.ReplayAll()
+ ret = self.inbound.ProcessIssueReply(
+ self.cnxn, self.project, self.issue.local_id, self.project_addr,
+ 'from_addr', 111L, [1, 2, 3], perms, 'awesome!')
+ self.mox.VerifyAll()
+ self.assertIsNone(ret)
+
+ def testProcessIssueReply_Success(self):
+ perms = permissions.COMMITTER_ACTIVE_PERMISSIONSET
+ mock_uia = commitlogcommands.UpdateIssueAction(self.issue.local_id)
+
+ self.mox.StubOutWithMock(commitlogcommands, 'UpdateIssueAction')
+ commitlogcommands.UpdateIssueAction(self.issue.local_id).AndReturn(mock_uia)
+
+ self.mox.StubOutWithMock(mock_uia, 'Parse')
+ mock_uia.Parse(
+ self.cnxn, self.project.project_name, 111L, ['awesome!'], self.services,
+ strip_quoted_lines=True)
+ self.mox.StubOutWithMock(mock_uia, 'Run')
+ mock_uia.Run(self.cnxn, self.services, allow_edit=True)
+
+ self.mox.ReplayAll()
+ ret = self.inbound.ProcessIssueReply(
+ self.cnxn, self.project, self.issue.local_id, self.project_addr,
+ 'from_addr', 111L, [1, 2, 3], perms, 'awesome!')
+ self.mox.VerifyAll()
+ self.assertIsNone(ret)
« no previous file with comments | « appengine/monorail/features/test/filterrules_views_test.py ('k') | appengine/monorail/features/test/notify_helpers_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698