def testProcessFormData_AcceptPhases(self):
        post_data = fake.PostData(name=['TestTemplate'],
                                  members_only=['on'],
                                  summary=['TLDR'],
                                  summary_must_be_edited=[''],
                                  content=['HEY WHY'],
                                  status=['Accepted'],
                                  owner=['*****@*****.**'],
                                  label=['label-One', 'label-Two'],
                                  custom_1=['NO'],
                                  custom_2=['MOOD'],
                                  components=['BackEnd'],
                                  component_required=['on'],
                                  owner_defaults_to_member=['on'],
                                  add_approvals=['on'],
                                  phase_0=['Canary'],
                                  phase_1=['Stable'],
                                  phase_2=[''],
                                  phase_3=[''],
                                  phase_4=[''],
                                  phase_5=[''],
                                  approval_3=['phase_0'],
                                  approval_4=['phase_1'])
        url = self.servlet.ProcessFormData(self.mr, post_data)

        self.assertTrue(
            '/templates/detail?saved=1&template=TestTemplate&' in url)

        self.services.template.UpdateIssueTemplateDef.assert_called_once_with(
            self.mr.cnxn,
            47925,
            12345,
            status='Accepted',
            component_required=True,
            phases=[
                tracker_pb2.Phase(name='Canary', rank=0, phase_id=0),
                tracker_pb2.Phase(name='Stable', rank=1, phase_id=1)
            ],
            approval_values=[
                tracker_pb2.ApprovalValue(approval_id=3, phase_id=0),
                tracker_pb2.ApprovalValue(approval_id=4, phase_id=1)
            ],
            name='TestTemplate',
            field_values=[
                tracker_pb2.FieldValue(field_id=1,
                                       str_value='NO',
                                       derived=False),
                tracker_pb2.FieldValue(field_id=2,
                                       str_value='MOOD',
                                       derived=False)
            ],
            labels=['label-One', 'label-Two'],
            owner_defaults_to_member=True,
            admin_ids=[],
            content='HEY WHY',
            component_ids=[1],
            summary_must_be_edited=False,
            summary='TLDR',
            members_only=True,
            owner_id=333)
 def testPrecomputeInfoForValueViews_SomeValues(self):
     """We can precompute info needed for an issue with fields and labels."""
     labels = [
         'Priority-Low', 'GoodFirstBug', 'Feature-UI', 'Feature-Installer',
         'Launch-Milestone-66'
     ]
     derived_labels = ['OS-Windows', 'OS-Linux']
     field_values = [
         tracker_bizobj.MakeFieldValue(1, 5, None, None, None, None, False),
     ]
     phase_1 = tracker_pb2.Phase(phase_id=1, name='Stable')
     phase_2 = tracker_pb2.Phase(phase_id=2, name='Beta')
     phase_3 = tracker_pb2.Phase(phase_id=3, name='stable')
     precomp_view_info = tracker_views._PrecomputeInfoForValueViews(
         labels,
         derived_labels,
         field_values,
         self.config,
         phases=[phase_1, phase_2, phase_3])
     (labels_by_prefix, der_labels_by_prefix, field_values_by_id,
      _label_docs, phases_by_name) = precomp_view_info
     self.assertEqual(
         {
             'priority': ['Low'],
             'feature': ['UI', 'Installer'],
             'launch-milestone': ['66']
         }, labels_by_prefix)
     self.assertEqual({'os': ['Windows', 'Linux']}, der_labels_by_prefix)
     self.assertEqual({1: field_values}, field_values_by_id)
     self.assertEqual({
         'stable': [phase_1, phase_3],
         'beta': [phase_2]
     }, phases_by_name)
  def testGatherPageData_Approvals(self):
    user = self.services.user.TestAddUser('user@invalid', 100)
    mr = testing_helpers.MakeMonorailRequest(
        path='/p/proj/issues/entry', services=self.services)
    mr.auth.user_view = framework_views.MakeUserView(
        'cnxn', self.services.user, 100)
    mr.template_name = 'rutabaga'

    self.mox.StubOutWithMock(self.services.user, 'GetUser')
    self.services.user.GetUser(
        mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(user)
    self.mox.ReplayAll()
    config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id)
    config.field_defs = [
    tracker_bizobj.MakeFieldDef(
        24, mr.project_id, 'UXReview',
        tracker_pb2.FieldTypes.APPROVAL_TYPE, None, '', False, False,
        False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)]
    self.services.config.StoreConfig(mr.cnxn, config)
    template = tracker_pb2.TemplateDef()
    template.phases = [tracker_pb2.Phase(
        phase_id=1, rank=4, name='Stable')]
    template.approval_values = [tracker_pb2.ApprovalValue(
        approval_id=24, phase_id=1,
        status=tracker_pb2.ApprovalStatus.NEEDS_REVIEW)]
    self.services.template.GetTemplateByName.return_value = template

    page_data = self.servlet.GatherPageData(mr)
    self.mox.VerifyAll()
    self.assertEqual(page_data['approvals'][0].field_name, 'UXReview')
    self.assertEqual(page_data['initial_phases'][0],
                          tracker_pb2.Phase(phase_id=1, name='Stable', rank=4))
    self.assertEqual(page_data['prechecked_approvals'], ['24_phase_0'])
    self.assertEqual(page_data['required_approval_ids'], [24])

    # phase fields row shown when config contains phase fields.
    config.field_defs.append(tracker_bizobj.MakeFieldDef(
        26, mr.project_id, 'GateTarget',
        tracker_pb2.FieldTypes.INT_TYPE, None, '', False, False, False,
        None, None, '', False, '', '', tracker_pb2.NotifyTriggers.NEVER,
        'no_action', 'doc', False, is_phase_field=True))
    self.services.config.StoreConfig(mr.cnxn, config)
    page_data = self.servlet.GatherPageData(mr)
    self.assertEqual(page_data['issue_phase_names'], ['stable'])

    # approval subfields in config hidden when chosen template does not contain
    # its parent approval
    template = tracker_pb2.TemplateDef()
    self.services.template.GetTemplateByName.return_value = template
    page_data = self.servlet.GatherPageData(mr)
    self.assertEqual(page_data['approvals'], [])
    # phase fields row hidden when template has no phases
    self.assertEqual(page_data['issue_phase_names'], [])
Exemple #4
0
    def testProcessFormData_AcceptPhases(self):
        self.services.template.GetTemplateByName = Mock(return_value=None)
        post_data = fake.PostData(name=['secondtemplate'],
                                  members_only=['on'],
                                  summary=['TLDR'],
                                  summary_must_be_edited=['on'],
                                  content=['HEY WHY'],
                                  status=['Accepted'],
                                  label=['label-One', 'label-Two'],
                                  custom_1=['NO'],
                                  component_required=['on'],
                                  owner_defaults_to_member=['no'],
                                  add_approvals=['on'],
                                  phase_0=['Canary'],
                                  phase_1=['Stable'],
                                  phase_2=[''],
                                  phase_3=[''],
                                  phase_4=[''],
                                  phase_5=[''],
                                  approval_2=['phase_0'],
                                  approval_3=['phase_1'],
                                  approval_3_required=['on'])

        url = self.servlet.ProcessFormData(self.mr, post_data)
        self.assertTrue('/adminTemplates?saved=1&ts' in url)

        fv = tracker_pb2.FieldValue(field_id=1, str_value='NO', derived=False)
        phases = [
            tracker_pb2.Phase(name='Canary', rank=0, phase_id=0),
            tracker_pb2.Phase(name='Stable', rank=1, phase_id=1)
        ]
        approval_values = [
            tracker_pb2.ApprovalValue(approval_id=2, phase_id=0),
            tracker_pb2.ApprovalValue(
                approval_id=3,
                status=tracker_pb2.ApprovalStatus(
                    tracker_pb2.ApprovalStatus.NEEDS_REVIEW),
                phase_id=1)
        ]
        self.services.template.CreateIssueTemplateDef.assert_called_once_with(
            self.mr.cnxn,
            47925,
            'secondtemplate',
            'HEY WHY',
            'TLDR',
            True,
            'Accepted',
            True,
            False,
            True,
            0, ['label-One', 'label-Two'], [], [], [fv],
            phases=phases,
            approval_values=approval_values)
  def testConvertApprovals(self):
    """Test we can convert ApprovalValues."""
    cnxn = None
    config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
    config.field_defs = [
      tracker_bizobj.MakeFieldDef(
            1, 789, 'DesignReview', tracker_pb2.FieldTypes.APPROVAL_TYPE, None,
            None, False, False, False, None, None, None, False, None, None,
            None, None, 'doc', False),
        tracker_bizobj.MakeFieldDef(
            2, 789, 'PrivacyReview', tracker_pb2.FieldTypes.APPROVAL_TYPE, None,
            None, False, False, False, 0, 99, None, False, None, None, None,
            None, 'doc', False),
        tracker_bizobj.MakeFieldDef(
            5, 789, 'UXReview', tracker_pb2.FieldTypes.APPROVAL_TYPE, None,
            None, False, False, False, None, None, None, False, None, None,
            None, None, 'doc', False),
        tracker_bizobj.MakeFieldDef(
            6, 789, 'Homepage', tracker_pb2.FieldTypes.URL_TYPE, None, None,
            False, False, False, None, None, None, False, None, None, None,
            None, 'doc', False),
        ]
    phases = [
        tracker_pb2.Phase(phase_id=1),
        tracker_pb2.Phase(phase_id=2, name="JustAPhase", rank=3),
    ]
    ts = 1536260059
    expected = [
        api_pb2_v1.Approval(
            approvalName="DesignReview",
            approvers=[self.person_1],
            setter=self.person_1,
            status=api_pb2_v1.ApprovalStatus.needsReview,
            setOn=datetime.datetime.fromtimestamp(ts),
        ),
        api_pb2_v1.Approval(
            approvalName="UXReview",
            approvers=[self.person_1],
            status=api_pb2_v1.ApprovalStatus.notSet,
            phaseName="JustAPhase",
        ),
    ]
    avs = [
        tracker_pb2.ApprovalValue(
            approval_id=1, approver_ids=[111], setter_id=111,
            status=tracker_pb2.ApprovalStatus.NEEDS_REVIEW, set_on=ts),
        tracker_pb2.ApprovalValue(
            approval_id=5, approver_ids=[111], phase_id=2)
    ]
    actual = api_pb2_v1_helpers.convert_approvals(
        cnxn, avs, self.services, config, phases)

    self.assertEqual(actual, expected)
Exemple #6
0
def GatherApprovalsPageData(approval_values, tmpl_phases, config):
    """Create the page data necessary for filling in the launch-gates-table."""
    filtered_avs, filtered_phases = FilterApprovalsAndPhases(
        approval_values, tmpl_phases, config)
    filtered_phases.sort(key=lambda phase: phase.rank)

    required_approval_ids = []
    prechecked_approvals = []

    phase_idx_by_id = {
        phase.phase_id: idx
        for idx, phase in enumerate(filtered_phases)
    }
    for av in filtered_avs:
        # approval is part of a phase and that phase can be found.
        if phase_idx_by_id.get(av.phase_id) is not None:
            idx = phase_idx_by_id.get(av.phase_id)
            prechecked_approvals.append('%d_phase_%d' % (av.approval_id, idx))
        else:
            prechecked_approvals.append('%d' % av.approval_id)
        if av.status is tracker_pb2.ApprovalStatus.NEEDS_REVIEW:
            required_approval_ids.append(av.approval_id)

    num_phases = len(filtered_phases)
    filtered_phases.extend([tracker_pb2.Phase()] *
                           (MAX_NUM_PHASES - num_phases))
    return prechecked_approvals, required_approval_ids, filtered_phases
 def testConvertPhases(self):
   """We can convert Phases."""
   phases = [
       tracker_pb2.Phase(name="JustAPhase", rank=1),
       tracker_pb2.Phase(name="Can'tPhaseMe", rank=4),
       tracker_pb2.Phase(phase_id=11, rank=5),
       tracker_pb2.Phase(rank=3),
       tracker_pb2.Phase(name="Phase"),
   ]
   expected = [
       api_pb2_v1.Phase(phaseName="JustAPhase", rank=1),
       api_pb2_v1.Phase(phaseName="Can'tPhaseMe", rank=4),
       api_pb2_v1.Phase(phaseName="Phase"),
   ]
   actual = api_pb2_v1_helpers.convert_phases(phases)
   self.assertEqual(actual, expected)
  def setUp(self):
    self.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
    self.config.field_defs = [
        tracker_bizobj.MakeFieldDef(
            1, 789, 'Goats', tracker_pb2.FieldTypes.INT_TYPE, None, None,
            False, False, False, None, None, None, False, None, None, None,
            None, 'Num of Goats in the season', False, is_phase_field=True),
        tracker_bizobj.MakeFieldDef(
            2, 789, 'DogNames', tracker_pb2.FieldTypes.STR_TYPE, None, None,
            False, False, False, None, None, None, False, None, None, None,
            None, 'good dog names', False),
        tracker_bizobj.MakeFieldDef(
            3, 789, 'Approval', tracker_pb2.FieldTypes.APPROVAL_TYPE,
            None, None, False, False, False, None, None, None, False, None,
            None, None, None, 'Tracks review from cows', False)
    ]
    self.config.approval_defs = [tracker_pb2.ApprovalDef(approval_id=3)]
    self.issue = MakeTestIssue(
        local_id=1, issue_id=100001, summary='One')
    self.issue.field_values = [
        tracker_bizobj.MakeFieldValue(
            1, 34, None, None, None, None, False, phase_id=23),
        tracker_bizobj.MakeFieldValue(
            1, 35, None, None, None, None, False, phase_id=24),
        tracker_bizobj.MakeFieldValue(
            2, None, 'Waffles', None, None, None, False),
    ]
    self.issue.phases = [
        tracker_pb2.Phase(phase_id=23, name='winter'),
        tracker_pb2.Phase(phase_id=24, name='summer')]
    self.issue.approval_values = [
        tracker_pb2.ApprovalValue(
            approval_id=3, approver_ids=[111, 222, 333])]
    self.users_by_id = {
        111: framework_views.StuffUserView(111, '*****@*****.**', False),
        222: framework_views.StuffUserView(222, '*****@*****.**', True),
    }

    self.summary_table_cell_kws = {
        'col': None,
        'users_by_id': {},
        'non_col_labels': [('lab', False)],
        'label_values': {},
        'related_issues': {},
        'config': 'fake_config',
        }
Exemple #9
0
    def testProcessFormData_Reject(self):
        post_data = fake.PostData(name=['sometemplate'],
                                  members_only=['on'],
                                  summary=['TLDR'],
                                  summary_must_be_edited=['on'],
                                  content=['HEY WHY'],
                                  status=['Accepted'],
                                  owner=['*****@*****.**'],
                                  label=['label-One', 'label-Two'],
                                  custom_1=['NO'],
                                  custom_2=['MOOD'],
                                  components=['hey, hey2,he3'],
                                  component_required=['on'],
                                  owner_defaults_to_member=['no'],
                                  add_approvals=['on'],
                                  phase_0=['Canary'],
                                  phase_1=['Stable-Exp'],
                                  phase_2=['Stable'],
                                  phase_3=[''],
                                  phase_4=[''],
                                  phase_5=[''],
                                  approval_2=['phase_1'],
                                  approval_3=['phase_2'])

        self.mox.StubOutWithMock(self.servlet, 'PleaseCorrect')
        self.servlet.PleaseCorrect(
            self.mr,
            initial_members_only=ezt.boolean(True),
            template_name='sometemplate',
            initial_content='TLDR',
            initial_must_edit_summary=ezt.boolean(True),
            initial_description='HEY WHY',
            initial_status='Accepted',
            initial_owner='*****@*****.**',
            initial_owner_defaults_to_member=ezt.boolean(False),
            initial_components='hey, hey2, he3',
            initial_component_required=ezt.boolean(True),
            initial_admins='',
            labels=['label-One', 'label-Two'],
            fields=mox.IgnoreArg(),
            initial_add_approvals=ezt.boolean(True),
            initial_phases=[
                tracker_pb2.Phase(name=name)
                for name in ['Canary', 'Stable-Exp', 'Stable', '', '', '']
            ],
            approvals=mox.IgnoreArg(),
            prechecked_approvals=['2_phase_1', '3_phase_2'],
            required_approval_ids=[])
        self.mox.ReplayAll()
        url = self.servlet.ProcessFormData(self.mr, post_data)
        self.mox.VerifyAll()
        self.assertEqual('Owner not found.', self.mr.errors.owner)
        self.assertEqual('Unknown component he3', self.mr.errors.components)
        self.assertEqual('Template with name sometemplate already exists',
                         self.mr.errors.name)
        self.assertEqual('Defined gates must have assigned approvals.',
                         self.mr.errors.phase_approvals)
        self.assertIsNone(url)
Exemple #10
0
  def testGatherApprovalsPageData(self):
    self.fd_3.is_deleted = True
    self.config.field_defs = [self.fd_3, self.fd_4, self.fd_5]
    approval_values = [
        tracker_pb2.ApprovalValue(approval_id=3, phase_id=8),
        tracker_pb2.ApprovalValue(
            approval_id=4, phase_id=9,
            status=tracker_pb2.ApprovalStatus.NEEDS_REVIEW),
        tracker_pb2.ApprovalValue(approval_id=5)
    ]
    tmpl_phases = [
        tracker_pb2.Phase(phase_id=8, rank=1, name='deletednoshow'),
        tracker_pb2.Phase(phase_id=9, rank=2, name='notdeleted')
    ]

    (prechecked_approvals, required_approval_ids,
     phases) = template_helpers.GatherApprovalsPageData(
         approval_values, tmpl_phases, self.config)
    self.assertItemsEqual(prechecked_approvals,
                          ['4_phase_0', '5'])
    self.assertEqual(required_approval_ids, [4])
    self.assertEqual(phases[0], tmpl_phases[1])
    self.assertIsNone(phases[1].name)
    self.assertEqual(len(phases), 6)
Exemple #11
0
    def testUpdateIssueTemplateDef(self):
        av_20 = tracker_pb2.ApprovalValue(approval_id=20, phase_id=11)
        av_21 = tracker_pb2.ApprovalValue(approval_id=21, phase_id=11)
        approval_values = [av_20, av_21]
        phases = [tracker_pb2.Phase(name='Canary', phase_id=11, rank=11)]
        self.template_service.UpdateIssueTemplateDef(
            self.cnxn,
            789,
            1,
            content='content',
            summary='summary',
            component_required=True,
            labels=[],
            admin_ids=[111],
            phases=phases,
            approval_values=approval_values)

        new_values = dict(content='content',
                          summary='summary',
                          component_required=True)
        self.template_service.template_tbl.Update\
            .assert_called_once_with(self.cnxn, new_values, id=1, commit=False)
        self.template_service.template2label_tbl.Delete\
            .assert_called_once_with(self.cnxn, template_id=1, commit=False)
        self.template_service.template2label_tbl.InsertRows\
            .assert_called_once_with(self.cnxn, template_svc.TEMPLATE2LABEL_COLS,
                [], commit=False)
        self.template_service.template2admin_tbl.Delete\
            .assert_called_once_with(self.cnxn, template_id=1, commit=False)
        self.template_service.template2admin_tbl.InsertRows\
            .assert_called_once_with(self.cnxn, template_svc.TEMPLATE2ADMIN_COLS,
                [(1, 111)], commit=False)
        self.template_service.template2approvalvalue_tbl.Delete\
            .assert_called_once_with(self.cnxn, template_id=1, commit=False)
        self.template_service.issuephasedef_tbl.InsertRow\
            .assert_called_once_with(self.cnxn, name='Canary',
                rank=11, commit=False)
        self.template_service.template2approvalvalue_tbl.InsertRows\
            .assert_called_once_with(self.cnxn,
                template_svc.TEMPLATE2APPROVALVALUE_COLS,
                [(20, 1, 1, 'not_set'), (21, 1, 1, 'not_set')], commit=False)
        self.cnxn.Commit.assert_called_once_with()
        self.template_service.template_set_2lc.InvalidateKeys\
            .assert_called_once_with(self.cnxn, [789])
        self.template_service.template_def_2lc.InvalidateKeys\
            .assert_called_once_with(self.cnxn, [1])
Exemple #12
0
def _GetPhasesAndApprovalsFromParsed(mr, phase_names, approvals_to_phase_idx,
                                     required_approval_ids):
    """Get Phase PBs from a parsed phase_names and approvals_by_phase_idx."""

    phases = []
    approvals = []
    valid_phase_names = []

    for name in phase_names:
        if name:
            if not tracker_constants.PHASE_NAME_RE.match(name):
                mr.errors.phase_approvals = 'Invalid gate name(s).'
                return phases, approvals
            valid_phase_names.append(name)
    if len(valid_phase_names) != len(
            set(name.lower() for name in valid_phase_names)):
        mr.errors.phase_approvals = 'Duplicate gate names.'
        return phases, approvals
    valid_phase_idxs = [idx for idx, name in enumerate(phase_names) if name]
    if set(valid_phase_idxs) != set(
        [idx for idx in approvals_to_phase_idx.values() if idx is not None]):
        mr.errors.phase_approvals = 'Defined gates must have assigned approvals.'
        return phases, approvals

    # Distributing the ranks over a wider range is not necessary since
    # any edits to template phases will cause a complete rewrite.
    # phase_id is temporarily the idx for keeping track of which approvals
    # belong to which phases.
    for idx, phase_name in enumerate(phase_names):
        if phase_name:
            phase = tracker_pb2.Phase(name=phase_name, rank=idx, phase_id=idx)
            phases.append(phase)

    for approval_id, phase_idx in approvals_to_phase_idx.items():
        av = tracker_pb2.ApprovalValue(approval_id=approval_id,
                                       phase_id=phase_idx)
        if approval_id in required_approval_ids:
            av.status = tracker_pb2.ApprovalStatus.NEEDS_REVIEW
        approvals.append(av)

    return phases, approvals
Exemple #13
0
 def testGetAllPhaseNames(self):
   issues = [
       fake.MakeTestIssue(789, 1, 'summary', 'New', 0,
                          phases=[
                              tracker_pb2.Phase(name='chicken'),
                              tracker_pb2.Phase(name='cow'),
                              tracker_pb2.Phase(name='dog'),
                              tracker_pb2.Phase(name='goat')]),
       fake.MakeTestIssue(789, 2, 'summary', 'New', 0,
                          phases=[
                              tracker_pb2.Phase(name='CHICKEN'),
                              tracker_pb2.Phase(name='hippo')]),
       fake.MakeTestIssue(789, 2, 'summary', 'New', 0),
       ]
   self.assertItemsEqual(
       issuelist._GetAllPhaseNames(issues),
       ['chicken', 'cow', 'dog', 'goat', 'hippo'])
 def testMakeAllFieldValueViews(self):
     labels = [
         'Priority-Low', 'GoodFirstBug', 'Feature-UI', 'Feature-Installer',
         'Launch-Milestone-66'
     ]
     derived_labels = ['OS-Windows', 'OS-Linux']
     self.config.field_defs.append(
         tracker_bizobj.MakeFieldDef(4,
                                     789,
                                     'UIMocks',
                                     tracker_pb2.FieldTypes.URL_TYPE,
                                     'Enhancement',
                                     None,
                                     False,
                                     False,
                                     False,
                                     None,
                                     None,
                                     None,
                                     False,
                                     None,
                                     None,
                                     None,
                                     'no_action',
                                     'descriptive docstring',
                                     False,
                                     approval_id=23,
                                     is_phase_field=False))
     self.config.field_defs.append(
         tracker_bizobj.MakeFieldDef(5,
                                     789,
                                     'LegalFAQs',
                                     tracker_pb2.FieldTypes.URL_TYPE,
                                     'Enhancement',
                                     None,
                                     False,
                                     False,
                                     False,
                                     None,
                                     None,
                                     None,
                                     False,
                                     None,
                                     None,
                                     None,
                                     'no_action',
                                     'descriptive docstring',
                                     False,
                                     approval_id=26,
                                     is_phase_field=False))
     self.config.field_defs.append(
         tracker_bizobj.MakeFieldDef(23,
                                     789,
                                     'Legal',
                                     tracker_pb2.FieldTypes.APPROVAL_TYPE,
                                     'Enhancement',
                                     None,
                                     False,
                                     False,
                                     False,
                                     None,
                                     None,
                                     None,
                                     False,
                                     None,
                                     None,
                                     None,
                                     'no_action',
                                     'descriptive docstring',
                                     False,
                                     approval_id=None,
                                     is_phase_field=False))
     self.config.field_defs.append(
         tracker_bizobj.MakeFieldDef(26,
                                     789,
                                     'UI',
                                     tracker_pb2.FieldTypes.APPROVAL_TYPE,
                                     'Enhancement',
                                     None,
                                     False,
                                     False,
                                     False,
                                     None,
                                     None,
                                     None,
                                     False,
                                     None,
                                     None,
                                     None,
                                     'no_action',
                                     'descriptive docstring',
                                     False,
                                     approval_id=None,
                                     is_phase_field=False))
     self.config.field_defs.append(
         tracker_bizobj.MakeFieldDef(27,
                                     789,
                                     'M-Target',
                                     tracker_pb2.FieldTypes.INT_TYPE,
                                     'Enhancement',
                                     None,
                                     False,
                                     False,
                                     False,
                                     None,
                                     None,
                                     None,
                                     False,
                                     None,
                                     None,
                                     None,
                                     'no_action',
                                     'descriptive docstring',
                                     False,
                                     approval_id=None,
                                     is_phase_field=True))
     field_values = [
         tracker_bizobj.MakeFieldValue(1, 5, None, None, None, None, False),
         tracker_bizobj.MakeFieldValue(27,
                                       74,
                                       None,
                                       None,
                                       None,
                                       None,
                                       False,
                                       phase_id=3),
         # phase_id=4 does not belong to any of the phases given below.
         # this field value should not show up in the views.
         tracker_bizobj.MakeFieldValue(27,
                                       79,
                                       None,
                                       None,
                                       None,
                                       None,
                                       False,
                                       phase_id=4),
     ]
     users_by_id = {}
     phase_1 = tracker_pb2.Phase(phase_id=1, name='Stable')
     phase_2 = tracker_pb2.Phase(phase_id=2, name='Beta')
     phase_3 = tracker_pb2.Phase(phase_id=3, name='stable')
     fvvs = tracker_views.MakeAllFieldValueViews(
         self.config,
         labels,
         derived_labels,
         field_values,
         users_by_id,
         parent_approval_ids=[23],
         phases=[phase_1, phase_2, phase_3])
     self.assertEqual(9, len(fvvs))
     # Values are sorted by (applicable_type, field_name).
     logging.info([fv.field_name for fv in fvvs])
     (estdays_fvv, launch_milestone_fvv, legal_fvv, legal_faq_fvv,
      beta_mtarget_fvv, stable_mtarget_fvv, os_fvv, ui_fvv,
      ui_mocks_fvv) = fvvs
     self.assertEqual('EstDays', estdays_fvv.field_name)
     self.assertEqual(1, len(estdays_fvv.values))
     self.assertEqual(0, len(estdays_fvv.derived_values))
     self.assertEqual('Launch-Milestone', launch_milestone_fvv.field_name)
     self.assertEqual(1, len(launch_milestone_fvv.values))
     self.assertEqual(0, len(launch_milestone_fvv.derived_values))
     self.assertEqual('OS', os_fvv.field_name)
     self.assertEqual(0, len(os_fvv.values))
     self.assertEqual(2, len(os_fvv.derived_values))
     self.assertEqual(ui_mocks_fvv.field_name, 'UIMocks')
     self.assertEqual(ui_mocks_fvv.phase_name, '')
     self.assertTrue(ui_mocks_fvv.applicable)
     self.assertEqual(legal_faq_fvv.field_name, 'LegalFAQs')
     self.assertFalse(legal_faq_fvv.applicable)
     self.assertFalse(legal_fvv.applicable)
     self.assertFalse(ui_fvv.applicable)
     self.assertEqual('M-Target', stable_mtarget_fvv.field_name)
     self.assertEqual('stable', stable_mtarget_fvv.phase_name)
     self.assertEqual(1, len(stable_mtarget_fvv.values))
     self.assertEqual(74, stable_mtarget_fvv.values[0].val)
     self.assertEqual(0, len(stable_mtarget_fvv.derived_values))
     self.assertEqual('M-Target', beta_mtarget_fvv.field_name)
     self.assertEqual('beta', beta_mtarget_fvv.phase_name)
     self.assertEqual(0, len(beta_mtarget_fvv.values))
     self.assertEqual(0, len(beta_mtarget_fvv.values))
Exemple #15
0
    def testIndexOrLexicalList_PhaseCustomFields(self):
        art = fake.MakeTestIssue(789, 1, 'sum 2', 'New', 111)
        art.labels = ['summer.goats-value1']
        art.field_values = [
            tracker_bizobj.MakeFieldValue(3,
                                          33,
                                          None,
                                          None,
                                          None,
                                          None,
                                          False,
                                          phase_id=77),
            tracker_bizobj.MakeFieldValue(3,
                                          34,
                                          None,
                                          None,
                                          None,
                                          None,
                                          False,
                                          phase_id=77),
            tracker_bizobj.MakeFieldValue(3,
                                          1000,
                                          None,
                                          None,
                                          None,
                                          None,
                                          False,
                                          phase_id=78)
        ]
        art.phases = [
            tracker_pb2.Phase(phase_id=77, name='summer'),
            tracker_pb2.Phase(phase_id=78, name='winter')
        ]

        all_field_defs = [
            tracker_bizobj.MakeFieldDef(3,
                                        789,
                                        'goats',
                                        tracker_pb2.FieldTypes.INT_TYPE,
                                        None,
                                        None,
                                        False,
                                        False,
                                        True,
                                        None,
                                        None,
                                        None,
                                        False,
                                        None,
                                        None,
                                        None,
                                        None,
                                        'goats love mineral',
                                        False,
                                        is_phase_field=True),
            tracker_bizobj.MakeFieldDef(4, 788, 'boo',
                                        tracker_pb2.FieldTypes.APPROVAL_TYPE,
                                        None, None, False, False, False, None,
                                        None, None, False, None, None, None,
                                        None, 'ahh', False),
        ]

        accessor = sorting._IndexOrLexicalList([], all_field_defs,
                                               'summer.goats', {})
        self.assertEqual([33, 34, 'value1'], accessor(art))
        neg_accessor = MakeDescending(accessor)
        self.assertEqual([sorting.DescendingValue('value1'), -34, -33],
                         neg_accessor(art))
  def testConvertIssue(self):
    """Convert an internal Issue PB to an IssueWrapper API PB."""
    self.services.project.TestAddProject(
        'test-project', owner_ids=[2], project_id=12345)
    self.services.user.TestAddUser('*****@*****.**', 111)

    mar = mock.Mock()
    mar.cnxn = None
    mar.project_name = 'test-project'
    mar.project_id = 12345
    mar.auth.effective_ids = {111}
    mar.perms = permissions.READ_ONLY_PERMISSIONSET
    mar.profiler = profiler.Profiler()
    mar.config = tracker_bizobj.MakeDefaultProjectIssueConfig(12345)
    mar.config.field_defs = [
        tracker_bizobj.MakeFieldDef(
            1, 12345, 'EstDays', tracker_pb2.FieldTypes.INT_TYPE, None, None,
            False, False, False, None, None, None, False, None, None, None,
            None, 'doc', False, approval_id=2),
        tracker_bizobj.MakeFieldDef(
            2, 12345, 'DesignReview', tracker_pb2.FieldTypes.APPROVAL_TYPE,
            None, None, False, False, False, None, None, None, False, None,
            None, None, None, 'doc', False),
        tracker_bizobj.MakeFieldDef(
            3, 12345, 'StringField', tracker_pb2.FieldTypes.STR_TYPE, None,
            None, False, False, False, None, None, None, False, None, None,
            None, None, 'doc', False),
        tracker_bizobj.MakeFieldDef(
            4, 12345, 'DressReview', tracker_pb2.FieldTypes.APPROVAL_TYPE,
            None, None, False, False, False, None, None, None, False, None,
            None, None, None, 'doc', False),
        ]
    self.services.config.StoreConfig(mar.cnxn, mar.config)

    now = 1472067725
    now_dt = datetime.datetime.fromtimestamp(now)

    fvs = [
      tracker_bizobj.MakeFieldValue(
          1, 4, None, None, None, None, False, phase_id=4),
      tracker_bizobj.MakeFieldValue(
          3, None, 'string', None, None, None, False, phase_id=4),
      # missing phase
      tracker_bizobj.MakeFieldValue(
          3, None, u'\xe2\x9d\xa4\xef\xb8\x8f', None, None, None, False,
          phase_id=2),
    ]
    phases = [
        tracker_pb2.Phase(phase_id=3, name="JustAPhase", rank=4),
        tracker_pb2.Phase(phase_id=4, name="NotAPhase", rank=9)
        ]
    approval_values = [
        tracker_pb2.ApprovalValue(
            approval_id=2, phase_id=3, approver_ids=[111]),
        tracker_pb2.ApprovalValue(approval_id=4, approver_ids=[111])
    ]
    issue = fake.MakeTestIssue(
        12345, 1, 'one', 'New', 111, field_values=fvs,
        approval_values=approval_values, phases=phases)
    issue.opened_timestamp = now
    issue.owner_modified_timestamp = now
    issue.status_modified_timestamp = now
    issue.component_modified_timestamp = now
    # TODO(jrobbins): set up a lot more fields.

    for cls in [api_pb2_v1.IssueWrapper, api_pb2_v1.IssuesGetInsertResponse]:
      result = api_pb2_v1_helpers.convert_issue(cls, issue, mar, self.services)
      self.assertEquals(1, result.id)
      self.assertEquals('one', result.title)
      self.assertEquals('one', result.summary)
      self.assertEquals(now_dt, result.published)
      self.assertEquals(now_dt, result.owner_modified)
      self.assertEquals(now_dt, result.status_modified)
      self.assertEquals(now_dt, result.component_modified)
      self.assertEquals(
          result.fieldValues,
          [api_pb2_v1.FieldValue(
              fieldName='EstDays', fieldValue='4', approvalName='DesignReview',
              derived=False),
           api_pb2_v1.FieldValue(fieldName='StringField', fieldValue='string',
                                 phaseName="NotAPhase", derived=False),
           api_pb2_v1.FieldValue(fieldName='StringField',
                                 fieldValue=u'\xe2\x9d\xa4\xef\xb8\x8f',
                                 derived=False),
          ]
      )
      self.assertEqual(
          result.approvalValues,
          [api_pb2_v1.Approval(
            approvalName="DesignReview",
            approvers=[self.person_1],
            status=api_pb2_v1.ApprovalStatus.notSet,
            phaseName="JustAPhase",
          ),
           api_pb2_v1.Approval(
               approvalName="DressReview",
               approvers=[self.person_1],
               status=api_pb2_v1.ApprovalStatus.notSet,
           )]
      )
      self.assertEqual(
          result.phases,
          [api_pb2_v1.Phase(phaseName="JustAPhase", rank=4),
           api_pb2_v1.Phase(phaseName="NotAPhase", rank=9)
          ])
Exemple #17
0
    def testMakeIssueJSON(self):
        config = self.services.config.GetProjectConfig(self.cnxn, 789)
        config.field_defs.extend([
            tracker_pb2.FieldDef(
                field_id=1,
                field_name='UXReview',
                field_type=tracker_pb2.FieldTypes.APPROVAL_TYPE),
            tracker_pb2.FieldDef(field_id=2,
                                 field_name='approvalsubfield',
                                 field_type=tracker_pb2.FieldTypes.STR_TYPE,
                                 approval_id=1),
            tracker_pb2.FieldDef(field_id=3,
                                 field_name='phasefield',
                                 field_type=tracker_pb2.FieldTypes.INT_TYPE,
                                 is_phase_field=True),
            tracker_pb2.FieldDef(field_id=4,
                                 field_name='normalfield',
                                 field_type=tracker_pb2.FieldTypes.STR_TYPE)
        ])
        self.services.config.StoreConfig(self.cnxn, config)

        phases = [
            tracker_pb2.Phase(phase_id=1, name='Phase1', rank=1),
            tracker_pb2.Phase(phase_id=2, name='Phase2', rank=2)
        ]
        avs = [
            tracker_pb2.ApprovalValue(
                approval_id=1,
                status=tracker_pb2.ApprovalStatus.APPROVED,
                setter_id=111,
                set_on=7,
                approver_ids=[333, 444],
                phase_id=1)
        ]
        fvs = [
            tracker_pb2.FieldValue(field_id=2, str_value='two'),
            tracker_pb2.FieldValue(field_id=3, int_value=3, phase_id=2),
            tracker_pb2.FieldValue(field_id=4, str_value='four')
        ]
        labels = ['test', 'Type-FLT-Launch']

        issue = fake.MakeTestIssue(self.project.project_id,
                                   1,
                                   'summary',
                                   'Open',
                                   111,
                                   labels=labels,
                                   issue_id=78901,
                                   reporter_id=222,
                                   opened_timestamp=1,
                                   closed_timestamp=2,
                                   modified_timestamp=3,
                                   project_name='project',
                                   field_values=fvs,
                                   phases=phases,
                                   approval_values=avs)

        email_dict = {
            111: '*****@*****.**',
            222: '*****@*****.**',
            333: '*****@*****.**',
            444: '*****@*****.**'
        }
        comment_list = [
            tracker_pb2.IssueComment(content='simple'),
            tracker_pb2.IssueComment(content='issue desc', is_description=True)
        ]
        starrer_id_list = [222, 333]

        issue_JSON = self.jsonfeed._MakeIssueJSON(self.mr, issue, email_dict,
                                                  comment_list,
                                                  starrer_id_list)
        expected_JSON = {
            'local_id':
            1,
            'reporter':
            '*****@*****.**',
            'summary':
            'summary',
            'owner':
            '*****@*****.**',
            'status':
            'Open',
            'cc': [],
            'labels':
            labels,
            'phases': [{
                'id': 1,
                'name': 'Phase1',
                'rank': 1
            }, {
                'id': 2,
                'name': 'Phase2',
                'rank': 2
            }],
            'fields': [{
                'field': 'approvalsubfield',
                'phase': None,
                'approval': 'UXReview',
                'str_value': 'two'
            }, {
                'field': 'phasefield',
                'phase': 'Phase2',
                'int_value': 3
            }, {
                'field': 'normalfield',
                'phase': None,
                'str_value': 'four'
            }],
            'approvals': [{
                'approval': 'UXReview',
                'status': 'APPROVED',
                'setter': '*****@*****.**',
                'set_on': 7,
                'approvers': ['*****@*****.**', '*****@*****.**'],
                'phase': 'Phase1'
            }],
            'starrers': ['*****@*****.**', '*****@*****.**'],
            'comments': [
                {
                    'content': 'simple',
                    'timestamp': None,
                    'amendments': [],
                    'commenter': None,
                    'attachments': [],
                    'description_num': None
                },
                {
                    'content': 'issue desc',
                    'timestamp': None,
                    'amendments': [],
                    'commenter': None,
                    'attachments': [],
                    'description_num': '1'
                },
            ],
            'opened':
            1,
            'modified':
            3,
            'closed':
            2,
        }

        self.assertEqual(expected_JSON, issue_JSON)
Exemple #18
0
  def FetchItems(self, cnxn, keys):
    """On RAM and memcache miss, hit the database.

    Args:
      cnxn: A MonorailConnection.
      keys: A list of template IDs (ints).

    Returns:
      A dict of {template_id: TemplateDef}.
    """
    template_dict = {}

    # Fetch template rows and relations.
    template_rows = self.template_service.template_tbl.Select(
        cnxn, cols=TEMPLATE_COLS, id=keys,
        order_by=[('name', [])])

    template2label_rows = self.template_service.\
        template2label_tbl.Select(
            cnxn, cols=TEMPLATE2LABEL_COLS, template_id=keys)
    template2component_rows = self.template_service.\
        template2component_tbl.Select(
            cnxn, cols=TEMPLATE2COMPONENT_COLS, template_id=keys)
    template2admin_rows = self.template_service.template2admin_tbl.Select(
        cnxn, cols=TEMPLATE2ADMIN_COLS, template_id=keys)
    template2fieldvalue_rows = self.template_service.\
        template2fieldvalue_tbl.Select(
            cnxn, cols=TEMPLATE2FIELDVALUE_COLS, template_id=keys)
    template2approvalvalue_rows = self.template_service.\
        template2approvalvalue_tbl.Select(
            cnxn, cols=TEMPLATE2APPROVALVALUE_COLS, template_id=keys)
    phase_ids = [av_row[2] for av_row in template2approvalvalue_rows]
    phase_rows = self.template_service.issuephasedef_tbl.Select(
        cnxn, cols=ISSUEPHASEDEF_COLS, id=list(set(phase_ids)))

    # Build TemplateDef with all related data.
    for template_row in template_rows:
      template = UnpackTemplate(template_row)
      template_dict[template.template_id] = template

    for template2label_row in template2label_rows:
      template_id, label = template2label_row
      template = template_dict.get(template_id)
      if template:
        template.labels.append(label)

    for template2component_row in template2component_rows:
      template_id, component_id = template2component_row
      template = template_dict.get(template_id)
      if template:
        template.component_ids.append(component_id)

    for template2admin_row in template2admin_rows:
      template_id, admin_id = template2admin_row
      template = template_dict.get(template_id)
      if template:
        template.admin_ids.append(admin_id)

    for fv_row in template2fieldvalue_rows:
      (template_id, field_id, int_value, str_value, user_id,
       date_value, url_value) = fv_row
      fv = tracker_bizobj.MakeFieldValue(
          field_id, int_value, str_value, user_id, date_value, url_value,
          False)
      template = template_dict.get(template_id)
      if template:
        template.field_values.append(fv)

    phases_by_id = {}
    for phase_row in phase_rows:
      (phase_id, name, rank) = phase_row
      phase = tracker_pb2.Phase(
          phase_id=phase_id, name=name, rank=rank)
      phases_by_id[phase_id] = phase

    # Note: there is no templateapproval2approver_tbl.
    for av_row in template2approvalvalue_rows:
      (approval_id, template_id, phase_id, status) = av_row
      approval_value = tracker_pb2.ApprovalValue(
          approval_id=approval_id, phase_id=phase_id,
          status=tracker_pb2.ApprovalStatus(status.upper()))
      template = template_dict.get(template_id)
      if template:
        template.approval_values.append(approval_value)
        phase = phases_by_id.get(phase_id)
        if phase and phase not in template.phases:
          template_dict.get(template_id).phases.append(phase)

    return template_dict
Exemple #19
0
    def testNotifyApprovalChangeTask_Normal(self):
        config = self.services.config.GetProjectConfig('cnxn', 12345)
        config.field_defs = [
            # issue's User field with any_comment is notified.
            tracker_bizobj.MakeFieldDef(
                121, 12345, 'TL', tracker_pb2.FieldTypes.USER_TYPE, '', '',
                False, False, False, None, None, None, False, '', None,
                tracker_pb2.NotifyTriggers.ANY_COMMENT, 'no_action',
                'TL, notified on everything', False),
            # issue's User field with never is not notified.
            tracker_bizobj.MakeFieldDef(
                122, 12345, 'silentTL', tracker_pb2.FieldTypes.USER_TYPE, '',
                '', False, False, False, None, None, None, False, '', None,
                tracker_pb2.NotifyTriggers.NEVER, 'no_action',
                'TL, notified on nothing', False),
            # approval's User field with any_comment is notified.
            tracker_bizobj.MakeFieldDef(123,
                                        12345,
                                        'otherapprovalTL',
                                        tracker_pb2.FieldTypes.USER_TYPE,
                                        '',
                                        '',
                                        False,
                                        False,
                                        False,
                                        None,
                                        None,
                                        None,
                                        False,
                                        '',
                                        None,
                                        tracker_pb2.NotifyTriggers.ANY_COMMENT,
                                        'no_action',
                                        'TL on the approvers team',
                                        False,
                                        approval_id=3),
            # another approval's User field with any_comment is not notified.
            tracker_bizobj.MakeFieldDef(124,
                                        12345,
                                        'otherapprovalTL',
                                        tracker_pb2.FieldTypes.USER_TYPE,
                                        '',
                                        '',
                                        False,
                                        False,
                                        False,
                                        None,
                                        None,
                                        None,
                                        False,
                                        '',
                                        None,
                                        tracker_pb2.NotifyTriggers.ANY_COMMENT,
                                        'no_action',
                                        'TL on another approvers team',
                                        False,
                                        approval_id=4),
            tracker_bizobj.MakeFieldDef(3, 12345, 'Goat-Approval',
                                        tracker_pb2.FieldTypes.APPROVAL_TYPE,
                                        '', '', False, False, False, None,
                                        None, None, False, '', None,
                                        tracker_pb2.NotifyTriggers.NEVER,
                                        'no_action', 'Get Approval from Goats',
                                        False)
        ]
        self.services.config.StoreConfig('cnxn', config)

        # Custom user_type field TLs
        self.services.user.TestAddUser('*****@*****.**', 111)
        self.services.user.TestAddUser('*****@*****.**', 222)
        self.services.user.TestAddUser('*****@*****.**', 333)
        self.services.user.TestAddUser('*****@*****.**', 444)

        # Approvers
        self.services.user.TestAddUser('*****@*****.**', 777)
        self.services.user.TestAddUser('*****@*****.**', 888)
        self.services.user.TestAddUser('*****@*****.**', 999)
        self.services.user.TestAddUser('*****@*****.**', 666)
        self.services.user.TestAddUser('*****@*****.**', 661)
        self.services.user.TestAddUser('*****@*****.**', 662)
        self.services.user.TestAddUser('*****@*****.**', 663)
        self.services.usergroup.TestAddGroupSettings(
            666, '*****@*****.**')
        self.services.usergroup.TestAddMembers(666, [661, 662, 663])
        canary_phase = tracker_pb2.Phase(name='Canary', phase_id=1, rank=1)
        approval_values = [
            tracker_pb2.ApprovalValue(approval_id=3,
                                      approver_ids=[888, 999, 666, 661])
        ]
        approval_issue = MakeTestIssue(project_id=12345,
                                       local_id=2,
                                       owner_id=2,
                                       reporter_id=1,
                                       is_spam=True)
        approval_issue.phases = [canary_phase]
        approval_issue.approval_values = approval_values
        approval_issue.field_values = [
            tracker_bizobj.MakeFieldValue(121, None, None, 111, None, None,
                                          False),
            tracker_bizobj.MakeFieldValue(122, None, None, 222, None, None,
                                          False),
            tracker_bizobj.MakeFieldValue(123, None, None, 333, None, None,
                                          False),
            tracker_bizobj.MakeFieldValue(124, None, None, 444, None, None,
                                          False),
        ]
        self.services.issue.TestAddIssue(approval_issue)

        amend = tracker_bizobj.MakeApprovalApproversAmendment([888], [777])

        comment = tracker_pb2.IssueComment(project_id=12345,
                                           user_id=999,
                                           issue_id=approval_issue.issue_id,
                                           amendments=[amend],
                                           timestamp=1234567890,
                                           content='just a comment.')
        attach = tracker_pb2.Attachment(attachment_id=4567,
                                        filename='sploot.jpg',
                                        mimetype='image/png',
                                        gcs_object_id='/pid/attachments/abcd',
                                        filesize=(1024 * 1023))
        comment.attachments.append(attach)
        self.services.issue.TestAddComment(comment, approval_issue.local_id)
        self.services.issue.TestAddAttachment(attach, comment.id,
                                              approval_issue.issue_id)

        task = notify.NotifyApprovalChangeTask(request=None,
                                               response=None,
                                               services=self.services)
        params = {
            'send_email': 1,
            'issue_id': approval_issue.issue_id,
            'approval_id': 3,
            'comment_id': comment.id,
        }
        mr = testing_helpers.MakeMonorailRequest(user_info={'user_id': 1},
                                                 params=params,
                                                 method='POST',
                                                 services=self.services)
        result = task.HandleRequest(mr)
        self.assertTrue('just a comment' in result['tasks'][0]['body'])
        self.assertTrue('Approvers: -approver' in result['tasks'][0]['body'])
        self.assertTrue('sploot.jpg' in result['tasks'][0]['body'])
        self.assertTrue(
            '/issues/attachment?aid=4567' in result['tasks'][0]['body'])
        self.assertItemsEqual([
            '*****@*****.**', '*****@*****.**',
            '*****@*****.**', '*****@*****.**',
            '*****@*****.**', '*****@*****.**',
            '*****@*****.**', '*****@*****.**'
        ], result['notified'])

        # Test no approvers/groups notified
        # Status change to NEED_INFO does not email approvers.
        amend2 = tracker_bizobj.MakeApprovalStatusAmendment(
            tracker_pb2.ApprovalStatus.NEED_INFO)
        comment2 = tracker_pb2.IssueComment(project_id=12345,
                                            user_id=999,
                                            issue_id=approval_issue.issue_id,
                                            amendments=[amend2],
                                            timestamp=1234567891,
                                            content='')
        self.services.issue.TestAddComment(comment2, approval_issue.local_id)
        task = notify.NotifyApprovalChangeTask(request=None,
                                               response=None,
                                               services=self.services)
        params = {
            'send_email': 1,
            'issue_id': approval_issue.issue_id,
            'approval_id': 3,
            'comment_id': comment2.id,
        }
        mr = testing_helpers.MakeMonorailRequest(user_info={'user_id': 1},
                                                 params=params,
                                                 method='POST',
                                                 services=self.services)
        result = task.HandleRequest(mr)
        self.assertTrue('Status: need_info' in result['tasks'][0]['body'])
        self.assertItemsEqual(
            ['*****@*****.**', '*****@*****.**', '*****@*****.**'],
            result['notified'])
Exemple #20
0
    def ProcessFormData(self, mr, post_data):
        """Validate and store the contents of the issues tracker admin page.

    Args:
      mr: commonly used info parsed from the request.
      post_data: HTML form data from the request.

    Returns:
      String URL to redirect the user to, or None if response was already sent.
    """

        config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id)
        parsed = template_helpers.ParseTemplateRequest(post_data, config)
        field_helpers.ShiftEnumFieldsIntoLabels(parsed.labels, [],
                                                parsed.field_val_strs, [],
                                                config)
        template = self.services.template.GetTemplateByName(
            mr.cnxn, parsed.name, mr.project_id)
        allow_edit = permissions.CanEditTemplate(mr.auth.effective_ids,
                                                 mr.perms, mr.project,
                                                 template)
        if not allow_edit:
            raise permissions.PermissionException(
                'User is not allowed edit this issue template.')

        if 'deletetemplate' in post_data:
            self.services.template.DeleteIssueTemplateDef(
                mr.cnxn, mr.project_id, template.template_id)
            return framework_helpers.FormatAbsoluteURL(mr,
                                                       urls.ADMIN_TEMPLATES,
                                                       deleted=1,
                                                       ts=int(time.time()))

        (admin_ids, owner_id, component_ids, field_values, phases,
         approvals) = template_helpers.GetTemplateInfoFromParsed(
             mr, self.services, parsed, config)

        if mr.errors.AnyErrors():
            field_views = tracker_views.MakeAllFieldValueViews(
                config, [], [], field_values, {})

            prechecked_approvals = template_helpers.GetCheckedApprovalsFromParsed(
                parsed.approvals_to_phase_idx)

            self.PleaseCorrect(
                mr,
                initial_members_only=ezt.boolean(parsed.members_only),
                template_name=parsed.name,
                initial_summary=parsed.summary,
                initial_must_edit_summary=ezt.boolean(
                    parsed.summary_must_be_edited),
                initial_content=parsed.content,
                initial_status=parsed.status,
                initial_owner=parsed.owner_str,
                initial_owner_defaults_to_member=ezt.boolean(
                    parsed.owner_defaults_to_member),
                initial_components=', '.join(parsed.component_paths),
                initial_component_required=ezt.boolean(
                    parsed.component_required),
                initial_admins=parsed.admin_str,
                labels=parsed.labels,
                fields=[
                    view for view in field_views
                    if view.field_def.type_name is not 'APPROVAL_TYPE'
                ],
                initial_add_approvals=ezt.boolean(parsed.add_approvals),
                initial_phases=[
                    tracker_pb2.Phase(name=name) for name in parsed.phase_names
                ],
                approvals=[
                    view for view in field_views
                    if view.field_def.type_name is 'APPROVAL_TYPE'
                ],
                prechecked_approvals=prechecked_approvals,
                required_approval_ids=parsed.required_approval_ids)
            return

        labels = [label for label in parsed.labels if label]
        self.services.template.UpdateIssueTemplateDef(
            mr.cnxn,
            mr.project_id,
            template.template_id,
            name=parsed.name,
            content=parsed.content,
            summary=parsed.summary,
            summary_must_be_edited=parsed.summary_must_be_edited,
            status=parsed.status,
            members_only=parsed.members_only,
            owner_defaults_to_member=parsed.owner_defaults_to_member,
            component_required=parsed.component_required,
            owner_id=owner_id,
            labels=labels,
            component_ids=component_ids,
            admin_ids=admin_ids,
            field_values=field_values,
            phases=phases,
            approval_values=approvals)

        return framework_helpers.FormatAbsoluteURL(mr,
                                                   urls.TEMPLATE_DETAIL,
                                                   template=template.name,
                                                   saved=1,
                                                   ts=int(time.time()))
Exemple #21
0
    def testFetchItems_Normal(self):
        template_9_row = (9, 1, 'template-9', 'content', 'summary', False, 111,
                          'status', False, False, False)
        template_8_row = (8, 1, 'template-8', 'content', 'summary', False, 111,
                          'status', False, False, False)
        template_7_row = (7, 2, 'template-7', 'content', 'summary', False, 111,
                          'status', False, False, False)

        self.template_def_2lc.template_service.template_tbl.Select\
            .return_value = [template_7_row, template_8_row,
                template_9_row]
        self.template_def_2lc.template_service.template2label_tbl.Select\
            .return_value = [(9, 'label-1'), (7, 'label-2')]
        self.template_def_2lc.template_service.template2component_tbl.Select\
            .return_value = [(9, 13), (7, 14)]
        self.template_def_2lc.template_service.template2admin_tbl.Select\
            .return_value = [(9, 111), (7, 222)]

        fv1_row = (15, None, 'fv-1', None, None, None, False)
        fv2_row = (16, None, 'fv-2', None, None, None, False)
        fv1 = tracker_bizobj.MakeFieldValue(*fv1_row)
        fv2 = tracker_bizobj.MakeFieldValue(*fv2_row)
        self.template_def_2lc.template_service.template2fieldvalue_tbl.Select\
            .return_value = [((9,) + fv1_row[:-1]), ((7,) + fv2_row[:-1])]

        av1_row = (17, 9, 19, 'na')
        av2_row = (18, 7, 20, 'not_set')
        av1 = tracker_pb2.ApprovalValue(
            approval_id=17,
            phase_id=19,
            status=tracker_pb2.ApprovalStatus('NA'))
        av2 = tracker_pb2.ApprovalValue(
            approval_id=18,
            phase_id=20,
            status=tracker_pb2.ApprovalStatus('NOT_SET'))
        phase1_row = (19, 'phase-1', 1)
        phase2_row = (20, 'phase-2', 2)
        phase1 = tracker_pb2.Phase(phase_id=19, name='phase-1', rank=1)
        phase2 = tracker_pb2.Phase(phase_id=20, name='phase-2', rank=2)

        self.template_def_2lc.template_service.template2approvalvalue_tbl.Select\
            .return_value = [av1_row, av2_row]
        self.template_def_2lc.template_service.issuephasedef_tbl.Select\
            .return_value = [phase1_row, phase2_row]

        actual = self.template_def_2lc.FetchItems(cnxn=None, keys=[7, 8, 9])
        self.assertEqual(3, len(list(actual.keys())))
        self.assertTrue(isinstance(actual[7], tracker_pb2.TemplateDef))
        self.assertTrue(isinstance(actual[8], tracker_pb2.TemplateDef))
        self.assertTrue(isinstance(actual[9], tracker_pb2.TemplateDef))

        self.assertEqual(7, actual[7].template_id)
        self.assertEqual(8, actual[8].template_id)
        self.assertEqual(9, actual[9].template_id)

        self.assertEqual(['label-2'], actual[7].labels)
        self.assertEqual([], actual[8].labels)
        self.assertEqual(['label-1'], actual[9].labels)

        self.assertEqual([14], actual[7].component_ids)
        self.assertEqual([], actual[8].component_ids)
        self.assertEqual([13], actual[9].component_ids)

        self.assertEqual([222], actual[7].admin_ids)
        self.assertEqual([], actual[8].admin_ids)
        self.assertEqual([111], actual[9].admin_ids)

        self.assertEqual([fv2], actual[7].field_values)
        self.assertEqual([], actual[8].field_values)
        self.assertEqual([fv1], actual[9].field_values)

        self.assertEqual([phase2], actual[7].phases)
        self.assertEqual([], actual[8].phases)
        self.assertEqual([phase1], actual[9].phases)

        self.assertEqual([av2], actual[7].approval_values)
        self.assertEqual([], actual[8].approval_values)
        self.assertEqual([av1], actual[9].approval_values)
    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)
Exemple #23
0
    def testCreateIssueTemplateDef(self):
        fv = tracker_bizobj.MakeFieldValue(1, None, 'somestring', None, None,
                                           None, False)
        av_23 = tracker_pb2.ApprovalValue(
            approval_id=23,
            phase_id=11,
            status=tracker_pb2.ApprovalStatus.NEEDS_REVIEW)
        av_24 = tracker_pb2.ApprovalValue(approval_id=24, phase_id=11)
        approval_values = [av_23, av_24]
        phases = [tracker_pb2.Phase(name='Canary', rank=11, phase_id=11)]

        actual_template_id = self.template_service.CreateIssueTemplateDef(
            self.cnxn,
            789,
            'template',
            'content',
            'summary',
            True,
            'Available',
            True,
            True,
            True,
            owner_id=111,
            labels=['label'],
            component_ids=[3],
            admin_ids=[222],
            field_values=[fv],
            phases=phases,
            approval_values=approval_values)

        self.assertEqual(1, actual_template_id)

        self.template_service.template_tbl.InsertRow\
            .assert_called_once_with(self.cnxn, project_id=789, name='template',
                content='content', summary='summary', summary_must_be_edited=True,
                owner_id=111, status='Available', members_only=True,
                owner_defaults_to_member=True, component_required=True,
                commit=False)
        self.template_service.template2label_tbl.InsertRows\
            .assert_called_once_with(self.cnxn, template_svc.TEMPLATE2LABEL_COLS,
                [(1, 'label')], commit=False)
        self.template_service.template2component_tbl.InsertRows\
            .assert_called_once_with(self.cnxn,
                template_svc.TEMPLATE2COMPONENT_COLS,
                [(1, 3)], commit=False)
        self.template_service.template2admin_tbl.InsertRows\
            .assert_called_once_with(self.cnxn, template_svc.TEMPLATE2ADMIN_COLS,
                [(1, 222)], commit=False)
        self.template_service.template2fieldvalue_tbl.InsertRows\
            .assert_called_once_with(self.cnxn,
                template_svc.TEMPLATE2FIELDVALUE_COLS,
                [(1, 1, None, 'somestring', None, None, None)], commit=False)
        self.template_service.issuephasedef_tbl.InsertRow\
            .assert_called_once_with(self.cnxn, name='Canary',
                rank=11, commit=False)
        self.template_service.template2approvalvalue_tbl.InsertRows\
            .assert_called_once_with(self.cnxn,
                template_svc.TEMPLATE2APPROVALVALUE_COLS,
                [(23, 1, 81, 'needs_review'), (24, 1, 81, 'not_set')], commit=False)
        self.cnxn.Commit.assert_called_once_with()
        self.template_service.template_set_2lc.InvalidateKeys\
            .assert_called_once_with(self.cnxn, [789])
  def testComputeUnshownColumns_FieldDefs(self):
    search_results = [
        fake.MakeTestIssue(
            789, 1, 'sum 1', 'New', 111,
            field_values=[
                tracker_bizobj.MakeFieldValue(
                    5, 74, None, None, None, None, False, phase_id=4),
                tracker_bizobj.MakeFieldValue(
                    6, 78, None, None, None, None, False, phase_id=5)],
            phases=[
                tracker_pb2.Phase(phase_id=4, name='goats'),
                tracker_pb2.Phase(phase_id=5, name='sheep')]),
        fake.MakeTestIssue(
            789, 2, 'sum 2', 'New', 111,
            field_values=[
                tracker_bizobj.MakeFieldValue(
                    5, 74, None, None, None, None, False, phase_id=3),
                tracker_bizobj.MakeFieldValue(
                    6, 77, None, None, None, None, False, phase_id=3)],
            phases=[
                tracker_pb2.Phase(phase_id=3, name='Goats'),
                tracker_pb2.Phase(phase_id=3, name='Goats-Exp')]),
    ]

    shown_cols = ['a', 'b', 'a1', 'a2-approver', 'f3', 'goats.g1', 'sheep.g2']
    config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
    config.default_col_spec = ''
    config.well_known_labels = []
    config.field_defs = [
      tracker_bizobj.MakeFieldDef(
          1, 789, 'a1', tracker_pb2.FieldTypes.APPROVAL_TYPE,
          None, None, False, False, False, None, None, None, False, None,
          None, None, None, 'Tracks review from cows', False),
      tracker_bizobj.MakeFieldDef(
          2, 789, 'a2', tracker_pb2.FieldTypes.APPROVAL_TYPE,
          None, None, False, False, False, None, None, None, False, None,
          None, None, None, 'Tracks review from chickens', False),
      tracker_bizobj.MakeFieldDef(
          3, 789, 'f3', tracker_pb2.FieldTypes.STR_TYPE,
          None, None, False, False, False, None, None, None, False, None,
          None, None, None, 'cow names', False),
      tracker_bizobj.MakeFieldDef(
          4, 789, 'f4', tracker_pb2.FieldTypes.INT_TYPE,
          None, None, False, False, False, None, None, None, False, None,
          None, None, None, 'chicken gobbles', False),
      tracker_bizobj.MakeFieldDef(
          5, 789, 'g1', tracker_pb2.FieldTypes.INT_TYPE,
          None, None, False, False, False, None, None, None, False, None,
          None, None, None, 'fluff', False, is_phase_field=True),
      tracker_bizobj.MakeFieldDef(
          6, 789, 'g2', tracker_pb2.FieldTypes.INT_TYPE,
          None, None, False, False, False, None, None, None, False, None,
          None, None, None, 'poof', False, is_phase_field=True),
    ]
    builtin_cols = []

    unshown = table_view_helpers.ComputeUnshownColumns(
        search_results, shown_cols, config, builtin_cols)
    self.assertEqual(unshown, [
        'a1-approver', 'a2', 'f4',
        'goats-exp.g1', 'goats-exp.g2', 'goats.g2', 'sheep.g1'])
Exemple #25
0
    def GatherPageData(self, mr):
        """Build up a dictionary of data values to use when rendering the page.

    Args:
      mr: commonly used info parsed from the request.

    Returns:
      Dict of values used by EZT for rendering the page.
    """

        config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id)
        field_views = tracker_views.MakeAllFieldValueViews(
            config, [], [], [], {})
        approval_subfields_present = any(fv.field_def.is_approval_subfield
                                         for fv in field_views)

        initial_phases = [tracker_pb2.Phase()
                          ] * template_helpers.MAX_NUM_PHASES
        return {
            'admin_tab_mode':
            self._PROCESS_SUBTAB,
            'allow_edit':
            ezt.boolean(True),
            'new_template_form':
            ezt.boolean(True),
            'initial_members_only':
            ezt.boolean(False),
            'template_name':
            '',
            'initial_content':
            '',
            'initial_must_edit_summary':
            ezt.boolean(False),
            'initial_summary':
            '',
            'initial_status':
            '',
            'initial_owner':
            '',
            'initial_owner_defaults_to_member':
            ezt.boolean(False),
            'initial_components':
            '',
            'initial_component_required':
            ezt.boolean(False),
            'initial_admins':
            '',
            'fields': [
                view for view in field_views
                if view.field_def.type_name is not "APPROVAL_TYPE"
            ],
            'initial_add_approvals':
            ezt.boolean(False),
            'initial_phases':
            initial_phases,
            'approvals': [
                view for view in field_views
                if view.field_def.type_name is "APPROVAL_TYPE"
            ],
            'prechecked_approvals': [],
            'required_approval_ids': [],
            'approval_subfields_present':
            ezt.boolean(approval_subfields_present),
            # We do not support setting phase field values during template creation.
            'phase_fields_present':
            ezt.boolean(False),
        }
Exemple #26
0
 def CreatePhasesCopies(self, phases):
     return [
         tracker_pb2.Phase(phase_id=phase.phase_id,
                           name=phase.name,
                           rank=phase.rank) for phase in phases
     ]