Esempio n. 1
0
 def setUp(self):
   self.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
   cd1 = tracker_bizobj.MakeComponentDef(
       1, 789, 'BackEnd', 'doc', False, [], [111], 0, 122)
   cd2 = tracker_bizobj.MakeComponentDef(
       2, 789, 'BackEnd>DB', 'doc', True, [], [111], 0, 122)
   self.config.component_defs = [cd1, cd2]
Esempio n. 2
0
 def setUp(self):
     self.mox = mox.Mox()
     self.default_cols = 'a b c'
     self.builtin_cols = 'a b x y z'
     self.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
     self.config.component_defs.append(
         tracker_bizobj.MakeComponentDef(11, 789, 'Database', 'doc', False,
                                         [], [], 0, 0))
     self.config.component_defs.append(
         tracker_bizobj.MakeComponentDef(22, 789, 'User Interface', 'doc',
                                         True, [], [], 0, 0))
     self.config.component_defs.append(
         tracker_bizobj.MakeComponentDef(33, 789, 'Installer', 'doc', False,
                                         [], [], 0, 0))
Esempio n. 3
0
    def testProcessEditComponent_RenameWithSubComponents(self):
        subcd_1 = tracker_bizobj.MakeComponentDef(2, self.project.project_id,
                                                  'BackEnd>Worker1', 'doc',
                                                  False, [], [111], 0, 125, 3,
                                                  126)
        subcd_2 = tracker_bizobj.MakeComponentDef(3, self.project.project_id,
                                                  'BackEnd>Worker2', 'doc',
                                                  False, [], [111], 0, 125, 4,
                                                  127)
        self.config.component_defs.extend([subcd_1, subcd_2])

        self.mox.StubOutWithMock(filterrules_helpers,
                                 'RecomputeAllDerivedFields')
        filterrules_helpers.RecomputeAllDerivedFields(self.mr.cnxn,
                                                      self.services,
                                                      self.mr.project,
                                                      self.config)
        self.mox.ReplayAll()
        post_data = fake.PostData(
            leaf_name=['BackEnds'],
            docstring=['This is where the magic happens'],
            deprecated=[True],
            admins=['*****@*****.**'],
            cc=['*****@*****.**'],
            labels=[''])

        self.servlet._ProcessEditComponent(self.mr, post_data, self.config,
                                           self.cd)

        self.mox.VerifyAll()
        config = self.services.config.GetProjectConfig(self.mr.cnxn,
                                                       self.mr.project_id)
        cd = tracker_bizobj.FindComponentDef('BackEnds', config)
        self.assertEqual('BackEnds', cd.path)
        subcd_1 = tracker_bizobj.FindComponentDef('BackEnds>Worker1', config)
        self.assertEqual('BackEnds>Worker1', subcd_1.path)
        # Assert that creator and modifier have not changed for subcd_1.
        self.assertEqual(125, subcd_1.creator_id)
        self.assertEqual(0, subcd_1.created)
        self.assertEqual(126, subcd_1.modifier_id)
        self.assertEqual(3, subcd_1.modified)

        subcd_2 = tracker_bizobj.FindComponentDef('BackEnds>Worker2', config)
        self.assertEqual('BackEnds>Worker2', subcd_2.path)
        # Assert that creator and modifier have not changed for subcd_2.
        self.assertEqual(125, subcd_2.creator_id)
        self.assertEqual(0, subcd_2.created)
        self.assertEqual(127, subcd_2.modifier_id)
        self.assertEqual(4, subcd_2.modified)
Esempio n. 4
0
    def setUp(self):
        self.services = service_manager.Services(
            user=fake.UserService(),
            issue=fake.IssueService(),
            config=fake.ConfigService(),
            template=Mock(spec=template_svc.TemplateService),
            project=fake.ProjectService())
        self.servlet = componentdetail.ComponentDetail('req',
                                                       'res',
                                                       services=self.services)
        self.project = self.services.project.TestAddProject('proj')
        self.mr = testing_helpers.MakeMonorailRequest(
            project=self.project, perms=permissions.OWNER_ACTIVE_PERMISSIONSET)
        self.mr.auth.email = '*****@*****.**'
        self.config = self.services.config.GetProjectConfig(
            'fake cnxn', self.project.project_id)
        self.services.config.StoreConfig('fake cnxn', self.config)
        self.cd = tracker_bizobj.MakeComponentDef(1, self.project.project_id,
                                                  'BackEnd', 'doc', False, [],
                                                  [111], 100000, 122, 10000000,
                                                  133)
        self.config.component_defs = [self.cd]
        self.services.user.TestAddUser('*****@*****.**', 111)
        self.services.user.TestAddUser('*****@*****.**', 122)
        self.services.user.TestAddUser('*****@*****.**', 133)
        self.mr.component_path = 'BackEnd'

        self.mox = mox.Mox()
Esempio n. 5
0
 def setUp(self):
     self.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
     self.cd1 = tracker_bizobj.MakeComponentDef(1, 789, 'FrontEnd', 'doc',
                                                False, [], [111], 0, 0)
     self.cd2 = tracker_bizobj.MakeComponentDef(2, 789, 'FrontEnd>Splash',
                                                'doc', False, [], [222], 0,
                                                0)
     self.cd3 = tracker_bizobj.MakeComponentDef(3, 789, 'BackEnd', 'doc',
                                                True, [], [111, 333], 0, 0)
     self.config.component_defs = [self.cd1, self.cd2, self.cd3]
     self.services = service_manager.Services(user=fake.UserService(),
                                              config=fake.ConfigService())
     self.services.user.TestAddUser('*****@*****.**', 111)
     self.services.user.TestAddUser('*****@*****.**', 222)
     self.services.user.TestAddUser('*****@*****.**', 333)
     self.mr = fake.MonorailRequest(self.services)
     self.mr.cnxn = fake.MonorailConnection()
Esempio n. 6
0
 def setUp(self):
     super(AdminComponentsTest,
           self).setUpServlet(issueadmin.AdminComponents)
     self.cd_clean = tracker_bizobj.MakeComponentDef(
         1, self.project.project_id, 'BackEnd', 'doc', False, [], [111],
         100000, 122, 10000000, 133)
     self.cd_with_subcomp = tracker_bizobj.MakeComponentDef(
         2, self.project.project_id, 'FrontEnd', 'doc', False, [], [111],
         100000, 122, 10000000, 133)
     self.subcd = tracker_bizobj.MakeComponentDef(3,
                                                  self.project.project_id,
                                                  'FrontEnd>Worker', 'doc',
                                                  False, [], [111], 100000,
                                                  122, 10000000, 133)
     self.cd_with_template = tracker_bizobj.MakeComponentDef(
         4, self.project.project_id, 'Middle', 'doc', False, [], [111],
         100000, 122, 10000000, 133)
Esempio n. 7
0
 def testGatherPageData_WithSubComponents(self):
     subcd = tracker_bizobj.MakeComponentDef(2, self.project.project_id,
                                             'BackEnd>Worker', 'doc', False,
                                             [], [111], 0, 122)
     self.config.component_defs.append(subcd)
     page_data = self.servlet.GatherPageData(self.mr)
     self.assertFalse(page_data['allow_delete'])
     self.assertEqual([subcd], page_data['subcomponents'])
Esempio n. 8
0
 def setUp(self):
     self.cnxn = 'fake cnxn'
     self.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
     self.config.component_defs.append(
         tracker_bizobj.MakeComponentDef(101, 789, 'UI', 'doc', False, [],
                                         [], 0, 0))
     self.config.component_defs.append(
         tracker_bizobj.MakeComponentDef(102, 789, 'UI>Search', 'doc',
                                         False, [], [], 0, 0))
     self.config.component_defs.append(
         tracker_bizobj.MakeComponentDef(201, 789, 'DB', 'doc', False, [],
                                         [], 0, 0))
     self.config.component_defs.append(
         tracker_bizobj.MakeComponentDef(301, 789, 'Search', 'doc', False,
                                         [], [], 0, 0))
     self.services = service_manager.Services(user=fake.UserService(),
                                              project=fake.ProjectService(),
                                              issue=fake.IssueService(),
                                              config=fake.ConfigService())
     self.services.user.TestAddUser('*****@*****.**', 111L)
Esempio n. 9
0
 def SetUpComponents(
     self, project_id, component_id, component_name, component_doc='doc',
     deprecated=False, admin_ids=None, cc_ids=None, created=100000, creator=1):
   admin_ids = admin_ids or []
   cc_ids = cc_ids or []
   self.config = self.services.config.GetProjectConfig(
       'fake cnxn', project_id)
   self.services.config.StoreConfig('fake cnxn', self.config)
   cd = tracker_bizobj.MakeComponentDef(
       component_id, project_id, component_name, component_doc, deprecated,
       admin_ids, cc_ids, created, creator)
   self.config.component_defs.append(cd)
Esempio n. 10
0
    def testProcessFormData_Delete_WithSubComponent(self):
        subcd = tracker_bizobj.MakeComponentDef(2, self.project.project_id,
                                                'BackEnd>Worker', 'doc', False,
                                                [], [111], 0, 122)
        self.config.component_defs.append(subcd)

        post_data = fake.PostData(name=['BackEnd'], deletecomponent=['Submit'])
        with self.assertRaises(permissions.PermissionException) as cm:
            self.servlet.ProcessFormData(self.mr, post_data)
        self.assertEquals(
            'User tried to delete component that had subcomponents',
            cm.exception.message)
 def setUp(self):
     self.services = service_manager.Services(user=fake.UserService(),
                                              config=fake.ConfigService())
     self.services.user.TestAddUser('*****@*****.**', 111)
     self.services.user.TestAddUser('*****@*****.**', 222)
     self.users_by_id = framework_views.MakeAllUserViews(
         'cnxn', self.services.user, [111, 222])
     self.services.config.TestAddLabelsDict({'Hot': 1, 'Cold': 2})
     self.cd = tracker_bizobj.MakeComponentDef(10,
                                               789,
                                               'UI',
                                               'User interface',
                                               False, [111], [222],
                                               0,
                                               111,
                                               label_ids=[1, 2])
Esempio n. 12
0
  def setUp(self):
    self.services = service_manager.Services(
        user=fake.UserService(),
        config=fake.ConfigService(),
        project=fake.ProjectService(),
        usergroup=fake.UserGroupService())
    self.project = self.services.project.TestAddProject('proj')
    self.mr = testing_helpers.MakeMonorailRequest(
        project=self.project)
    self.config = self.services.config.GetProjectConfig(
        'fake cnxn', self.project.project_id)
    self.fd_1 =  tracker_bizobj.MakeFieldDef(
        1, 789, 'UXReview', tracker_pb2.FieldTypes.STR_TYPE, None,
        '', False, False, False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action',
        'Approval for UX review', False)
    self.fd_2 =  tracker_bizobj.MakeFieldDef(
        2, 789, 'UXReview', tracker_pb2.FieldTypes.STR_TYPE, None,
        '', False, False, False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action',
        'Approval for UX review', False)
    self.fd_3 = tracker_bizobj.MakeFieldDef(
        3, 789, 'UXApproval', tracker_pb2.FieldTypes.APPROVAL_TYPE, None,
        '', False, False, False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action',
        'Approval for UX review', False)
    self.fd_4 = tracker_bizobj.MakeFieldDef(
        4, 789, 'TestApproval', tracker_pb2.FieldTypes.APPROVAL_TYPE, None,
        '', False, False, False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action',
        'Approval for Test review', False)
    self.fd_5 = tracker_bizobj.MakeFieldDef(
        5, 789, 'SomeApproval', tracker_pb2.FieldTypes.APPROVAL_TYPE, None,
        '', False, False, False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action',
        'Approval for Test review', False)
    self.ad_3 = tracker_pb2.ApprovalDef(approval_id=3)
    self.ad_4 = tracker_pb2.ApprovalDef(approval_id=4)
    self.ad_5 = tracker_pb2.ApprovalDef(approval_id=5)
    self.cd_1 = tracker_bizobj.MakeComponentDef(
        1, 789, 'BackEnd', 'doc', False, [111], [], 100000, 222)

    self.services.user.TestAddUser('*****@*****.**', 111)
    self.services.user.TestAddUser('*****@*****.**', 222)
    self.services.user.TestAddUser('*****@*****.**', 333)
    self.services.project.TestAddProjectMembers(
        [111], self.project, 'OWNER_ROLE')
Esempio n. 13
0
 def setUp(self):
   self.services = service_manager.Services(
       user=fake.UserService(),
       config=fake.ConfigService(),
       project=fake.ProjectService())
   self.servlet = componentcreate.ComponentCreate(
       'req', 'res', services=self.services)
   self.project = self.services.project.TestAddProject('proj')
   self.mr = testing_helpers.MakeMonorailRequest(
       project=self.project, perms=permissions.OWNER_ACTIVE_PERMISSIONSET)
   self.mr.auth.email = '*****@*****.**'
   self.config = self.services.config.GetProjectConfig(
       'fake cnxn', self.project.project_id)
   self.services.config.StoreConfig('fake cnxn', self.config)
   self.cd = tracker_bizobj.MakeComponentDef(
       1, self.project.project_id, 'BackEnd', 'doc', False, [], [111], 0,
       122)
   self.config.component_defs = [self.cd]
   self.services.user.TestAddUser('*****@*****.**', 111)
   self.services.user.TestAddUser('*****@*****.**', 122)
Esempio n. 14
0
    def setUp(self):
        self.cnxn = 'fake cnxn'
        mock_template_service = Mock(spec=template_svc.TemplateService)
        self.services = service_manager.Services(
            project=fake.ProjectService(),
            config=fake.ConfigService(),
            template=mock_template_service,
            usergroup=fake.UserGroupService(),
            user=fake.UserService())
        self.servlet = templatedetail.TemplateDetail('req',
                                                     'res',
                                                     services=self.services)

        self.services.user.TestAddUser('*****@*****.**', 111)
        self.services.user.TestAddUser('*****@*****.**', 222)
        self.services.user.TestAddUser('*****@*****.**', 111)
        self.services.user.TestAddUser('*****@*****.**', 333)

        self.project = self.services.project.TestAddProject('proj')
        self.services.project.TestAddProjectMembers([333], self.project,
                                                    'CONTRIBUTOR_ROLE')

        self.template = self.test_template = tracker_bizobj.MakeIssueTemplate(
            'TestTemplate',
            'sum',
            'New',
            111,
            'content', ['label1', 'label2'], [], [222], [],
            summary_must_be_edited=True,
            owner_defaults_to_member=True,
            component_required=False,
            members_only=False)
        self.template.template_id = 12345
        self.services.template.GetTemplateByName = Mock(
            return_value=self.template)

        self.mr = testing_helpers.MakeMonorailRequest(project=self.project)
        self.mr.template_name = 'TestTemplate'

        self.mox = mox.Mox()

        self.fd_1 = tracker_bizobj.MakeFieldDef(
            1,
            789,
            'UXReview',
            tracker_pb2.FieldTypes.STR_TYPE,
            None,
            '',
            False,
            False,
            False,
            None,
            None,
            '',
            False,
            '',
            '',
            tracker_pb2.NotifyTriggers.NEVER,
            'no_action',
            'Approval for UX review',
            False,
            approval_id=2)
        self.fd_2 = tracker_bizobj.MakeFieldDef(
            2, 789, 'UXReview', tracker_pb2.FieldTypes.STR_TYPE, None, '',
            False, False, False, None, None, '', False, '', '',
            tracker_pb2.NotifyTriggers.NEVER, 'no_action',
            'Approval for UX review', False)
        self.fd_3 = tracker_bizobj.MakeFieldDef(
            3, 789, 'TestApproval', tracker_pb2.FieldTypes.APPROVAL_TYPE, None,
            '', False, False, False, None, None, '', False, '', '',
            tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'Approval for Test',
            False)
        self.fd_4 = tracker_bizobj.MakeFieldDef(
            4, 789, 'SecurityApproval', tracker_pb2.FieldTypes.APPROVAL_TYPE,
            None, '', False, False, False, None, None, '', False, '', '',
            tracker_pb2.NotifyTriggers.NEVER, 'no_action',
            'Approval for Security', False)
        self.fd_5 = tracker_bizobj.MakeFieldDef(
            5,
            789,
            'GateTarget',
            tracker_pb2.FieldTypes.INT_TYPE,
            None,
            '',
            False,
            False,
            False,
            None,
            None,
            '',
            False,
            '',
            '',
            tracker_pb2.NotifyTriggers.NEVER,
            'no_action',
            'milestone target',
            False,
            is_phase_field=True)
        self.fd_6 = tracker_bizobj.MakeFieldDef(
            6,
            789,
            'Choices',
            tracker_pb2.FieldTypes.ENUM_TYPE,
            None,
            '',
            False,
            False,
            False,
            None,
            None,
            '',
            False,
            '',
            '',
            tracker_pb2.NotifyTriggers.NEVER,
            'no_action',
            'milestone target',
            False,
            is_phase_field=True)

        self.ad_3 = tracker_pb2.ApprovalDef(approval_id=3)
        self.ad_4 = tracker_pb2.ApprovalDef(approval_id=4)

        self.cd_1 = tracker_bizobj.MakeComponentDef(1, 789, 'BackEnd', 'doc',
                                                    False, [111], [], 100000,
                                                    222)
        self.template.component_ids.append(1)

        self.canary_phase = tracker_pb2.Phase(name='Canary',
                                              phase_id=1,
                                              rank=1)
        self.av_3 = tracker_pb2.ApprovalValue(approval_id=3, phase_id=1)
        self.stable_phase = tracker_pb2.Phase(name='Stable',
                                              phase_id=2,
                                              rank=3)
        self.av_4 = tracker_pb2.ApprovalValue(approval_id=4, phase_id=2)
        self.template.phases.extend([self.stable_phase, self.canary_phase])
        self.template.approval_values.extend([self.av_3, self.av_4])

        self.config = self.services.config.GetProjectConfig(
            'fake cnxn', self.project.project_id)
        self.templates = testing_helpers.DefaultTemplates()
        self.template.labels.extend([
            'GateTarget-Should-Not', 'GateTarget-Be-Masked', 'Choices-Wrapped',
            'Choices-Burritod'
        ])
        self.templates.append(self.template)
        self.services.template.GetProjectTemplates = Mock(
            return_value=self.templates)
        self.services.template.FindTemplateByName = Mock(
            return_value=self.template)
        self.config.component_defs.append(self.cd_1)
        self.config.field_defs.extend(
            [self.fd_1, self.fd_2, self.fd_3, self.fd_4, self.fd_5, self.fd_6])
        self.config.approval_defs.extend([self.ad_3, self.ad_4])
        self.services.config.StoreConfig(None, self.config)
    def testCompareComponents_Normal(self):
        config = tracker_pb2.ProjectIssueConfig()
        config.component_defs.append(
            tracker_bizobj.MakeComponentDef(100, 789, 'UI', 'doc', False, [],
                                            [], 0, 0))
        config.component_defs.append(
            tracker_bizobj.MakeComponentDef(110, 789, 'UI>Help', 'doc', False,
                                            [], [], 0, 0))
        config.component_defs.append(
            tracker_bizobj.MakeComponentDef(200, 789, 'Networking', 'doc',
                                            False, [], [], 0, 0))

        # Check if the issue is in a specified component or subcomponent.
        self.assertTrue(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.EQ,
                                                   ['UI'], [100]))
        self.assertTrue(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.EQ,
                                                   ['UI>Help'], [110]))
        self.assertTrue(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.EQ,
                                                   ['UI'], [100, 110]))
        self.assertFalse(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.EQ,
                                                   ['UI'], []))
        self.assertFalse(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.EQ,
                                                   ['UI'], [110]))
        self.assertFalse(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.EQ,
                                                   ['UI'], [200]))
        self.assertFalse(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.EQ,
                                                   ['UI>Help'], [100]))
        self.assertFalse(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.EQ,
                                                   ['Networking'], [100]))

        self.assertTrue(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.NE,
                                                   ['UI'], []))
        self.assertFalse(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.NE,
                                                   ['UI'], [100]))
        self.assertTrue(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.NE,
                                                   ['Networking'], [100]))

        # Exact vs non-exact.
        self.assertFalse(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.EQ,
                                                   ['Help'], [110]))
        self.assertTrue(
            filterrules_helpers._CompareComponents(config,
                                                   ast_pb2.QueryOp.TEXT_HAS,
                                                   ['UI'], [110]))
        self.assertFalse(
            filterrules_helpers._CompareComponents(config,
                                                   ast_pb2.QueryOp.TEXT_HAS,
                                                   ['Help'], [110]))
        self.assertFalse(
            filterrules_helpers._CompareComponents(
                config, ast_pb2.QueryOp.NOT_TEXT_HAS, ['UI'], [110]))
        self.assertTrue(
            filterrules_helpers._CompareComponents(
                config, ast_pb2.QueryOp.NOT_TEXT_HAS, ['Help'], [110]))

        # Multivalued issues and Quick-OR notation
        self.assertTrue(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.EQ,
                                                   ['Networking'], [200]))
        self.assertFalse(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.EQ,
                                                   ['Networking'], [100, 110]))
        self.assertTrue(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.EQ,
                                                   ['UI', 'Networking'],
                                                   [100]))
        self.assertFalse(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.EQ,
                                                   ['UI', 'Networking'],
                                                   [110]))
        self.assertTrue(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.EQ,
                                                   ['UI', 'Networking'],
                                                   [200]))
        self.assertTrue(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.EQ,
                                                   ['UI', 'Networking'],
                                                   [110, 200]))
        self.assertTrue(
            filterrules_helpers._CompareComponents(config,
                                                   ast_pb2.QueryOp.TEXT_HAS,
                                                   ['UI', 'Networking'],
                                                   [110, 200]))
        self.assertTrue(
            filterrules_helpers._CompareComponents(config, ast_pb2.QueryOp.EQ,
                                                   ['UI>Help', 'Networking'],
                                                   [110, 200]))
    def testComputeDerivedFields_Components(self):
        cnxn = 'fake sql connection'
        rules = []
        component_defs = [
            tracker_bizobj.MakeComponentDef(
                10,
                789,
                'DB',
                'database',
                False, [], [
                    TEST_ID_MAP['*****@*****.**'],
                    TEST_ID_MAP['*****@*****.**']
                ],
                0,
                0,
                label_ids=[
                    TEST_LABEL_IDS['i18n'], TEST_LABEL_IDS['Priority-High']
                ]),
            tracker_bizobj.MakeComponentDef(20, 789, 'Install', 'installer',
                                            False, [], [], 0, 0),
            tracker_bizobj.MakeComponentDef(
                30,
                789,
                'UI',
                'doc',
                False, [], [
                    TEST_ID_MAP['*****@*****.**'],
                    TEST_ID_MAP['*****@*****.**']
                ],
                0,
                0,
                label_ids=[
                    TEST_LABEL_IDS['i18n'], TEST_LABEL_IDS['l10n'],
                    TEST_LABEL_IDS['Priority-Medium']
                ]),
        ]
        excl_prefixes = ['Priority', 'type', 'milestone']
        config = tracker_pb2.ProjectIssueConfig(
            exclusive_label_prefixes=excl_prefixes,
            component_defs=component_defs)
        predicate_asts = filterrules_helpers.ParsePredicateASTs(
            rules, config, None)

        # No components.
        issue = fake.MakeTestIssue(789,
                                   1,
                                   ORIG_SUMMARY,
                                   'New',
                                   0L,
                                   labels=ORIG_LABELS)
        self.assertEquals(
            (0, '', [], [], []),
            filterrules_helpers._ComputeDerivedFields(cnxn, self.services,
                                                      issue, config, rules,
                                                      predicate_asts))

        # One component, no CCs or labels added
        issue.component_ids = [20]
        issue = fake.MakeTestIssue(789,
                                   1,
                                   ORIG_SUMMARY,
                                   'New',
                                   0L,
                                   labels=ORIG_LABELS)
        self.assertEquals(
            (0, '', [], [], []),
            filterrules_helpers._ComputeDerivedFields(cnxn, self.services,
                                                      issue, config, rules,
                                                      predicate_asts))

        # One component, some CCs and labels added
        issue = fake.MakeTestIssue(789,
                                   1,
                                   ORIG_SUMMARY,
                                   'New',
                                   0L,
                                   labels=ORIG_LABELS,
                                   component_ids=[10])
        self.assertEquals(
            (0, '', [
                TEST_ID_MAP['*****@*****.**'], TEST_ID_MAP['*****@*****.**']
            ], ['i18n', 'Priority-High'], []),
            filterrules_helpers._ComputeDerivedFields(cnxn, self.services,
                                                      issue, config, rules,
                                                      predicate_asts))

        # One component, CCs and labels not added because of labels on the issue.
        issue = fake.MakeTestIssue(789,
                                   1,
                                   ORIG_SUMMARY,
                                   'New',
                                   0L,
                                   labels=['Priority-Low', 'i18n'],
                                   component_ids=[10])
        issue.cc_ids = [TEST_ID_MAP['*****@*****.**']]
        self.assertEquals(
            (0, '', [TEST_ID_MAP['*****@*****.**']], [], []),
            filterrules_helpers._ComputeDerivedFields(cnxn, self.services,
                                                      issue, config, rules,
                                                      predicate_asts))

        # Multiple components, added CCs treated as a set, exclusive labels in later
        # components take priority over earlier ones.
        issue = fake.MakeTestIssue(789,
                                   1,
                                   ORIG_SUMMARY,
                                   'New',
                                   0L,
                                   labels=ORIG_LABELS,
                                   component_ids=[10, 30])
        self.assertEquals(
            (0, '', [
                TEST_ID_MAP['*****@*****.**'],
                TEST_ID_MAP['*****@*****.**'], TEST_ID_MAP['*****@*****.**']
            ], ['i18n', 'l10n', 'Priority-Medium'], []),
            filterrules_helpers._ComputeDerivedFields(cnxn, self.services,
                                                      issue, config, rules,
                                                      predicate_asts))