# Copyright 2018 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

"""Tests for the projects servicer."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import json
import mock
import unittest
import mox

from google.protobuf import wrappers_pb2

from components.prpc import codes
from components.prpc import context
from components.prpc import server

from api import converters
from api.api_proto import common_pb2
from api.api_proto import features_pb2
from api.api_proto import features_objects_pb2
from api.api_proto import issue_objects_pb2
from framework import authdata
from framework import exceptions
from framework import monorailcontext
from framework import permissions
from framework import sorting
from testing import fake
from testing import testing_helpers
from tracker import tracker_bizobj
from services import features_svc
from services import service_manager

# Import component_helpers_test to mock cloudstorage before it is imported by
# component_helpers via features servicer.
from features.test import component_helpers_test
from api import features_servicer  # pylint: disable=ungrouped-imports


class FeaturesServicerTest(unittest.TestCase):

  def setUp(self):
    self.mox = mox.Mox()
    self.cnxn = fake.MonorailConnection()
    self.services = service_manager.Services(
        cache_manager=fake.CacheManager(),
        config=fake.ConfigService(),
        issue=fake.IssueService(),
        user=fake.UserService(),
        usergroup=fake.UserGroupService(),
        project=fake.ProjectService(),
        features=fake.FeaturesService(),
        hotlist_star=fake.HotlistStarService())
    sorting.InitializeArtValues(self.services)

    self.project = self.services.project.TestAddProject(
        'proj', project_id=789, owner_ids=[111], contrib_ids=[222, 333])
    self.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
    self.user1 = self.services.user.TestAddUser('owner@example.com', 111)
    self.user2 = self.services.user.TestAddUser('editor@example.com', 222)
    self.user3 = self.services.user.TestAddUser('foo@example.com', 333)
    self.user4 = self.services.user.TestAddUser('bar@example.com', 444)
    self.features_svcr = features_servicer.FeaturesServicer(
        self.services, make_rate_limiter=False)
    self.prpc_context = context.ServicerContext()
    self.prpc_context.set_code(codes.StatusCode.OK)
    self.issue_1 = fake.MakeTestIssue(
        789, 1, 'sum', 'New', 111, project_name='proj', issue_id=78901)
    self.issue_2 = fake.MakeTestIssue(
        789, 2, 'sum', 'Fixed', 111, project_name='proj', issue_id=78902,
        closed_timestamp=112223344)
    self.issue_3 = fake.MakeTestIssue(
        789, 3, 'sum', 'New', 111, project_name='proj', issue_id=78903)

    self.services.issue.TestAddIssue(self.issue_1)
    self.services.issue.TestAddIssue(self.issue_2)
    self.services.issue.TestAddIssue(self.issue_3)

    self.project_2 = self.services.project.TestAddProject(
        'proj2', project_id=788, owner_ids=[111], contrib_ids=[222, 333])
    self.config_2 = tracker_bizobj.MakeDefaultProjectIssueConfig(788)
    self.issue_21 = fake.MakeTestIssue(
        788, 1, 'sum', 'New', 111, project_name='proj2', issue_id=78801)
    self.issue_22 = fake.MakeTestIssue(
        788, 2, 'sum', 'New', 111, project_name='proj2', issue_id=78802)
    self.issue_23 = fake.MakeTestIssue(
        788, 3, 'sum', 'New', 111, project_name='proj2', issue_id=78803)
    self.services.issue.TestAddIssue(self.issue_21)
    self.services.issue.TestAddIssue(self.issue_22)
    self.services.issue.TestAddIssue(self.issue_23)

    self.PAST_TIME = 123456

    # For testing PredictComponent
    self._ml_engine = component_helpers_test.FakeMLEngine(self)
    self._top_words = None
    self._components_by_index = None

    mock.patch(
        'services.ml_helpers.setup_ml_engine', lambda: self._ml_engine).start()
    mock.patch(
        'features.component_helpers._GetTopWords',
        lambda _: self._top_words).start()
    mock.patch('cloudstorage.open', self.cloudstorageOpen).start()
    mock.patch('settings.component_features', 5).start()

    self.addCleanup(mock.patch.stopall)

  def cloudstorageOpen(self, name, mode):
    """Create a file mock that returns self._components_by_index when read."""
    open_fn = mock.mock_open(read_data=json.dumps(self._components_by_index))
    return open_fn(name, mode)

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

  def CallWrapped(self, wrapped_handler, *args, **kwargs):
    return wrapped_handler.wrapped(self.features_svcr, *args, **kwargs)

  def testListHotlistsByUser_SearchByEmail(self):
    """We can get a list of hotlists for a given email."""
    # Public hostlist owned by 'owner@example.com'
    self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222])

    # Query for issues for 'owner@example.com'
    user_ref = common_pb2.UserRef(display_name='owner@example.com')
    request = features_pb2.ListHotlistsByUserRequest(user=user_ref)

    # We're not authenticated
    mc = monorailcontext.MonorailContext(self.services, cnxn=self.cnxn)

    response = self.CallWrapped(self.features_svcr.ListHotlistsByUser, mc,
                                request)
    self.assertEqual(1, len(response.hotlists))
    hotlist = response.hotlists[0]
    self.assertEqual(111, hotlist.owner_ref.user_id)
    self.assertEqual('ow...@example.com', hotlist.owner_ref.display_name)
    self.assertEqual('Fake-Hotlist', hotlist.name)
    self.assertEqual('Summary', hotlist.summary)
    self.assertEqual('Description', hotlist.description)

  def testListHotlistsByUser_SearchByOwner(self):
    """We can get a list of hotlists for a given user."""
    # Public hostlist owned by 'owner@example.com'
    self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222])

    # Query for issues for 'owner@example.com'
    user_ref = common_pb2.UserRef(user_id=111)
    request = features_pb2.ListHotlistsByUserRequest(user=user_ref)

    # We're authenticated as 'foo@example.com'
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='foo@example.com')

    response = self.CallWrapped(self.features_svcr.ListHotlistsByUser, mc,
                                request)
    self.assertEqual(1, len(response.hotlists))
    hotlist = response.hotlists[0]
    self.assertEqual(111, hotlist.owner_ref.user_id)
    # User1 and user3 share self.project.
    self.assertEqual('owner@example.com', hotlist.owner_ref.display_name)
    self.assertEqual('Fake-Hotlist', hotlist.name)
    self.assertEqual('Summary', hotlist.summary)
    self.assertEqual('Description', hotlist.description)

  def testListHotlistsByUser_SearchByEditor(self):
    """We can get a list of hotlists for a given user."""
    # Public hostlist owned by 'owner@example.com'
    self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222])

    # Query for issues for 'editor@example.com'
    user_ref = common_pb2.UserRef(user_id=222)
    request = features_pb2.ListHotlistsByUserRequest(user=user_ref)

    # We're authenticated as 'foo@example.com'
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='foo@example.com')

    response = self.CallWrapped(self.features_svcr.ListHotlistsByUser, mc,
                                request)
    self.assertEqual(1, len(response.hotlists))
    hotlist = response.hotlists[0]
    self.assertEqual(111, hotlist.owner_ref.user_id)
    # User1 and user3 share self.project.
    self.assertEqual('owner@example.com', hotlist.owner_ref.display_name)
    self.assertEqual('Fake-Hotlist', hotlist.name)
    self.assertEqual('Summary', hotlist.summary)
    self.assertEqual('Description', hotlist.description)

  def testListHotlistsByUser_NotSignedIn(self):
    # Public hostlist owned by 'owner@example.com'
    self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222])

    # Query for issues for 'owner@example.com'
    user_ref = common_pb2.UserRef(user_id=111)
    request = features_pb2.ListHotlistsByUserRequest(user=user_ref)

    # We're not authenticated
    mc = monorailcontext.MonorailContext(self.services, cnxn=self.cnxn)
    response = self.CallWrapped(self.features_svcr.ListHotlistsByUser, mc,
                                request)

    self.assertEqual(1, len(response.hotlists))
    hotlist = response.hotlists[0]
    self.assertEqual(111, hotlist.owner_ref.user_id)

  def testListHotlistsByUser_Empty(self):
    """There are no hotlists for the given user."""
    # Public hostlist owned by 'owner@example.com'
    self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222])

    # Query for issues for 'bar@example.com'
    user_ref = common_pb2.UserRef(user_id=444)
    request = features_pb2.ListHotlistsByUserRequest(user=user_ref)

    # We're authenticated as 'foo@example.com'
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='foo@example.com')
    response = self.CallWrapped(self.features_svcr.ListHotlistsByUser, mc,
                                request)

    self.assertEqual(0, len(response.hotlists))

  def testListHotlistsByUser_NoHotlists(self):
    """There are no hotlists."""
    # No hotlists
    # Query for issues for 'owner@example.com'
    user_ref = common_pb2.UserRef(user_id=111)
    request = features_pb2.ListHotlistsByUserRequest(user=user_ref)

    # We're authenticated as 'foo@example.com'
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='foo@example.com')
    response = self.CallWrapped(self.features_svcr.ListHotlistsByUser, mc,
                                request)
    self.assertEqual(0, len(response.hotlists))

  def testListHotlistsByUser_PrivateIssueAsOwner(self):
    # Private hostlist owned by 'owner@example.com'
    self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222], is_private=True)

    # Query for issues for 'owner@example.com'
    user_ref = common_pb2.UserRef(user_id=111)
    request = features_pb2.ListHotlistsByUserRequest(user=user_ref)

    # We're authenticated as 'owner@example.com'
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(self.features_svcr.ListHotlistsByUser, mc,
                                request)

    self.assertEqual(1, len(response.hotlists))
    hotlist = response.hotlists[0]
    self.assertEqual(111, hotlist.owner_ref.user_id)

  def testListHotlistsByUser_PrivateIssueAsEditor(self):
    # Private hostlist owned by 'owner@example.com'
    self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222], is_private=True)

    # Query for issues for 'owner@example.com'
    user_ref = common_pb2.UserRef(user_id=111)
    request = features_pb2.ListHotlistsByUserRequest(user=user_ref)

    # We're authenticated as 'editor@example.com'
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='editor@example.com')
    response = self.CallWrapped(self.features_svcr.ListHotlistsByUser, mc,
                                request)

    self.assertEqual(1, len(response.hotlists))
    hotlist = response.hotlists[0]
    self.assertEqual(111, hotlist.owner_ref.user_id)

  def testListHotlistsByUser_PrivateIssueNoAccess(self):
    # Private hostlist owned by 'owner@example.com'
    self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222], is_private=True)

    # Query for issues for 'owner@example.com'
    user_ref = common_pb2.UserRef(user_id=111)
    request = features_pb2.ListHotlistsByUserRequest(user=user_ref)

    # We're authenticated as 'foo@example.com'
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='foo@example.com')
    response = self.CallWrapped(self.features_svcr.ListHotlistsByUser, mc,
                                request)

    self.assertEqual(0, len(response.hotlists))

  def testListHotlistsByUser_PrivateIssueNotSignedIn(self):
    # Private hostlist owned by 'owner@example.com'
    self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222], is_private=True)

    # Query for issues for 'owner@example.com'
    user_ref = common_pb2.UserRef(user_id=111)
    request = features_pb2.ListHotlistsByUserRequest(user=user_ref)

    # We're not authenticated
    mc = monorailcontext.MonorailContext(self.services, cnxn=self.cnxn)
    response = self.CallWrapped(self.features_svcr.ListHotlistsByUser, mc,
                                request)

    self.assertEqual(0, len(response.hotlists))

  def AddIssueToHotlist(self, hotlist_id, issue_id=78901, adder_id=111):
    self.services.features.AddIssuesToHotlists(
        self.cnxn, [hotlist_id], [(issue_id, adder_id, 0, '')],
        None, None, None)

  def testListHotlistsByIssue_Normal(self):
    hotlist = self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222])
    self.AddIssueToHotlist(hotlist.hotlist_id)

    issue_ref = common_pb2.IssueRef(project_name='proj', local_id=1)
    request = features_pb2.ListHotlistsByIssueRequest(issue=issue_ref)

    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='foo@example.com')
    response = self.CallWrapped(self.features_svcr.ListHotlistsByIssue, mc,
                                request)

    self.assertEqual(1, len(response.hotlists))
    hotlist = response.hotlists[0]
    self.assertEqual('Fake-Hotlist', hotlist.name)

  def testListHotlistsByIssue_NotSignedIn(self):
    # Public hostlist owned by 'owner@example.com'
    hotlist = self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222])
    self.AddIssueToHotlist(hotlist.hotlist_id)

    issue_ref = common_pb2.IssueRef(project_name='proj', local_id=1)
    request = features_pb2.ListHotlistsByIssueRequest(issue=issue_ref)

    # We're not authenticated
    mc = monorailcontext.MonorailContext(self.services, cnxn=self.cnxn)
    response = self.CallWrapped(self.features_svcr.ListHotlistsByIssue, mc,
                                request)

    self.assertEqual(1, len(response.hotlists))
    hotlist = response.hotlists[0]
    self.assertEqual('Fake-Hotlist', hotlist.name)

  def testListHotlistsByIssue_Empty(self):
    """There are no hotlists with the given issue."""
    # Public hostlist owned by 'owner@example.com'
    self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222])

    issue_ref = common_pb2.IssueRef(project_name='proj', local_id=1)
    request = features_pb2.ListHotlistsByIssueRequest(issue=issue_ref)

    # We're authenticated as 'foo@example.com'
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='foo@example.com')
    response = self.CallWrapped(self.features_svcr.ListHotlistsByIssue, mc,
                                request)

    self.assertEqual(0, len(response.hotlists))

  def testListHotlistsByIssue_NoHotlists(self):
    issue_ref = common_pb2.IssueRef(project_name='proj', local_id=1)
    request = features_pb2.ListHotlistsByIssueRequest(issue=issue_ref)

    # We're authenticated as 'foo@example.com'
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='foo@example.com')
    response = self.CallWrapped(self.features_svcr.ListHotlistsByIssue, mc,
                                request)
    self.assertEqual(0, len(response.hotlists))

  def testListHotlistsByIssue_PrivateHotlistAsOwner(self):
    """An owner can view their private issues."""
    # Private hostlist owned by 'owner@example.com'
    hotlist = self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222], is_private=True)
    self.AddIssueToHotlist(hotlist.hotlist_id)

    issue_ref = common_pb2.IssueRef(project_name='proj', local_id=1)
    request = features_pb2.ListHotlistsByIssueRequest(issue=issue_ref)

    # We're authenticated as 'owner@example.com'
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(self.features_svcr.ListHotlistsByIssue, mc,
                                request)

    self.assertEqual(1, len(response.hotlists))
    hotlist = response.hotlists[0]
    self.assertEqual('Fake-Hotlist', hotlist.name)

  def testListHotlistsByIssue_PrivateHotlistNoAccess(self):
    # Private hostlist owned by 'owner@example.com'
    hotlist = self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222], is_private=True)
    self.AddIssueToHotlist(hotlist.hotlist_id)

    issue_ref = common_pb2.IssueRef(project_name='proj', local_id=1)
    request = features_pb2.ListHotlistsByIssueRequest(issue=issue_ref)

    # We're authenticated as 'foo@example.com'
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='foo@example.com')
    response = self.CallWrapped(self.features_svcr.ListHotlistsByIssue, mc,
                                request)

    self.assertEqual(0, len(response.hotlists))

  def testListHotlistsByIssue_NonProjectHotlists(self):
    hotlist = self.services.features.CreateHotlist(
        self.cnxn,
        'Fake-Hotlist',
        'Summary',
        'Description',
        owner_ids=[111],
        editor_ids=[222])
    spam_hotlist = self.services.features.CreateHotlist(
        self.cnxn,
        'Spam-Hotlist',
        'Summary',
        'Description',
        owner_ids=[444],
        editor_ids=[])
    another_hotlist = self.services.features.CreateHotlist(
        self.cnxn,
        'Another-Hotlist',
        'Summary',
        'Description',
        owner_ids=[111],
        editor_ids=[])
    self.AddIssueToHotlist(hotlist.hotlist_id)
    self.AddIssueToHotlist(spam_hotlist.hotlist_id)
    self.AddIssueToHotlist(another_hotlist.hotlist_id)

    issue_ref = common_pb2.IssueRef(project_name='proj', local_id=1)
    request = features_pb2.ListHotlistsByIssueRequest(issue=issue_ref)

    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='foo@example.com')
    response = self.CallWrapped(
        self.features_svcr.ListHotlistsByIssue, mc, request)

    self.assertEqual(2, len(response.hotlists))
    self.assertEqual('Fake-Hotlist', response.hotlists[0].name)
    self.assertEqual('Another-Hotlist', response.hotlists[1].name)

  def testListRecentlyVisitedHotlists(self):
    hotlists = [
        self.services.features.CreateHotlist(
            self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
            owner_ids=[self.user2.user_id], editor_ids=[self.user1.user_id],
            default_col_spec='chicken'),
        self.services.features.CreateHotlist(
            self.cnxn, 'Fake-Hotlist-2', 'Summary', 'Description',
            owner_ids=[self.user1.user_id], editor_ids=[self.user2.user_id],
            default_col_spec='honk'),
        self.services.features.CreateHotlist(
            self.cnxn, 'Private-Hotlist', 'Summary', 'Description',
            owner_ids=[self.user3.user_id], editor_ids=[self.user2.user_id],
            is_private=True)]

    for hotlist in hotlists:
      self.services.user.AddVisitedHotlist(
          self.cnxn, self.user1.user_id, hotlist.hotlist_id)

    request = features_pb2.ListRecentlyVisitedHotlistsRequest()
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.user1.email)
    response = self.CallWrapped(
        self.features_svcr.ListRecentlyVisitedHotlists, mc, request)

    expected_hotlists = [
        features_objects_pb2.Hotlist(
            owner_ref=common_pb2.UserRef(
                user_id=self.user2.user_id, display_name=self.user2.email),
            editor_refs=[
                common_pb2.UserRef(
                    user_id=self.user1.user_id, display_name=self.user1.email)
            ],
            name='Fake-Hotlist',
            summary='Summary',
            description='Description',
            is_private=False,
            default_col_spec='chicken'),
        features_objects_pb2.Hotlist(
            owner_ref=common_pb2.UserRef(
                user_id=self.user1.user_id, display_name=self.user1.email),
            editor_refs=[
                common_pb2.UserRef(
                    user_id=self.user2.user_id, display_name=self.user2.email)
            ],
            name='Fake-Hotlist-2',
            summary='Summary',
            description='Description',
            is_private=False,
            default_col_spec='honk')
    ]

    # We don't have permission to see the last issue, because it is marked as
    # private and we're not owners or editors.
    self.assertEqual(expected_hotlists, list(response.hotlists))

  def testListRecentlyVisitedHotlists_Anon(self):
    request = features_pb2.ListRecentlyVisitedHotlistsRequest()
    mc = monorailcontext.MonorailContext(self.services, cnxn=self.cnxn)
    response = self.CallWrapped(
        self.features_svcr.ListRecentlyVisitedHotlists, mc, request)
    self.assertEqual(0, len(response.hotlists))

  def testListStarredHotlists(self):
    hotlists = [
        self.services.features.CreateHotlist(
            self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
            owner_ids=[self.user2.user_id], editor_ids=[self.user1.user_id],
            default_col_spec='cow chicken'),
        self.services.features.CreateHotlist(
            self.cnxn, 'Fake-Hotlist-2', 'Summary', 'Description',
            owner_ids=[self.user1.user_id],
            editor_ids=[self.user2.user_id, self.user3.user_id],
            default_col_spec=''),
        self.services.features.CreateHotlist(
            self.cnxn, 'Private-Hotlist', 'Summary', 'Description',
            owner_ids=[self.user3.user_id], editor_ids=[self.user2.user_id],
            is_private=True, default_col_spec='chicken')]

    for hotlist in hotlists:
      self.services.hotlist_star.SetStar(
          self.cnxn, hotlist.hotlist_id, self.user1.user_id, True)

    request = features_pb2.ListStarredHotlistsRequest()
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.features_svcr.ListStarredHotlists, mc, request)

    expected_hotlists = [
        features_objects_pb2.Hotlist(
            owner_ref=common_pb2.UserRef(
                user_id=self.user2.user_id, display_name=self.user2.email),
            editor_refs=[
                common_pb2.UserRef(
                    user_id=self.user1.user_id, display_name=self.user1.email)
            ],
            name='Fake-Hotlist',
            summary='Summary',
            description='Description',
            is_private=False,
            default_col_spec='cow chicken'),
        features_objects_pb2.Hotlist(
            owner_ref=common_pb2.UserRef(
                user_id=self.user1.user_id, display_name=self.user1.email),
            editor_refs=[
                common_pb2.UserRef(
                    user_id=self.user2.user_id, display_name=self.user2.email),
                common_pb2.UserRef(
                    user_id=self.user3.user_id, display_name=self.user3.email)
            ],
            name='Fake-Hotlist-2',
            summary='Summary',
            description='Description',
            is_private=False)
    ]

    # We don't have permission to see the last issue, because it is marked as
    # private and we're not owners or editors.
    self.assertEqual(expected_hotlists, list(response.hotlists))

  def testListStarredHotlists_Anon(self):
    request = features_pb2.ListStarredHotlistsRequest()
    mc = monorailcontext.MonorailContext(self.services, cnxn=self.cnxn)
    response = self.CallWrapped(
        self.features_svcr.ListStarredHotlists, mc, request)
    self.assertEqual(0, len(response.hotlists))

  def CallGetStarCount(self):
    # Query for hotlists for 'owner@example.com'
    owner_ref = common_pb2.UserRef(user_id=111)
    hotlist_ref = common_pb2.HotlistRef(name='Fake-Hotlist', owner=owner_ref)
    request = features_pb2.GetHotlistStarCountRequest(hotlist_ref=hotlist_ref)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.features_svcr.GetHotlistStarCount, mc, request)
    return response.star_count

  def CallStar(self, requester='owner@example.com', starred=True):
    # Query for hotlists for 'owner@example.com'
    owner_ref = common_pb2.UserRef(user_id=111)
    hotlist_ref = common_pb2.HotlistRef(name='Fake-Hotlist', owner=owner_ref)
    request = features_pb2.StarHotlistRequest(
        hotlist_ref=hotlist_ref, starred=starred)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=requester)
    response = self.CallWrapped(
        self.features_svcr.StarHotlist, mc, request)
    return response.star_count

  def testStarCount_Normal(self):
    self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222])
    self.assertEqual(0, self.CallGetStarCount())
    self.assertEqual(1, self.CallStar())
    self.assertEqual(1, self.CallGetStarCount())

  def testStarCount_StarTwiceSameUser(self):
    self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222])
    self.assertEqual(1, self.CallStar())
    self.assertEqual(1, self.CallStar())
    self.assertEqual(1, self.CallGetStarCount())

  def testStarCount_StarTwiceDifferentUser(self):
    self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222])
    self.assertEqual(1, self.CallStar())
    self.assertEqual(2, self.CallStar(requester='user_222@example.com'))
    self.assertEqual(2, self.CallGetStarCount())

  def testStarCount_RemoveStarTwiceSameUser(self):
    self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222])
    self.assertEqual(1, self.CallStar())
    self.assertEqual(1, self.CallGetStarCount())

    self.assertEqual(0, self.CallStar(starred=False))
    self.assertEqual(0, self.CallStar(starred=False))
    self.assertEqual(0, self.CallGetStarCount())

  def testStarCount_RemoveStarTwiceDifferentUser(self):
    self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[222])
    self.assertEqual(1, self.CallStar())
    self.assertEqual(2, self.CallStar(requester='user_222@example.com'))
    self.assertEqual(2, self.CallGetStarCount())

    self.assertEqual(1, self.CallStar(starred=False))
    self.assertEqual(
        0, self.CallStar(requester='user_222@example.com', starred=False))
    self.assertEqual(0, self.CallGetStarCount())

  def testGetHotlist(self):
    hotlist = self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[self.user3.user_id], editor_ids=[self.user4.user_id],
        is_private=True, default_col_spec='corgi butts')

    owner_ref = common_pb2.UserRef(user_id=self.user3.user_id)
    hotlist_ref = common_pb2.HotlistRef(
        name=hotlist.name, owner=owner_ref)
    request = features_pb2.GetHotlistRequest(hotlist_ref=hotlist_ref)

    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.user4.email)
    mc.LookupLoggedInUserPerms(None)
    response = self.CallWrapped(
        self.features_svcr.GetHotlist, mc, request)

    self.assertEqual(
        response.hotlist,
        features_objects_pb2.Hotlist(
          owner_ref=common_pb2.UserRef(
              user_id=self.user3.user_id,
              display_name=testing_helpers.ObscuredEmail(self.user3.email)),
          editor_refs=[common_pb2.UserRef(
              user_id=self.user4.user_id,
              display_name=self.user4.email)],
          name=hotlist.name,
          summary=hotlist.summary,
          description=hotlist.description,
          default_col_spec='corgi butts',
          is_private=True))

  def testGetHotlist_BadInput(self):
    hotlist_ref = common_pb2.HotlistRef()
    request = features_pb2.GetHotlistRequest(hotlist_ref=hotlist_ref)

    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='foo@example.com')
    with self.assertRaises(features_svc.NoSuchHotlistException):
      self.CallWrapped(self.features_svcr.GetHotlist, mc, request)

  def testCreateHotlist_Normal(self):
    request = features_pb2.CreateHotlistRequest(
        name='Fake-Hotlist',
        summary='Summary',
        description='Description',
        editor_refs=[
            common_pb2.UserRef(user_id=222),
            common_pb2.UserRef(display_name='foo@example.com')],
        issue_refs=[
            common_pb2.IssueRef(project_name='proj', local_id=1),
            common_pb2.IssueRef(project_name='proj', local_id=2)],
        is_private=True)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    self.CallWrapped(self.features_svcr.CreateHotlist, mc, request)

    # Check that the hotlist was successfuly added.
    hotlist_id = self.services.features.LookupHotlistIDs(
        self.cnxn, ['Fake-Hotlist'], [111]).get(('fake-hotlist', 111))
    hotlist = self.services.features.GetHotlist(self.cnxn, hotlist_id)
    self.assertEqual('Summary', hotlist.summary)
    self.assertEqual('Description', hotlist.description)
    self.assertEqual([111], hotlist.owner_ids)
    self.assertEqual([222, 333], hotlist.editor_ids)
    self.assertEqual(
        [self.issue_1.issue_id, self.issue_2.issue_id],
        [item.issue_id for item in hotlist.items])
    self.assertTrue(hotlist.is_private)

  def testCreateHotlist_Simple(self):
    request = features_pb2.CreateHotlistRequest(
        name='Fake-Hotlist',
        summary='Summary',
        description='Description')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    self.CallWrapped(self.features_svcr.CreateHotlist, mc, request)

    # Check that the hotlist was successfuly added.
    hotlist_id = self.services.features.LookupHotlistIDs(
        self.cnxn, ['Fake-Hotlist'], [111]).get(('fake-hotlist', 111))
    hotlist = self.services.features.GetHotlist(self.cnxn, hotlist_id)
    self.assertEqual('Summary', hotlist.summary)
    self.assertEqual('Description', hotlist.description)
    self.assertEqual([111], hotlist.owner_ids)
    self.assertEqual([], hotlist.editor_ids)
    self.assertEqual(0, len(hotlist.items))
    self.assertFalse(hotlist.is_private)

  def testCheckHotlistName_OK(self):
    request = features_pb2.CheckHotlistNameRequest(name='Fake-Hotlist')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    result = self.CallWrapped(self.features_svcr.CheckHotlistName, mc, request)
    self.assertEqual('', result.error)

  def testCheckHotlistName_Anon(self):
    request = features_pb2.CheckHotlistNameRequest(name='Fake-Hotlist')
    mc = monorailcontext.MonorailContext(self.services, cnxn=self.cnxn)

    with self.assertRaises(exceptions.InputException):
      self.CallWrapped(self.features_svcr.CheckHotlistName, mc, request)

  def testCheckHotlistName_InvalidName(self):
    request = features_pb2.CheckHotlistNameRequest(name='**Invalid**')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')

    result = self.CallWrapped(self.features_svcr.CheckHotlistName, mc, request)
    self.assertNotEqual('', result.error)

  def testCheckHotlistName_AlreadyExists(self):
    self.services.features.CreateHotlist(
        self.cnxn, 'Fake-Hotlist', 'Summary', 'Description',
        owner_ids=[111], editor_ids=[])

    request = features_pb2.CheckHotlistNameRequest(name='Fake-Hotlist')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')

    result = self.CallWrapped(self.features_svcr.CheckHotlistName, mc, request)
    self.assertNotEqual('', result.error)

  def testRemoveIssuesFromHotlists(self):
    # Create two hotlists with issues 1 and 2.
    hotlist_1 = self.services.features.CreateHotlist(
        self.cnxn, 'Hotlist-1', 'Summary', 'Description', owner_ids=[111],
        editor_ids=[])
    hotlist_2 = self.services.features.CreateHotlist(
        self.cnxn, 'Hotlist-2', 'Summary', 'Description', owner_ids=[111],
        editor_ids=[])
    self.services.features.AddIssuesToHotlists(
        self.cnxn,
        [hotlist_1.hotlist_id, hotlist_2.hotlist_id],
        [(self.issue_1.issue_id, 111, 0, ''),
         (self.issue_2.issue_id, 111, 0, '')],
        None, None, None)

    # Remove Issue 1 from both hotlists.
    request = features_pb2.RemoveIssuesFromHotlistsRequest(
        hotlist_refs=[
            common_pb2.HotlistRef(
                name='Hotlist-1',
                owner=common_pb2.UserRef(user_id=111)),
            common_pb2.HotlistRef(
                name='Hotlist-2',
                owner=common_pb2.UserRef(user_id=111))],
        issue_refs=[
            common_pb2.IssueRef(project_name='proj', local_id=1)])

    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    self.CallWrapped(self.features_svcr.RemoveIssuesFromHotlists, mc, request)

    # Only Issue 2 should remain in both lists.
    self.assertEqual(
        [self.issue_2.issue_id],
        [item.issue_id for item in hotlist_1.items])
    self.assertEqual(
        [self.issue_2.issue_id],
        [item.issue_id for item in hotlist_2.items])

  def testAddIssuesToHotlists(self):
    # Create two hotlists
    hotlist_1 = self.services.features.CreateHotlist(
        self.cnxn, 'Hotlist-1', 'Summary', 'Description', owner_ids=[111],
        editor_ids=[])
    hotlist_2 = self.services.features.CreateHotlist(
        self.cnxn, 'Hotlist-2', 'Summary', 'Description', owner_ids=[111],
        editor_ids=[])

    # Add Issue 1 to both hotlists
    request = features_pb2.AddIssuesToHotlistsRequest(
        note='Foo',
        hotlist_refs=[
            common_pb2.HotlistRef(
                name='Hotlist-1',
                owner=common_pb2.UserRef(user_id=111)),
            common_pb2.HotlistRef(
                name='Hotlist-2',
                owner=common_pb2.UserRef(user_id=111))],
        issue_refs=[
            common_pb2.IssueRef(project_name='proj', local_id=1)])

    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    self.CallWrapped(self.features_svcr.AddIssuesToHotlists, mc, request)

    self.assertEqual(
        [self.issue_1.issue_id],
        [item.issue_id for item in hotlist_1.items])
    self.assertEqual(
        [self.issue_1.issue_id],
        [item.issue_id for item in hotlist_2.items])

    self.assertEqual('Foo', hotlist_1.items[0].note)
    self.assertEqual('Foo', hotlist_2.items[0].note)

  def testRerankHotlistIssues(self):
    """Rerank a hotlist."""
    issue_3 = fake.MakeTestIssue(
        789, 3, 'sum', 'New', 111, project_name='proj', issue_id=78903)
    issue_4 = fake.MakeTestIssue(
        789, 4, 'sum', 'New', 111, project_name='proj', issue_id=78904)
    self.services.issue.TestAddIssue(issue_3)
    self.services.issue.TestAddIssue(issue_4)

    owner_ids = [self.user1.user_id]
    follower_ids = [self.user2.user_id]
    editor_ids = [self.user3.user_id]
    hotlist_items = [
        (78904, 31, self.user2.user_id, self.PAST_TIME, 'note'),
        (78903, 21, self.user2.user_id, self.PAST_TIME, 'note'),
        (78902, 11, self.user2.user_id, self.PAST_TIME, 'note'),
        (78901, 1, self.user2.user_id, self.PAST_TIME, 'note')]
    hotlist = self.services.features.TestAddHotlist(
        'RerankHotlistName', summary='summary', owner_ids=owner_ids,
        editor_ids=editor_ids, follower_ids=follower_ids,
        hotlist_id=1236, hotlist_item_fields=hotlist_items)

    request = features_pb2.RerankHotlistIssuesRequest(
        hotlist_ref=common_pb2.HotlistRef(
            name='RerankHotlistName',
            owner=common_pb2.UserRef(user_id=self.user1.user_id)),
        moved_refs=[common_pb2.IssueRef(
            project_name='proj', local_id=2)],
        target_ref=common_pb2.IssueRef(project_name='proj', local_id=4),
        split_above=True)

    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.user1.email)
    mc.LookupLoggedInUserPerms(self.project)
    self.CallWrapped(self.features_svcr.RerankHotlistIssues, mc, request)

    self.assertEqual(
        [item.issue_id for item in hotlist.items],
        [78901, 78903, 78902, 78904])

  def testUpdateHotlistIssueNote(self):
    hotlist = self.services.features.CreateHotlist(
        self.cnxn, 'Hotlist-1', 'Summary', 'Description', owner_ids=[111],
        editor_ids=[])
    self.services.features.AddIssuesToHotlists(
        self.cnxn,
        [hotlist.hotlist_id], [(self.issue_1.issue_id, 111, 0, '')],
        None, None, None)

    request = features_pb2.UpdateHotlistIssueNoteRequest(
        hotlist_ref=common_pb2.HotlistRef(
            name='Hotlist-1',
            owner=common_pb2.UserRef(user_id=111)),
        issue_ref=common_pb2.IssueRef(
            project_name='proj',
            local_id=1),
        note='Note')

    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    self.CallWrapped(self.features_svcr.UpdateHotlistIssueNote, mc, request)

    self.assertEqual('Note', hotlist.items[0].note)

  def testUpdateHotlistIssueNote_NotAllowed(self):
    hotlist = self.services.features.CreateHotlist(
        self.cnxn, 'Hotlist-1', 'Summary', 'Description', owner_ids=[222],
        editor_ids=[])
    self.services.features.AddIssuesToHotlists(
        self.cnxn,
        [hotlist.hotlist_id], [(self.issue_1.issue_id, 222, 0, '')],
        None, None, None)

    request = features_pb2.UpdateHotlistIssueNoteRequest(
        hotlist_ref=common_pb2.HotlistRef(
            name='Hotlist-1',
            owner=common_pb2.UserRef(user_id=222)),
        issue_ref=common_pb2.IssueRef(
            project_name='proj',
            local_id=1),
        note='Note')

    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    with self.assertRaises(permissions.PermissionException):
      self.CallWrapped(self.features_svcr.UpdateHotlistIssueNote, mc, request)

    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.user2.email)
    mc.LookupLoggedInUserPerms(None)

    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.user2.email)
    mc.LookupLoggedInUserPerms(None)

  def testDeleteHotlist(self):
    """Test we can delete a hotlist via the API."""
    owner_ids = [self.user2.user_id]
    editor_ids = []
    hotlist = self.services.features.TestAddHotlist(
        name='Hotlist-1', summary='summary', description='description',
        owner_ids=owner_ids, editor_ids=editor_ids, hotlist_id=1235)
    request = features_pb2.DeleteHotlistRequest(
        hotlist_ref=common_pb2.HotlistRef(
            name=hotlist.name,
            owner=common_pb2.UserRef(user_id=self.user2.user_id)))

    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.user2.email)
    mc.LookupLoggedInUserPerms(None)
    self.CallWrapped(self.features_svcr.DeleteHotlist, mc, request)

    self.assertTrue(
        hotlist.hotlist_id in self.services.features.expunged_hotlist_ids)

  def testPredictComponent_Normal(self):
    """Test normal case when predicted component exists."""
    component_id = self.services.config.CreateComponentDef(
        cnxn=None, project_id=self.project.project_id, path='Ruta>Baga',
        docstring='', deprecated=False, admin_ids=[], cc_ids=[], created=None,
        creator_id=None, label_ids=[])

    self._top_words = {
        'foo': 0,
        'bar': 1,
        'baz': 2}
    self._components_by_index = {
        '0': '123',
        '1': str(component_id),
        '2': '789'}
    self._ml_engine.expected_features = [3, 0, 1, 0, 0]
    self._ml_engine.scores = [5, 10, 3]

    request = features_pb2.PredictComponentRequest(
        project_name='proj',
        text='foo baz foo foo')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    result = self.CallWrapped(self.features_svcr.PredictComponent, mc, request)

    self.assertEqual(
        common_pb2.ComponentRef(
            path='Ruta>Baga'),
        result.component_ref)

  def testPredictComponent_NoPrediction(self):
    """Test case when no component id was predicted."""
    self._top_words = {
        'foo': 0,
        'bar': 1,
        'baz': 2}
    self._components_by_index = {
        '0': '123',
        '1': '456',
        '2': '789'}
    self._ml_engine.expected_features = [3, 0, 1, 0, 0]
    self._ml_engine.scores = [5, 10, 3]

    request = features_pb2.PredictComponentRequest(
        project_name='proj',
        text='foo baz foo foo')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    result = self.CallWrapped(self.features_svcr.PredictComponent, mc, request)

    self.assertEqual(common_pb2.ComponentRef(), result.component_ref)
