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