blob: 580d095e469e8d85b462fdef4d43444775d5e28d [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001# 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"""Unit tests for the fieldcreate servlet."""
7from __future__ import print_function
8from __future__ import division
9from __future__ import absolute_import
10
11import mox
12import mock
13import unittest
14import logging
15
16import ezt
17
18from framework import permissions
19from proto import tracker_pb2
20from services import service_manager
21from testing import fake
22from testing import testing_helpers
23from tracker import fieldcreate
24from tracker import tracker_bizobj
25
26
27class FieldCreateTest(unittest.TestCase):
28
29 def setUp(self):
30 self.cnxn = 'fake cnxn'
31 self.services = service_manager.Services(
32 user=fake.UserService(),
33 config=fake.ConfigService(),
34 project=fake.ProjectService())
35 self.servlet = fieldcreate.FieldCreate(
36 'req', 'res', services=self.services)
37 self.project = self.services.project.TestAddProject('proj')
38 self.mr = testing_helpers.MakeMonorailRequest(
39 project=self.project, perms=permissions.OWNER_ACTIVE_PERMISSIONSET)
40 self.services.user.TestAddUser('gatsby@example.com', 111)
41 self.services.user.TestAddUser('sport@example.com', 222)
42
43 self.mox = mox.Mox()
44
45 def tearDown(self):
46 self.mox.UnsetStubs()
47 self.mox.ResetAll()
48
49 def testAssertBasePermission(self):
50 # Anon users can never do it
51 self.mr.perms = permissions.READ_ONLY_PERMISSIONSET
52 self.assertRaises(
53 permissions.PermissionException,
54 self.servlet.AssertBasePermission, self.mr)
55
56 # Project owner can do it.
57 self.mr.perms = permissions.OWNER_ACTIVE_PERMISSIONSET
58 self.servlet.AssertBasePermission(self.mr)
59
60 # Project member cannot do it
61 self.mr.perms = permissions.COMMITTER_ACTIVE_PERMISSIONSET
62 self.assertRaises(
63 permissions.PermissionException,
64 self.servlet.AssertBasePermission, self.mr)
65 self.mr.perms = permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET
66 self.assertRaises(
67 permissions.PermissionException,
68 self.servlet.AssertBasePermission, self.mr)
69
70 def testGatherPageData(self):
71 approval_fd = tracker_bizobj.MakeFieldDef(
72 1, self.mr.project_id, 'LaunchApproval',
73 tracker_pb2.FieldTypes.APPROVAL_TYPE, None, '', False,
74 False, False, None, None, '', False, '', '',
75 tracker_pb2.NotifyTriggers.NEVER, 'no_action',
76 'some approval thing', False)
77 config = self.services.config.GetProjectConfig(
78 self.mr.cnxn, self.mr.project_id)
79 config.field_defs.append(approval_fd)
80 self.services.config.StoreConfig(self.cnxn, config)
81 page_data = self.servlet.GatherPageData(self.mr)
82 self.assertEqual(self.servlet.PROCESS_TAB_LABELS,
83 page_data['admin_tab_mode'])
84 self.assertItemsEqual(
85 ['Defect', 'Enhancement', 'Task', 'Other'],
86 page_data['well_known_issue_types'])
87 self.assertEqual(['LaunchApproval'], page_data['approval_names'])
88 self.assertEqual('', page_data['initial_admins'])
89 self.assertEqual('', page_data['initial_editors'])
90 self.assertIsNone(page_data['initial_is_restricted_field'])
91
92 def testProcessFormData(self):
93 post_data = fake.PostData(
94 name=['somefield'],
95 field_type=['INT_TYPE'],
96 min_value=['1'],
97 max_value=['99'],
98 notify_on=['any_comment'],
99 importance=['required'],
100 is_multivalued=['Yes'],
101 docstring=['It is just some field'],
102 applicable_type=['Defect'],
103 date_action=['no_action'],
104 admin_names=['gatsby@example.com'],
105 editor_names=['sport@example.com'],
106 is_restricted_field=['Yes'])
107 url = self.servlet.ProcessFormData(self.mr, post_data)
108 self.assertTrue('/adminLabels?saved=1&' in url)
109 config = self.services.config.GetProjectConfig(
110 self.mr.cnxn, self.mr.project_id)
111
112 fd = tracker_bizobj.FindFieldDef('somefield', config)
113 self.assertEqual('somefield', fd.field_name)
114 self.assertEqual(tracker_pb2.FieldTypes.INT_TYPE, fd.field_type)
115 self.assertEqual(1, fd.min_value)
116 self.assertEqual(99, fd.max_value)
117 self.assertEqual(tracker_pb2.NotifyTriggers.ANY_COMMENT, fd.notify_on)
118 self.assertTrue(fd.is_required)
119 self.assertFalse(fd.is_niche)
120 self.assertTrue(fd.is_multivalued)
121 self.assertEqual('It is just some field', fd.docstring)
122 self.assertEqual('Defect', fd.applicable_type)
123 self.assertEqual('', fd.applicable_predicate)
124 self.assertEqual([111], fd.admin_ids)
125 self.assertEqual([222], fd.editor_ids)
126
127 def testProcessFormData_Reject_EditorsForNonRestrictedField(self):
128 # This method tests that an exception is raised
129 # when trying to add editors to a non restricted field.
130 post_data = fake.PostData(
131 name=['somefield'],
132 field_type=['INT_TYPE'],
133 min_value=['1'],
134 max_value=['99'],
135 notify_on=['any_comment'],
136 importance=['required'],
137 is_multivalued=['Yes'],
138 docstring=['It is just some field'],
139 applicable_type=['Defect'],
140 date_action=['no_action'],
141 admin_names=['gatsby@example.com'],
142 editor_names=['sport@example.com'])
143
144 self.assertRaises(
145 AssertionError, self.servlet.ProcessFormData, self.mr, post_data)
146
147 def testProcessFormData_Reject_EditorsForApprovalField(self):
148 #This method tests that an exception is raised
149 #when trying to add editors to an approval field.
150 post_data = fake.PostData(
151 name=['approval_field'],
152 field_type=['approval_type'],
153 notify_on=['any_comment'],
154 importance=['required'],
155 is_multivalued=['Yes'],
156 docstring=['It is just some field'],
157 applicable_type=['Defect'],
158 date_action=['no_action'],
159 approver_names=['gatsby@example.com'],
160 is_restricted_field=['Yes'],
161 admin_names=['gatsby@example.com'],
162 editor_names=[''])
163
164 self.assertRaises(
165 AssertionError, self.servlet.ProcessFormData, self.mr, post_data)
166
167 @mock.patch('framework.servlet.Servlet.PleaseCorrect')
168 def testProcessFormData_RejectAssertions(self, fake_servlet_pc):
169 #This method tests when errors are found using when the
170 #field_helpers.ParsedFieldDefAssertions is triggered.
171 post_data = fake.PostData(
172 name=['somefield'],
173 field_type=['INT_TYPE'],
174 min_value=['1'],
175 max_value=['99'],
176 notify_on=['any_comment'],
177 importance=['required'],
178 is_multivalued=['Yes'],
179 docstring=['It is just some field'],
180 applicable_type=['Defect'],
181 date_action=['wrong_date_action'],
182 admin_names=['gatsby@example.com'],
183 editor_names=[''])
184
185 self.servlet.ProcessFormData(self.mr, post_data)
186
187 fake_servlet_pc.assert_called_once_with(
188 self.mr,
189 initial_field_name='somefield',
190 initial_type='INT_TYPE',
191 initial_parent_approval_name='',
192 initial_field_docstring='It is just some field',
193 initial_applicable_type='Defect',
194 initial_applicable_predicate='',
195 initial_needs_member=None,
196 initial_needs_perm='',
197 initial_importance='required',
198 initial_is_multivalued='yes',
199 initial_grants_perm='',
200 initial_notify_on=1,
201 initial_date_action='wrong_date_action',
202 initial_choices='',
203 initial_approvers='',
204 initial_survey='',
205 initial_is_phase_field=False,
206 initial_admins='gatsby@example.com',
207 initial_editors='',
208 initial_is_restricted_field=False)
209 self.assertTrue(self.mr.errors.AnyErrors())
210
211
212 def testProcessFormData_RejectNoApprover(self):
213 post_data = fake.PostData(
214 name=['approvalField'],
215 field_type=['approval_type'],
216 approver_names=[''],
217 admin_names=[''],
218 editor_names=[''],
219 parent_approval_name=['UIApproval'],
220 is_phase_field=['on'])
221
222 self.mox.StubOutWithMock(self.servlet, 'PleaseCorrect')
223 self.servlet.PleaseCorrect(
224 self.mr,
225 initial_field_name=post_data.get('name'),
226 initial_type=post_data.get('field_type'),
227 initial_field_docstring=post_data.get('docstring', ''),
228 initial_applicable_type=post_data.get('applical_type', ''),
229 initial_applicable_predicate='',
230 initial_needs_member=ezt.boolean('needs_member' in post_data),
231 initial_needs_perm=post_data.get('needs_perm', '').strip(),
232 initial_importance=post_data.get('importance'),
233 initial_is_multivalued=ezt.boolean('is_multivalued' in post_data),
234 initial_grants_perm=post_data.get('grants_perm', '').strip(),
235 initial_notify_on=0,
236 initial_date_action=post_data.get('date_action'),
237 initial_choices=post_data.get('choices', ''),
238 initial_approvers=post_data.get('approver_names'),
239 initial_parent_approval_name=post_data.get('parent_approval_name', ''),
240 initial_survey=post_data.get('survey', ''),
241 initial_is_phase_field=False,
242 initial_admins=post_data.get('admin_names'),
243 initial_editors=post_data.get('editor_names'),
244 initial_is_restricted_field=False)
245 self.mox.ReplayAll()
246 url = self.servlet.ProcessFormData(self.mr, post_data)
247 self.mox.VerifyAll()
248 self.assertEqual(
249 'Please provide at least one default approver.',
250 self.mr.errors.approvers)
251 self.assertIsNone(url)
252
253
254class FieldCreateMethodsTest(unittest.TestCase):
255
256 def setUp(self):
257 self.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
258
259 def testFieldNameErrorMessage_NoConflict(self):
260 self.assertIsNone(fieldcreate.FieldNameErrorMessage(
261 'somefield', self.config))
262
263 def testFieldNameErrorMessage_PrefixReserved(self):
264 self.assertEqual(
265 'That name is reserved.',
266 fieldcreate.FieldNameErrorMessage('owner', self.config))
267
268 def testFieldNameErrorMessage_SuffixReserved(self):
269 self.assertEqual(
270 'That suffix is reserved.',
271 fieldcreate.FieldNameErrorMessage('doh-approver', self.config))
272
273 def testFieldNameErrorMessage_AlreadyInUse(self):
274 fd = tracker_bizobj.MakeFieldDef(
275 123, 789, 'CPU', tracker_pb2.FieldTypes.INT_TYPE, None,
276 '', False, False, False, None, None, '', False, '', '',
277 tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
278 self.config.field_defs.append(fd)
279 self.assertEqual(
280 'That name is already in use.',
281 fieldcreate.FieldNameErrorMessage('CPU', self.config))
282
283 def testFieldNameErrorMessage_PrefixOfExisting(self):
284 fd = tracker_bizobj.MakeFieldDef(
285 123, 789, 'sign-off', tracker_pb2.FieldTypes.INT_TYPE, None,
286 '', False, False, False, None, None, '', False, '', '',
287 tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
288 self.config.field_defs.append(fd)
289 self.assertEqual(
290 'That name is a prefix of an existing field name.',
291 fieldcreate.FieldNameErrorMessage('sign', self.config))
292
293 def testFieldNameErrorMessage_IncludesExisting(self):
294 fd = tracker_bizobj.MakeFieldDef(
295 123, 789, 'opt', tracker_pb2.FieldTypes.INT_TYPE, None,
296 '', False, False, False, None, None, '', False, '', '',
297 tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
298 self.config.field_defs.append(fd)
299 self.assertEqual(
300 'An existing field name is a prefix of that name.',
301 fieldcreate.FieldNameErrorMessage('opt-in', self.config))