# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

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

import unittest
from mock import patch

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

from api import projects_servicer
from api.api_proto import common_pb2
from api.api_proto import issue_objects_pb2
from api.api_proto import project_objects_pb2
from api.api_proto import projects_pb2
from framework import exceptions
from framework import monorailcontext
from framework import permissions
from mrproto import tracker_pb2
from mrproto import project_pb2
from tracker import tracker_bizobj
from tracker import tracker_constants
from testing import fake
from testing import testing_helpers
from services import service_manager


class ProjectsServicerTest(unittest.TestCase):

  def setUp(self):
    self.cnxn = fake.MonorailConnection()
    self.services = service_manager.Services(
        config=fake.ConfigService(),
        issue=fake.IssueService(),
        user=fake.UserService(),
        usergroup=fake.UserGroupService(),
        project=fake.ProjectService(),
        project_star=fake.ProjectStarService(),
        features=fake.FeaturesService())

    self.admin = self.services.user.TestAddUser('admin@example.com', 123)
    self.admin.is_site_admin = True
    self.owner = self.services.user.TestAddUser('owner@example.com', 111)
    self.services.user.TestAddUser('user_222@example.com', 222)
    self.services.user.TestAddUser('user_333@example.com', 333)
    self.services.user.TestAddUser('user_444@example.com', 444)
    self.services.user.TestAddUser('user_666@example.com', 666)

    # User group 888 has members: user_555 and proj@monorail.com
    self.services.user.TestAddUser('group888@googlegroups.com', 888)
    self.services.usergroup.TestAddGroupSettings(
        888, 'group888@googlegroups.com')
    self.services.usergroup.TestAddMembers(888, [555, 1001])

    # User group 999 has members: user_111 and user_444
    self.services.user.TestAddUser('group999@googlegroups.com', 999)
    self.services.usergroup.TestAddGroupSettings(
        999, 'group999@googlegroups.com')
    self.services.usergroup.TestAddMembers(999, [111, 444])

    # User group 777 has members: user_666 and group 999.
    self.services.user.TestAddUser('group777@googlegroups.com', 777)
    self.services.usergroup.TestAddGroupSettings(
        777, 'group777@googlegroups.com')
    self.services.usergroup.TestAddMembers(777, [666, 999])

    self.project = self.services.project.TestAddProject(
        'proj',
        project_id=789,
        owner_ids=[111],
        committer_ids=[222],
        contrib_ids=[333])
    self.projects_svcr = projects_servicer.ProjectsServicer(
        self.services, make_rate_limiter=False)
    self.prpc_context = context.ServicerContext()
    self.prpc_context.set_code(codes.StatusCode.OK)

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

  def testListProjects_Normal(self):
    """We can get a list of all projects on the site."""
    request = projects_pb2.ListProjectsRequest()
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(self.projects_svcr.ListProjects, mc, request)
    self.assertEqual(2, len(response.projects))

  def testGetConfig_Normal(self):
    """We can get a project config."""
    request = projects_pb2.GetConfigRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(self.projects_svcr.GetConfig, mc, request)
    self.assertEqual('proj', response.project_name)

  def testGetConfig_NoSuchProject(self):
    """We reject a request to get a config for a non-existent project."""
    request = projects_pb2.GetConfigRequest(project_name='unknown-proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    with self.assertRaises(exceptions.NoSuchProjectException):
      self.CallWrapped(self.projects_svcr.GetConfig, mc, request)

  def testGetConfig_PermissionDenied(self):
    """We reject a request to get a config for a non-viewable project."""
    self.project.access = project_pb2.ProjectAccess.MEMBERS_ONLY
    request = projects_pb2.GetConfigRequest(project_name='proj')

    # User is a member of the members-only project.
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(self.projects_svcr.GetConfig, mc, request)
    self.assertEqual('proj', response.project_name)

    # User is not a member of the members-only project.
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='nonmember@example.com')
    with self.assertRaises(permissions.PermissionException):
      self.CallWrapped(self.projects_svcr.GetConfig, mc, request)

  @patch('businesslogic.work_env.WorkEnv.ListProjectTemplates')
  def testListProjectTemplates_Normal(self, mockListProjectTemplates):
    fd_1 = tracker_pb2.FieldDef(
        field_name='FirstField', field_id=1,
        field_type=tracker_pb2.FieldTypes.STR_TYPE)
    fd_2 = tracker_pb2.FieldDef(
        field_name='LegalApproval', field_id=2,
        field_type=tracker_pb2.FieldTypes.APPROVAL_TYPE)
    component = tracker_pb2.ComponentDef(component_id=1, path='dude')
    status_def = tracker_pb2.StatusDef(status='New', means_open=True)
    config = tracker_pb2.ProjectIssueConfig(
        project_id=789, field_defs=[fd_1, fd_2], component_defs=[component],
        well_known_statuses=[status_def])
    self.services.config.StoreConfig(self.cnxn, config)
    admin1 = self.services.user.TestAddUser('admin@example.com', 222)
    appr1 = self.services.user.TestAddUser('approver@example.com', 333)
    setter = self.services.user.TestAddUser('setter@example.com', 444)
    template = tracker_pb2.TemplateDef(
        name='Chicken', content='description', summary='summary',
        status='New', admin_ids=[admin1.user_id],
        field_values=[tracker_bizobj.MakeFieldValue(
            fd_1.field_id, None, 'Cow', None, None, None, False)],
        component_ids=[component.component_id],
        approval_values=[tracker_pb2.ApprovalValue(
            approval_id=2, approver_ids=[appr1.user_id],
            setter_id=setter.user_id)])
    mockListProjectTemplates.return_value = [template]

    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    request = projects_pb2.ListProjectTemplatesRequest(project_name='proj')
    response = self.CallWrapped(
        self.projects_svcr.ListProjectTemplates, mc, request)
    self.assertEqual(
        response,
        projects_pb2.ListProjectTemplatesResponse(
            templates=[project_objects_pb2.TemplateDef(
                template_name='Chicken',
                content='description',
                summary='summary',
                status_ref=common_pb2.StatusRef(
                    status='New',
                    is_derived=False,
                    means_open=True),
                owner_defaults_to_member=True,
                admin_refs=[
                  common_pb2.UserRef(
                      user_id=admin1.user_id,
                      display_name=testing_helpers.ObscuredEmail(admin1.email),
                      is_derived=False)],
                field_values=[
                  issue_objects_pb2.FieldValue(
                    field_ref=common_pb2.FieldRef(
                        field_id=fd_1.field_id,
                        field_name=fd_1.field_name,
                        type=common_pb2.STR_TYPE),
                    value='Cow')],
                component_refs=[
                    common_pb2.ComponentRef(
                        path=component.path, is_derived=False)],
                approval_values=[
                  issue_objects_pb2.Approval(
                    field_ref=common_pb2.FieldRef(
                        field_id=fd_2.field_id,
                        field_name=fd_2.field_name,
                        type=common_pb2.APPROVAL_TYPE),
                    setter_ref=common_pb2.UserRef(
                        user_id=setter.user_id,
                        display_name=testing_helpers.ObscuredEmail(
                            setter.email)),
                    phase_ref=issue_objects_pb2.PhaseRef(),
                    approver_refs=[common_pb2.UserRef(
                        user_id=appr1.user_id,
                        display_name=testing_helpers.ObscuredEmail(appr1.email),
                        is_derived=False)])],
          )]))

  def testListProjectTemplates_NoProjectName(self):
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    request = projects_pb2.ListProjectTemplatesRequest()
    with self.assertRaises(exceptions.InputException):
      self.CallWrapped(self.projects_svcr.ListProjectTemplates, mc, request)

  def testListProjectTemplates_NoSuchProject(self):
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    request = projects_pb2.ListProjectTemplatesRequest(project_name='ghost')
    with self.assertRaises(exceptions.NoSuchProjectException):
      self.CallWrapped(self.projects_svcr.ListProjectTemplates, mc, request)

  def testListProjectTemplates_PermissionDenied(self):
    self.project.access = project_pb2.ProjectAccess.MEMBERS_ONLY
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='nonmember@example.com')
    request = projects_pb2.GetConfigRequest(project_name='proj')
    with self.assertRaises(permissions.PermissionException):
      self.CallWrapped(self.projects_svcr.ListProjectTemplates, mc, request)

  def testGetPresentationConfig_Normal(self):
    """Test getting project summary, thumbnail url, custom issue entry, etc."""
    config = tracker_pb2.ProjectIssueConfig(project_id=789)
    self.project.summary = 'project summary'
    config.custom_issue_entry_url = 'issue entry url'
    config.member_default_query = 'default query'
    config.default_col_spec = 'ID Summary'
    config.default_sort_spec = 'Priority Status'
    config.default_x_attr = 'Priority'
    config.default_y_attr = 'Status'
    self.project.revision_url_format = 'revision url format'
    self.services.config.StoreConfig(self.cnxn, config)

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

    request = projects_pb2.GetPresentationConfigRequest(project_name='proj')
    response = self.CallWrapped(
        self.projects_svcr.GetPresentationConfig, mc, request)

    self.assertEqual('project summary', response.project_summary)
    self.assertEqual('issue entry url', response.custom_issue_entry_url)
    self.assertEqual('default query', response.default_query)
    self.assertEqual('ID Summary', response.default_col_spec)
    self.assertEqual('Priority Status', response.default_sort_spec)
    self.assertEqual('Priority', response.default_x_attr)
    self.assertEqual('Status', response.default_y_attr)
    self.assertEqual('revision url format', response.revision_url_format)

  def testGetPresentationConfig_SavedQueriesAllowed(self):
    """Only project members or higher can see project saved queries."""
    self.services.features.UpdateCannedQueries(self.cnxn, 789, [
        tracker_pb2.SavedQuery(query_id=101, name='test', query='owner:me'),
        tracker_pb2.SavedQuery(query_id=202, name='hello', query='world')
    ])

    # User 333 is a contributor.
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='user_333@example.com')

    request = projects_pb2.GetPresentationConfigRequest(project_name='proj')
    response = self.CallWrapped(self.projects_svcr.GetPresentationConfig, mc,
        request)

    self.assertEqual(2, len(response.saved_queries))

    self.assertEqual(101, response.saved_queries[0].query_id)
    self.assertEqual('test', response.saved_queries[0].name)
    self.assertEqual('owner:me', response.saved_queries[0].query)

    self.assertEqual(202, response.saved_queries[1].query_id)
    self.assertEqual('hello', response.saved_queries[1].name)
    self.assertEqual('world', response.saved_queries[1].query)

  def testGetPresentationConfig_SavedQueriesDenied(self):
    """Only project members or higher can see project saved queries."""
    self.services.features.UpdateCannedQueries(self.cnxn, 789, [
        tracker_pb2.SavedQuery(query_id=101, name='test', query='owner:me'),
        tracker_pb2.SavedQuery(query_id=202, name='hello', query='world')
    ])

    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='nonmember@example.com')

    request = projects_pb2.GetPresentationConfigRequest(project_name='proj')
    response = self.CallWrapped(self.projects_svcr.GetPresentationConfig, mc,
        request)

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

  def testGetCustomPermissions_Normal(self):
    self.project.extra_perms = [
        project_pb2.Project.ExtraPerms(
            member_id=111,
            perms=['FooPerm', 'BarPerm'])]

    request = projects_pb2.GetConfigRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='foo@example.org')
    response = self.CallWrapped(
        self.projects_svcr.GetCustomPermissions, mc, request)
    self.assertEqual(['BarPerm', 'FooPerm'], response.permissions)

  def testGetCustomPermissions_PermissionsAreDedupped(self):
    self.project.extra_perms = [
        project_pb2.Project.ExtraPerms(
            member_id=111,
            perms=['FooPerm', 'FooPerm']),
        project_pb2.Project.ExtraPerms(
            member_id=222,
            perms=['FooPerm'])]

    request = projects_pb2.GetConfigRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='foo@example.org')
    response = self.CallWrapped(
        self.projects_svcr.GetCustomPermissions, mc, request)
    self.assertEqual(['FooPerm'], response.permissions)

  def testGetCustomPermissions_PermissionsAreSorted(self):
    self.project.extra_perms = [
        project_pb2.Project.ExtraPerms(
            member_id=111,
            perms=['FooPerm', 'BarPerm']),
        project_pb2.Project.ExtraPerms(
            member_id=222,
            perms=['BazPerm'])]

    request = projects_pb2.GetConfigRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='foo@example.org')
    response = self.CallWrapped(
        self.projects_svcr.GetCustomPermissions, mc, request)
    self.assertEqual(['BarPerm', 'BazPerm', 'FooPerm'], response.permissions)

  def testGetCustomPermissions_IgnoreStandardPermissions(self):
    self.project.extra_perms = [
        project_pb2.Project.ExtraPerms(
            member_id=111,
            perms=permissions.STANDARD_PERMISSIONS + ['FooPerm'])]

    request = projects_pb2.GetConfigRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='foo@example.org')
    response = self.CallWrapped(
        self.projects_svcr.GetCustomPermissions, mc, request)
    self.assertEqual(['FooPerm'], response.permissions)

  def testGetCustomPermissions_NoCustomPermissions(self):
    self.project.extra_perms = []
    request = projects_pb2.GetConfigRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='foo@example.org')
    response = self.CallWrapped(
        self.projects_svcr.GetCustomPermissions, mc, request)
    self.assertEqual([], response.permissions)

  def assertVisibleMembers(self, expected_user_ids, expected_group_ids,
                           requester=None):
    request = projects_pb2.GetVisibleMembersRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=requester)
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(
        self.projects_svcr.GetVisibleMembers, mc, request)
    self.assertEqual(
        expected_user_ids,
        [user_ref.user_id for user_ref in response.user_refs])
    # Assert that we get the full email address.
    self.assertEqual(
        [self.services.user.LookupUserEmail(self.cnxn, user_id)
         for user_id in expected_user_ids],
        [user_ref.display_name for user_ref in response.user_refs])
    self.assertEqual(
        expected_group_ids,
        [group_ref.user_id for group_ref in response.group_refs])
    # Assert that we get the full email address.
    self.assertEqual(
        [self.services.user.LookupUserEmail(self.cnxn, user_id)
         for user_id in expected_group_ids],
        [group_ref.display_name for group_ref in response.group_refs])
    return response

  def testGetVisibleMembers_Normal(self):
    # Not logged in - Test users have their email addresses obscured to
    # non-project members by default.
    self.assertVisibleMembers([], [])
    # Logged in as non project member
    self.assertVisibleMembers([], [], requester='foo@example.com')
    # Logged in as owner
    self.assertVisibleMembers([111, 222, 333], [],
                              requester='owner@example.com')
    # Logged in as committer
    self.assertVisibleMembers([111, 222, 333], [],
                              requester='user_222@example.com')
    # Logged in as contributor
    self.assertVisibleMembers([111, 222, 333], [],
                              requester='user_333@example.com')

  def testGetVisibleMembers_OnlyOwnersSeeContributors(self):
    self.project.only_owners_see_contributors = True
    # Not logged in
    with self.assertRaises(permissions.PermissionException):
      self.assertVisibleMembers([111, 222], [])
    # Logged in with a non-member
    with self.assertRaises(permissions.PermissionException):
      self.assertVisibleMembers([111, 222], [], requester='foo@example.com')
    # Logged in as owner
    self.assertVisibleMembers([111, 222, 333], [],
                              requester='owner@example.com')
    # Logged in as committer
    self.assertVisibleMembers([111, 222, 333], [],
                              requester='user_222@example.com')
    # Logged in as contributor
    with self.assertRaises(permissions.PermissionException):
      self.assertVisibleMembers(
          [111, 222], [], requester='user_333@example.com')

  def testGetVisibleMembers_MemberIsGroup(self):
    self.project.contributor_ids.extend([999])
    self.assertVisibleMembers([999, 111, 222, 333, 444], [999],
                              requester='owner@example.com')

  def testGetVisibleMembers_AcExclusion(self):
    self.services.project.ac_exclusion_ids[self.project.project_id] = [333]
    self.assertVisibleMembers([111, 222], [], requester='owner@example.com')

  def testGetVisibleMembers_NoExpand(self):
    self.services.project.no_expand_ids[self.project.project_id] = [999]
    self.project.contributor_ids.extend([999])
    self.assertVisibleMembers([999, 111, 222, 333], [999],
                              requester='owner@example.com')

  def testGetVisibleMembers_ObscuredEmails(self):
    # Unobscure the owner's email. Non-project members can see.
    self.services.user.UpdateUserSettings(
        self.cnxn, 111, self.owner, obscure_email=False)

    # Not logged in
    self.assertVisibleMembers([111], [])
    # Logged in as not a project member
    self.assertVisibleMembers([111], [], requester='foo@example.com')
    # Logged in as owner
    self.assertVisibleMembers(
        [111, 222, 333], [], requester='owner@example.com')
    # Logged in as committer
    self.assertVisibleMembers(
        [111, 222, 333], [], requester='user_222@example.com')
    # Logged in as contributor
    self.assertVisibleMembers(
        [111, 222, 333], [], requester='user_333@example.com')

  def testListStatuses(self):
    request = projects_pb2.ListStatusesRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.projects_svcr.ListStatuses, mc, request)
    self.assertFalse(response.restrict_to_known)
    self.assertEqual(
        [('New', True),
         ('Accepted', True),
         ('Started', True),
         ('Fixed', False),
         ('Verified', False),
         ('Invalid', False),
         ('Duplicate', False),
         ('WontFix', False),
         ('Done', False)],
        [(status_def.status, status_def.means_open)
         for status_def in response.status_defs])
    self.assertEqual(
        [('Duplicate', False)],
        [(status_def.status, status_def.means_open)
         for status_def in response.statuses_offer_merge])

  def testListComponents(self):
    self.services.config.CreateComponentDef(
        self.cnxn, self.project.project_id, 'Foo', 'Foo Component', True, [],
        [], True, 111, [])
    self.services.config.CreateComponentDef(
        self.cnxn, self.project.project_id, 'Bar', 'Bar Component', False, [],
        [], True, 111, [])
    self.services.config.CreateComponentDef(
        self.cnxn, self.project.project_id, 'Bar>Baz', 'Baz Component',
        False, [], [], True, 111, [])

    request = projects_pb2.ListComponentsRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.projects_svcr.ListComponents, mc, request)

    self.assertEqual(
        [project_objects_pb2.ComponentDef(
            path='Foo',
            docstring='Foo Component',
            deprecated=True),
         project_objects_pb2.ComponentDef(
             path='Bar',
             docstring='Bar Component',
             deprecated=False),
         project_objects_pb2.ComponentDef(
             path='Bar>Baz',
             docstring='Baz Component',
             deprecated=False)],
        list(response.component_defs))

  def testListComponents_IncludeAdminInfo(self):
    self.services.config.CreateComponentDef(
        self.cnxn, self.project.project_id, 'Foo', 'Foo Component', True, [],
        [], 1234567, 111, [])
    self.services.config.CreateComponentDef(
        self.cnxn, self.project.project_id, 'Bar', 'Bar Component', False, [],
        [], 1234568, 111, [])
    self.services.config.CreateComponentDef(
        self.cnxn, self.project.project_id, 'Bar>Baz', 'Baz Component',
        False, [], [], 1234569, 111, [])
    creator_ref = common_pb2.UserRef(
        user_id=111,
        display_name='owner@example.com')

    request = projects_pb2.ListComponentsRequest(
        project_name='proj', include_admin_info=True)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.projects_svcr.ListComponents, mc, request)

    self.assertEqual(
        [project_objects_pb2.ComponentDef(
            path='Foo',
            docstring='Foo Component',
            deprecated=True,
            created=1234567,
            creator_ref=creator_ref),
         project_objects_pb2.ComponentDef(
             path='Bar',
             docstring='Bar Component',
             deprecated=False,
             created=1234568,
             creator_ref=creator_ref),
         project_objects_pb2.ComponentDef(
             path='Bar>Baz',
             docstring='Baz Component',
             deprecated=False,
             created=1234569,
             creator_ref=creator_ref),
            ],
        list(response.component_defs))

  def AddField(self, name, **kwargs):
    if kwargs.get('needs_perm'):
      kwargs['needs_member'] = True
    kwargs.setdefault('cnxn', self.cnxn)
    kwargs.setdefault('project_id', self.project.project_id)
    kwargs.setdefault('field_name', name)
    kwargs.setdefault('field_type_str', 'USER_TYPE')
    for arg in ('applic_type', 'applic_pred', 'is_required', 'is_niche',
                'is_multivalued', 'min_value', 'max_value', 'regex',
                'needs_member', 'needs_perm', 'grants_perm', 'notify_on',
                'date_action_str', 'docstring'):
      kwargs.setdefault(arg, None)
    for arg in ('admin_ids', 'editor_ids'):
      kwargs.setdefault(arg, [])

    self.services.config.CreateFieldDef(**kwargs)

  def testListFields_Normal(self):
    self.AddField('Foo Field', needs_perm=permissions.EDIT_ISSUE)

    request = projects_pb2.ListFieldsRequest(
        project_name='proj', include_user_choices=True)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.projects_svcr.ListFields, mc, request)

    self.assertEqual(1, len(response.field_defs))
    field = response.field_defs[0]
    self.assertEqual('Foo Field', field.field_ref.field_name)
    self.assertEqual(
        [111, 222],
        sorted([user_ref.user_id for user_ref in field.user_choices]))
    self.assertEqual(
        ['owner@example.com', 'user_222@example.com'],
        sorted([user_ref.display_name for user_ref in field.user_choices]))

  def testListFields_DontIncludeUserChoices(self):
    self.AddField('Foo Field', needs_perm=permissions.EDIT_ISSUE)

    request = projects_pb2.ListFieldsRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.projects_svcr.ListFields, mc, request)

    self.assertEqual(1, len(response.field_defs))
    field = response.field_defs[0]
    self.assertEqual(0, len(field.user_choices))

  def testListFields_IncludeAdminInfo(self):
    self.AddField('Foo Field', needs_perm=permissions.EDIT_ISSUE, is_niche=True,
                  applic_type='Foo Applic Type')

    request = projects_pb2.ListFieldsRequest(
        project_name='proj', include_admin_info=True)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.projects_svcr.ListFields, mc, request)

    self.assertEqual(1, len(response.field_defs))
    field = response.field_defs[0]
    self.assertEqual('Foo Field', field.field_ref.field_name)
    self.assertEqual(True, field.is_niche)
    self.assertEqual('Foo Applic Type', field.applicable_type)

  def testListFields_EnumFieldChoices(self):
    self.AddField('Type', field_type_str='ENUM_TYPE')

    request = projects_pb2.ListFieldsRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.projects_svcr.ListFields, mc, request)

    self.assertEqual(1, len(response.field_defs))
    field = response.field_defs[0]
    self.assertEqual('Type', field.field_ref.field_name)
    self.assertEqual(
        ['Defect', 'Enhancement', 'Task', 'Other'],
        [label.label for label in field.enum_choices])

  def testListFields_CustomPermission(self):
    self.AddField('Foo Field', needs_perm='FooPerm')
    self.project.extra_perms = [
        project_pb2.Project.ExtraPerms(
            member_id=111,
            perms=['UnrelatedPerm']),
        project_pb2.Project.ExtraPerms(
            member_id=222,
            perms=['FooPerm'])]

    request = projects_pb2.ListFieldsRequest(
        project_name='proj', include_user_choices=True)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.projects_svcr.ListFields, mc, request)

    self.assertEqual(1, len(response.field_defs))
    field = response.field_defs[0]
    self.assertEqual('Foo Field', field.field_ref.field_name)
    self.assertEqual(
        [222],
        sorted([user_ref.user_id for user_ref in field.user_choices]))
    self.assertEqual(
        ['user_222@example.com'],
        sorted([user_ref.display_name for user_ref in field.user_choices]))

  def testListFields_IndirectPermission(self):
    """Test that the permissions of effective ids are also considered."""
    self.AddField('Foo Field', needs_perm='FooPerm')
    self.project.contributor_ids.extend([999])
    self.project.extra_perms = [
        project_pb2.Project.ExtraPerms(
            member_id=999,
            perms=['FooPerm', 'BarPerm'])]

    request = projects_pb2.ListFieldsRequest(
        project_name='proj', include_user_choices=True)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(
        self.projects_svcr.ListFields, mc, request)

    self.assertEqual(1, len(response.field_defs))
    field = response.field_defs[0]
    self.assertEqual('Foo Field', field.field_ref.field_name)
    # Users 111 and 444 are members of group 999, which has the needed
    # permission.
    self.assertEqual(
        [111, 444, 999],
        sorted([user_ref.user_id for user_ref in field.user_choices]))
    self.assertEqual(
        ['group999@googlegroups.com', 'owner@example.com',
         'user_444@example.com'],
        sorted([user_ref.display_name for user_ref in field.user_choices]))

  def testListFields_TwiceIndirectPermission(self):
    """Test that only direct memberships are considered."""
    self.AddField('Foo Field', needs_perm='FooPerm')
    # User group 777 has members: user_666 and group 999.
    self.project.contributor_ids.extend([777])
    self.project.contributor_ids.extend([999])
    self.project.extra_perms = [
        project_pb2.Project.ExtraPerms(
            member_id=777, perms=['FooPerm', 'BarPerm'])
    ]

    request = projects_pb2.ListFieldsRequest(
        project_name='proj', include_user_choices=True)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(self.projects_svcr.ListFields, mc, request)

    self.assertEqual(1, len(response.field_defs))
    field = response.field_defs[0]
    self.assertEqual('Foo Field', field.field_ref.field_name)
    self.assertEqual(
        [666, 777, 999],
        sorted([user_ref.user_id for user_ref in field.user_choices]))
    self.assertEqual(
        [
            'group777@googlegroups.com', 'group999@googlegroups.com',
            'user_666@example.com'
        ], sorted([user_ref.display_name for user_ref in field.user_choices]))

  def testListFields_NoPermissionsNeeded(self):
    self.AddField('Foo Field')

    request = projects_pb2.ListFieldsRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.projects_svcr.ListFields, mc, request)

    self.assertEqual(1, len(response.field_defs))
    field = response.field_defs[0]
    self.assertEqual('Foo Field', field.field_ref.field_name)

  def testListFields_MultipleFields(self):
    self.AddField('Bar Field', needs_perm=permissions.VIEW)
    self.AddField('Foo Field', needs_perm=permissions.EDIT_ISSUE)

    request = projects_pb2.ListFieldsRequest(
        project_name='proj', include_user_choices=True)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.projects_svcr.ListFields, mc, request)

    self.assertEqual(2, len(response.field_defs))
    field_defs = sorted(
        response.field_defs, key=lambda field: field.field_ref.field_name)

    self.assertEqual(
        ['Bar Field', 'Foo Field'],
        [field.field_ref.field_name for field in field_defs])
    self.assertEqual(
        [[111, 222, 333],
         [111, 222]],
        [sorted(user_ref.user_id for user_ref in field.user_choices)
         for field in field_defs])
    self.assertEqual(
        [['owner@example.com', 'user_222@example.com', 'user_333@example.com'],
         ['owner@example.com', 'user_222@example.com']],
        [sorted(user_ref.display_name for user_ref in field.user_choices)
         for field in field_defs])

  def testListFields_NoFields(self):
    request = projects_pb2.ListFieldsRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.projects_svcr.ListFields, mc, request)

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

  def testGetLabelOptions_Normal(self):
    request = projects_pb2.GetLabelOptionsRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.projects_svcr.GetLabelOptions, mc, request)

    expected_label_names = [
        label[0] for label in tracker_constants.DEFAULT_WELL_KNOWN_LABELS]
    expected_label_names += [
        'Restrict-View-EditIssue', 'Restrict-AddIssueComment-EditIssue',
        'Restrict-View-CoreTeam']
    self.assertEqual(
        sorted(expected_label_names),
        sorted(label.label for label in response.label_options))

  def testGetLabelOptions_CustomPermissions(self):
    self.project.extra_perms = [
        project_pb2.Project.ExtraPerms(
            member_id=222,
            perms=['FooPerm', 'BarPerm'])]

    request = projects_pb2.GetLabelOptionsRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.projects_svcr.GetLabelOptions, mc, request)

    expected_label_names = [
        label[0] for label in tracker_constants.DEFAULT_WELL_KNOWN_LABELS]
    expected_label_names += [
        'Restrict-View-EditIssue', 'Restrict-AddIssueComment-EditIssue']
    expected_label_names += [
        'Restrict-%s-%s' % (std_perm, custom_perm)
        for std_perm in permissions.STANDARD_ISSUE_PERMISSIONS
        for custom_perm in ('BarPerm', 'FooPerm')]

    self.assertEqual(
        sorted(expected_label_names),
        sorted(label.label for label in response.label_options))

  def testGetLabelOptions_FieldMasksLabel(self):
    self.AddField('Type', field_type_str='ENUM_TYPE')

    request = projects_pb2.GetLabelOptionsRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.projects_svcr.GetLabelOptions, mc, request)

    expected_label_names = [
        label[0] for label in tracker_constants.DEFAULT_WELL_KNOWN_LABELS
        if not label[0].startswith('Type-')
    ]
    expected_label_names += [
        'Restrict-View-EditIssue', 'Restrict-AddIssueComment-EditIssue',
        'Restrict-View-CoreTeam']
    self.assertEqual(
        sorted(expected_label_names),
        sorted(label.label for label in response.label_options))

  def CallGetStarCount(self):
    request = projects_pb2.GetProjectStarCountRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    response = self.CallWrapped(
        self.projects_svcr.GetProjectStarCount, mc, request)
    return response.star_count

  def CallStar(self, requester='owner@example.com', starred=True):
    request = projects_pb2.StarProjectRequest(
        project_name='proj', starred=starred)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=requester)
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(
        self.projects_svcr.StarProject, mc, request)
    return response.star_count

  def testStarCount_Normal(self):
    self.assertEqual(0, self.CallGetStarCount())
    self.assertEqual(1, self.CallStar())
    self.assertEqual(1, self.CallGetStarCount())

  def testStarCount_StarTwiceSameUser(self):
    self.assertEqual(1, self.CallStar())
    self.assertEqual(1, self.CallStar())
    self.assertEqual(1, self.CallGetStarCount())

  def testStarCount_StarTwiceDifferentUser(self):
    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.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.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 testCheckProjectName_OK(self):
    """We can check a project name."""
    request = projects_pb2.CheckProjectNameRequest(project_name='foo')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='admin@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(
        self.projects_svcr.CheckProjectName, mc, request)

    self.assertEqual('', response.error)

  def testCheckProjectName_InvalidProjectName(self):
    """We reject an invalid project name."""
    request = projects_pb2.CheckProjectNameRequest(project_name='Foo')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='admin@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(
        self.projects_svcr.CheckProjectName, mc, request)

    self.assertNotEqual('', response.error)

  def testCheckProjectName_NotAllowed(self):
    """Users that can't create a project shouldn't get any information."""
    request = projects_pb2.CheckProjectNameRequest(project_name='Foo')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='owner@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    with self.assertRaises(permissions.PermissionException):
      self.CallWrapped(self.projects_svcr.CheckProjectName, mc, request)

  def testCheckProjectName_ProjectAlreadyExists(self):
    """There is already a project with that name."""
    request = projects_pb2.CheckProjectNameRequest(project_name='proj')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='admin@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(
        self.projects_svcr.CheckProjectName, mc, request)

    self.assertNotEqual('', response.error)

  def testCheckComponentName_OK(self):
    request = projects_pb2.CheckComponentNameRequest(
        project_name='proj',
        component_name='Component')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='admin@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(
        self.projects_svcr.CheckComponentName, mc, request)

    self.assertEqual('', response.error)

  def testCheckComponentName_ParentComponentOK(self):
    self.services.config.CreateComponentDef(
        self.cnxn, self.project.project_id, 'Component', 'Docstring',
        False, [], [], 0, 111, [])
    request = projects_pb2.CheckComponentNameRequest(
        project_name='proj',
        parent_path='Component',
        component_name='Path')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='admin@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(
        self.projects_svcr.CheckComponentName, mc, request)

    self.assertEqual('', response.error)

  def testCheckComponentName_InvalidComponentName(self):
    request = projects_pb2.CheckComponentNameRequest(
        project_name='proj',
        component_name='Component-')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='admin@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(
        self.projects_svcr.CheckComponentName, mc, request)

    self.assertNotEqual('', response.error)

  def testCheckComponentName_ComponentAlreadyExists(self):
    self.services.config.CreateComponentDef(
        self.cnxn, self.project.project_id, 'Component', 'Docstring',
        False, [], [], 0, 111, [])
    request = projects_pb2.CheckComponentNameRequest(
        project_name='proj',
        component_name='Component')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='admin@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(
        self.projects_svcr.CheckComponentName, mc, request)

    self.assertNotEqual('', response.error)

  def testCheckComponentName_NotAllowedToViewProject(self):
    self.project.access = project_pb2.ProjectAccess.MEMBERS_ONLY
    request = projects_pb2.CheckComponentNameRequest(
        project_name='proj',
        parent_path='Component',
        component_name='Path')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='user_444@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    with self.assertRaises(permissions.PermissionException):
      self.CallWrapped(self.projects_svcr.CheckComponentName, mc, request)

  def testCheckComponentName_ParentComponentDoesntExist(self):
    request = projects_pb2.CheckComponentNameRequest(
        project_name='proj',
        parent_path='Component',
        component_name='Path')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='admin@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    with self.assertRaises(exceptions.NoSuchComponentException):
      self.CallWrapped(self.projects_svcr.CheckComponentName, mc, request)

  def testCheckFieldName_OK(self):
    request = projects_pb2.CheckFieldNameRequest(
        project_name='proj',
        field_name='Foo')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='admin@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(self.projects_svcr.CheckFieldName, mc, request)
    self.assertEqual('', response.error)

  def testCheckFieldName_InvalidFieldName(self):
    request = projects_pb2.CheckFieldNameRequest(
        project_name='proj',
        field_name='**Foo**')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='admin@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(self.projects_svcr.CheckFieldName, mc, request)
    self.assertNotEqual('', response.error)

  def testCheckFieldName_InvalidFieldName_ApproverSuffix(self):
    request = projects_pb2.CheckFieldNameRequest(
        project_name='proj',
        field_name='Foo-aPprOver')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='admin@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(self.projects_svcr.CheckFieldName, mc, request)
    self.assertNotEqual('', response.error)

  def testCheckFieldName_FieldAlreadyExists(self):
    self.AddField('Foo')
    request = projects_pb2.CheckFieldNameRequest(
        project_name='proj',
        field_name='Foo')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='admin@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(self.projects_svcr.CheckFieldName, mc, request)
    self.assertNotEqual('', response.error)

  def testCheckFieldName_FieldIsPrefixOfAnother(self):
    self.AddField('Foo-Bar')
    request = projects_pb2.CheckFieldNameRequest(
        project_name='proj',
        field_name='Foo')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='admin@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(self.projects_svcr.CheckFieldName, mc, request)
    self.assertNotEqual('', response.error)

  def testCheckFieldName_AnotherFieldIsPrefix(self):
    self.AddField('Foo')
    request = projects_pb2.CheckFieldNameRequest(
        project_name='proj',
        field_name='Foo-Bar')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='admin@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    response = self.CallWrapped(self.projects_svcr.CheckFieldName, mc, request)
    self.assertNotEqual('', response.error)

  def testCheckFieldName_NotAllowedToViewProject(self):
    self.project.access = project_pb2.ProjectAccess.MEMBERS_ONLY
    request = projects_pb2.CheckFieldNameRequest(
        project_name='proj',
        field_name='Foo')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester='user_444@example.com')
    mc.LookupLoggedInUserPerms(self.project)
    with self.assertRaises(permissions.PermissionException):
      self.CallWrapped(self.projects_svcr.CheckFieldName, mc, request)
