# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd

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

import unittest

from mock import Mock, patch

try:
  from mox3 import mox
except ImportError:
  import mox

from features import filterrules_helpers
from framework import permissions
from proto import project_pb2
from services import service_manager
from services import template_svc
from testing import fake
from testing import testing_helpers
from tracker import componentdetail
from tracker import tracker_bizobj

import webapp2


class ComponentDetailTest(unittest.TestCase):

  def setUp(self):
    self.services = service_manager.Services(
        user=fake.UserService(),
        issue=fake.IssueService(),
        config=fake.ConfigService(),
        template=Mock(spec=template_svc.TemplateService),
        project=fake.ProjectService())
    self.servlet = componentdetail.ComponentDetail(
        'req', 'res', services=self.services)
    self.project = self.services.project.TestAddProject('proj')
    self.mr = testing_helpers.MakeMonorailRequest(
        project=self.project, perms=permissions.OWNER_ACTIVE_PERMISSIONSET)
    self.mr.auth.email = 'b@example.com'
    self.config = self.services.config.GetProjectConfig(
        'fake cnxn', self.project.project_id)
    self.services.config.StoreConfig('fake cnxn', self.config)
    self.cd = tracker_bizobj.MakeComponentDef(
        1, self.project.project_id, 'BackEnd', 'doc', False, [], [111], 100000,
        122, 10000000, 133)
    self.config.component_defs = [self.cd]
    self.services.user.TestAddUser('a@example.com', 111)
    self.services.user.TestAddUser('b@example.com', 122)
    self.services.user.TestAddUser('c@example.com', 133)
    self.mr.component_path = 'BackEnd'

    self.mox = mox.Mox()

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

  def testGetComponentDef_NotFound(self):
    self.mr.component_path = 'NeverHeardOfIt'
    self.assertRaises(
        webapp2.HTTPException,
        self.servlet._GetComponentDef, self.mr)

  def testGetComponentDef_Normal(self):
    actual_config, actual_cd = self.servlet._GetComponentDef(self.mr)
    self.assertEqual(self.config, actual_config)
    self.assertEqual(self.cd, actual_cd)

  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 component 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_COMPONENTS,
                     page_data['admin_tab_mode'])
    self.assertTrue(page_data['allow_edit'])
    self.assertEqual([], page_data['initial_admins'])
    component_def_view = page_data['component_def']
    self.assertEqual('BackEnd', component_def_view.path)

  def testGatherPageData_ReadOnly(self):
    self.mr.perms = permissions.READ_ONLY_PERMISSIONSET
    page_data = self.servlet.GatherPageData(self.mr)
    self.assertEqual(self.servlet.PROCESS_TAB_COMPONENTS,
                     page_data['admin_tab_mode'])
    self.assertFalse(page_data['allow_edit'])
    self.assertFalse(page_data['allow_delete'])
    self.assertEqual([], page_data['initial_admins'])
    component_def_view = page_data['component_def']
    self.assertEqual('BackEnd', component_def_view.path)

  def testGatherPageData_ObscuredCreatorModifier(self):
    page_data = self.servlet.GatherPageData(self.mr)

    self.assertEqual('b...@example.com', page_data['creator'].display_name)
    self.assertEqual('/u/122/', page_data['creator'].profile_url)
    self.assertEqual('Jan 1970', page_data['created'])
    self.assertEqual('c...@example.com', page_data['modifier'].display_name)
    self.assertEqual('/u/133/', page_data['modifier'].profile_url)
    self.assertEqual('Apr 1970', page_data['modified'])

  def testGatherPageData_VisibleCreatorModifierForAdmin(self):
    self.mr.auth.user_pb.is_site_admin = True
    page_data = self.servlet.GatherPageData(self.mr)

    self.assertEqual('b@example.com', page_data['creator'].display_name)
    self.assertEqual('/u/b@example.com/', page_data['creator'].profile_url)
    self.assertEqual('Jan 1970', page_data['created'])
    self.assertEqual('c@example.com', page_data['modifier'].display_name)
    self.assertEqual('/u/c@example.com/', page_data['modifier'].profile_url)
    self.assertEqual('Apr 1970', page_data['modified'])

  def testGatherPageData_VisibleCreatorForSelf(self):
    self.mr.auth.user_id = 122
    page_data = self.servlet.GatherPageData(self.mr)

    self.assertEqual('b@example.com', page_data['creator'].display_name)
    self.assertEqual('/u/b@example.com/', page_data['creator'].profile_url)
    self.assertEqual('Jan 1970', page_data['created'])
    # Modifier should still be obscured.
    self.assertEqual('c...@example.com', page_data['modifier'].display_name)
    self.assertEqual('/u/133/', page_data['modifier'].profile_url)
    self.assertEqual('Apr 1970', page_data['modified'])

  def testGatherPageData_VisibleCreatorModifierForUnobscuredEmail(self):
    creator = self.services.user.GetUser(self.mr.cnxn, 122)
    creator.obscure_email = False
    modifier = self.services.user.GetUser(self.mr.cnxn, 133)
    modifier.obscure_email = False
    page_data = self.servlet.GatherPageData(self.mr)

    self.assertEqual('b@example.com', page_data['creator'].display_name)
    self.assertEqual('/u/b@example.com/', page_data['creator'].profile_url)
    self.assertEqual('Jan 1970', page_data['created'])
    self.assertEqual('c@example.com', page_data['modifier'].display_name)
    self.assertEqual('/u/c@example.com/', page_data['modifier'].profile_url)
    self.assertEqual('Apr 1970', page_data['modified'])

  def testGatherPageData_WithSubComponents(self):
    subcd = tracker_bizobj.MakeComponentDef(
        2, self.project.project_id, 'BackEnd>Worker', 'doc', False, [], [111],
        0, 122)
    self.config.component_defs.append(subcd)
    page_data = self.servlet.GatherPageData(self.mr)
    self.assertFalse(page_data['allow_delete'])
    self.assertEqual([subcd], page_data['subcomponents'])

  def testGatherPageData_WithTemplates(self):
    self.services.template.TemplatesWithComponent.return_value = ['template']
    page_data = self.servlet.GatherPageData(self.mr)
    self.assertFalse(page_data['allow_delete'])
    self.assertEqual(['template'], page_data['templates'])

  def testProcessFormData_Permission(self):
    """Only owners can edit components."""
    mr = testing_helpers.MakeMonorailRequest(
        project=self.project,
        perms=permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET)
    mr.component_path = 'BackEnd'
    post_data = fake.PostData(
        name=['BackEnd'],
        deletecomponent=['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=['BackEnd'],
        deletecomponent=['Submit'])
    url = self.servlet.ProcessFormData(self.mr, post_data)
    self.assertTrue('/adminComponents?deleted=1&' in url)
    self.assertIsNone(
        tracker_bizobj.FindComponentDef('BackEnd', self.config))

  def testProcessFormData_Delete_WithSubComponent(self):
    subcd = tracker_bizobj.MakeComponentDef(
        2, self.project.project_id, 'BackEnd>Worker', 'doc', False, [], [111],
        0, 122)
    self.config.component_defs.append(subcd)

    post_data = fake.PostData(
        name=['BackEnd'],
        deletecomponent=['Submit'])
    with self.assertRaises(permissions.PermissionException) as cm:
      self.servlet.ProcessFormData(self.mr, post_data)
    self.assertEqual(
        'User tried to delete component that had subcomponents',
        cm.exception.message)

  def testProcessFormData_Edit(self):
    post_data = fake.PostData(
        leaf_name=['BackEnd'],
        docstring=['This is where the magic happens'],
        deprecated=[True],
        admins=['a@example.com'],
        cc=['a@example.com'],
        labels=['Hot, Cold'])

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

    self.mox.VerifyAll()
    self.assertTrue('/components/detail?component=BackEnd&saved=1&' in url)
    config = self.services.config.GetProjectConfig(
        self.mr.cnxn, self.mr.project_id)

    cd = tracker_bizobj.FindComponentDef('BackEnd', config)
    self.assertEqual('BackEnd', cd.path)
    self.assertEqual(
        'This is where the magic happens',
        cd.docstring)
    self.assertEqual(True, cd.deprecated)
    self.assertEqual([111], cd.admin_ids)
    self.assertEqual([111], cd.cc_ids)

  def testProcessDeleteComponent(self):
    self.servlet._ProcessDeleteComponent(self.mr, self.cd)
    self.assertIsNone(
        tracker_bizobj.FindComponentDef('BackEnd', self.config))

  def testProcessEditComponent(self):
    post_data = fake.PostData(
        leaf_name=['BackEnd'],
        docstring=['This is where the magic happens'],
        deprecated=[True],
        admins=['a@example.com'],
        cc=['a@example.com'],
        labels=['Hot, Cold'])

    self.servlet._ProcessEditComponent(
        self.mr, post_data, self.config, self.cd)

    self.mox.VerifyAll()
    config = self.services.config.GetProjectConfig(
        self.mr.cnxn, self.mr.project_id)
    cd = tracker_bizobj.FindComponentDef('BackEnd', config)
    self.assertEqual('BackEnd', cd.path)
    self.assertEqual(
        'This is where the magic happens',
        cd.docstring)
    self.assertEqual(True, cd.deprecated)
    self.assertEqual([111], cd.admin_ids)
    self.assertEqual([111], cd.cc_ids)
    # Assert that creator and created were not updated.
    self.assertEqual(122, cd.creator_id)
    self.assertEqual(100000, cd.created)
    # Assert that modifier and modified were updated.
    self.assertEqual(122, cd.modifier_id)
    self.assertTrue(cd.modified > 10000000)

  def testProcessEditComponent_RenameWithSubComponents(self):
    subcd_1 = tracker_bizobj.MakeComponentDef(
        2, self.project.project_id, 'BackEnd>Worker1', 'doc', False, [], [111],
        0, 125, 3, 126)
    subcd_2 = tracker_bizobj.MakeComponentDef(
        3, self.project.project_id, 'BackEnd>Worker2', 'doc', False, [], [111],
        0, 125, 4, 127)
    self.config.component_defs.extend([subcd_1, subcd_2])

    self.mox.StubOutWithMock(filterrules_helpers, 'RecomputeAllDerivedFields')
    filterrules_helpers.RecomputeAllDerivedFields(
        self.mr.cnxn, self.services, self.mr.project, self.config)
    self.mox.ReplayAll()
    post_data = fake.PostData(
        leaf_name=['BackEnds'],
        docstring=['This is where the magic happens'],
        deprecated=[True],
        admins=['a@example.com'],
        cc=['a@example.com'],
        labels=[''])

    self.servlet._ProcessEditComponent(
        self.mr, post_data, self.config, self.cd)

    self.mox.VerifyAll()
    config = self.services.config.GetProjectConfig(
        self.mr.cnxn, self.mr.project_id)
    cd = tracker_bizobj.FindComponentDef('BackEnds', config)
    self.assertEqual('BackEnds', cd.path)
    subcd_1 = tracker_bizobj.FindComponentDef('BackEnds>Worker1', config)
    self.assertEqual('BackEnds>Worker1', subcd_1.path)
    # Assert that creator and modifier have not changed for subcd_1.
    self.assertEqual(125, subcd_1.creator_id)
    self.assertEqual(0, subcd_1.created)
    self.assertEqual(126, subcd_1.modifier_id)
    self.assertEqual(3, subcd_1.modified)

    subcd_2 = tracker_bizobj.FindComponentDef('BackEnds>Worker2', config)
    self.assertEqual('BackEnds>Worker2', subcd_2.path)
    # Assert that creator and modifier have not changed for subcd_2.
    self.assertEqual(125, subcd_2.creator_id)
    self.assertEqual(0, subcd_2.created)
    self.assertEqual(127, subcd_2.modifier_id)
    self.assertEqual(4, subcd_2.modified)
