Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 1 | # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 | # Use of this source code is governed by a BSD-style |
| 3 | # license that can be found in the LICENSE file or at |
| 4 | # https://developers.google.com/open-source/licenses/bsd |
| 5 | |
| 6 | """Tests for the issueoriginal module.""" |
| 7 | from __future__ import print_function |
| 8 | from __future__ import division |
| 9 | from __future__ import absolute_import |
| 10 | |
| 11 | import mock |
| 12 | import unittest |
| 13 | |
| 14 | import webapp2 |
| 15 | |
| 16 | from framework import exceptions |
| 17 | from framework import framework_helpers |
| 18 | from framework import monorailrequest |
| 19 | from framework import permissions |
| 20 | from proto import tracker_pb2 |
| 21 | from services import service_manager |
| 22 | from testing import fake |
| 23 | from testing import testing_helpers |
| 24 | from tracker import issueoriginal |
| 25 | |
| 26 | |
| 27 | STRIPPED_MSG = 'Are you sure that it is plugged in?\n' |
| 28 | ORIG_MSG = ('Are you sure that it is plugged in?\n' |
| 29 | '\n' |
| 30 | '> Issue 1 entered by user foo:\n' |
| 31 | '> http://blah blah\n' |
| 32 | '> The screen is just dark when I press power on\n') |
| 33 | XXX_GOOD_UNICODE_MSG = u'Thanks,\n\342\230\206*username*'.encode('utf-8') |
| 34 | GOOD_UNICODE_MSG = u'Thanks,\n XXX *username*' |
| 35 | XXX_BAD_UNICODE_MSG = ORIG_MSG + ('\xff' * 1000) |
| 36 | BAD_UNICODE_MSG = ORIG_MSG + 'XXX' |
| 37 | GMAIL_CRUFT_MSG = ORIG_MSG # XXX .replace(' ', ' \xa0 ') |
| 38 | |
| 39 | |
| 40 | class IssueOriginalTest(unittest.TestCase): |
| 41 | |
| 42 | def setUp(self): |
| 43 | self.services = service_manager.Services( |
| 44 | project=fake.ProjectService(), |
| 45 | config=fake.ConfigService(), |
| 46 | issue=fake.IssueService(), |
| 47 | user=fake.UserService()) |
| 48 | self.servlet = issueoriginal.IssueOriginal( |
| 49 | 'req', 'res', services=self.services) |
| 50 | |
| 51 | self.proj = self.services.project.TestAddProject('proj', project_id=789) |
| 52 | summary = 'System wont boot' |
| 53 | status = 'New' |
| 54 | cnxn = 'fake connection' |
| 55 | self.services.user.TestAddUser('commenter@example.com', 222) |
| 56 | |
| 57 | created_issue_1 = fake.MakeTestIssue( |
| 58 | 789, 1, summary, status, 111, reporter_id=111) |
| 59 | self.services.issue.TestAddIssue(created_issue_1) |
| 60 | self.local_id_1 = created_issue_1.local_id |
| 61 | comment_0 = tracker_pb2.IssueComment( |
| 62 | issue_id=created_issue_1.issue_id, |
| 63 | user_id=222, |
| 64 | project_id=789, |
| 65 | content=STRIPPED_MSG, |
| 66 | inbound_message=ORIG_MSG) |
| 67 | self.services.issue.InsertComment(cnxn, comment_0) |
| 68 | comment_1 = tracker_pb2.IssueComment( |
| 69 | issue_id=created_issue_1.issue_id, |
| 70 | user_id=222, |
| 71 | project_id=789, |
| 72 | content=STRIPPED_MSG, |
| 73 | inbound_message=BAD_UNICODE_MSG) |
| 74 | self.services.issue.InsertComment(cnxn, comment_1) |
| 75 | comment_2 = tracker_pb2.IssueComment( |
| 76 | issue_id=created_issue_1.issue_id, |
| 77 | user_id=222, |
| 78 | project_id=789, |
| 79 | content=STRIPPED_MSG, |
| 80 | inbound_message=GMAIL_CRUFT_MSG) |
| 81 | self.services.issue.InsertComment(cnxn, comment_2) |
| 82 | comment_3 = tracker_pb2.IssueComment( |
| 83 | issue_id=created_issue_1.issue_id, |
| 84 | user_id=222, |
| 85 | project_id=789, |
| 86 | content=STRIPPED_MSG, |
| 87 | inbound_message=GOOD_UNICODE_MSG) |
| 88 | self.services.issue.InsertComment(cnxn, comment_3) |
| 89 | self.issue_1 = self.services.issue.GetIssueByLocalID( |
| 90 | cnxn, 789, self.local_id_1) |
| 91 | self.comments = [comment_0, comment_1, comment_2, comment_3] |
| 92 | |
| 93 | @mock.patch('framework.permissions.GetPermissions') |
| 94 | def testAssertBasePermission(self, mock_getpermissions): |
| 95 | """Permit users who can view issue, view inbound message and delete.""" |
| 96 | _request, mr = testing_helpers.GetRequestObjects( |
| 97 | path='/p/proj/issues/original?id=1&seq=1', |
| 98 | project=self.proj) |
| 99 | |
| 100 | # Allow the user to view the issue itself. |
| 101 | mock_getpermissions.return_value = ( |
| 102 | permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET) |
| 103 | |
| 104 | # Someone without VIEW permission cannot view the inbound email. |
| 105 | mr.perms = permissions.EMPTY_PERMISSIONSET |
| 106 | self.assertRaises(permissions.PermissionException, |
| 107 | self.servlet.AssertBasePermission, mr) |
| 108 | |
| 109 | # Contributors don't have VIEW_INBOUND_MESSAGES. |
| 110 | mr.perms = permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET |
| 111 | self.assertRaises(permissions.PermissionException, |
| 112 | self.servlet.AssertBasePermission, mr) |
| 113 | |
| 114 | # Committers do have VIEW_INBOUND_MESSAGES. |
| 115 | mr.perms = permissions.COMMITTER_ACTIVE_PERMISSIONSET |
| 116 | self.servlet.AssertBasePermission(mr) |
| 117 | |
| 118 | # But, a committer cannot use that if they cannot view the issue. |
| 119 | self.issue_1.labels.append('Restrict-View-Foo') |
| 120 | mr.perms = permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET |
| 121 | self.assertRaises(permissions.PermissionException, |
| 122 | self.servlet.AssertBasePermission, mr) |
| 123 | |
| 124 | # Project owners have VIEW_INBOUND_MESSAGES and bypass restrictions. |
| 125 | mock_getpermissions.return_value = ( |
| 126 | permissions.OWNER_ACTIVE_PERMISSIONSET) |
| 127 | mr.perms = permissions.OWNER_ACTIVE_PERMISSIONSET |
| 128 | self.servlet.AssertBasePermission(mr) |
| 129 | |
| 130 | def testGatherPageData_Normal(self): |
| 131 | _request, mr = testing_helpers.GetRequestObjects( |
| 132 | path='/p/proj/issues/original?id=1&seq=1', |
| 133 | project=self.proj) |
| 134 | page_data = self.servlet.GatherPageData(mr) |
| 135 | self.assertEqual(1, page_data['local_id']) |
| 136 | self.assertEqual(1, page_data['seq']) |
| 137 | self.assertFalse(page_data['is_binary']) |
| 138 | self.assertEqual(ORIG_MSG, page_data['message_body']) |
| 139 | |
| 140 | def testGatherPageData_GoodUnicode(self): |
| 141 | _request, mr = testing_helpers.GetRequestObjects( |
| 142 | path='/p/proj/issues/original?id=1&seq=4', |
| 143 | project=self.proj) |
| 144 | page_data = self.servlet.GatherPageData(mr) |
| 145 | self.assertEqual(1, page_data['local_id']) |
| 146 | self.assertEqual(4, page_data['seq']) |
| 147 | self.assertEqual(GOOD_UNICODE_MSG, page_data['message_body']) |
| 148 | self.assertFalse(page_data['is_binary']) |
| 149 | |
| 150 | def testGatherPageData_BadUnicode(self): |
| 151 | _request, mr = testing_helpers.GetRequestObjects( |
| 152 | path='/p/proj/issues/original?id=1&seq=2', |
| 153 | project=self.proj) |
| 154 | page_data = self.servlet.GatherPageData(mr) |
| 155 | self.assertEqual(1, page_data['local_id']) |
| 156 | self.assertEqual(2, page_data['seq']) |
| 157 | # xxx: should be true if cruft was there. |
| 158 | # self.assertTrue(page_data['is_binary']) |
| 159 | |
| 160 | def testGatherPageData_GmailCruft(self): |
| 161 | _request, mr = testing_helpers.GetRequestObjects( |
| 162 | path='/p/proj/issues/original?id=1&seq=3', |
| 163 | project=self.proj) |
| 164 | page_data = self.servlet.GatherPageData(mr) |
| 165 | self.assertEqual(1, page_data['local_id']) |
| 166 | self.assertEqual(3, page_data['seq']) |
| 167 | self.assertFalse(page_data['is_binary']) |
| 168 | self.assertEqual(ORIG_MSG, page_data['message_body']) |
| 169 | |
| 170 | def testGatherPageData_404(self): |
| 171 | _request, mr = testing_helpers.GetRequestObjects( |
| 172 | path='/p/proj/issues/original', |
| 173 | project=self.proj) |
| 174 | with self.assertRaises(webapp2.HTTPException) as cm: |
| 175 | self.servlet.GatherPageData(mr) |
| 176 | self.assertEqual(404, cm.exception.code) |
| 177 | |
| 178 | _request, mr = testing_helpers.GetRequestObjects( |
| 179 | path='/p/proj/issues/original?id=1&seq=999', |
| 180 | project=self.proj) |
| 181 | with self.assertRaises(webapp2.HTTPException) as cm: |
| 182 | self.servlet.GatherPageData(mr) |
| 183 | self.assertEqual(404, cm.exception.code) |
| 184 | |
| 185 | _request, mr = testing_helpers.GetRequestObjects( |
| 186 | path='/p/proj/issues/original?id=999&seq=1', |
| 187 | project=self.proj) |
| 188 | with self.assertRaises(exceptions.NoSuchIssueException) as cm: |
| 189 | self.servlet.GatherPageData(mr) |
| 190 | |
| 191 | def testGetIssueAndComment_Normal(self): |
| 192 | _request, mr = testing_helpers.GetRequestObjects( |
| 193 | path='/p/proj/issues/original?id=1&seq=1', |
| 194 | project=self.proj) |
| 195 | issue, comment = self.servlet._GetIssueAndComment(mr) |
| 196 | self.assertEqual(self.issue_1, issue) |
| 197 | self.assertEqual(self.comments[1].content, comment.content) |
| 198 | |
| 199 | def testGetIssueAndComment_NoSuchComment(self): |
| 200 | _request, mr = testing_helpers.GetRequestObjects( |
| 201 | path='/p/proj/issues/original?id=1&seq=99', |
| 202 | project=self.proj) |
| 203 | with self.assertRaises(webapp2.HTTPException) as cm: |
| 204 | self.servlet._GetIssueAndComment(mr) |
| 205 | self.assertEqual(404, cm.exception.code) |
| 206 | |
| 207 | def testGetIssueAndComment_Malformed(self): |
| 208 | _request, mr = testing_helpers.GetRequestObjects( |
| 209 | path='/p/proj/issues/original', |
| 210 | project=self.proj) |
| 211 | with self.assertRaises(webapp2.HTTPException) as cm: |
| 212 | self.servlet._GetIssueAndComment(mr) |
| 213 | self.assertEqual(404, cm.exception.code) |
| 214 | |
| 215 | _request, mr = testing_helpers.GetRequestObjects( |
| 216 | path='/p/proj/issues/original?id=1', |
| 217 | project=self.proj) |
| 218 | with self.assertRaises(webapp2.HTTPException) as cm: |
| 219 | self.servlet._GetIssueAndComment(mr) |
| 220 | self.assertEqual(404, cm.exception.code) |
| 221 | |
| 222 | _request, mr = testing_helpers.GetRequestObjects( |
| 223 | path='/p/proj/issues/original?seq=1', |
| 224 | project=self.proj) |
| 225 | with self.assertRaises(exceptions.NoSuchIssueException) as cm: |
| 226 | self.servlet._GetIssueAndComment(mr) |