# 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 fielddetail 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 unittest
import logging

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


class FieldDetailTest(unittest.TestCase):

  def setUp(self):
    self.services = service_manager.Services(
        user=fake.UserService(),
        config=fake.ConfigService(),
        project=fake.ProjectService())
    self.servlet = fielddetail.FieldDetail(services=self.services)
    self.project = self.services.project.TestAddProject('proj')
    self.mr = testing_helpers.MakeMonorailRequest(
        project=self.project, perms=permissions.OWNER_ACTIVE_PERMISSIONSET)
    self.config = self.services.config.GetProjectConfig(
        'fake cnxn', self.project.project_id)
    self.services.config.StoreConfig('fake cnxn', self.config)
    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.fd.admin_ids = [111]
    self.fd.editor_ids = [222]
    self.config.field_defs.append(self.fd)
    self.services.user.TestAddUser('gatsby@example.com', 111)
    self.services.user.TestAddUser('sport@example.com', 222)
    self.mr.field_name = 'CPU'

    # Approvals
    self.approval_def = tracker_pb2.ApprovalDef(
        approval_id=234, approver_ids=[111], survey='Question 1?')
    self.sub_fd = tracker_pb2.FieldDef(
        field_name='UIMocks', approval_id=234, applicable_type='')
    self.sub_fd_deleted = tracker_pb2.FieldDef(
        field_name='UIMocksDeleted', approval_id=234, applicable_type='',
        is_deleted=True)
    self.config.field_defs.extend([self.sub_fd, self.sub_fd_deleted])
    self.config.approval_defs.append(self.approval_def)
    self.approval_fd = tracker_bizobj.MakeFieldDef(
        234, 789, 'UIReview', tracker_pb2.FieldTypes.APPROVAL_TYPE, None,
        '', False, False, False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
    self.config.field_defs.append(self.approval_fd)

    self.mox = mox.Mox()

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

  def testGetFieldDef_NotFound(self):
    self.mr.field_name = 'NeverHeardOfIt'
    self.assertRaises(Exception, self.servlet._GetFieldDef, self.mr)

  def testGetFieldDef_Normal(self):
    actual_config, actual_fd = self.servlet._GetFieldDef(self.mr)
    self.assertEqual(self.config, actual_config)
    self.assertEqual(self.fd, actual_fd)

  def testAssertBasePermission_AnyoneCanView(self):
    self.servlet.AssertBasePermission(self.mr)
    self.mr.perms = permissions.COMMITTER_ACTIVE_PERMISSIONSET
    self.servlet.AssertBasePermission(self.mr)
    self.mr.perms = permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET
    self.servlet.AssertBasePermission(self.mr)
    self.mr.perms = permissions.READ_ONLY_PERMISSIONSET
    self.servlet.AssertBasePermission(self.mr)

  def testAssertBasePermission_MembersOnly(self):
    self.project.access = project_pb2.ProjectAccess.MEMBERS_ONLY
    # The project members can view the field definition.
    self.servlet.AssertBasePermission(self.mr)
    self.mr.perms = permissions.COMMITTER_ACTIVE_PERMISSIONSET
    self.servlet.AssertBasePermission(self.mr)
    self.mr.perms = permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET
    self.servlet.AssertBasePermission(self.mr)
    # Non-member is not allowed to view anything in the project.
    self.mr.perms = permissions.EMPTY_PERMISSIONSET
    self.assertRaises(
        permissions.PermissionException,
        self.servlet.AssertBasePermission, self.mr)

  def testGatherPageData_ReadWrite(self):
    page_data = self.servlet.GatherPageData(self.mr)
    self.assertEqual(self.servlet.PROCESS_TAB_LABELS,
                     page_data['admin_tab_mode'])
    self.assertTrue(page_data['allow_edit'])
    self.assertEqual('gatsby@example.com', page_data['initial_admins'])
    self.assertEqual('sport@example.com', page_data['initial_editors'])
    field_def_view = page_data['field_def']
    self.assertEqual('CPU', field_def_view.field_name)
    self.assertEqual(page_data['approval_subfields'], [])
    self.assertEqual(page_data['initial_approvers'], '')

  def testGatherPageData_ReadOnly(self):
    self.mr.perms = permissions.READ_ONLY_PERMISSIONSET
    page_data = self.servlet.GatherPageData(self.mr)
    self.assertEqual(self.servlet.PROCESS_TAB_LABELS,
                     page_data['admin_tab_mode'])
    self.assertFalse(page_data['allow_edit'])
    self.assertEqual('gatsby@example.com', page_data['initial_admins'])
    self.assertEqual('sport@example.com', page_data['initial_editors'])
    field_def_view = page_data['field_def']
    self.assertEqual('CPU', field_def_view.field_name)
    self.assertEqual(page_data['approval_subfields'], [])
    self.assertEqual(page_data['initial_approvers'], '')

  def testGatherPageData_Approval(self):
    self.mr.field_name = 'UIReview'
    page_data = self.servlet.GatherPageData(self.mr)
    self.assertEqual(page_data['approval_subfields'], [self.sub_fd])
    self.assertEqual(page_data['initial_approvers'], 'gatsby@example.com')
    field_def_view = page_data['field_def']
    self.assertEqual(field_def_view.field_name, 'UIReview')
    self.assertEqual(field_def_view.survey, 'Question 1?')

  def testProcessFormData_Permission(self):
    """Only owners can edit fields."""
    mr = testing_helpers.MakeMonorailRequest(
        project=self.project,
        perms=permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET)
    mr.field_name = 'CPU'
    post_data = fake.PostData(
        name=['CPU'],
        deletefield=['Submit'])
    self.assertRaises(permissions.PermissionException,
                      self.servlet.ProcessFormData, mr, post_data)

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

  def testProcessFormData_Delete(self):
    post_data = fake.PostData(
        name=['CPU'],
        deletefield=['Submit'])
    url = self.servlet.ProcessFormData(self.mr, post_data)
    self.assertTrue('/adminLabels?deleted=1&' in url)
    fd = tracker_bizobj.FindFieldDef('CPU', self.config)
    self.assertEqual('CPU', fd.field_name)
    self.assertTrue(fd.is_deleted)

  def testProcessFormData_Cancel(self):
    post_data = fake.PostData(
        name=['CPU'],
        cancel=['Submit'],
        max_value=['200'])
    url = self.servlet.ProcessFormData(self.mr, post_data)
    logging.info(url)
    self.assertTrue('/adminLabels?ts=' in url)
    config = self.services.config.GetProjectConfig(
        self.mr.cnxn, self.mr.project_id)

    fd = tracker_bizobj.FindFieldDef('CPU', config)
    self.assertIsNone(fd.max_value)
    self.assertIsNone(fd.min_value)

  def testProcessFormData_Edit(self):
    post_data = fake.PostData(
        name=['CPU'],
        field_type=['INT_TYPE'],
        min_value=['2'],
        max_value=['98'],
        notify_on=['never'],
        is_required=[],
        is_multivalued=[],
        docstring=['It is just some field'],
        applicable_type=['Defect'],
        admin_names=['gatsby@example.com'])
    url = self.servlet.ProcessFormData(self.mr, post_data)
    self.assertTrue('/fields/detail?field=CPU&saved=1&' in url)
    config = self.services.config.GetProjectConfig(
        self.mr.cnxn, self.mr.project_id)

    fd = tracker_bizobj.FindFieldDef('CPU', config)
    self.assertEqual('CPU', fd.field_name)
    self.assertEqual(2, fd.min_value)
    self.assertEqual(98, fd.max_value)
    self.assertEqual([111], fd.admin_ids)
    self.assertEqual([], fd.editor_ids)

  def testProcessDeleteField(self):
    self.servlet._ProcessDeleteField(self.mr, self.config, self.fd)
    self.assertTrue(self.fd.is_deleted)

  def testProcessDeleteField_subfields(self):
    approval_fd = tracker_bizobj.MakeFieldDef(
        3, 789, 'Legal', tracker_pb2.FieldTypes.APPROVAL_TYPE, None,
        '', False, False, False, None, None, '', False, '', '',
        tracker_pb2.NotifyTriggers.NEVER, 'no_action', 'doc', False)
    self.fd.approval_id=3
    self.config.field_defs.append(approval_fd)
    self.servlet._ProcessDeleteField(self.mr, self.config, approval_fd)
    self.assertTrue(self.fd.is_deleted)
    self.assertTrue(approval_fd.is_deleted)

  def testProcessEditField_Normal(self):
    post_data = fake.PostData(
        name=['CPU'],
        field_type=['INT_TYPE'],
        min_value=['2'],
        admin_names=['gatsby@example.com'],
        editor_names=['sport@example.com'],
        is_restricted_field=['Yes'])
    self.servlet._ProcessEditField(
        self.mr, post_data, self.config, self.fd)
    fd = tracker_bizobj.FindFieldDef('CPU', self.config)
    self.assertEqual('CPU', fd.field_name)
    self.assertEqual(2, fd.min_value)
    self.assertEqual([111], fd.admin_ids)
    self.assertEqual([222], fd.editor_ids)

  def testProcessEditField_Reject(self):
    post_data = fake.PostData(
        name=['CPU'],
        field_type=['INT_TYPE'],
        min_value=['4'],
        max_value=['1'],
        admin_names=[''],
        editor_names=[''])

    self.mox.StubOutWithMock(self.servlet, 'PleaseCorrect')
    self.servlet.PleaseCorrect(
        self.mr,
        field_def=mox.IgnoreArg(),
        initial_applicable_type='',
        initial_choices='',
        initial_admins='',
        initial_editors='',
        initial_approvers='',
        initial_is_restricted_field=False)
    self.mox.ReplayAll()

    url = self.servlet._ProcessEditField(
        self.mr, post_data, self.config, self.fd)
    self.assertEqual('Minimum value must be less than maximum.',
                     self.mr.errors.min_value)
    self.assertIsNone(url)

    fd = tracker_bizobj.FindFieldDef('CPU', self.config)
    self.assertIsNone(fd.min_value)
    self.assertIsNone(fd.max_value)

  def testProcessEditField_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=['CPU'],
        field_type=['INT_TYPE'],
        min_value=['2'],
        admin_names=[''],
        editor_names=['gatsby@example.com'])

    self.assertRaises(
        AssertionError, self.servlet._ProcessEditField, self.mr, post_data,
        self.config, self.fd)

  def testProcessEditField_RejectAssertions_1(self):
    # This method tests that an exception is raised
    # when trying to add editors to an approval field.
    post_data = fake.PostData(
        name=['CPU'],
        approver_names=['gatsby@example.com'],
        admin_names=[''],
        editor_names=['sports@example.com'])

    self.assertRaises(
        AssertionError, self.servlet._ProcessEditField, self.mr, post_data,
        self.config, self.approval_fd)

  def testProcessEditField_RejectAssertions_2(self):
    #This method tests that an exception is raised
    #when trying to restrict an approval field.
    post_data = fake.PostData(
        name=['CPU'],
        approver_names=['gatsby@example.com'],
        is_restricted_field=['Yes'],
        admin_names=[''],
        editor_names=[''])

    self.assertRaises(
        AssertionError, self.servlet._ProcessEditField, self.mr, post_data,
        self.config, self.approval_fd)

  def testProcessEditField_RejectApproval(self):
    self.mr.field_name = 'UIReview'
    post_data = fake.PostData(
        name=['UIReview'],
        admin_names=[''],
        editor_names=[''],
        survey=['WIll there be UI changes?'],
        approver_names=[''])

    self.mox.StubOutWithMock(self.servlet, 'PleaseCorrect')
    self.servlet.PleaseCorrect(
        self.mr,
        field_def=mox.IgnoreArg(),
        initial_applicable_type='',
        initial_choices='',
        initial_admins='',
        initial_editors='',
        initial_approvers='',
        initial_is_restricted_field=False)
    self.mox.ReplayAll()

    url = self.servlet._ProcessEditField(
        self.mr, post_data, self.config, self.approval_fd)
    self.assertEqual('Please provide at least one default approver.',
                     self.mr.errors.approvers)
    self.assertIsNone(url)

  def testProcessEditField_Approval(self):
    self.mr.field_name = 'UIReview'
    post_data = fake.PostData(
        name=['UIReview'],
        admin_names=[''],
        editor_names=[''],
        survey=['WIll there be UI changes?'],
        approver_names=['sport@example.com, gatsby@example.com'])


    url = self.servlet._ProcessEditField(
        self.mr, post_data, self.config, self.approval_fd)
    self.assertTrue('/fields/detail?field=UIReview&saved=1&' in url)

    approval_def = tracker_bizobj.FindApprovalDef('UIReview', self.config)
    self.assertEqual(len(approval_def.approver_ids), 2)
    self.assertEqual(sorted(approval_def.approver_ids), sorted([111, 222]))
