# 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
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 proto import tracker_pb2
from proto 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)
