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