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

"""Unittests for monorail.tracker.issuedetailezt."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

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

import settings
from businesslogic import work_env
from mrproto import features_pb2
from features import hotlist_views
from features import send_notifications
from framework import authdata
from framework import exceptions
from framework import framework_views
from framework import framework_helpers
from framework import urls
from framework import permissions
from framework import profiler
from framework import sorting
from framework import template_helpers
from mrproto import project_pb2
from mrproto import tracker_pb2
from mrproto import user_pb2
from services import service_manager
from services import issue_svc
from services import tracker_fulltext
from testing import fake
from testing import testing_helpers
from tracker import issuedetailezt
from tracker import tracker_constants
from tracker import tracker_helpers


class GetAdjacentIssueTest(unittest.TestCase):

  def setUp(self):
    self.cnxn = 'fake cnxn'
    self.services = service_manager.Services(
        config=fake.ConfigService(),
        issue=fake.IssueService(),
        user=fake.UserService(),
        project=fake.ProjectService(),
        issue_star=fake.IssueStarService(),
        spam=fake.SpamService())
    self.services.project.TestAddProject('proj', project_id=789)
    self.mr = testing_helpers.MakeMonorailRequest()
    self.mr.auth.user_id = 111
    self.mr.auth.effective_ids = {111}
    self.mr.me_user_id = 111
    self.work_env = work_env.WorkEnv(
      self.mr, self.services, 'Testing phase')

  def testGetAdjacentIssue_PrevIssue(self):
    cur_issue = fake.MakeTestIssue(789, 2, 'sum', 'New', 111, issue_id=78902)
    next_issue = fake.MakeTestIssue(789, 3, 'sum', 'New', 111, issue_id=78903)
    prev_issue = fake.MakeTestIssue(789, 1, 'sum', 'New', 111, issue_id=78901)
    self.services.issue.TestAddIssue(cur_issue)
    self.services.issue.TestAddIssue(next_issue)
    self.services.issue.TestAddIssue(prev_issue)

    with self.work_env as we:
      we.FindIssuePositionInSearch = mock.Mock(
          return_value=[78901, 1, 78903, 3])

      actual_issue = issuedetailezt.GetAdjacentIssue(
         self.mr, we, cur_issue)
      self.assertEqual(prev_issue, actual_issue)
      we.FindIssuePositionInSearch.assert_called_once_with(cur_issue)

  def testGetAdjacentIssue_NextIssue(self):
    cur_issue = fake.MakeTestIssue(789, 2, 'sum', 'New', 111, issue_id=78902)
    next_issue = fake.MakeTestIssue(789, 3, 'sum', 'New', 111, issue_id=78903)
    prev_issue = fake.MakeTestIssue(789, 1, 'sum', 'New', 111, issue_id=78901)
    self.services.issue.TestAddIssue(cur_issue)
    self.services.issue.TestAddIssue(next_issue)
    self.services.issue.TestAddIssue(prev_issue)

    with self.work_env as we:
      we.FindIssuePositionInSearch = mock.Mock(
          return_value=[78901, 1, 78903, 3])

      actual_issue = issuedetailezt.GetAdjacentIssue(
          self.mr, we, cur_issue, next_issue=True)
      self.assertEqual(next_issue, actual_issue)
      we.FindIssuePositionInSearch.assert_called_once_with(cur_issue)

  def testGetAdjacentIssue_NotFound(self):
    cur_issue = fake.MakeTestIssue(789, 2, 'sum', 'New', 111, issue_id=78902)
    prev_issue = fake.MakeTestIssue(789, 1, 'sum', 'New', 111, issue_id=78901)
    self.services.issue.TestAddIssue(cur_issue)
    self.services.issue.TestAddIssue(prev_issue)

    with self.work_env as we:
      we.FindIssuePositionInSearch = mock.Mock(
          return_value=[78901, 1, 78903, 3])

      with self.assertRaises(exceptions.NoSuchIssueException):
        issuedetailezt.GetAdjacentIssue(
            self.mr, we, cur_issue, next_issue=True)
      we.FindIssuePositionInSearch.assert_called_once_with(cur_issue)

  def testGetAdjacentIssue_Hotlist(self):
    cur_issue = fake.MakeTestIssue(789, 2, 'sum', 'New', 111, issue_id=78902)
    next_issue = fake.MakeTestIssue(789, 3, 'sum', 'New', 111, issue_id=78903)
    prev_issue = fake.MakeTestIssue(789, 1, 'sum', 'New', 111, issue_id=78901)
    self.services.issue.TestAddIssue(cur_issue)
    self.services.issue.TestAddIssue(next_issue)
    self.services.issue.TestAddIssue(prev_issue)
    hotlist = fake.Hotlist('name', 678, owner_ids=[111])

    with self.work_env as we:
      we.GetIssuePositionInHotlist = mock.Mock(
          return_value=[78901, 1, 78903, 3])

      actual_issue = issuedetailezt.GetAdjacentIssue(
          self.mr, we, cur_issue, hotlist=hotlist, next_issue=True)
      self.assertEqual(next_issue, actual_issue)
      we.GetIssuePositionInHotlist.assert_called_once_with(
          cur_issue, hotlist, self.mr.can, self.mr.sort_spec,
          self.mr.group_by_spec)


class FlipperRedirectTest(unittest.TestCase):

  def setUp(self):
    self.services = service_manager.Services(
        config=fake.ConfigService(),
        features=fake.FeaturesService(),
        issue=fake.IssueService(),
        user=fake.UserService(),
        project=fake.ProjectService())
    self.project = self.services.project.TestAddProject(
      'proj', project_id=987, committer_ids=[111])
    self.next_servlet = issuedetailezt.FlipperNext(services=self.services)
    self.prev_servlet = issuedetailezt.FlipperPrev(services=self.services)
    self.list_servlet = issuedetailezt.FlipperList(services=self.services)
    mr = testing_helpers.MakeMonorailRequest(project=self.project)
    mr.local_id = 123
    mr.me_user_id = 111

    self.next_servlet.mr = mr
    self.prev_servlet.mr = mr
    self.list_servlet.mr = mr

    self.fake_issue_1 = fake.MakeTestIssue(987, 123, 'summary', 'New', 111,
        project_name='rutabaga')
    self.services.issue.TestAddIssue(self.fake_issue_1)
    self.fake_issue_2 = fake.MakeTestIssue(987, 456, 'summary', 'New', 111,
        project_name='rutabaga')
    self.services.issue.TestAddIssue(self.fake_issue_2)
    self.fake_issue_3 = fake.MakeTestIssue(987, 789, 'summary', 'New', 111,
        project_name='potato')
    self.services.issue.TestAddIssue(self.fake_issue_3)

    self.next_servlet.redirect = mock.Mock()
    self.prev_servlet.redirect = mock.Mock()
    self.list_servlet.redirect = mock.Mock()

  @mock.patch('tracker.issuedetailezt.GetAdjacentIssue')
  def testFlipperNext(self, patchGetAdjacentIssue):
    patchGetAdjacentIssue.return_value = self.fake_issue_2
    self.next_servlet.mr.GetIntParam = mock.Mock(return_value=None)

    self.next_servlet.get()
    self.next_servlet.mr.GetIntParam.assert_called_once_with('hotlist_id')
    patchGetAdjacentIssue.assert_called_once()
    self.next_servlet.redirect.assert_called_once_with(
      '/p/rutabaga/issues/detail?id=456')

  @mock.patch('tracker.issuedetailezt.GetAdjacentIssue')
  def testFlipperNext_Hotlist(self, patchGetAdjacentIssue):
    patchGetAdjacentIssue.return_value = self.fake_issue_3
    self.next_servlet.mr.GetIntParam = mock.Mock(return_value=123)
    # TODO(jeffcarp): Mock hotlist_id param on path here.

    self.next_servlet.get()
    self.next_servlet.mr.GetIntParam.assert_called_with('hotlist_id')
    self.next_servlet.redirect.assert_called_once_with(
      '/p/potato/issues/detail?id=789')

  @mock.patch('tracker.issuedetailezt.GetAdjacentIssue')
  def testFlipperPrev(self, patchGetAdjacentIssue):
    patchGetAdjacentIssue.return_value = self.fake_issue_2
    self.next_servlet.mr.GetIntParam = mock.Mock(return_value=None)

    self.prev_servlet.get()
    self.prev_servlet.mr.GetIntParam.assert_called_with('hotlist_id')
    patchGetAdjacentIssue.assert_called_once()
    self.prev_servlet.redirect.assert_called_once_with(
      '/p/rutabaga/issues/detail?id=456')

  @mock.patch('tracker.issuedetailezt.GetAdjacentIssue')
  def testFlipperPrev_Hotlist(self, patchGetAdjacentIssue):
    patchGetAdjacentIssue.return_value = self.fake_issue_3
    self.prev_servlet.mr.GetIntParam = mock.Mock(return_value=123)
    # TODO(jeffcarp): Mock hotlist_id param on path here.

    self.prev_servlet.get()
    self.prev_servlet.mr.GetIntParam.assert_called_with('hotlist_id')
    self.prev_servlet.redirect.assert_called_once_with(
      '/p/potato/issues/detail?id=789')

  @mock.patch('tracker.issuedetailezt._ComputeBackToListURL')
  def testFlipperList(self, patch_ComputeBackToListURL):
    patch_ComputeBackToListURL.return_value = '/p/test/issues/list'
    self.list_servlet.mr.GetIntParam = mock.Mock(return_value=None)

    self.list_servlet.get()

    self.list_servlet.mr.GetIntParam.assert_called_with('hotlist_id')
    patch_ComputeBackToListURL.assert_called_once()
    self.list_servlet.redirect.assert_called_once_with(
      '/p/test/issues/list')

  @mock.patch('tracker.issuedetailezt._ComputeBackToListURL')
  def testFlipperList_Hotlist(self, patch_ComputeBackToListURL):
    patch_ComputeBackToListURL.return_value = '/p/test/issues/list'
    self.list_servlet.mr.GetIntParam = mock.Mock(return_value=123)

    self.list_servlet.get()

    self.list_servlet.mr.GetIntParam.assert_called_with('hotlist_id')
    self.list_servlet.redirect.assert_called_once_with(
      '/p/test/issues/list')


class ShouldShowFlipperTest(unittest.TestCase):

  def setUp(self):
    self.cnxn = 'fake cnxn'

  def VerifyShouldShowFlipper(
      self, expected, query, sort_spec, can, create_issues=0):
    """Instantiate a _Flipper and check if makes a pipeline or not."""
    services = service_manager.Services(
        config=fake.ConfigService(),
        issue=fake.IssueService(),
        project=fake.ProjectService(),
        user=fake.UserService())
    project = services.project.TestAddProject(
      'proj', project_id=987, committer_ids=[111])
    mr = testing_helpers.MakeMonorailRequest(project=project)
    mr.query = query
    mr.sort_spec = sort_spec
    mr.can = can
    mr.project_name = project.project_name
    mr.project = project

    for idx in range(create_issues):
      _created_issue = fake.MakeTestIssue(
          project.project_id,
          idx,
          'summary_%d' % idx,
          'status',
          111,
          reporter_id=111)
      services.issue.TestAddIssue(_created_issue)

    self.assertEqual(expected, issuedetailezt._ShouldShowFlipper(mr, services))

  def testShouldShowFlipper_RegularSizedProject(self):
    # If the user is looking for a specific issue, no flipper.
    self.VerifyShouldShowFlipper(
        False, '123', '', tracker_constants.OPEN_ISSUES_CAN)
    self.VerifyShouldShowFlipper(False, '123', '', 5)
    self.VerifyShouldShowFlipper(
        False, '123', 'priority', tracker_constants.OPEN_ISSUES_CAN)

    # If the user did a search or sort or all in a small can, show flipper.
    self.VerifyShouldShowFlipper(
        True, 'memory leak', '', tracker_constants.OPEN_ISSUES_CAN)
    self.VerifyShouldShowFlipper(
        True, 'id=1,2,3', '', tracker_constants.OPEN_ISSUES_CAN)
    # Any can other than 1 or 2 is doing a query and so it should have a
    # failry narrow result set size.  5 is issues starred by me.
    self.VerifyShouldShowFlipper(True, '', '', 5)
    self.VerifyShouldShowFlipper(
        True, '', 'status', tracker_constants.OPEN_ISSUES_CAN)

    # In a project without a huge number of issues, still show the flipper even
    # if there was no specific query.
    self.VerifyShouldShowFlipper(
        True, '', '', tracker_constants.OPEN_ISSUES_CAN)

  def testShouldShowFlipper_LargeSizedProject(self):
    settings.threshold_to_suppress_prev_next = 1

    # In a project that has tons of issues, save time by not showing the
    # flipper unless there was a specific query, sort, or can.
    self.VerifyShouldShowFlipper(
        False, '', '', tracker_constants.ALL_ISSUES_CAN, create_issues=3)
    self.VerifyShouldShowFlipper(
        False, '', '', tracker_constants.OPEN_ISSUES_CAN, create_issues=3)
