OLD | NEW |
(Empty) | |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is govered 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 issue admin pages.""" |
| 7 |
| 8 import mox |
| 9 import unittest |
| 10 |
| 11 from framework import permissions |
| 12 from framework import urls |
| 13 from services import service_manager |
| 14 from testing import fake |
| 15 from testing import testing_helpers |
| 16 from tracker import issueadmin |
| 17 from tracker import tracker_bizobj |
| 18 from tracker import tracker_constants |
| 19 |
| 20 |
| 21 class TestBase(unittest.TestCase): |
| 22 |
| 23 def setUpServlet(self, servlet_factory): |
| 24 # pylint: disable=attribute-defined-outside-init |
| 25 self.services = service_manager.Services( |
| 26 project=fake.ProjectService(), |
| 27 config=fake.ConfigService(), |
| 28 user=fake.UserService(), |
| 29 issue=fake.IssueService(), |
| 30 features=fake.FeaturesService()) |
| 31 self.servlet = servlet_factory('req', 'res', services=self.services) |
| 32 self.project = self.services.project.TestAddProject('proj', project_id=789) |
| 33 self.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789) |
| 34 self.services.config.StoreConfig(None, self.config) |
| 35 self.cnxn = fake.MonorailConnection() |
| 36 self.mr = testing_helpers.MakeMonorailRequest( |
| 37 path='/p/proj/admin', project=self.project) |
| 38 self.mox = mox.Mox() |
| 39 |
| 40 def tearDown(self): |
| 41 self.mox.UnsetStubs() |
| 42 self.mox.ResetAll() |
| 43 |
| 44 def _mockGetUser(self): |
| 45 self.mox.StubOutWithMock(self.services.user, 'GetUser') |
| 46 user = self.services.user.TestAddUser('user@invalid', 100) |
| 47 self.services.user.GetUser( |
| 48 mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(user) |
| 49 |
| 50 |
| 51 class IssueAdminBaseTest(TestBase): |
| 52 |
| 53 def setUp(self): |
| 54 super(IssueAdminBaseTest, self).setUpServlet(issueadmin.IssueAdminBase) |
| 55 |
| 56 def testGatherPageData(self): |
| 57 self._mockGetUser() |
| 58 self.mox.ReplayAll() |
| 59 page_data = self.servlet.GatherPageData(self.mr) |
| 60 self.mox.VerifyAll() |
| 61 |
| 62 self.assertItemsEqual(['admin_tab_mode', 'config'], page_data.keys()) |
| 63 config_view = page_data['config'] |
| 64 self.assertEqual(789, config_view.project_id) |
| 65 |
| 66 |
| 67 class AdminStatusesTest(TestBase): |
| 68 |
| 69 def setUp(self): |
| 70 super(AdminStatusesTest, self).setUpServlet(issueadmin.AdminStatuses) |
| 71 |
| 72 def testProcessSubtabForm_MissingInput(self): |
| 73 post_data = fake.PostData() |
| 74 next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 75 self.assertEqual(urls.ADMIN_STATUSES, next_url) |
| 76 self.assertEqual([], self.config.well_known_statuses) |
| 77 self.assertEqual([], self.config.statuses_offer_merge) |
| 78 |
| 79 def testProcessSubtabForm_EmptyInput(self): |
| 80 post_data = fake.PostData( |
| 81 predefinedopen=[''], predefinedclosed=[''], statuses_offer_merge=['']) |
| 82 next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 83 self.assertEqual(urls.ADMIN_STATUSES, next_url) |
| 84 self.assertEqual([], self.config.well_known_statuses) |
| 85 self.assertEqual([], self.config.statuses_offer_merge) |
| 86 |
| 87 def testProcessSubtabForm_Normal(self): |
| 88 post_data = fake.PostData( |
| 89 predefinedopen=['New = newly reported'], |
| 90 predefinedclosed=['Fixed\nDuplicate'], |
| 91 statuses_offer_merge=['Duplicate']) |
| 92 next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 93 self.assertEqual(urls.ADMIN_STATUSES, next_url) |
| 94 self.assertEqual(3, len(self.config.well_known_statuses)) |
| 95 self.assertEqual('New', self.config.well_known_statuses[0].status) |
| 96 self.assertTrue(self.config.well_known_statuses[0].means_open) |
| 97 self.assertEqual('Fixed', self.config.well_known_statuses[1].status) |
| 98 self.assertFalse(self.config.well_known_statuses[1].means_open) |
| 99 self.assertEqual('Duplicate', self.config.well_known_statuses[2].status) |
| 100 self.assertFalse(self.config.well_known_statuses[2].means_open) |
| 101 self.assertEqual(['Duplicate'], self.config.statuses_offer_merge) |
| 102 |
| 103 |
| 104 class AdminLabelsTest(TestBase): |
| 105 |
| 106 def setUp(self): |
| 107 super(AdminLabelsTest, self).setUpServlet(issueadmin.AdminLabels) |
| 108 |
| 109 def testGatherPageData(self): |
| 110 self._mockGetUser() |
| 111 self.mox.ReplayAll() |
| 112 page_data = self.servlet.GatherPageData(self.mr) |
| 113 self.mox.VerifyAll() |
| 114 |
| 115 self.assertItemsEqual( |
| 116 ['admin_tab_mode', 'config', 'field_defs'], page_data.keys()) |
| 117 config_view = page_data['config'] |
| 118 self.assertEqual(789, config_view.project_id) |
| 119 self.assertEqual([], page_data['field_defs']) |
| 120 |
| 121 def testProcessSubtabForm_MissingInput(self): |
| 122 post_data = fake.PostData() |
| 123 next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 124 self.assertEqual(urls.ADMIN_LABELS, next_url) |
| 125 self.assertEqual([], self.config.well_known_labels) |
| 126 self.assertEqual([], self.config.exclusive_label_prefixes) |
| 127 |
| 128 def testProcessSubtabForm_EmptyInput(self): |
| 129 post_data = fake.PostData( |
| 130 predefinedlabels=[''], excl_prefixes=['']) |
| 131 next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 132 self.assertEqual(urls.ADMIN_LABELS, next_url) |
| 133 self.assertEqual([], self.config.well_known_labels) |
| 134 self.assertEqual([], self.config.exclusive_label_prefixes) |
| 135 |
| 136 def testProcessSubtabForm_Normal(self): |
| 137 post_data = fake.PostData( |
| 138 predefinedlabels=['Pri-0 = Burning issue\nPri-4 = It can wait'], |
| 139 excl_prefixes=['pri']) |
| 140 next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 141 self.assertEqual(urls.ADMIN_LABELS, next_url) |
| 142 self.assertEqual(2, len(self.config.well_known_labels)) |
| 143 self.assertEqual('Pri-0', self.config.well_known_labels[0].label) |
| 144 self.assertEqual('Pri-4', self.config.well_known_labels[1].label) |
| 145 self.assertEqual(['pri'], self.config.exclusive_label_prefixes) |
| 146 |
| 147 |
| 148 class AdminTemplatesTest(TestBase): |
| 149 |
| 150 def setUp(self): |
| 151 super(AdminTemplatesTest, self).setUpServlet(issueadmin.AdminTemplates) |
| 152 self.test_template = tracker_bizobj.MakeIssueTemplate( |
| 153 'Test Template', 'sum', 'New', 111L, 'content', [], [], [], []) |
| 154 self.test_template.template_id = 12345 |
| 155 |
| 156 def testGatherPageData(self): |
| 157 self._mockGetUser() |
| 158 self.mox.ReplayAll() |
| 159 page_data = self.servlet.GatherPageData(self.mr) |
| 160 self.mox.VerifyAll() |
| 161 |
| 162 self.assertItemsEqual( |
| 163 ['admin_tab_mode', 'config', 'fields'], page_data.keys()) |
| 164 config_view = page_data['config'] |
| 165 self.assertEqual(789, config_view.project_id) |
| 166 self.assertEqual([], page_data['fields']) |
| 167 |
| 168 def testProcessSubtabForm_NoEditProjectPerm(self): |
| 169 """If user lacks perms, ignore the attempt to set default templates.""" |
| 170 self.config.templates.append(self.test_template) |
| 171 post_data = fake.PostData( |
| 172 default_template_for_developers=['Test Template'], |
| 173 default_template_for_users=['Test Template']) |
| 174 self.servlet._ParseAllTemplates = lambda x, y: self.config.templates |
| 175 self.mr.perms = permissions.EMPTY_PERMISSIONSET |
| 176 next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 177 self.assertEqual(urls.ADMIN_TEMPLATES, next_url) |
| 178 self.assertEqual(0, self.config.default_template_for_developers) |
| 179 self.assertEqual(0, self.config.default_template_for_users) |
| 180 |
| 181 def testProcessSubtabForm_Normal(self): |
| 182 """If user lacks perms, ignore the attempt to set default templates.""" |
| 183 self.config.templates.append(self.test_template) |
| 184 post_data = fake.PostData( |
| 185 default_template_for_developers=['Test Template'], |
| 186 default_template_for_users=['Test Template']) |
| 187 self.servlet._ParseAllTemplates = lambda x, y: self.config.templates |
| 188 next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 189 self.assertEqual(urls.ADMIN_TEMPLATES, next_url) |
| 190 self.assertEqual(12345, self.config.default_template_for_developers) |
| 191 self.assertEqual(12345, self.config.default_template_for_users) |
| 192 |
| 193 def testParseTemplate(self): |
| 194 pass # TODO(jrobbins): write this |
| 195 |
| 196 def testParseDefaultTempalteSelections_NotSpecified(self): |
| 197 self.config.templates.append(self.test_template) |
| 198 post_data = fake.PostData() |
| 199 for_devs, for_users = self.servlet._ParseDefaultTemplateSelections( |
| 200 post_data, self.config.tempaltes) |
| 201 self.assertEqual(None, for_devs) |
| 202 self.assertEqual(None, for_users) |
| 203 |
| 204 def testParseDefaultTempalteSelections_NotSpecified(self): |
| 205 self.config.templates.append(self.test_template) |
| 206 post_data = fake.PostData( |
| 207 default_template_for_developers=['Bad value'], |
| 208 default_template_for_users=['Bad value']) |
| 209 for_devs, for_users = self.servlet._ParseDefaultTemplateSelections( |
| 210 post_data, self.config.templates) |
| 211 self.assertEqual(None, for_devs) |
| 212 self.assertEqual(None, for_users) |
| 213 |
| 214 def testParseDefaultTempalteSelections_Normal(self): |
| 215 self.config.templates.append(self.test_template) |
| 216 post_data = fake.PostData( |
| 217 default_template_for_developers=['Test Template'], |
| 218 default_template_for_users=['Test Template']) |
| 219 for_devs, for_users = self.servlet._ParseDefaultTemplateSelections( |
| 220 post_data, self.config.templates) |
| 221 self.assertEqual(12345, for_devs) |
| 222 self.assertEqual(12345, for_users) |
| 223 |
| 224 |
| 225 |
| 226 class AdminComponentsTest(TestBase): |
| 227 |
| 228 def setUp(self): |
| 229 super(AdminComponentsTest, self).setUpServlet(issueadmin.AdminComponents) |
| 230 self.cd_clean = tracker_bizobj.MakeComponentDef( |
| 231 1, self.project.project_id, 'BackEnd', 'doc', False, [], [111L], 100000, |
| 232 122L, 10000000, 133L) |
| 233 self.cd_with_subcomp = tracker_bizobj.MakeComponentDef( |
| 234 2, self.project.project_id, 'FrontEnd', 'doc', False, [], [111L], |
| 235 100000, 122L, 10000000, 133L) |
| 236 self.subcd = tracker_bizobj.MakeComponentDef( |
| 237 3, self.project.project_id, 'FrontEnd>Worker', 'doc', False, [], [111L], |
| 238 100000, 122L, 10000000, 133L) |
| 239 self.cd_with_template = tracker_bizobj.MakeComponentDef( |
| 240 4, self.project.project_id, 'Middle', 'doc', False, [], [111L], |
| 241 100000, 122L, 10000000, 133L) |
| 242 |
| 243 def testGatherPageData(self): |
| 244 self._mockGetUser() |
| 245 self.mox.ReplayAll() |
| 246 page_data = self.servlet.GatherPageData(self.mr) |
| 247 self.mox.VerifyAll() |
| 248 |
| 249 self.assertItemsEqual( |
| 250 ['admin_tab_mode', 'config', 'component_defs', |
| 251 'failed_perm', 'failed_subcomp', 'failed_templ'], page_data.keys()) |
| 252 config_view = page_data['config'] |
| 253 self.assertEqual(789, config_view.project_id) |
| 254 self.assertEqual([], page_data['component_defs']) |
| 255 |
| 256 def testProcessFormData_NoErrors(self): |
| 257 self.config.component_defs = [ |
| 258 self.cd_clean, self.cd_with_subcomp, self.subcd, self.cd_with_template] |
| 259 post_data = { |
| 260 'delete_components' : '%s,%s,%s' % ( |
| 261 self.cd_clean.path, self.cd_with_subcomp.path, self.subcd.path)} |
| 262 url = self.servlet.ProcessFormData(self.mr, post_data) |
| 263 self.assertTrue( |
| 264 url.startswith('http://127.0.0.1/p/proj/adminComponents?deleted=' |
| 265 'FrontEnd%3EWorker%2CFrontEnd%2CBackEnd&failed_perm=&' |
| 266 'failed_subcomp=&failed_templ=&ts=')) |
| 267 |
| 268 def testProcessFormData_SubCompError(self): |
| 269 self.config.component_defs = [ |
| 270 self.cd_clean, self.cd_with_subcomp, self.subcd, self.cd_with_template] |
| 271 post_data = { |
| 272 'delete_components' : '%s,%s' % ( |
| 273 self.cd_clean.path, self.cd_with_subcomp.path)} |
| 274 url = self.servlet.ProcessFormData(self.mr, post_data) |
| 275 self.assertTrue( |
| 276 url.startswith('http://127.0.0.1/p/proj/adminComponents?deleted=' |
| 277 'BackEnd&failed_perm=&failed_subcomp=FrontEnd&' |
| 278 'failed_templ=&ts=')) |
| 279 |
| 280 def testProcessFormData_TemplateError(self): |
| 281 self.config.component_defs = [ |
| 282 self.cd_clean, self.cd_with_subcomp, self.subcd, self.cd_with_template] |
| 283 self.services.config.component_ids_to_templates[4] = 'Test Template' |
| 284 post_data = { |
| 285 'delete_components' : '%s,%s,%s,%s' % ( |
| 286 self.cd_clean.path, self.cd_with_subcomp.path, self.subcd.path, |
| 287 self.cd_with_template.path)} |
| 288 url = self.servlet.ProcessFormData(self.mr, post_data) |
| 289 self.assertTrue( |
| 290 url.startswith('http://127.0.0.1/p/proj/adminComponents?deleted=' |
| 291 'FrontEnd%3EWorker%2CFrontEnd%2CBackEnd&failed_perm=&' |
| 292 'failed_subcomp=&failed_templ=Middle&ts=')) |
| 293 |
| 294 |
| 295 class AdminViewsTest(TestBase): |
| 296 |
| 297 def setUp(self): |
| 298 super(AdminViewsTest, self).setUpServlet(issueadmin.AdminViews) |
| 299 |
| 300 def testGatherPageData(self): |
| 301 self._mockGetUser() |
| 302 self.mox.ReplayAll() |
| 303 page_data = self.servlet.GatherPageData(self.mr) |
| 304 self.mox.VerifyAll() |
| 305 |
| 306 self.assertItemsEqual( |
| 307 ['admin_tab_mode', 'config', 'issue_notify', |
| 308 'new_query_indexes', 'max_queries'], |
| 309 page_data.keys()) |
| 310 config_view = page_data['config'] |
| 311 self.assertEqual(789, config_view.project_id) |
| 312 |
| 313 def testProcessSubtabForm(self): |
| 314 post_data = fake.PostData( |
| 315 default_col_spec=['id pri mstone owner status summary'], |
| 316 default_sort_spec=['mstone pri'], |
| 317 default_x_attr=['owner'], default_y_attr=['mstone']) |
| 318 next_url = self.servlet.ProcessSubtabForm(post_data, self.mr) |
| 319 self.assertEqual(urls.ADMIN_VIEWS, next_url) |
| 320 self.assertEqual( |
| 321 'id pri mstone owner status summary', self.config.default_col_spec) |
| 322 self.assertEqual('mstone pri', self.config.default_sort_spec) |
| 323 self.assertEqual('owner', self.config.default_x_attr) |
| 324 self.assertEqual('mstone', self.config.default_y_attr) |
| 325 |
| 326 |
| 327 class AdminViewsFunctionsTest(unittest.TestCase): |
| 328 |
| 329 def testParseListPreferences(self): |
| 330 # If no input, col_spec will be default column spec. |
| 331 # For other fiels empty strings should be returned. |
| 332 col_spec, sort_spec, x_attr, y_attr = issueadmin._ParseListPreferences( |
| 333 {}) |
| 334 self.assertEqual(tracker_constants.DEFAULT_COL_SPEC, col_spec) |
| 335 self.assertEqual('', sort_spec) |
| 336 self.assertEqual('', x_attr) |
| 337 self.assertEqual('', y_attr) |
| 338 |
| 339 # Test how hyphens in input are treated. |
| 340 spec = 'label1-sub1 label2 label3-sub3' |
| 341 col_spec, sort_spec, x_attr, y_attr = issueadmin._ParseListPreferences( |
| 342 fake.PostData(default_col_spec=[spec], |
| 343 default_sort_spec=[spec], |
| 344 default_x_attr=[spec], |
| 345 default_y_attr=[spec]), |
| 346 ) |
| 347 |
| 348 # Hyphens (and anything following) should be stripped from each term. |
| 349 self.assertEqual('label1-sub1 label2 label3-sub3', col_spec) |
| 350 |
| 351 # The sort spec should be as given (except with whitespace condensed). |
| 352 self.assertEqual(' '.join(spec.split()), sort_spec) |
| 353 |
| 354 # Only the first term (up to the first hyphen) should be used for x- or |
| 355 # y-attr. |
| 356 self.assertEqual('label1-sub1', x_attr) |
| 357 self.assertEqual('label1-sub1', y_attr) |
| 358 |
| 359 # Test that multibyte strings are not mangled. |
| 360 spec = ('\xe7\xaa\xbf\xe8\x8b\xa5-\xe7\xb9\xb9 ' |
| 361 '\xe5\x9c\xb0\xe3\x81\xa6-\xe5\xbd\x93-\xe3\x81\xbe\xe3\x81\x99') |
| 362 spec = spec.decode('utf-8') |
| 363 col_spec, sort_spec, x_attr, y_attr = issueadmin._ParseListPreferences( |
| 364 fake.PostData(default_col_spec=[spec], |
| 365 default_sort_spec=[spec], |
| 366 default_x_attr=[spec], |
| 367 default_y_attr=[spec]), |
| 368 ) |
| 369 self.assertEqual(spec, col_spec) |
| 370 self.assertEqual(' '.join(spec.split()), sort_spec) |
| 371 self.assertEqual('\xe7\xaa\xbf\xe8\x8b\xa5-\xe7\xb9\xb9'.decode('utf-8'), |
| 372 x_attr) |
| 373 self.assertEqual('\xe7\xaa\xbf\xe8\x8b\xa5-\xe7\xb9\xb9'.decode('utf-8'), |
| 374 y_attr) |
| 375 |
| 376 |
| 377 class AdminRulesTest(TestBase): |
| 378 |
| 379 def setUp(self): |
| 380 super(AdminRulesTest, self).setUpServlet(issueadmin.AdminRules) |
| 381 |
| 382 def testGatherPageData(self): |
| 383 self._mockGetUser() |
| 384 self.mox.ReplayAll() |
| 385 page_data = self.servlet.GatherPageData(self.mr) |
| 386 self.mox.VerifyAll() |
| 387 |
| 388 self.assertItemsEqual( |
| 389 ['admin_tab_mode', 'config', 'rules', 'new_rule_indexes', 'max_rules'], |
| 390 page_data.keys()) |
| 391 config_view = page_data['config'] |
| 392 self.assertEqual(789, config_view.project_id) |
| 393 self.assertEqual([], page_data['rules']) |
| 394 |
| 395 def testProcessSubtabForm(self): |
| 396 pass # TODO(jrobbins): write this test |
| 397 |
| 398 |
| 399 if __name__ == '__main__': |
| 400 unittest.main() |
OLD | NEW |