# 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.

"""Unittest for the template helpers module."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import logging
import six
import unittest

import settings

from services import service_manager
from testing import fake
from testing import testing_helpers
from tracker import template_helpers
from tracker import tracker_bizobj
from mrproto import tracker_pb2


class TemplateHelpers(unittest.TestCase):

  def setUp(self):
    self.services = service_manager.Services(
        user=fake.UserService(),
        config=fake.ConfigService(),
        project=fake.ProjectService(),
        usergroup=fake.UserGroupService())
    self.project = self.services.project.TestAddProject('proj')
    self.mr = testing_helpers.MakeMonorailRequest(
        project=self.project)
    self.config = self.services.config.GetProjectConfig(
        'fake cnxn', self.project.project_id)
    self.fd_1 =  tracker_bizobj.MakeFieldDef(
        1, 789, 'UXReview', tracker_pb2.FieldTypes.STR_TYPE, None,
        '', False, False, False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action',
        'Approval for UX review', False)
    self.fd_2 =  tracker_bizobj.MakeFieldDef(
        2, 789, 'UXReview', tracker_pb2.FieldTypes.STR_TYPE, None,
        '', False, False, False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action',
        'Approval for UX review', False)
    self.fd_3 = tracker_bizobj.MakeFieldDef(
        3, 789, 'UXApproval', tracker_pb2.FieldTypes.APPROVAL_TYPE, None,
        '', False, False, False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action',
        'Approval for UX review', False)
    self.fd_4 = tracker_bizobj.MakeFieldDef(
        4, 789, 'TestApproval', tracker_pb2.FieldTypes.APPROVAL_TYPE, None,
        '', False, False, False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action',
        'Approval for Test review', False)
    self.fd_5 = tracker_bizobj.MakeFieldDef(
        5, 789, 'SomeApproval', tracker_pb2.FieldTypes.APPROVAL_TYPE, None,
        '', False, False, False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action',
        'Approval for Test review', False)
    self.ad_3 = tracker_pb2.ApprovalDef(approval_id=3)
    self.ad_4 = tracker_pb2.ApprovalDef(approval_id=4)
    self.ad_5 = tracker_pb2.ApprovalDef(approval_id=5)
    self.cd_1 = tracker_bizobj.MakeComponentDef(
        1, 789, 'BackEnd', 'doc', False, [111], [], 100000, 222)

    self.services.user.TestAddUser('1@ex.com', 111)
    self.services.user.TestAddUser('2@ex.com', 222)
    self.services.user.TestAddUser('3@ex.com', 333)
    self.services.project.TestAddProjectMembers(
        [111], self.project, 'OWNER_ROLE')

  def testParseTemplateRequest_Empty(self):
    post_data = fake.PostData()
    parsed = template_helpers.ParseTemplateRequest(post_data, self.config)
    self.assertEqual(parsed.name, '')
    self.assertFalse(parsed.members_only)
    self.assertEqual(parsed.summary, '')
    self.assertFalse(parsed.summary_must_be_edited)
    self.assertEqual(parsed.content, '')
    self.assertEqual(parsed.status, '')
    self.assertEqual(parsed.owner_str, '')
    self.assertEqual(parsed.labels, [])
    self.assertEqual(parsed.field_val_strs, {})
    self.assertEqual(parsed.component_paths, [])
    self.assertFalse(parsed.component_required)
    self.assertFalse(parsed.owner_defaults_to_member)
    self.assertFalse(parsed.add_approvals)
    six.assertCountEqual(self, parsed.phase_names, ['', '', '', '', '', ''])
    self.assertEqual(parsed.approvals_to_phase_idx, {})
    self.assertEqual(parsed.required_approval_ids, [])

  def testParseTemplateRequest_Normal(self):
    self.config.field_defs.extend([self.fd_1, self.fd_2])
    self.config.approval_defs.extend([self.ad_3, self.ad_4])
    post_data = fake.PostData(
        name=['sometemplate'],
        members_only=['on'],
        summary=['TLDR'],
        summary_must_be_edited=['on'],
        content=['HEY WHY'],
        status=['Accepted'],
        owner=['someone@world.com'],
        label=['label-One', 'label-Two'],
        custom_1=['NO'],
        custom_2=['MOOD'],
        components=['hey, hey2,he3'],
        component_required=['on'],
        owner_defaults_to_memeber=['no'],
        admin_names=['jojwang@test.com, annajo@test.com'],
        add_approvals=['on'],
        phase_0=['Canary'],
        phase_1=['Stable-Exp'],
        phase_2=['Stable'],
        phase_3=[''],
        phase_4=[''],
        phase_5=['Oops'],
        approval_3=['phase_2'],
        approval_4=['no_phase'],
        approval_3_required=['on'],
        approval_4_required=['on'],
        # ignore required cb for omitted approvals
        approval_5_required=['on']
    )

    parsed = template_helpers.ParseTemplateRequest(post_data, self.config)
    self.assertEqual(parsed.name, 'sometemplate')
    self.assertTrue(parsed.members_only)
    self.assertEqual(parsed.summary, 'TLDR')
    self.assertTrue(parsed.summary_must_be_edited)
    self.assertEqual(parsed.content, 'HEY WHY')
    self.assertEqual(parsed.status, 'Accepted')
    self.assertEqual(parsed.owner_str, 'someone@world.com')
    self.assertEqual(parsed.labels, ['label-One', 'label-Two'])
    self.assertEqual(parsed.field_val_strs, {1: ['NO'], 2: ['MOOD']})
    self.assertEqual(parsed.component_paths, ['hey', 'hey2', 'he3'])
    self.assertTrue(parsed.component_required)
    self.assertFalse(parsed.owner_defaults_to_member)
    self.assertTrue(parsed.add_approvals)
    self.assertEqual(parsed.admin_str, 'jojwang@test.com, annajo@test.com')
    six.assertCountEqual(
        self, parsed.phase_names,
        ['Canary', 'Stable-Exp', 'Stable', '', '', 'Oops'])
    self.assertEqual(parsed.approvals_to_phase_idx, {3: 2, 4: None})
    six.assertCountEqual(self, parsed.required_approval_ids, [3, 4])

  def testGetTemplateInfoFromParsed_Normal(self):
    self.config.field_defs.extend([self.fd_1, self.fd_2])
    self.config.component_defs.append(self.cd_1)
    parsed = template_helpers.ParsedTemplate(
        'template', True, 'summary', True, 'content', 'Available',
        '1@ex.com', ['label1', 'label1'], {1: ['NO'], 2: ['MOOD']},
        ['BackEnd'], True, True, '2@ex.com', False, [], {}, [])
    (admin_ids, owner_id, component_ids,
     field_values, phases,
     approval_values) = template_helpers.GetTemplateInfoFromParsed(
        self.mr, self.services, parsed, self.config)
    self.assertEqual(admin_ids, [222])
    self.assertEqual(owner_id, 111)
    self.assertEqual(component_ids, [1])
    self.assertEqual(field_values[0].str_value, 'NO')
    self.assertEqual(field_values[1].str_value, 'MOOD')
    self.assertEqual(phases, [])
    self.assertEqual(approval_values, [])

  def testGetTemplateInfoFromParsed_Errors(self):
    self.config.field_defs.extend([self.fd_1, self.fd_2])
    parsed = template_helpers.ParsedTemplate(
        'template', True, 'summary', True, 'content', 'Available',
        '4@ex.com', ['label1', 'label1'], {1: ['NO'], 2: ['MOOD']},
        ['BackEnd'], True, True, '2@ex.com', False, [], {}, [])
    (admin_ids, _owner_id, _component_ids,
     field_values, phases,
     approval_values) = template_helpers.GetTemplateInfoFromParsed(
        self.mr, self.services, parsed, self.config)
    self.assertEqual(admin_ids, [222])
    self.assertEqual(field_values[0].str_value, 'NO')
    self.assertEqual(field_values[1].str_value, 'MOOD')
    self.assertEqual(self.mr.errors.owner, 'Owner not found.')
    self.assertEqual(self.mr.errors.components, 'Unknown component BackEnd')
    self.assertEqual(phases, [])
    self.assertEqual(approval_values, [])

  def testGetPhasesAndApprovalsFromParsed_Normal(self):
    self.config.field_defs.extend([self.fd_1, self.fd_2])
    self.config.approval_defs.extend([self.ad_3, self.ad_4, self.ad_5])

    phase_names = ['Canary', '', 'Stable-Exp', '', '', '']
    approvals_to_phase_idx = {3: 0, 4: None, 5: 2}
    required_approval_ids = [3, 5]

    phases, approval_values = template_helpers._GetPhasesAndApprovalsFromParsed(
        self.mr, phase_names, approvals_to_phase_idx, required_approval_ids)
    self.assertEqual(len(phases), 2)
    self.assertEqual(len(approval_values), 3)

    canary = tracker_bizobj.FindPhase('canary', phases)
    self.assertEqual(canary.rank, 0)
    av_3 = tracker_bizobj.FindApprovalValueByID(3, approval_values)
    self.assertEqual(av_3.status, tracker_pb2.ApprovalStatus.NEEDS_REVIEW)
    self.assertEqual(av_3.phase_id, canary.phase_id)

    av_4 = tracker_bizobj.FindApprovalValueByID(4, approval_values)
    self.assertEqual(av_4.status, tracker_pb2.ApprovalStatus.NOT_SET)
    self.assertIsNone(av_4.phase_id)

    stable_exp = tracker_bizobj.FindPhase('stable-exp', phases)
    self.assertEqual(stable_exp.rank, 2)
    av_5 = tracker_bizobj.FindApprovalValueByID(5, approval_values)
    self.assertEqual(av_5.status, tracker_pb2.ApprovalStatus.NEEDS_REVIEW)
    self.assertEqual(av_5.phase_id, stable_exp.phase_id)

    self.assertIsNone(self.mr.errors.phase_approvals)

  def testGetPhasesAndApprovalsFromParsed_Errors(self):
    self.config.field_defs.extend([self.fd_1, self.fd_2])
    self.config.approval_defs.extend([self.ad_3, self.ad_4, self.ad_5])
    required_approval_ids = []

    phase_names = ['Canary', 'Extra', 'Stable-Exp', '', '', '']
    approvals_to_phase_idx = {3: 0, 4: None, 5: 2}

    template_helpers._GetPhasesAndApprovalsFromParsed(
        self.mr, phase_names, approvals_to_phase_idx, required_approval_ids)
    self.assertEqual(self.mr.errors.phase_approvals,
                     'Defined gates must have assigned approvals.')

  def testGetPhasesAndApprovalsFromParsed_DupsErrors(self):
    self.config.field_defs.extend([self.fd_1, self.fd_2])
    self.config.approval_defs.extend([self.ad_3, self.ad_4, self.ad_5])
    required_approval_ids = []

    phase_names = ['Canary', 'canary', 'Stable-Exp', '', '', '']
    approvals_to_phase_idx = {3: 0, 4: None, 5: 2}

    template_helpers._GetPhasesAndApprovalsFromParsed(
        self.mr, phase_names, approvals_to_phase_idx, required_approval_ids)
    self.assertEqual(self.mr.errors.phase_approvals,
                     'Duplicate gate names.')

  def testGetPhasesAndApprovalsFromParsed_InvalidPhaseName(self):
    self.config.field_defs.extend([self.fd_1, self.fd_2])
    self.config.approval_defs.extend([self.ad_3, self.ad_4, self.ad_5])
    required_approval_ids = []

    phase_names = ['Canary', 'A B', 'Stable-Exp', '', '', '']
    approvals_to_phase_idx = {3: 0, 4: None, 5: 2}

    template_helpers._GetPhasesAndApprovalsFromParsed(
        self.mr, phase_names, approvals_to_phase_idx, required_approval_ids)
    self.assertEqual(self.mr.errors.phase_approvals,
                     'Invalid gate name(s).')

  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)
    six.assertCountEqual(self, 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)

  def testGetCheckedApprovalsFromParsed(self):
    approvals_to_phase_idx = {23: 0, 25: 1, 26: None}
    checked = template_helpers.GetCheckedApprovalsFromParsed(
        approvals_to_phase_idx)
    six.assertCountEqual(self, checked, ['23_phase_0', '25_phase_1', '26'])

  def testGetIssueFromTemplate(self):
    """Can fill and return the templated issue"""
    expected_fvs = [
        tracker_pb2.FieldValue(field_id=123, str_value='fv_1_value'),
        tracker_pb2.FieldValue(field_id=124, str_value='fv_2_value'),
    ]
    expected_phases = [
        tracker_pb2.Phase(phase_id=123, name='phase_1_name', rank=1)
    ]
    expected_avs = [
        tracker_pb2.ApprovalValue(
            approval_id=1,
            setter_id=111,
            set_on=1232352,
            approver_ids=[111],
            phase_id=123),
    ]
    input_template = tracker_pb2.TemplateDef(
        summary='expected_summary',
        owner_id=111,
        status='expected_status',
        labels=['expected-label_1, expected-label_2'],
        field_values=expected_fvs,
        component_ids=[987],
        phases=expected_phases,
        approval_values=expected_avs)
    reporter_id = 321
    project_id = 1

    actual = template_helpers.GetIssueFromTemplate(
        input_template, project_id, reporter_id)
    expected = tracker_pb2.Issue(
        project_id=project_id,
        summary='expected_summary',
        status='expected_status',
        owner_id=111,
        labels=['expected-label_1, expected-label_2'],
        component_ids=[987],
        reporter_id=reporter_id,
        field_values=expected_fvs,
        phases=expected_phases,
        approval_values=expected_avs)
    self.assertEqual(actual, expected)

  def testGetIssueFromTemplate_NoOwner(self):
    """Uses reporter as owner when owner_defaults_to_member"""
    input_template = tracker_pb2.TemplateDef(owner_defaults_to_member=False)

    actual = template_helpers.GetIssueFromTemplate(input_template, 1, 1)
    self.assertEqual(actual.owner_id, None)

  def testGetIssueFromTemplate_DefaultsOwnerToReporter(self):
    """Uses reporter as owner when owner_defaults_to_member"""
    input_template = tracker_pb2.TemplateDef(owner_defaults_to_member=True)
    reporter_id = 321

    actual = template_helpers.GetIssueFromTemplate(
        input_template, 1, reporter_id)
    self.assertEqual(actual.owner_id, reporter_id)

  def testGetIssueFromTemplate_SpecifiedOwnerOverridesReporter(self):
    """Specified owner overrides owner_defaults_to_member"""
    expected_owner_id = 111
    input_template = tracker_pb2.TemplateDef(
        owner_id=expected_owner_id, owner_defaults_to_member=True)
    reporter_id = 321

    actual = template_helpers.GetIssueFromTemplate(
        input_template, 1, reporter_id)
    self.assertEqual(actual.owner_id, expected_owner_id)
