# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unittests for the flt launch issues conversion task."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
import copy
import unittest
import settings
import mock

from businesslogic import work_env
from framework import exceptions
from framework import permissions
from services import service_manager
from services import template_svc
from tracker import fltconversion
from tracker import tracker_bizobj
from testing import fake
from testing import testing_helpers
from mrproto import tracker_pb2

class FLTConvertTask(unittest.TestCase):

  def setUp(self):
    self.services = service_manager.Services(
        issue=fake.IssueService(),
        user=fake.UserService(),
        project=fake.ProjectService(),
        config=fake.ConfigService(),
        template=mock.Mock(spec=template_svc.TemplateService),)
    self.mr = testing_helpers.MakeMonorailRequest()
    self.task = fltconversion.FLTConvertTask(services=self.services)
    self.task.mr = self.mr
    self.issue = fake.MakeTestIssue(
        789, 1, 'summary', 'New', 111, issue_id=78901)
    self.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
    self.work_env = work_env.WorkEnv(
        self.mr, self.services, 'Testing')
    self.issue1 = fake.MakeTestIssue(
        789, 1, 'sum', 'New', 111, issue_id=78901,
        labels=[
            'Launch-M-Approved-71-Stable', 'Launch-M-Target-70-Beta',
            'Launch-UI-Yes', 'Launch-Privacy-NeedInfo',
            'pm-jojwang', 'tl-annajo', 'ux-shiba', 'Type-Launch'])
    self.issue2 = fake.MakeTestIssue(
        789, 2, 'sum', 'New', 111, issue_id=78902,
        labels=[
            'Launch-M-Target-71-Stable', 'Launch-M-Approved-70-Beta',
            'pm-jojwang', 'tl-annajo', 'OS-Chrome', 'OS-Android',
            'Type-Launch'])
    self.issue3 = fake.MakeTestIssue(
        789, 3, 'sum', 'New', 111, issue_id=78903,
        labels=['Launch-M-Approved-71-Stable',
                'Launch-M-Approved-79-Stable-Exp', 'Launch-M-Target-70-Beta',
                'Launch-M-Target-70-Stable', 'Launch-UI-Yes',
                'Launch-Exp-Leadership-Yes', 'pm-annajo', 'tl-jojwang',
                'OS-Chrome', 'Type-Launch'])
    self.issue4 = fake.MakeTestIssue(
        789, 4, 'sum', 'New', 111, issue_id=78904,
        labels=['Launch-UI-Yes', 'OS-Chrome', 'Type-Launch'])
    self.issue5 = fake.MakeTestIssue(
        789, 5, 'sum', 'New', 111, issue_id=78905,
        labels=['Launch-M-Approved-71-Stable',
                'Launch-M-Approved-79-Stable-Exp', 'Launch-M-Target-70-Beta',
                'Launch-M-Target-70-Stable', 'Launch-UI-Yes',
                'Launch-Privacy-NeedInfo', 'Launch-Exp-Leadership-Yes',
                'pm-annajo', 'tl-jojwang', 'OS-Chrome', 'Type-Launch'])

    self.approval_values = [
        tracker_pb2.ApprovalValue(
            approval_id=7, status=tracker_pb2.ApprovalStatus.NOT_SET),
        tracker_pb2.ApprovalValue(
            approval_id=8, status=tracker_pb2.ApprovalStatus.NEEDS_REVIEW)]
    self.phases = [tracker_pb2.Phase(name='Stable', phase_id=88),
              tracker_pb2.Phase(name='Beta', phase_id=89)]

  def testAssertBasePermission(self):
    self.mr.auth.user_pb.is_site_admin = True
    settings.app_id = 'monorail-staging'
    self.task.AssertBasePermission(self.mr)

    settings.app_id = 'monorail-prod'
    self.task.AssertBasePermission(self.mr)

    self.mr.auth.user_pb.is_site_admin = False
    self.assertRaises(permissions.PermissionException,
                      self.task.AssertBasePermission, self.mr)

  def testHandleRequest(self):
    # Set up Objects
    project_info = fltconversion.ProjectInfo(
        self.config, 'q=query', self.approval_values, self.phases,
        11, 12, 13, 16, 14, 15, fltconversion.BROWSER_PHASE_MAP,
        fltconversion.BROWSER_APPROVALS_TO_LABELS,
        fltconversion.BROWSER_M_LABELS_RE)

    self.config.field_defs = [
        tracker_pb2.FieldDef(field_id=7, field_name='Chrome-UX',
                             field_type=tracker_pb2.FieldTypes.APPROVAL_TYPE),
        tracker_pb2.FieldDef(field_id=8, field_name='Chrome-Privacy',
                             field_type=tracker_pb2.FieldTypes.APPROVAL_TYPE)
    ]

    # Set up mocks
    patcher = mock.patch(
        'search.frontendsearchpipeline.FrontendSearchPipeline',
        spec=True, visible_results=[self.issue1, self.issue2])
    mockPipeline = patcher.start()

    self.task.services.issue.GetIssue = mock.Mock(
        side_effect=[self.issue1, self.issue2])

    self.task.FetchAndAssertProjectInfo = mock.Mock(return_value=project_info)

    with self.work_env as we:
      we.ListIssues = mock.Mock(return_value=mockPipeline)

    def side_effect(_cnxn, email):
      if email == 'jojwang@chromium.org':
        return 111
      if email == 'annajo@google.com':
        return 222
      if email == 'shiba@google.com':
        return 333
      raise exceptions.NoSuchUserException
    self.task.services.user.LookupUserID = mock.Mock(side_effect=side_effect)

    self.task.ExecuteIssueChanges = mock.Mock(return_value=[])

    # Call
    json = self.task.HandleRequest(self.mr)

    # assert
    self.assertEqual(json['converted_issues'], [1, 2])

    new_approvals1 = [
        tracker_pb2.ApprovalValue(
            approval_id=7, status=tracker_pb2.ApprovalStatus.APPROVED),
        tracker_pb2.ApprovalValue(
            approval_id=8, status=tracker_pb2.ApprovalStatus.NEED_INFO)]
    new_fvs1 = [
      # M-Approved Stable
      tracker_bizobj.MakeFieldValue(
          15, 71, None, None, None, None, False, phase_id=88),
      # M-Target Beta
      tracker_bizobj.MakeFieldValue(
          14, 70, None, None, None, None, False, phase_id=89),
      # PM field
      tracker_bizobj.MakeFieldValue(
          11, None, None, 111, None, None, False),
      # TL field
      tracker_bizobj.MakeFieldValue(
          12, None, None, 222, None, None, False),
      # UX field
      tracker_bizobj.MakeFieldValue(
          16, None, None, 333, None, None, False)
    ]


    new_approvals2 = [
        tracker_pb2.ApprovalValue(
            approval_id=7, status=tracker_pb2.ApprovalStatus.NOT_SET),
        tracker_pb2.ApprovalValue(
            approval_id=8, status=tracker_pb2.ApprovalStatus.NEEDS_REVIEW)
    ]
    new_fvs2 = [
        tracker_bizobj.MakeFieldValue(
            14, 71, None, None, None, None, False, phase_id=88),
        tracker_bizobj.MakeFieldValue(
            15, 70, None, None, None, None, False, phase_id=89),
        # PM field
        tracker_bizobj.MakeFieldValue(
            11, None, None, 111, None, None, False),
        # TL field
        tracker_bizobj.MakeFieldValue(
            12, None, None, 222, None, None, False)]

    execute_calls = [
        mock.call(
            self.config, self.issue1, new_approvals1, self.phases, new_fvs1),
        mock.call(
            self.config, self.issue2, new_approvals2, self.phases, new_fvs2)]
    self.task.ExecuteIssueChanges.assert_has_calls(execute_calls)

    patcher.stop()

  def testHandleRequest_UndoConversion(self):
    # test Delete() is actually called
    mr = testing_helpers.MakeMonorailRequest(path='url/url?launch=delete')
    self.task.UndoConversion = mock.Mock(return_value={'deleteing': [1, 2]})
    actualReturn = self.task.HandleRequest(mr)
    self.assertEqual({'deleteing': [1, 2]}, actualReturn)

  def testUndoConversion(self):
    # Set up objects
    self.issue1.field_values = [
        # Test non phase and TL/PM/TE field_values are not deleted
        tracker_bizobj.MakeFieldValue(
            17, None, 'strvalue', None, None, None, False)]
    issue1 = copy.deepcopy(self.issue1)
    issue2 = copy.deepcopy(self.issue2)
    fvs = [
        tracker_bizobj.MakeFieldValue(
            11, None, None, 222, None, None, False),
        tracker_bizobj.MakeFieldValue(
            12, None, None, 111, None, None, False),
        tracker_bizobj.MakeFieldValue(
            16, None, None, 111, None, None, False)]
    self.config.field_defs = [
        tracker_pb2.FieldDef(field_id=11, field_name='PM'),
        tracker_pb2.FieldDef(field_id=12, field_name='TL'),
        tracker_pb2.FieldDef(field_id=13, field_name='TE'),
        tracker_pb2.FieldDef(field_id=16, field_name='UX')]
    # Make element edits made during conversion that should be undone.
    issue1.labels.extend(['Type-FLT-Launch', 'FLT-Conversion'])
    issue1.labels.remove('Type-Launch')
    issue2.labels.extend(['Type-FLT-Launch', 'FLT-Conversion'])
    issue2.labels.remove('Type-Launch')
    issue1.approval_values = self.approval_values
    issue2.approval_values = self.approval_values
    issue1.phases = self.phases
    issue2.phases = self.phases
    issue1.field_values.extend(fvs)

    # Set up mocks
    patcher = mock.patch(
        'search.frontendsearchpipeline.FrontendSearchPipeline',
        spec=True, visible_results=[issue1, issue2])  # converted issues
    mockPipeline = patcher.start()
    self.task.services.project.GetProjectByName = mock.Mock()
    self.task.services.config.GetProjectConfig = mock.Mock(
        return_value=self.config)
    self.task.services.issue.GetIssue = mock.Mock(
        side_effect=[issue1, issue2])
    self.task.services.issue._UpdateIssuesApprovals = mock.Mock()
    self.task.services.issue.UpdateIssue = mock.Mock()

    with self.work_env as we:
      we.ListIssues = mock.Mock(return_value=mockPipeline)

    json = self.task.UndoConversion(self.mr)
    self.assertEqual(json['deleting'], [1, 2])
    # assert convert issue1 is back to the pre-conversion state, self.issue1.
    self.assertEqual(issue1, self.issue1)
    self.assertEqual(issue2, self.issue2)

    # assert UpdateIssue calls were made with pre-conversion state issues.
    update_calls = [
        mock.call(self.mr.cnxn, self.issue1),
        mock.call(self.mr.cnxn, self.issue2)]
    self.task.services.issue._UpdateIssuesApprovals.assert_has_calls(
        update_calls)
    self.task.services.issue.UpdateIssue.assert_has_calls(update_calls)
    patcher.stop()

  def testVerifyConversion(self):
    # Set up objects
    self.issue1.labels.extend(
        # Launch-M-Target-70-Stable-Exp should be ignored
        ['Rollout-Type-Default', 'Launch-M-Target-70-Stable-Exp'])
    self.issue1.phases = [tracker_pb2.Phase(name='Beta', phase_id=1),
                          tracker_pb2.Phase(name='Stable', phase_id=2)]
    self.issue1.approval_values = [
      tracker_pb2.ApprovalValue(
          approval_id=1, status=tracker_pb2.ApprovalStatus.NOT_SET),
      tracker_pb2.ApprovalValue(
          approval_id=2, status=tracker_pb2.ApprovalStatus.APPROVED),
      tracker_pb2.ApprovalValue(
          approval_id=3, status=tracker_pb2.ApprovalStatus.NEED_INFO),
    ]
    self.issue1.field_values = [
        # problem = expected field for TL
        tracker_bizobj.MakeFieldValue(4, None, None, 111, None, None, False),
        tracker_pb2.FieldValue(field_id=7, int_value=70, phase_id=1),
        tracker_pb2.FieldValue(field_id=8, int_value=71, phase_id=2),
    ]

    self.issue2.labels.extend(['Rollout-Type-Finch'])
    self.issue2.phases = [tracker_pb2.Phase(name='Beta', phase_id=1),
                          tracker_pb2.Phase(name='Stable-Full', phase_id=2),
                          tracker_pb2.Phase(name='Stable-Exp', phase_id=3)]
    self.issue2.approval_values = [
        tracker_pb2.ApprovalValue(
            approval_id=1, status=tracker_pb2.ApprovalStatus.NOT_SET),
        tracker_pb2.ApprovalValue(
            approval_id=2, status=tracker_pb2.ApprovalStatus.NOT_SET),
        tracker_pb2.ApprovalValue(
            # problem = approval Chrome-Privacy has status approved for None
            approval_id=3, status=tracker_pb2.ApprovalStatus.APPROVED),
    ]
    self.issue2.field_values = [
        # problem = no phase field for label 'Launch-M-Approved-70-Beta'
        tracker_pb2.FieldValue(field_id=7, int_value=71, phase_id=2),
        tracker_bizobj.MakeFieldValue(4, None, None, 111, None, None, False),
        tracker_bizobj.MakeFieldValue(5, None, None, 111, None, None, False),
        ]

    self.issue3.labels.extend(['Rollout-Type-Default'])
    self.issue3.phases = [tracker_pb2.Phase(name='Feature Freeze', phase_id=4),
                          tracker_pb2.Phase(name='Branch', phase_id=5),
                          tracker_pb2.Phase(name='Stable', phase_id=6)]
    self.issue3.approval_values = [
      tracker_pb2.ApprovalValue(
          approval_id=9, status=tracker_pb2.ApprovalStatus.APPROVED),
      tracker_pb2.ApprovalValue(
          approval_id=10, status=tracker_pb2.ApprovalStatus.NEEDS_REVIEW)]
    # problem = no phase field label Launch-M-Target-70-Stable
    # problem = missing a field for TL
    self.issue3.field_values = [
        tracker_pb2.FieldValue(field_id=8, int_value=71, phase_id=6),
        tracker_bizobj.MakeFieldValue(4, None, None, 111, None, None, False)
    ]

    self.issue4.labels.extend(['Rollout-Type-Default'])
    # problem = incorrect phases for OS default launch
    self.issue4.phases = [tracker_pb2.Phase(name='Branch', phase_id=5),
                          tracker_pb2.Phase(name='Stable-Exp', phase_id=7)]
    # problem = approval ChromeOS-UX has status 'NEEDS_REVIEW'
    # for label value Yes
    self.issue4.approval_values = [
      tracker_pb2.ApprovalValue(
          approval_id=9, status=tracker_pb2.ApprovalStatus.NEEDS_REVIEW)]

    self.issue5.labels.extend(['Rollout-Type-Finch'])
    self.issue5.phases = [tracker_pb2.Phase(name='Branch', phase_id=5),
                          tracker_pb2.Phase(name='Feature Freeze', phase_id=4),
                          tracker_pb2.Phase(name='Stable-Exp', phase_id=7),
                          tracker_pb2.Phase(name='Stable-Full', phase_id=8)]
    self.issue5.approval_values = [
        tracker_pb2.ApprovalValue(
            approval_id=9, status=tracker_pb2.ApprovalStatus.APPROVED),
        # problem = approval ChromeOS-Privacy has status 'REVIEW_REQUESTED'
        # for label value NeedInfo
        tracker_pb2.ApprovalValue(
            approval_id=11, status=tracker_pb2.ApprovalStatus.REVIEW_REQUESTED),
        # problem = approval ChromeOS-Leadership-Exp has status 'NA' for label
        # value Yes.
        tracker_pb2.ApprovalValue(
            approval_id=13, status=tracker_pb2.ApprovalStatus.NA)
    ]

    # problem = no phase field for label Launch-M-Approved-79-Stable-Exp
    # problem = no phase field for label Launch-M-Target-70-Stable
    self.issue5.field_values = [
        tracker_pb2.FieldValue(field_id=8, int_value=71, phase_id=8),
        tracker_bizobj.MakeFieldValue(4, None, None, 111, None, None, False),
        tracker_bizobj.MakeFieldValue(5, None, None, 111, None, None, False)]

    self.config.field_defs = [
        tracker_pb2.FieldDef(field_id=1, field_name='Chrome-Test'),
        tracker_pb2.FieldDef(field_id=2, field_name='Chrome-UX'),
        tracker_pb2.FieldDef(field_id=3, field_name='Chrome-Privacy'),
        tracker_pb2.FieldDef(field_id=4, field_name='PM'),
        tracker_pb2.FieldDef(field_id=5, field_name='TL'),
        tracker_pb2.FieldDef(field_id=6, field_name='TE'),
        tracker_pb2.FieldDef(field_id=12, field_name='UX'),
        tracker_pb2.FieldDef(field_id=7, field_name='M-Target'),
        tracker_pb2.FieldDef(field_id=8, field_name='M-Approved'),
        tracker_pb2.FieldDef(field_id=9, field_name='ChromeOS-UX'),
        tracker_pb2.FieldDef(field_id=10, field_name='ChromeOS-Enterprise'),
        tracker_pb2.FieldDef(field_id=11, field_name='ChromeOS-Privacy'),
        tracker_pb2.FieldDef(field_id=13, field_name='ChromeOS-Leadership-Exp')
    ]

    # Set up mocks
    patcher = mock.patch(
        'search.frontendsearchpipeline.FrontendSearchPipeline',
        spec=True, allowed_results=[
            self.issue1, self.issue2, self.issue3, self.issue4, self.issue5])
    mockPipeline = patcher.start()
    self.task.services.project.GetProjectByName = mock.Mock()
    self.task.services.config.GetProjectConfig = mock.Mock(
        return_value=self.config)
    self.task.services.issue.GetIssue = mock.Mock(
        side_effect=[
            self.issue1, self.issue2, self.issue3, self.issue4, self.issue5])
    self.task.services.user.LookupUserID = mock.Mock(return_value=111)
    with self.work_env as we:
      we.ListIssues = mock.Mock(return_value=mockPipeline)

    # Assert
    json = self.task.VerifyConversion(self.mr)
    self.assertEqual(json['issues verified'],
                     ['issue 1', 'issue 2', 'issue 3', 'issue 4', 'issue 5'])
    problems = json['problems found']
    expected_problems = [
        'issue 1: missing a field for TL',
        'issue 1: missing a field for UX',
        'issue 2: approval Chrome-Privacy has status \'APPROVED\' for '
        'label value None',
        'issue 2: no phase field for label Launch-M-Approved-70-Beta',
        'issue 3: missing a field for TL',
        'issue 3: no phase field for label Launch-M-Target-70-Stable',
        'issue 4: incorrect phases for OS default launch.',
        'issue 4: approval ChromeOS-UX has status \'NEEDS_REVIEW\' for '
        'label value Yes',
        'issue 5: approval ChromeOS-Privacy has status \'REVIEW_REQUESTED\' '
        'for label value NeedInfo',
        'issue 5: approval ChromeOS-Leadership-Exp has status \'NA\' for label '
        'value Yes',
        'issue 5: no phase field for label Launch-M-Approved-79-Stable-Exp',
        'issue 5: no phase field for label Launch-M-Target-70-Stable',
    ]
    self.assertEqual(problems, expected_problems)
    patcher.stop()

  def testFetchAndAssertProjectInfo(self):

    # test no 'launch' in request
    self.assertRaisesRegex(
        AssertionError, r'bad launch type:',
        self.task.FetchAndAssertProjectInfo, self.mr)

    # test bad 'launch' in request
    mr = testing_helpers.MakeMonorailRequest(path='url/url?launch=bad')
    self.assertRaisesRegex(
        AssertionError, r'bad launch type: bad',
        self.task.FetchAndAssertProjectInfo, mr)

    self.task.services.project.GetProjectByName = mock.Mock()
    self.task.services.config.GetProjectConfig = mock.Mock(
        return_value=self.config)

    mr = testing_helpers.MakeMonorailRequest(path='url/url?launch=default')
    # test no template
    self.task.services.template.GetTemplateByName = mock.Mock(
        return_value=None)
    self.assertRaisesRegex(
        AssertionError, r'not found in chromium project',
        self.task.FetchAndAssertProjectInfo, mr)

    # test template has no phases/approvals
    template = tracker_bizobj.MakeIssueTemplate(
        'template', 'sum', 'New', 111, 'content', [], [], [], [])
    self.task.services.template.GetTemplateByName = mock.Mock(
        return_value=template)
    self.assertRaisesRegex(
        AssertionError, 'no approvals or phases in',
        self.task.FetchAndAssertProjectInfo, mr)

    # test phases not recognized
    template.phases = [tracker_pb2.Phase(name='WeirdPhase')]
    template.approval_values = [tracker_pb2.ApprovalValue()]
    self.assertRaisesRegex(
        AssertionError, 'one or more phases not recognized',
        self.task.FetchAndAssertProjectInfo, mr)

    template.phases = [tracker_pb2.Phase(name='Stable'),
                       tracker_pb2.Phase(name='Stable-Exp')]
    template.approval_values = [
        tracker_pb2.ApprovalValue(approval_id=1),
        tracker_pb2.ApprovalValue(approval_id=2),
        tracker_pb2.ApprovalValue(approval_id=3)]

    # test approvals not recognized
    self.assertRaisesRegex(
        AssertionError, 'one or more approvals not recognized',
        self.task.FetchAndAssertProjectInfo, mr)

    self.config.field_defs = [
        tracker_pb2.FieldDef(field_id=1, field_name='ChromeOS-Enterprise',
                             field_type=tracker_pb2.FieldTypes.APPROVAL_TYPE),
        tracker_pb2.FieldDef(field_id=2, field_name='Chrome-UX',
                             field_type=tracker_pb2.FieldTypes.APPROVAL_TYPE),
        tracker_pb2.FieldDef(field_id=3, field_name='Chrome-Privacy',
                             field_type=tracker_pb2.FieldTypes.APPROVAL_TYPE)
    ]

    # test approvals not in config's approval_defs
    self.assertRaisesRegex(
        AssertionError, 'one or more approvals not in config.approval_defs',
        self.task.FetchAndAssertProjectInfo, mr)

    self.config.approval_defs = [
        tracker_pb2.ApprovalDef(approval_id=1),
        tracker_pb2.ApprovalDef(approval_id=2),
        tracker_pb2.ApprovalDef(approval_id=3)]

    # test no pm field exists in project
    self.assertRaisesRegex(
        AssertionError, 'project has no FieldDef %s' % fltconversion.PM_FIELD,
        self.task.FetchAndAssertProjectInfo, mr)

    self.config.field_defs.extend([
      tracker_pb2.FieldDef(field_id=4, field_name='PM',
                           field_type=tracker_pb2.FieldTypes.USER_TYPE),
      tracker_pb2.FieldDef(field_id=5, field_name='TL',
                           field_type=tracker_pb2.FieldTypes.USER_TYPE),
      tracker_pb2.FieldDef(field_id=9, field_name='UX',
                           field_type=tracker_pb2.FieldTypes.USER_TYPE),
      tracker_pb2.FieldDef(field_id=6, field_name='TE')
    ])

    # test no USER_TYPE te field exists in project
    self.assertRaisesRegex(
        AssertionError, 'project has no FieldDef %s' % fltconversion.TE_FIELD,
        self.task.FetchAndAssertProjectInfo, mr)

    self.config.field_defs[-1].field_type = tracker_pb2.FieldTypes.USER_TYPE
    self.config.field_defs.extend([
        tracker_pb2.FieldDef(
            field_id=7, field_name='M-Target', is_phase_field=True),
        tracker_pb2.FieldDef(
            field_id=8, field_name='M-Approved', is_multivalued=True,
            field_type=tracker_pb2.FieldTypes.INT_TYPE)
        ])

    # test no M-Target INT_TYPE multivalued Phase FieldDefs
    self.assertRaisesRegex(
        AssertionError,
        'project has no FieldDef %s' % fltconversion.MTARGET_FIELD,
        self.task.FetchAndAssertProjectInfo, mr)

    self.config.field_defs[-2].field_type = tracker_pb2.FieldTypes.INT_TYPE
    self.config.field_defs[-2].is_multivalued = True

    # test no M-Approved INT_TYPE multivalued Phase FieldDefs
    self.assertRaisesRegex(
        AssertionError,
        'project has no FieldDef %s' % fltconversion.MAPPROVED_FIELD,
        self.task.FetchAndAssertProjectInfo, mr)

    self.config.field_defs[-1].is_phase_field = True

    self.assertEqual(
        self.task.FetchAndAssertProjectInfo(mr),
        fltconversion.ProjectInfo(
            self.config, fltconversion.QUERY_MAP['default'],
            template.approval_values, template.phases, 4, 5, 6, 9, 7, 8,
            fltconversion.BROWSER_PHASE_MAP,
            fltconversion.BROWSER_APPROVALS_TO_LABELS,
            fltconversion.BROWSER_M_LABELS_RE))

    # FINCH special case
    # test approvals for Finch not required
    mr = testing_helpers.MakeMonorailRequest(path='url/url?launch=finch')
    self.assertRaisesRegex(
        AssertionError, 'finch template not set up correctly',
        self.task.FetchAndAssertProjectInfo, mr)

    for av in template.approval_values:
      av.status = tracker_pb2.ApprovalStatus.NEEDS_REVIEW

    self.assertEqual(
        self.task.FetchAndAssertProjectInfo(mr),
        fltconversion.ProjectInfo(
            self.config, fltconversion.QUERY_MAP['finch'],
            template.approval_values, template.phases, 4, 5, 6, 9, 7, 8,
            fltconversion.BROWSER_PHASE_MAP,
            fltconversion.BROWSER_APPROVALS_TO_LABELS,
            fltconversion.BROWSER_M_LABELS_RE))

  def testFetchAndAssertProjectInfo_OS(self):
    self.task.services.project.GetProjectByName = mock.Mock()
    self.task.services.config.GetProjectConfig = mock.Mock(
        return_value=self.config)

    mr = testing_helpers.MakeMonorailRequest(path='url/url?launch=os')
    template = tracker_bizobj.MakeIssueTemplate(
        'template', 'sum', 'New', 111, 'content', [], [], [], [])
    self.task.services.template.GetTemplateByName = mock.Mock(
        return_value=template)

    # test phases not recognized
    template.phases = [tracker_pb2.Phase(name='Chrome-Test')]
    template.approval_values = [tracker_pb2.ApprovalValue()]
    self.assertRaisesRegex(
        AssertionError, 'one or more phases not recognized',
        self.task.FetchAndAssertProjectInfo, mr)

    template.phases = [tracker_pb2.Phase(name='feature freeze'),
                       tracker_pb2.Phase(name='branch')]

    # test template not set up correctly
    template.approval_values = [
        tracker_pb2.ApprovalValue(approval_id=1),
        tracker_pb2.ApprovalValue(approval_id=2),
        tracker_pb2.ApprovalValue(approval_id=3)]
    self.assertRaisesRegex(
        AssertionError, 'os template not set up correctly',
        self.task.FetchAndAssertProjectInfo, mr)

    for av in template.approval_values:
      av.status = tracker_pb2.ApprovalStatus.NEEDS_REVIEW

    # test approvals not recognized
    self.assertRaisesRegex(
        AssertionError, 'one or more approvals not recognized',
        self.task.FetchAndAssertProjectInfo, mr)

    self.config.field_defs = [
        tracker_pb2.FieldDef(field_id=1, field_name='ChromeOS-Enterprise',
                             field_type=tracker_pb2.FieldTypes.APPROVAL_TYPE),
        tracker_pb2.FieldDef(field_id=2, field_name='ChromeOS-UX',
                             field_type=tracker_pb2.FieldTypes.APPROVAL_TYPE),
        tracker_pb2.FieldDef(field_id=3, field_name='ChromeOS-Privacy',
                             field_type=tracker_pb2.FieldTypes.APPROVAL_TYPE)
    ]

    # Skip remaining checks. No different from Browser process.
    self.config.approval_defs = [
        tracker_pb2.ApprovalDef(approval_id=1),
        tracker_pb2.ApprovalDef(approval_id=2),
        tracker_pb2.ApprovalDef(approval_id=3)]

    self.config.field_defs.extend([
      tracker_pb2.FieldDef(field_id=4, field_name='PM',
                           field_type=tracker_pb2.FieldTypes.USER_TYPE),
      tracker_pb2.FieldDef(field_id=5, field_name='TL',
                           field_type=tracker_pb2.FieldTypes.USER_TYPE),
      tracker_pb2.FieldDef(field_id=6, field_name='TE',
                           field_type=tracker_pb2.FieldTypes.USER_TYPE),
      tracker_pb2.FieldDef(field_id=9, field_name='UX',
                           field_type=tracker_pb2.FieldTypes.USER_TYPE)
    ])
    self.config.field_defs.extend([
        tracker_pb2.FieldDef(
            field_id=7, field_name='M-Target', is_phase_field=True,
            is_multivalued=True, field_type=tracker_pb2.FieldTypes.INT_TYPE),
        tracker_pb2.FieldDef(
            field_id=8, field_name='M-Approved', is_phase_field=True,
            is_multivalued=True, field_type=tracker_pb2.FieldTypes.INT_TYPE)
    ])

    self.assertEqual(
        self.task.FetchAndAssertProjectInfo(mr),
        fltconversion.ProjectInfo(
            self.config, fltconversion.QUERY_MAP['os'],
            template.approval_values, template.phases, 4, 5, 6, 9, 7, 8,
            fltconversion.OS_PHASE_MAP, fltconversion.OS_APPROVALS_TO_LABELS,
            fltconversion.OS_M_LABELS_RE))

  @mock.patch('time.time')
  def testExecuteIssueChanges(self, mockTime):
    mockTime.return_value = 123
    self.task.services.issue._UpdateIssuesApprovals = mock.Mock()
    self.task.services.issue.DeltaUpdateIssue = mock.Mock(
        return_value=([], None))
    self.task.services.issue.InsertComment = mock.Mock()
    self.config.approval_defs = [
        tracker_pb2.ApprovalDef(
            # test empty survey
            approval_id=1, survey='', approver_ids=[111, 222]),
        tracker_pb2.ApprovalDef(approval_id=2), # test missing survey
        tracker_pb2.ApprovalDef(survey='Missing approval_id should not error.'),
        tracker_pb2.ApprovalDef(approval_id=3, survey='Q1\nQ2\n\nQ3'),
        tracker_pb2.ApprovalDef(approval_id=4, survey='Q1\nQ2\n\nQ3 two'),
        tracker_pb2.ApprovalDef()]

    new_avs = [tracker_pb2.ApprovalValue(
        approval_id=1, status=tracker_pb2.ApprovalStatus.APPROVED),
               tracker_pb2.ApprovalValue(approval_id=4),
               tracker_pb2.ApprovalValue(approval_id=2),
               tracker_pb2.ApprovalValue(approval_id=3)]

    phases = [tracker_pb2.Phase(phase_id=1, name='Phase1', rank=1)]
    new_fvs = [tracker_bizobj.MakeFieldValue(
        11, 70, None, None, None, None, False, phase_id=1),
               tracker_bizobj.MakeFieldValue(
                   12, None, 'strfield', None, None, None, False)]
    _amendments = self.task.ExecuteIssueChanges(
        self.config, self.issue, new_avs, phases, new_fvs)

    # approver_ids set in ExecuteIssueChanges()
    new_avs[0].approver_ids = [111, 222]
    self.issue.approval_values = new_avs
    self.issue.phases = phases
    delta = tracker_pb2.IssueDelta(
        labels_add=['Type-FLT-Launch', 'FLT-Conversion'],
        labels_remove=['Type-Launch'], field_vals_add=new_fvs)
    cmt_1 = tracker_pb2.IssueComment(
        issue_id=78901, project_id=789, user_id=self.mr.auth.user_id,
        content='', is_description=True, approval_id=1, timestamp=123)
    cmt_2 = tracker_pb2.IssueComment(
        issue_id=78901, project_id=789, user_id=self.mr.auth.user_id,
        content='', is_description=True, approval_id=2, timestamp=123)
    cmt_3 = tracker_pb2.IssueComment(
        issue_id=78901, project_id=789, user_id=self.mr.auth.user_id,
        content='<b>Q1</b>\n<b>Q2</b>\n<b></b>\n<b>Q3</b>',
        is_description=True, approval_id=3, timestamp=123)
    cmt_4 = tracker_pb2.IssueComment(
        issue_id=78901, project_id=789, user_id=self.mr.auth.user_id,
        content='<b>Q1</b>\n<b>Q2</b>\n<b></b>\n<b>Q3 two</b>',
        is_description=True, approval_id=4, timestamp=123)


    comment_calls = [mock.call(self.mr.cnxn, cmt_1),
                     mock.call(self.mr.cnxn, cmt_4),
                     mock.call(self.mr.cnxn, cmt_2),
                     mock.call(self.mr.cnxn, cmt_3)]
    self.task.services.issue.InsertComment.assert_has_calls(comment_calls)

    self.task.services.issue._UpdateIssuesApprovals.assert_called_once_with(
        self.mr.cnxn, self.issue)
    self.task.services.issue.DeltaUpdateIssue.assert_called_once_with(
        self.mr.cnxn, self.task.services, self.mr.auth.user_id, 789,
        self.config, self.issue, delta,
        comment=fltconversion.CONVERSION_COMMENT)

  def testConvertPeopleLabels(self):
    self.task.services.user.LookupUserID = mock.Mock(
        side_effect=[1, 2, 3, 4, 5, 6])
    labels = [
        'pm-u1', 'pm-u2', 'tl-u2', 'test-3', 'test-4', 'ux-u5', 'ux-6']
    fvs = self.task.ConvertPeopleLabels(self.mr, labels, 11, 12, 13, 14)
    expected = [
        tracker_bizobj.MakeFieldValue(11, None, None, 1, None, None, False),
        tracker_bizobj.MakeFieldValue(12, None, None, 2, None, None, False),
        tracker_bizobj.MakeFieldValue(13, None, None, 3, None, None, False),
        tracker_bizobj.MakeFieldValue(13, None, None, 4, None, None, False),
        tracker_bizobj.MakeFieldValue(14, None, None, 5, None, None, False),
        tracker_bizobj.MakeFieldValue(14, None, None, 6, None, None, False),
        ]
    self.assertEqual(fvs, expected)

  def testConvertPeopleLabels_NoUsers(self):
    def side_effect(_cnxn, _email):
      raise exceptions.NoSuchUserException()
    labels = []
    self.task.services.user.LookupUserID = mock.Mock(side_effect=side_effect)
    self.assertFalse(
        len(self.task.ConvertPeopleLabels(self.mr, labels, 11, 12, 13, 14)))

  def testCreateUserFieldValue_Chromium(self):
    self.task.services.user.LookupUserID = mock.Mock(return_value=1)
    actual = self.task.CreateUserFieldValue(self.mr, 'ldap', 11)
    expected = tracker_bizobj.MakeFieldValue(
        11, None, None, 1, None, None, False)
    self.assertEqual(actual, expected)
    self.task.services.user.LookupUserID.assert_called_once_with(
        self.mr.cnxn, 'ldap@chromium.org')

  def testCreateUserFieldValue_Goog(self):
    def side_effect(_cnxn, email):
      if email.endswith('chromium.org'):
        raise exceptions.NoSuchUserException()
      else:
        return 2
    self.task.services.user.LookupUserID = mock.Mock(side_effect=side_effect)
    actual = self.task.CreateUserFieldValue(self.mr, 'ldap', 11)
    expected = tracker_bizobj.MakeFieldValue(
        11, None, None, 2, None, None, False)
    self.assertEqual(actual, expected)
    self.task.services.user.LookupUserID.assert_any_call(
        self.mr.cnxn, 'ldap@chromium.org')
    self.task.services.user.LookupUserID.assert_any_call(
        self.mr.cnxn, 'ldap@google.com')

  def testCreateUserFieldValue_NoUserFound(self):
    def side_effect(_cnxn, _email):
      raise exceptions.NoSuchUserException()
    self.task.services.user.LookupUserID = mock.Mock(side_effect=side_effect)
    self.assertIsNone(self.task.CreateUserFieldValue(self.mr, 'ldap', 11))


class ConvertMLabels(unittest.TestCase):

  def setUp(self):
    self.target_id = 24
    self.approved_id = 27
    self.beta_phase = tracker_pb2.Phase(phase_id=1, name='bEtA')
    self.stable_phase = tracker_pb2.Phase(phase_id=2, name='StAbLe')
    self.stable_full_phase = tracker_pb2.Phase(phase_id=3, name='stable-FULL')
    self.stable_exp_phase = tracker_pb2.Phase(phase_id=4, name='STABLE-exp')
    self.feature_freeze_phase = tracker_pb2.Phase(
        phase_id=5, name='FEATURE Freeze')
    self.branch_phase = tracker_pb2.Phase(phase_id=6, name='bRANCH')

  def testConvertMLabels_NormalFinch(self):

    phases = [self.stable_exp_phase, self.beta_phase, self.stable_full_phase]
    labels = [
        'launch-m-approved-81-beta',  # beta:M-Approved=81
        'launch-m-target-80-stable-car',  # ignore
        'a-Launch-M-Target-80-Stable-car',  # ignore
        'launch-m-target-70-Stable',  # stable-full:M-Target=70
        'LAUNCH-M-TARGET-71-STABLE',  # stable-full:M-Target=71
        'launch-m-target-70-stable-exp',  # stable-exp:M-Target=70
        'launch-m-target-69-stable-exp',  # stable-exp:M-Target=69
        'launch-M-APPROVED-70-Stable-Exp',  # stable-exp:M-Approved-70
        'launch-m-approved-73-stable',  # stable-full:M-Approved-73
        'launch-m-error-73-stable',  # ignore
        'launch-m-approved-8-stable',  #ignore
        'irrelevant label-weird',  # ignore
    ]
    actual_fvs = fltconversion.ConvertMLabels(
        labels, phases, self.target_id, self.approved_id,
        fltconversion.BROWSER_M_LABELS_RE, fltconversion.BROWSER_PHASE_MAP)

    expected_fvs = [
      tracker_pb2.FieldValue(
          field_id=self.approved_id, int_value=81,
          phase_id=self.beta_phase.phase_id, derived=False,),
      tracker_pb2.FieldValue(
          field_id=self.target_id, int_value=70,
          phase_id=self.stable_full_phase.phase_id, derived=False),
      tracker_pb2.FieldValue(
          field_id=self.target_id, int_value=71,
          phase_id=self.stable_full_phase.phase_id, derived=False),
      tracker_pb2.FieldValue(
          field_id=self.target_id, int_value=70,
          phase_id=self.stable_exp_phase.phase_id, derived=False),
      tracker_pb2.FieldValue(
          field_id=self.target_id, int_value=69,
          phase_id=self.stable_exp_phase.phase_id, derived=False),
      tracker_pb2.FieldValue(
          field_id=self.approved_id, int_value=70,
          phase_id=self.stable_exp_phase.phase_id, derived=False),
      tracker_pb2.FieldValue(
          field_id=self.approved_id, int_value=73,
          phase_id=self.stable_full_phase.phase_id, derived=False)
    ]

    self.assertEqual(actual_fvs, expected_fvs)

  def testConvertMLabels_OS(self):
    phases = [self.feature_freeze_phase, self.branch_phase, self.stable_phase]
    labels = [
        'launch-m-approved-81-beta',  # ignore
        'launch-m-target-80-stable-car',  # ignore
        'a-Launch-M-Target-80-Stable-car',  # ignore
        'launch-m-target-70-Stable',  # stable:M-Target=70
        'LAUNCH-M-TARGET-71-STABLE',  # stable:M-Target=71
        'launch-m-target-70-stable-exp',  # ignore
        'launch-M-APPROVED-70-Stable-Exp',  # ignore
        'launch-m-approved-73-stable',  # stable:M-Approved-73
        'launch-m-error-73-stable',  # ignore
        'launch-m-approved-8-stable',  #ignore
        'irrelevant label-weird',  # ignore
        ]
    actual_fvs = fltconversion.ConvertMLabels(
        labels, phases, self.target_id, self.approved_id,
        fltconversion.OS_M_LABELS_RE, fltconversion.OS_PHASE_MAP)

    expected_fvs = [
      tracker_pb2.FieldValue(
          field_id=self.target_id, int_value=70,
          phase_id=self.stable_phase.phase_id, derived=False,),
      tracker_pb2.FieldValue(
          field_id=self.target_id, int_value=71,
          phase_id=self.stable_phase.phase_id, derived=False),
      tracker_pb2.FieldValue(
          field_id=self.approved_id, int_value=73,
          phase_id=self.stable_phase.phase_id, derived=False)
    ]

    self.assertEqual(actual_fvs, expected_fvs)


class ConvertLaunchLabels(unittest.TestCase):

  def setUp(self):
    self.project_fds = [
        tracker_pb2.FieldDef(
            field_id=1, project_id=789, field_name='String',
            field_type=tracker_pb2.FieldTypes.STR_TYPE),
        tracker_pb2.FieldDef(
            field_id=2, project_id=789, field_name='Chrome-UX',
            field_type=tracker_pb2.FieldTypes.APPROVAL_TYPE),
        tracker_pb2.FieldDef(
            field_id=3, project_id=789, field_name='Chrome-Privacy',
            field_type=tracker_pb2.FieldTypes.APPROVAL_TYPE)
        ]
    approvalUX = tracker_pb2.ApprovalValue(
        approval_id=2, status=tracker_pb2.ApprovalStatus.NEEDS_REVIEW)
    approvalPrivacy = tracker_pb2.ApprovalValue(approval_id=3)
    self.approvals = [approvalUX, approvalPrivacy]

  def testConvertLaunchLabels_Normal(self):
    labels = [
        'Launch-UX-NotReviewed', 'Launch-Privacy-Yes', 'Launch-NotRelevant']
    actual = fltconversion.ConvertLaunchLabels(
        labels, self.approvals, self.project_fds,
        fltconversion.BROWSER_APPROVALS_TO_LABELS)
    expected = [
      tracker_pb2.ApprovalValue(
          approval_id=2, status=tracker_pb2.ApprovalStatus.NEEDS_REVIEW),
      tracker_pb2.ApprovalValue(
          approval_id=3, status=tracker_pb2.ApprovalStatus.APPROVED)
    ]
    self.assertEqual(actual, expected)

  def testConvertLaunchLabels_ExtraAndMissingLabels(self):
    labels = [
        'Blah-Launch-Privacy-Yes',  # Missing, this is not a valid Label
        'Launch-Security-Yes',  # Extra, no matching approval in given approvals
        'Launch-UI-Yes']  # Missing Launch-Privacy
    actual = fltconversion.ConvertLaunchLabels(
        labels, self.approvals, self.project_fds,
        fltconversion.BROWSER_APPROVALS_TO_LABELS)
    expected = [
        tracker_pb2.ApprovalValue(
            approval_id=2, status=tracker_pb2.ApprovalStatus.APPROVED),
      tracker_pb2.ApprovalValue(
          approval_id=3, status=tracker_pb2.ApprovalStatus.NOT_SET)
        ]
    self.assertEqual(actual, expected)

class ExtractLabelLDAPs(unittest.TestCase):

  def testExtractLabelLDAPs_Normal(self):
    labels = [
        'tl-USER1',
        'pm-',
        'tL-User2',
        'test-user4',
        'PM-USER3',
        'pm',
        'test-user5',
        'test-',
        'ux-user9']
    (actual_pm, actual_tl, actual_tests,
     actual_ux) = fltconversion.ExtractLabelLDAPs(labels)
    self.assertEqual(actual_pm, 'user3')
    self.assertEqual(actual_tl, 'user2')
    self.assertEqual(actual_tests, ['user4', 'user5'])
    self.assertEqual(actual_ux, ['user9'])

  def testExtractLabelLDAPs_NoLabels(self):
    (actual_pm, actual_tl, actual_tests,
     actual_ux) = fltconversion.ExtractLabelLDAPs([])
    self.assertIsNone(actual_pm)
    self.assertIsNone(actual_tl)
    self.assertFalse(len(actual_tests))
    self.assertFalse(len(actual_ux))
