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

"""Unit tests for the fieldcreate servlet."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

try:
  from mox3 import mox
except ImportError:
  import mox
import mock
import six
import unittest
import logging

import ezt

from framework import permissions
from mrproto import tracker_pb2
from services import service_manager
from testing import fake
from testing import testing_helpers
from tracker import fieldcreate
from tracker import tracker_bizobj


class FieldCreateTest(unittest.TestCase):

  def setUp(self):
    self.cnxn = 'fake cnxn'
    self.services = service_manager.Services(
        user=fake.UserService(),
        config=fake.ConfigService(),
        project=fake.ProjectService())
    self.servlet = fieldcreate.FieldCreate(services=self.services)
    self.project = self.services.project.TestAddProject('proj')
    self.mr = testing_helpers.MakeMonorailRequest(
        project=self.project, perms=permissions.OWNER_ACTIVE_PERMISSIONSET)
    self.services.user.TestAddUser('gatsby@example.com', 111)
    self.services.user.TestAddUser('sport@example.com', 222)

    self.mox = mox.Mox()

  def tearDown(self):
    self.mox.UnsetStubs()
    self.mox.ResetAll()

  def testAssertBasePermission(self):
    # Anon users can never do it
    self.mr.perms = permissions.READ_ONLY_PERMISSIONSET
    self.assertRaises(
        permissions.PermissionException,
        self.servlet.AssertBasePermission, self.mr)

    # Project owner can do it.
    self.mr.perms = permissions.OWNER_ACTIVE_PERMISSIONSET
    self.servlet.AssertBasePermission(self.mr)

    # Project member cannot do it
    self.mr.perms = permissions.COMMITTER_ACTIVE_PERMISSIONSET
    self.assertRaises(
        permissions.PermissionException,
        self.servlet.AssertBasePermission, self.mr)
    self.mr.perms = permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET
    self.assertRaises(
        permissions.PermissionException,
        self.servlet.AssertBasePermission, self.mr)

  def testGatherPageData(self):
    approval_fd = tracker_bizobj.MakeFieldDef(
        1, self.mr.project_id, 'LaunchApproval',
        tracker_pb2.FieldTypes.APPROVAL_TYPE, None, '', False,
        False, False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action',
        'some approval thing', False)
    config = self.services.config.GetProjectConfig(
        self.mr.cnxn, self.mr.project_id)
    config.field_defs.append(approval_fd)
    self.services.config.StoreConfig(self.cnxn, config)
    page_data = self.servlet.GatherPageData(self.mr)
    self.assertEqual(self.servlet.PROCESS_TAB_LABELS,
                     page_data['admin_tab_mode'])
    six.assertCountEqual(
        self, ['Defect', 'Enhancement', 'Task', 'Other'],
        page_data['well_known_issue_types'])
    self.assertEqual(['LaunchApproval'], page_data['approval_names'])
    self.assertEqual('', page_data['initial_admins'])
    self.assertEqual('', page_data['initial_editors'])
    self.assertIsNone(page_data['initial_is_restricted_field'])

  def testProcessFormData(self):
    post_data = fake.PostData(
        name=['somefield'],
        field_type=['INT_TYPE'],
        min_value=['1'],
        max_value=['99'],
        notify_on=['any_comment'],
        importance=['required'],
        is_multivalued=['Yes'],
        docstring=['It is just some field'],
        applicable_type=['Defect'],
        date_action=['no_action'],
        admin_names=['gatsby@example.com'],
        editor_names=['sport@example.com'],
        is_restricted_field=['Yes'])
    url = self.servlet.ProcessFormData(self.mr, post_data)
    self.assertTrue('/adminLabels?saved=1&' in url)
    config = self.services.config.GetProjectConfig(
        self.mr.cnxn, self.mr.project_id)

    fd = tracker_bizobj.FindFieldDef('somefield', config)
    self.assertEqual('somefield', fd.field_name)
    self.assertEqual(tracker_pb2.FieldTypes.INT_TYPE, fd.field_type)
    self.assertEqual(1, fd.min_value)
    self.assertEqual(99, fd.max_value)
    self.assertEqual(tracker_pb2.NotifyTriggers.ANY_COMMENT, fd.notify_on)
    self.assertTrue(fd.is_required)
    self.assertFalse(fd.is_niche)
    self.assertTrue(fd.is_multivalued)
    self.assertEqual('It is just some field', fd.docstring)
    self.assertEqual('Defect', fd.applicable_type)
    self.assertEqual('', fd.applicable_predicate)
    self.assertEqual([111], fd.admin_ids)
    self.assertEqual([222], fd.editor_ids)

  def testProcessFormData_Reject_EditorsForNonRestrictedField(self):
    # This method tests that an exception is raised
    # when trying to add editors to a non restricted field.
    post_data = fake.PostData(
        name=['somefield'],
        field_type=['INT_TYPE'],
        min_value=['1'],
        max_value=['99'],
        notify_on=['any_comment'],
        importance=['required'],
        is_multivalued=['Yes'],
        docstring=['It is just some field'],
        applicable_type=['Defect'],
        date_action=['no_action'],
        admin_names=['gatsby@example.com'],
        editor_names=['sport@example.com'])

    self.assertRaises(
        AssertionError, self.servlet.ProcessFormData, self.mr, post_data)

  def testProcessFormData_Reject_EditorsForApprovalField(self):
    #This method tests that an exception is raised
    #when trying to add editors to an approval field.
    post_data = fake.PostData(
        name=['approval_field'],
        field_type=['approval_type'],
        notify_on=['any_comment'],
        importance=['required'],
        is_multivalued=['Yes'],
        docstring=['It is just some field'],
        applicable_type=['Defect'],
        date_action=['no_action'],
        approver_names=['gatsby@example.com'],
        is_restricted_field=['Yes'],
        admin_names=['gatsby@example.com'],
        editor_names=[''])

    self.assertRaises(
        AssertionError, self.servlet.ProcessFormData, self.mr, post_data)

  @mock.patch('framework.servlet.Servlet.PleaseCorrect')
  def testProcessFormData_RejectAssertions(self, fake_servlet_pc):
    #This method tests when errors are found using when the
    #field_helpers.ParsedFieldDefAssertions is triggered.
    post_data = fake.PostData(
        name=['somefield'],
        field_type=['INT_TYPE'],
        min_value=['1'],
        max_value=['99'],
        notify_on=['any_comment'],
        importance=['required'],
        is_multivalued=['Yes'],
        docstring=['It is just some field'],
        applicable_type=['Defect'],
        date_action=['wrong_date_action'],
        admin_names=['gatsby@example.com'],
        editor_names=[''])

    self.servlet.ProcessFormData(self.mr, post_data)

    fake_servlet_pc.assert_called_once_with(
        self.mr,
        initial_field_name='somefield',
        initial_type='INT_TYPE',
        initial_parent_approval_name='',
        initial_field_docstring='It is just some field',
        initial_applicable_type='Defect',
        initial_applicable_predicate='',
        initial_needs_member=None,
        initial_needs_perm='',
        initial_importance='required',
        initial_is_multivalued='yes',
        initial_grants_perm='',
        initial_notify_on=1,
        initial_date_action='wrong_date_action',
        initial_choices='',
        initial_approvers='',
        initial_survey='',
        initial_is_phase_field=False,
        initial_admins='gatsby@example.com',
        initial_editors='',
        initial_is_restricted_field=False)
    self.assertTrue(self.mr.errors.AnyErrors())


  def testProcessFormData_RejectNoApprover(self):
    post_data = fake.PostData(
        name=['approvalField'],
        field_type=['approval_type'],
        approver_names=[''],
        admin_names=[''],
        editor_names=[''],
        parent_approval_name=['UIApproval'],
        is_phase_field=['on'])

    self.mox.StubOutWithMock(self.servlet, 'PleaseCorrect')
    self.servlet.PleaseCorrect(
        self.mr,
        initial_field_name=post_data.get('name'),
        initial_type=post_data.get('field_type'),
        initial_field_docstring=post_data.get('docstring', ''),
        initial_applicable_type=post_data.get('applical_type', ''),
        initial_applicable_predicate='',
        initial_needs_member=ezt.boolean('needs_member' in post_data),
        initial_needs_perm=post_data.get('needs_perm', '').strip(),
        initial_importance=post_data.get('importance'),
        initial_is_multivalued=ezt.boolean('is_multivalued' in post_data),
        initial_grants_perm=post_data.get('grants_perm', '').strip(),
        initial_notify_on=0,
        initial_date_action=post_data.get('date_action'),
        initial_choices=post_data.get('choices', ''),
        initial_approvers=post_data.get('approver_names'),
        initial_parent_approval_name=post_data.get('parent_approval_name', ''),
        initial_survey=post_data.get('survey', ''),
        initial_is_phase_field=False,
        initial_admins=post_data.get('admin_names'),
        initial_editors=post_data.get('editor_names'),
        initial_is_restricted_field=False)
    self.mox.ReplayAll()
    url = self.servlet.ProcessFormData(self.mr, post_data)
    self.mox.VerifyAll()
    self.assertEqual(
        'Please provide at least one default approver.',
        self.mr.errors.approvers)
    self.assertIsNone(url)


class FieldCreateMethodsTest(unittest.TestCase):

  def setUp(self):
    self.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)

  def testFieldNameErrorMessage_NoConflict(self):
    self.assertIsNone(fieldcreate.FieldNameErrorMessage(
        'somefield', self.config))

  def testFieldNameErrorMessage_PrefixReserved(self):
    self.assertEqual(
        'That name is reserved.',
        fieldcreate.FieldNameErrorMessage('owner', self.config))

  def testFieldNameErrorMessage_SuffixReserved(self):
    self.assertEqual(
        'That suffix is reserved.',
        fieldcreate.FieldNameErrorMessage('doh-approver', self.config))

  def testFieldNameErrorMessage_AlreadyInUse(self):
    fd = tracker_bizobj.MakeFieldDef(
        123, 789, 'CPU', tracker_pb2.FieldTypes.INT_TYPE, None,
        '', False, False, False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
    self.config.field_defs.append(fd)
    self.assertEqual(
        'That name is already in use.',
        fieldcreate.FieldNameErrorMessage('CPU', self.config))

  def testFieldNameErrorMessage_PrefixOfExisting(self):
    fd = tracker_bizobj.MakeFieldDef(
        123, 789, 'sign-off', tracker_pb2.FieldTypes.INT_TYPE, None,
        '', False, False, False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
    self.config.field_defs.append(fd)
    self.assertEqual(
        'That name is a prefix of an existing field name.',
        fieldcreate.FieldNameErrorMessage('sign', self.config))

  def testFieldNameErrorMessage_IncludesExisting(self):
    fd = tracker_bizobj.MakeFieldDef(
        123, 789, 'opt', tracker_pb2.FieldTypes.INT_TYPE, None,
        '', False, False, False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
    self.config.field_defs.append(fd)
    self.assertEqual(
        'An existing field name is a prefix of that name.',
        fieldcreate.FieldNameErrorMessage('opt-in', self.config))
