# 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 unittest
try:
  from mox3 import mox
except ImportError:
  import mox

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

from api.api_proto import common_pb2
from api.api_proto import features_pb2
from api.api_proto import features_objects_pb2
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

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

  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)
