Adrià Vilanova Martínez | f19ea43 | 2024-01-23 20:20:52 +0100 | [diff] [blame] | 1 | # 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. |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 4 | |
| 5 | """Tests for the issue admin pages.""" |
| 6 | from __future__ import print_function |
| 7 | from __future__ import division |
| 8 | from __future__ import absolute_import |
| 9 | |
Adrià Vilanova Martínez | 9f9ade5 | 2022-10-10 23:20:11 +0200 | [diff] [blame] | 10 | try: |
| 11 | from mox3 import mox |
| 12 | except ImportError: |
| 13 | import mox |
Adrià Vilanova Martínez | f19ea43 | 2024-01-23 20:20:52 +0100 | [diff] [blame] | 14 | import six |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 15 | import unittest |
| 16 | |
Adrià Vilanova Martínez | f19ea43 | 2024-01-23 20:20:52 +0100 | [diff] [blame] | 17 | import settings |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 18 | from mock import Mock, patch |
| 19 | |
| 20 | from framework import permissions |
| 21 | from framework import urls |
Adrià Vilanova Martínez | f19ea43 | 2024-01-23 20:20:52 +0100 | [diff] [blame] | 22 | from mrproto import tracker_pb2 |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 23 | from services import service_manager |
| 24 | from services import template_svc |
| 25 | from testing import fake |
| 26 | from testing import testing_helpers |
| 27 | from tracker import issueadmin |
| 28 | from tracker import tracker_bizobj |
| 29 | from tracker import tracker_constants |
| 30 | |
| 31 | |
| 32 | class TestBase(unittest.TestCase): |
| 33 | |
| 34 | def setUpServlet(self, servlet_factory): |
| 35 | # pylint: disable=attribute-defined-outside-init |
| 36 | self.services = service_manager.Services( |
| 37 | project=fake.ProjectService(), |
| 38 | config=fake.ConfigService(), |
| 39 | user=fake.UserService(), |
| 40 | issue=fake.IssueService(), |
| 41 | template=Mock(spec=template_svc.TemplateService), |
| 42 | features=fake.FeaturesService()) |
Adrià Vilanova Martínez | f19ea43 | 2024-01-23 20:20:52 +0100 | [diff] [blame] | 43 | self.servlet = servlet_factory(services=self.services) |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 44 | self.project = self.services.project.TestAddProject( |
| 45 | 'proj', project_id=789, contrib_ids=[333]) |
| 46 | self.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789) |
| 47 | self.services.config.StoreConfig(None, self.config) |
| 48 | self.cnxn = fake.MonorailConnection() |
| 49 | self.mr = testing_helpers.MakeMonorailRequest( |
| 50 | path='/p/proj/admin', project=self.project) |
Adrià Vilanova Martínez | f19ea43 | 2024-01-23 20:20:52 +0100 | [diff] [blame] | 51 | # Default to admin perms given that most tests assume the user can edit. |
| 52 | self.mr.perms = permissions.ADMIN_PERMISSIONSET |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 53 | self.mox = mox.Mox() |
| 54 | self.test_template = tracker_bizobj.MakeIssueTemplate( |
| 55 | 'Test Template', 'sum', 'New', 111, 'content', [], [], [], []) |
| 56 | self.test_template.template_id = 12345 |
| 57 | self.test_templates = testing_helpers.DefaultTemplates() |
| 58 | self.test_templates.append(self.test_template) |
| 59 | self.services.template.GetProjectTemplates\ |
| 60 | .return_value = self.test_templates |
| 61 | self.services.template.GetTemplateSetForProject\ |
| 62 | .return_value = [(12345, 'Test template', 0)] |
| 63 | |
Adrià Vilanova Martínez | f19ea43 | 2024-01-23 20:20:52 +0100 | [diff] [blame] | 64 | settings.config_freeze_project_ids = {} |
| 65 | |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 66 | def tearDown(self): |
| 67 | self.mox.UnsetStubs() |
| 68 | self.mox.ResetAll() |
| 69 | |
| 70 | def _mockGetUser(self): |
| 71 | self.mox.StubOutWithMock(self.services.user, 'GetUser') |
| 72 | user = self.services.user.TestAddUser('user@invalid', 100) |
| 73 | self.services.user.GetUser( |
| 74 | mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(user) |
| 75 | |
| 76 | |
| 77 | class IssueAdminBaseTest(TestBase): |
| 78 | |
| 79 | def setUp(self): |
| 80 | super(IssueAdminBaseTest, self).setUpServlet(issueadmin.IssueAdminBase) |
| 81 | |
| 82 | def testGatherPageData(self): |
| 83 | self._mockGetUser() |
| 84 | self.mox.ReplayAll() |
| 85 | page_data = self.servlet.GatherPageData(self.mr) |
| 86 | self.mox.VerifyAll() |
| 87 | |
Adrià Vilanova Martínez | f19ea43 | 2024-01-23 20:20:52 +0100 | [diff] [blame] | 88 | six.assertCountEqual( |
| 89 | self, [ |
| 90 | 'admin_tab_mode', 'config', 'open_text', 'closed_text', |
| 91 | 'labels_text', 'can_edit_project' |
| 92 | ], list(page_data.keys())) |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 93 | config_view = page_data['config'] |
| 94 | self.assertEqual(789, config_view.project_id) |
| 95 | |
| 96 | |
| 97 | class AdminStatusesTest(TestBase): |
| 98 | |
| 99 | def setUp(self): |
| 100 | super(AdminStatusesTest, self).setUpServlet(issueadmin.AdminStatuses) |
Adrià Vilanova Martínez | f19ea43 | 2024-01-23 20:20:52 +0100 | [diff] [blame] | 101 | self.servlet.mr = self.mr |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 102 | |
| 103 | @patch('framework.servlet.Servlet.PleaseCorrect') |
| 104 | def testProcessSubtabForm_MissingInput(self, mock_pc): |
| 105 | post_data = fake.PostData() |
| 106 | next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 107 | self.assertIsNone(next_url) |
| 108 | mock_pc.assert_called_once() |
| 109 | self.assertEqual(len(tracker_constants.DEFAULT_WELL_KNOWN_STATUSES), |
| 110 | len(self.config.well_known_statuses)) |
| 111 | self.assertEqual(tracker_constants.DEFAULT_STATUSES_OFFER_MERGE, |
| 112 | self.config.statuses_offer_merge) |
| 113 | |
| 114 | @patch('framework.servlet.Servlet.PleaseCorrect') |
| 115 | def testProcessSubtabForm_EmptyInput(self, mock_pc): |
| 116 | post_data = fake.PostData( |
| 117 | predefinedopen=[''], predefinedclosed=[''], statuses_offer_merge=['']) |
| 118 | next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 119 | self.assertIsNone(next_url) |
| 120 | mock_pc.assert_called_once() |
| 121 | self.assertEqual(len(tracker_constants.DEFAULT_WELL_KNOWN_STATUSES), |
| 122 | len(self.config.well_known_statuses)) |
| 123 | self.assertEqual(tracker_constants.DEFAULT_STATUSES_OFFER_MERGE, |
| 124 | self.config.statuses_offer_merge) |
| 125 | |
| 126 | def testProcessSubtabForm_Normal(self): |
| 127 | post_data = fake.PostData( |
| 128 | predefinedopen=['New = newly reported'], |
| 129 | predefinedclosed=['Fixed\nDuplicate'], |
| 130 | statuses_offer_merge=['Duplicate']) |
| 131 | next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 132 | self.assertEqual(urls.ADMIN_STATUSES, next_url) |
| 133 | self.assertEqual(3, len(self.config.well_known_statuses)) |
| 134 | self.assertEqual('New', self.config.well_known_statuses[0].status) |
| 135 | self.assertTrue(self.config.well_known_statuses[0].means_open) |
| 136 | self.assertEqual('Fixed', self.config.well_known_statuses[1].status) |
| 137 | self.assertFalse(self.config.well_known_statuses[1].means_open) |
| 138 | self.assertEqual('Duplicate', self.config.well_known_statuses[2].status) |
| 139 | self.assertFalse(self.config.well_known_statuses[2].means_open) |
| 140 | self.assertEqual(['Duplicate'], self.config.statuses_offer_merge) |
| 141 | |
| 142 | |
| 143 | class AdminLabelsTest(TestBase): |
| 144 | |
| 145 | def setUp(self): |
| 146 | super(AdminLabelsTest, self).setUpServlet(issueadmin.AdminLabels) |
| 147 | |
| 148 | def testGatherPageData(self): |
| 149 | self._mockGetUser() |
| 150 | self.mox.ReplayAll() |
| 151 | page_data = self.servlet.GatherPageData(self.mr) |
| 152 | self.mox.VerifyAll() |
| 153 | |
Adrià Vilanova Martínez | f19ea43 | 2024-01-23 20:20:52 +0100 | [diff] [blame] | 154 | six.assertCountEqual( |
| 155 | self, [ |
| 156 | 'admin_tab_mode', 'config', 'field_defs', 'open_text', |
| 157 | 'closed_text', 'labels_text', 'can_edit_project' |
| 158 | ], list(page_data.keys())) |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 159 | config_view = page_data['config'] |
| 160 | self.assertEqual(789, config_view.project_id) |
| 161 | self.assertEqual([], page_data['field_defs']) |
| 162 | |
| 163 | @patch('framework.servlet.Servlet.PleaseCorrect') |
| 164 | def testProcessSubtabForm_MissingInput(self, mock_pc): |
| 165 | post_data = fake.PostData() |
| 166 | next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 167 | self.assertIsNone(next_url) |
| 168 | mock_pc.assert_called_once() |
| 169 | self.assertEqual(len(tracker_constants.DEFAULT_WELL_KNOWN_LABELS), |
| 170 | len(self.config.well_known_labels)) |
| 171 | self.assertEqual(tracker_constants.DEFAULT_EXCL_LABEL_PREFIXES, |
| 172 | self.config.exclusive_label_prefixes) |
| 173 | |
| 174 | @patch('framework.servlet.Servlet.PleaseCorrect') |
| 175 | def testProcessSubtabForm_EmptyInput(self, mock_pc): |
| 176 | post_data = fake.PostData( |
| 177 | predefinedlabels=[''], excl_prefixes=['']) |
| 178 | next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 179 | self.assertIsNone(next_url) # Because PleaseCorrect() was called. |
| 180 | mock_pc.assert_called_once() |
| 181 | self.assertEqual(len(tracker_constants.DEFAULT_WELL_KNOWN_LABELS), |
| 182 | len(self.config.well_known_labels)) |
| 183 | self.assertEqual(tracker_constants.DEFAULT_EXCL_LABEL_PREFIXES, |
| 184 | self.config.exclusive_label_prefixes) |
| 185 | |
| 186 | def testProcessSubtabForm_Normal(self): |
| 187 | post_data = fake.PostData( |
| 188 | predefinedlabels=['Pri-0 = Burning issue\nPri-4 = It can wait'], |
| 189 | excl_prefixes=['pri']) |
| 190 | next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 191 | self.assertEqual(urls.ADMIN_LABELS, next_url) |
| 192 | self.assertEqual(2, len(self.config.well_known_labels)) |
| 193 | self.assertEqual('Pri-0', self.config.well_known_labels[0].label) |
| 194 | self.assertEqual('Pri-4', self.config.well_known_labels[1].label) |
| 195 | self.assertEqual(['pri'], self.config.exclusive_label_prefixes) |
| 196 | |
| 197 | @patch('framework.servlet.Servlet.PleaseCorrect') |
| 198 | def testProcessSubtabForm_Duplicates(self, mock_pc): |
| 199 | post_data = fake.PostData( |
| 200 | predefinedlabels=['Pri-0\nPri-4\npri-0'], |
| 201 | excl_prefixes=['pri']) |
| 202 | next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 203 | self.assertIsNone(next_url) |
| 204 | mock_pc.assert_called_once() |
| 205 | self.assertEqual( |
| 206 | 'Duplicate label: pri-0', |
| 207 | self.mr.errors.label_defs) |
| 208 | |
| 209 | @patch('framework.servlet.Servlet.PleaseCorrect') |
| 210 | def testProcessSubtabForm_Conflict(self, mock_pc): |
| 211 | post_data = fake.PostData( |
| 212 | predefinedlabels=['Multi-Part-One\nPri-4\npri-0'], |
| 213 | excl_prefixes=['pri']) |
| 214 | self.config.field_defs = [ |
| 215 | tracker_pb2.FieldDef( |
| 216 | field_name='Multi-Part', |
| 217 | field_type=tracker_pb2.FieldTypes.ENUM_TYPE)] |
| 218 | next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 219 | self.assertIsNone(next_url) |
| 220 | mock_pc.assert_called_once() |
| 221 | self.assertEqual( |
| 222 | 'Label "Multi-Part-One" should be defined in enum "multi-part"', |
| 223 | self.mr.errors.label_defs) |
| 224 | |
| 225 | |
| 226 | class AdminTemplatesTest(TestBase): |
| 227 | |
| 228 | def setUp(self): |
| 229 | super(AdminTemplatesTest, self).setUpServlet(issueadmin.AdminTemplates) |
| 230 | self.mr.auth.user_id = 333 |
| 231 | self.mr.auth.effective_ids = {333} |
| 232 | |
| 233 | def testGatherPageData(self): |
| 234 | self._mockGetUser() |
| 235 | self.mox.ReplayAll() |
| 236 | page_data = self.servlet.GatherPageData(self.mr) |
| 237 | self.mox.VerifyAll() |
| 238 | |
| 239 | config_view = page_data['config'] |
| 240 | self.assertEqual(789, config_view.project_id) |
| 241 | |
| 242 | def testProcessSubtabForm_NoEditProjectPerm(self): |
| 243 | """If user lacks perms, raise an exception.""" |
| 244 | post_data = fake.PostData( |
| 245 | default_template_for_developers=['Test Template'], |
| 246 | default_template_for_users=['Test Template']) |
| 247 | self.mr.perms = permissions.EMPTY_PERMISSIONSET |
| 248 | self.assertRaises( |
| 249 | permissions.PermissionException, |
| 250 | self.servlet.ProcessSubtabForm, post_data, self.mr) |
| 251 | self.assertEqual(0, self.config.default_template_for_developers) |
| 252 | self.assertEqual(0, self.config.default_template_for_users) |
| 253 | |
| 254 | def testProcessSubtabForm_Normal(self): |
| 255 | """If user has perms, set default templates.""" |
| 256 | post_data = fake.PostData( |
| 257 | default_template_for_developers=['Test Template'], |
| 258 | default_template_for_users=['Test Template']) |
| 259 | next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 260 | self.assertEqual(urls.ADMIN_TEMPLATES, next_url) |
| 261 | self.assertEqual(12345, self.config.default_template_for_developers) |
| 262 | self.assertEqual(12345, self.config.default_template_for_users) |
| 263 | |
| 264 | def testParseDefaultTemplateSelections_NotSpecified(self): |
| 265 | post_data = fake.PostData() |
| 266 | for_devs, for_users = self.servlet._ParseDefaultTemplateSelections( |
| 267 | post_data, self.test_templates) |
| 268 | self.assertEqual(None, for_devs) |
| 269 | self.assertEqual(None, for_users) |
| 270 | |
| 271 | def testParseDefaultTemplateSelections_TemplateNotFoundIsIgnored(self): |
| 272 | post_data = fake.PostData( |
| 273 | default_template_for_developers=['Bad value'], |
| 274 | default_template_for_users=['Bad value']) |
| 275 | for_devs, for_users = self.servlet._ParseDefaultTemplateSelections( |
| 276 | post_data, self.test_templates) |
| 277 | self.assertEqual(None, for_devs) |
| 278 | self.assertEqual(None, for_users) |
| 279 | |
| 280 | def testParseDefaultTemplateSelections_Normal(self): |
| 281 | post_data = fake.PostData( |
| 282 | default_template_for_developers=['Test Template'], |
| 283 | default_template_for_users=['Test Template']) |
| 284 | for_devs, for_users = self.servlet._ParseDefaultTemplateSelections( |
| 285 | post_data, self.test_templates) |
| 286 | self.assertEqual(12345, for_devs) |
| 287 | self.assertEqual(12345, for_users) |
| 288 | |
| 289 | |
| 290 | class AdminComponentsTest(TestBase): |
| 291 | |
| 292 | def setUp(self): |
| 293 | super(AdminComponentsTest, self).setUpServlet(issueadmin.AdminComponents) |
| 294 | self.cd_clean = tracker_bizobj.MakeComponentDef( |
| 295 | 1, self.project.project_id, 'BackEnd', 'doc', False, [], [111], 100000, |
| 296 | 122, 10000000, 133) |
| 297 | self.cd_with_subcomp = tracker_bizobj.MakeComponentDef( |
| 298 | 2, self.project.project_id, 'FrontEnd', 'doc', False, [], [111], |
| 299 | 100000, 122, 10000000, 133) |
| 300 | self.subcd = tracker_bizobj.MakeComponentDef( |
| 301 | 3, self.project.project_id, 'FrontEnd>Worker', 'doc', False, [], [111], |
| 302 | 100000, 122, 10000000, 133) |
| 303 | self.cd_with_template = tracker_bizobj.MakeComponentDef( |
| 304 | 4, self.project.project_id, 'Middle', 'doc', False, [], [111], |
| 305 | 100000, 122, 10000000, 133) |
| 306 | |
| 307 | def testGatherPageData(self): |
| 308 | self._mockGetUser() |
| 309 | self.mox.ReplayAll() |
| 310 | page_data = self.servlet.GatherPageData(self.mr) |
| 311 | self.mox.VerifyAll() |
Adrià Vilanova Martínez | f19ea43 | 2024-01-23 20:20:52 +0100 | [diff] [blame] | 312 | six.assertCountEqual( |
| 313 | self, [ |
| 314 | 'admin_tab_mode', 'failed_templ', 'component_defs', 'failed_perm', |
| 315 | 'config', 'failed_subcomp', 'open_text', 'closed_text', |
| 316 | 'labels_text', 'can_edit_project' |
| 317 | ], list(page_data.keys())) |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 318 | config_view = page_data['config'] |
| 319 | self.assertEqual(789, config_view.project_id) |
| 320 | self.assertEqual([], page_data['component_defs']) |
| 321 | |
| 322 | def testProcessFormData_NoErrors(self): |
| 323 | self.config.component_defs = [ |
| 324 | self.cd_clean, self.cd_with_subcomp, self.subcd, self.cd_with_template] |
| 325 | self.services.template.TemplatesWithComponent.return_value = [] |
| 326 | post_data = { |
| 327 | 'delete_components' : '%s,%s,%s' % ( |
| 328 | self.cd_clean.path, self.cd_with_subcomp.path, self.subcd.path)} |
| 329 | url = self.servlet.ProcessFormData(self.mr, post_data) |
| 330 | self.assertTrue( |
| 331 | url.startswith('http://127.0.0.1/p/proj/adminComponents?deleted=' |
| 332 | 'FrontEnd%3EWorker%2CFrontEnd%2CBackEnd&failed_perm=&' |
| 333 | 'failed_subcomp=&failed_templ=&ts=')) |
| 334 | |
| 335 | def testProcessFormData_SubCompError(self): |
| 336 | self.config.component_defs = [ |
| 337 | self.cd_clean, self.cd_with_subcomp, self.subcd, self.cd_with_template] |
| 338 | self.services.template.TemplatesWithComponent.return_value = [] |
| 339 | post_data = { |
| 340 | 'delete_components' : '%s,%s' % ( |
| 341 | self.cd_clean.path, self.cd_with_subcomp.path)} |
| 342 | url = self.servlet.ProcessFormData(self.mr, post_data) |
| 343 | self.assertTrue( |
| 344 | url.startswith('http://127.0.0.1/p/proj/adminComponents?deleted=' |
| 345 | 'BackEnd&failed_perm=&failed_subcomp=FrontEnd&' |
| 346 | 'failed_templ=&ts=')) |
| 347 | |
| 348 | def testProcessFormData_TemplateError(self): |
| 349 | self.config.component_defs = [ |
| 350 | self.cd_clean, self.cd_with_subcomp, self.subcd, self.cd_with_template] |
| 351 | |
| 352 | def mockTemplatesWithComponent(_cnxn, component_id): |
| 353 | if component_id == 4: |
| 354 | return 'template' |
| 355 | self.services.template.TemplatesWithComponent\ |
| 356 | .side_effect = mockTemplatesWithComponent |
| 357 | |
| 358 | post_data = { |
| 359 | 'delete_components' : '%s,%s,%s,%s' % ( |
| 360 | self.cd_clean.path, self.cd_with_subcomp.path, self.subcd.path, |
| 361 | self.cd_with_template.path)} |
| 362 | url = self.servlet.ProcessFormData(self.mr, post_data) |
| 363 | self.assertTrue( |
| 364 | url.startswith('http://127.0.0.1/p/proj/adminComponents?deleted=' |
| 365 | 'FrontEnd%3EWorker%2CFrontEnd%2CBackEnd&failed_perm=&' |
| 366 | 'failed_subcomp=&failed_templ=Middle&ts=')) |
| 367 | |
| 368 | |
| 369 | class AdminViewsTest(TestBase): |
| 370 | |
| 371 | def setUp(self): |
| 372 | super(AdminViewsTest, self).setUpServlet(issueadmin.AdminViews) |
| 373 | |
| 374 | def testGatherPageData(self): |
| 375 | self._mockGetUser() |
| 376 | self.mox.ReplayAll() |
| 377 | page_data = self.servlet.GatherPageData(self.mr) |
| 378 | self.mox.VerifyAll() |
| 379 | |
Adrià Vilanova Martínez | f19ea43 | 2024-01-23 20:20:52 +0100 | [diff] [blame] | 380 | six.assertCountEqual( |
| 381 | self, [ |
| 382 | 'canned_queries', 'admin_tab_mode', 'config', 'issue_notify', |
| 383 | 'new_query_indexes', 'max_queries', 'open_text', 'closed_text', |
| 384 | 'labels_text', 'can_edit_project' |
| 385 | ], list(page_data.keys())) |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 386 | config_view = page_data['config'] |
| 387 | self.assertEqual(789, config_view.project_id) |
| 388 | |
| 389 | def testProcessSubtabForm(self): |
| 390 | post_data = fake.PostData( |
| 391 | default_col_spec=['id pri mstone owner status summary'], |
| 392 | default_sort_spec=['mstone pri'], |
| 393 | default_x_attr=['owner'], default_y_attr=['mstone']) |
| 394 | next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 395 | self.assertEqual(urls.ADMIN_VIEWS, next_url) |
| 396 | self.assertEqual( |
| 397 | 'id pri mstone owner status summary', self.config.default_col_spec) |
| 398 | self.assertEqual('mstone pri', self.config.default_sort_spec) |
| 399 | self.assertEqual('owner', self.config.default_x_attr) |
| 400 | self.assertEqual('mstone', self.config.default_y_attr) |
| 401 | |
| 402 | |
| 403 | class AdminViewsFunctionsTest(unittest.TestCase): |
| 404 | |
| 405 | def testParseListPreferences(self): |
| 406 | # If no input, col_spec will be default column spec. |
| 407 | # For other fiels empty strings should be returned. |
| 408 | (col_spec, sort_spec, x_attr, y_attr, member_default_query, |
| 409 | ) = issueadmin._ParseListPreferences({}) |
| 410 | self.assertEqual(tracker_constants.DEFAULT_COL_SPEC, col_spec) |
| 411 | self.assertEqual('', sort_spec) |
| 412 | self.assertEqual('', x_attr) |
| 413 | self.assertEqual('', y_attr) |
| 414 | self.assertEqual('', member_default_query) |
| 415 | |
| 416 | # Test how hyphens in input are treated. |
| 417 | spec = 'label1-sub1 label2 label3-sub3' |
| 418 | (col_spec, sort_spec, x_attr, y_attr, member_default_query, |
| 419 | ) = issueadmin._ParseListPreferences( |
| 420 | fake.PostData(default_col_spec=[spec], |
| 421 | default_sort_spec=[spec], |
| 422 | default_x_attr=[spec], |
| 423 | default_y_attr=[spec]), |
| 424 | ) |
| 425 | |
| 426 | # Hyphens (and anything following) should be stripped from each term. |
| 427 | self.assertEqual('label1-sub1 label2 label3-sub3', col_spec) |
| 428 | |
| 429 | # The sort spec should be as given (except with whitespace condensed). |
| 430 | self.assertEqual(' '.join(spec.split()), sort_spec) |
| 431 | |
| 432 | # Only the first term (up to the first hyphen) should be used for x- or |
| 433 | # y-attr. |
| 434 | self.assertEqual('label1-sub1', x_attr) |
| 435 | self.assertEqual('label1-sub1', y_attr) |
| 436 | |
| 437 | # Test that multibyte strings are not mangled. |
Adrià Vilanova Martínez | f19ea43 | 2024-01-23 20:20:52 +0100 | [diff] [blame] | 438 | spec = ( |
| 439 | b'\xe7\xaa\xbf\xe8\x8b\xa5-\xe7\xb9\xb9 ' |
| 440 | b'\xe5\x9c\xb0\xe3\x81\xa6-\xe5\xbd\x93-\xe3\x81\xbe\xe3\x81\x99') |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 441 | spec = spec.decode('utf-8') |
| 442 | (col_spec, sort_spec, x_attr, y_attr, member_default_query, |
| 443 | ) = issueadmin._ParseListPreferences( |
| 444 | fake.PostData(default_col_spec=[spec], |
| 445 | default_sort_spec=[spec], |
| 446 | default_x_attr=[spec], |
| 447 | default_y_attr=[spec], |
| 448 | member_default_query=[spec]), |
| 449 | ) |
| 450 | self.assertEqual(spec, col_spec) |
| 451 | self.assertEqual(' '.join(spec.split()), sort_spec) |
Adrià Vilanova Martínez | f19ea43 | 2024-01-23 20:20:52 +0100 | [diff] [blame] | 452 | self.assertEqual( |
| 453 | b'\xe7\xaa\xbf\xe8\x8b\xa5-\xe7\xb9\xb9'.decode('utf-8'), x_attr) |
| 454 | self.assertEqual( |
| 455 | b'\xe7\xaa\xbf\xe8\x8b\xa5-\xe7\xb9\xb9'.decode('utf-8'), y_attr) |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 456 | self.assertEqual(spec, member_default_query) |
| 457 | |
| 458 | |
| 459 | class AdminRulesTest(TestBase): |
| 460 | |
| 461 | def setUp(self): |
| 462 | super(AdminRulesTest, self).setUpServlet(issueadmin.AdminRules) |
| 463 | |
| 464 | def testGatherPageData(self): |
| 465 | self._mockGetUser() |
| 466 | self.mox.ReplayAll() |
| 467 | page_data = self.servlet.GatherPageData(self.mr) |
| 468 | self.mox.VerifyAll() |
| 469 | |
Adrià Vilanova Martínez | f19ea43 | 2024-01-23 20:20:52 +0100 | [diff] [blame] | 470 | six.assertCountEqual( |
| 471 | self, [ |
| 472 | 'admin_tab_mode', 'config', 'rules', 'new_rule_indexes', |
| 473 | 'max_rules', 'open_text', 'closed_text', 'labels_text', |
| 474 | 'can_edit_project' |
| 475 | ], list(page_data.keys())) |
Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 476 | config_view = page_data['config'] |
| 477 | self.assertEqual(789, config_view.project_id) |
| 478 | self.assertEqual([], page_data['rules']) |
| 479 | |
| 480 | def testProcessSubtabForm(self): |
| 481 | pass # TODO(jrobbins): write this test |