# Copyright 2020 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 issues servicer."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import copy
import unittest
import mock

from api.v3 import converters
from api.v3 import issues_servicer
from api.v3.api_proto import issues_pb2
from api.v3.api_proto import issue_objects_pb2
from framework import exceptions
from framework import framework_helpers
from framework import monorailcontext
from framework import permissions
from proto import tracker_pb2
from testing import fake
from services import service_manager

from google.appengine.ext import testbed
from google.protobuf import timestamp_pb2
from google.protobuf import field_mask_pb2


def _Issue(project_id, local_id):
  issue = tracker_pb2.Issue(owner_id=0)
  issue.project_name = 'proj-%d' % project_id
  issue.project_id = project_id
  issue.local_id = local_id
  issue.issue_id = project_id * 100 + local_id
  return issue


CURRENT_TIME = 12346.78


class IssuesServicerTest(unittest.TestCase):

  def setUp(self):
    # memcache and datastore needed for generating page tokens.
    self.testbed = testbed.Testbed()
    self.testbed.activate()
    self.testbed.init_memcache_stub()
    self.testbed.init_datastore_v3_stub()

    self.cnxn = fake.MonorailConnection()
    self.services = service_manager.Services(
        config=fake.ConfigService(),
        issue=fake.IssueService(),
        issue_star=fake.IssueStarService(),
        project=fake.ProjectService(),
        features=fake.FeaturesService(),
        spam=fake.SpamService(),
        user=fake.UserService(),
        usergroup=fake.UserGroupService())
    self.issues_svcr = issues_servicer.IssuesServicer(
        self.services, make_rate_limiter=False)
    self.PAST_TIME = int(CURRENT_TIME - 1)

    self.owner = self.services.user.TestAddUser('owner@example.com', 111)
    self.user_2 = self.services.user.TestAddUser('user_2@example.com', 222)

    self.project_1 = self.services.project.TestAddProject(
        'chicken', project_id=789)
    self.issue_1_resource_name = 'projects/chicken/issues/1234'
    self.issue_1 = fake.MakeTestIssue(
        self.project_1.project_id,
        1234,
        'sum',
        'New',
        self.owner.user_id,
        labels=['find-me', 'pri-3'],
        project_name=self.project_1.project_name)
    self.services.issue.TestAddIssue(self.issue_1)

    self.project_2 = self.services.project.TestAddProject('cow', project_id=788)
    self.issue_2_resource_name = 'projects/cow/issues/1235'
    self.issue_2 = fake.MakeTestIssue(
        self.project_2.project_id,
        1235,
        'sum',
        'New',
        self.user_2.user_id,
        project_name=self.project_2.project_name)
    self.services.issue.TestAddIssue(self.issue_2)
    self.issue_3 = fake.MakeTestIssue(
        self.project_2.project_id,
        1236,
        'sum',
        'New',
        self.user_2.user_id,
        labels=['find-me', 'pri-1'],
        project_name=self.project_2.project_name)
    self.services.issue.TestAddIssue(self.issue_3)

  def CallWrapped(self, wrapped_handler, mc, *args, **kwargs):
    self.issues_svcr.converter = converters.Converter(mc, self.services)
    return wrapped_handler.wrapped(self.issues_svcr, mc, *args, **kwargs)

  def testGetIssue(self):
    """We can get an issue."""
    request = issues_pb2.GetIssueRequest(name=self.issue_1_resource_name)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    actual_response = self.CallWrapped(self.issues_svcr.GetIssue, mc, request)
    self.assertEqual(
        actual_response, self.issues_svcr.converter.ConvertIssue(self.issue_1))

  def testBatchGetIssues(self):
    """We can batch get issues."""
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    request = issues_pb2.BatchGetIssuesRequest(
        names=['projects/cow/issues/1235', 'projects/cow/issues/1236'])
    actual_response = self.CallWrapped(
        self.issues_svcr.BatchGetIssues, mc, request)
    self.assertEqual(
        [issue.name for issue in actual_response.issues],
        ['projects/cow/issues/1235', 'projects/cow/issues/1236'])

  def testBatchGetIssues_Empty(self):
    """We can return a response if the request has no names."""
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    request = issues_pb2.BatchGetIssuesRequest(names=[])
    actual_response = self.CallWrapped(
        self.issues_svcr.BatchGetIssues, mc, request)
    self.assertEqual(
        actual_response, issues_pb2.BatchGetIssuesResponse(issues=[]))

  def testBatchGetIssues_WithParent(self):
    """We can batch get issues with a given parent."""
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    request = issues_pb2.BatchGetIssuesRequest(
        parent='projects/cow',
        names=['projects/cow/issues/1235', 'projects/cow/issues/1236'])
    actual_response = self.CallWrapped(
        self.issues_svcr.BatchGetIssues, mc, request)
    self.assertEqual(
        [issue.name for issue in actual_response.issues],
        ['projects/cow/issues/1235', 'projects/cow/issues/1236'])

  def testBatchGetIssues_FromMultipleProjects(self):
    """We can batch get issues from multiple projects."""
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    request = issues_pb2.BatchGetIssuesRequest(
        names=[
            'projects/chicken/issues/1234', 'projects/cow/issues/1235',
            'projects/cow/issues/1236'
        ])
    actual_response = self.CallWrapped(
        self.issues_svcr.BatchGetIssues, mc, request)
    self.assertEqual(
        [issue.name for issue in actual_response.issues], [
            'projects/chicken/issues/1234', 'projects/cow/issues/1235',
            'projects/cow/issues/1236'
        ])

  def testBatchGetIssues_WithBadInput(self):
    """We raise an exception with bad input to batch get issues."""
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    request = issues_pb2.BatchGetIssuesRequest(
        parent='projects/cow',
        names=['projects/cow/issues/1235', 'projects/chicken/issues/1234'])
    with self.assertRaisesRegexp(
        exceptions.InputException,
        'projects/chicken/issues/1234 is not a child issue of projects/cow.'):
      self.CallWrapped(self.issues_svcr.BatchGetIssues, mc, request)

    request = issues_pb2.BatchGetIssuesRequest(
        parent='projects/sheep',
        names=['projects/cow/issues/1235', 'projects/chicken/issues/1234'])
    with self.assertRaisesRegexp(
        exceptions.InputException,
        'projects/cow/issues/1235 is not a child issue of projects/sheep.\n' +
        'projects/chicken/issues/1234 is not a child issue of projects/sheep.'):
      self.CallWrapped(self.issues_svcr.BatchGetIssues, mc, request)

    request = issues_pb2.BatchGetIssuesRequest(
        parent='projects/cow',
        names=['projects/cow/badformat/1235', 'projects/chicken/issues/1234'])
    with self.assertRaisesRegexp(
        exceptions.InputException,
        'Invalid resource name: projects/cow/badformat/1235.'):
      self.CallWrapped(self.issues_svcr.BatchGetIssues, mc, request)

  def testBatchGetIssues_NonExistentIssues(self):
    """We raise an exception with bad input to batch get issues."""
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    request = issues_pb2.BatchGetIssuesRequest(
        parent='projects/chicken',
        names=['projects/chicken/issues/1', 'projects/chicken/issues/2'])
    with self.assertRaisesRegexp(
        exceptions.NoSuchIssueException,
        "\['projects/chicken/issues/1', 'projects/chicken/issues/2'\] not found"
    ):
      self.CallWrapped(self.issues_svcr.BatchGetIssues, mc, request)

  @mock.patch('api.v3.api_constants.MAX_BATCH_ISSUES', 2)
  def testBatchGetIssues(self):
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    request = issues_pb2.BatchGetIssuesRequest(
        parent='projects/cow',
        names=[
            'projects/cow/issues/1235', 'projects/chicken/issues/1234',
            'projects/cow/issues/1233'
        ])
    with self.assertRaises(exceptions.InputException):
      self.CallWrapped(self.issues_svcr.BatchGetIssues, mc, request)

  @mock.patch('search.frontendsearchpipeline.FrontendSearchPipeline')
  @mock.patch('api.v3.api_constants.MAX_ISSUES_PER_PAGE', 2)
  def testSearchIssues(self, mock_pipeline):
    """We can search for issues in some projects."""
    request = issues_pb2.SearchIssuesRequest(
        projects=['projects/chicken', 'projects/cow'],
        query='label:find-me',
        order_by='-pri',
        page_size=3)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.user_2.email)

    instance = mock.Mock(
        spec=True, total_count=3, visible_results=[self.issue_1, self.issue_3])
    mock_pipeline.return_value = instance
    instance.SearchForIIDs = mock.Mock()
    instance.MergeAndSortIssues = mock.Mock()
    instance.Paginate = mock.Mock()

    actual_response = self.CallWrapped(
        self.issues_svcr.SearchIssues, mc, request)
    # start index is 0.
    # number of items is coerced from 3 -> 2
    mock_pipeline.assert_called_once_with(
        self.cnxn,
        self.services,
        mc.auth, [222],
        'label:find-me', ['chicken', 'cow'],
        2,
        0,
        1,
        '',
        '-pri',
        mc.warnings,
        mc.errors,
        True,
        mc.profiler,
        project=None)
    self.assertEqual(
        [issue.name for issue in actual_response.issues],
        ['projects/chicken/issues/1234', 'projects/cow/issues/1236'])

    # Check the `next_page_token` can be used to get the next page of results.
    request.page_token = actual_response.next_page_token
    self.CallWrapped(self.issues_svcr.SearchIssues, mc, request)
    # start index is now 2.
    mock_pipeline.assert_called_with(
        self.cnxn,
        self.services,
        mc.auth, [222],
        'label:find-me', ['chicken', 'cow'],
        2,
        2,
        1,
        '',
        '-pri',
        mc.warnings,
        mc.errors,
        True,
        mc.profiler,
        project=None)

  @mock.patch('search.frontendsearchpipeline.FrontendSearchPipeline')
  @mock.patch('api.v3.api_constants.MAX_ISSUES_PER_PAGE', 2)
  def testSearchIssues_PaginationErrorOrderByChanged(self, mock_pipeline):
    """Error when changing the order_by and using the same page_otoken."""
    request = issues_pb2.SearchIssuesRequest(
        projects=['projects/chicken', 'projects/cow'],
        query='label:find-me',
        order_by='-pri',
        page_size=3)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.user_2.email)

    instance = mock.Mock(
        spec=True, total_count=3, visible_results=[self.issue_1, self.issue_3])
    mock_pipeline.return_value = instance
    instance.SearchForIIDs = mock.Mock()
    instance.MergeAndSortIssues = mock.Mock()
    instance.Paginate = mock.Mock()

    actual_response = self.CallWrapped(
        self.issues_svcr.SearchIssues, mc, request)

    # The request should fail if we use `next_page_token` and change parameters.
    request.page_token = actual_response.next_page_token
    request.order_by = 'owner'
    with self.assertRaises(exceptions.PageTokenException):
      self.CallWrapped(self.issues_svcr.SearchIssues, mc, request)

  # Note the 'empty' case doesn't make sense for ListComments, as one is created
  # for every issue.
  def testListComments(self):
    comment_2 = tracker_pb2.IssueComment(
        id=123,
        issue_id=self.issue_1.issue_id,
        project_id=self.issue_1.project_id,
        user_id=self.owner.user_id,
        content='comment 2')
    self.services.issue.TestAddComment(comment_2, self.issue_1.local_id)
    request = issues_pb2.ListCommentsRequest(
        parent=self.issue_1_resource_name, page_size=1)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    actual_response = self.CallWrapped(
        self.issues_svcr.ListComments, mc, request)
    self.assertEqual(len(actual_response.comments), 1)

    # Check the `next_page_token` can be used to get the next page of results
    request.page_token = actual_response.next_page_token
    next_actual_response = self.CallWrapped(
        self.issues_svcr.ListComments, mc, request)
    self.assertEqual(len(next_actual_response.comments), 1)
    self.assertEqual(next_actual_response.comments[0].content, 'comment 2')

  def testListComments_UnsupportedFilter(self):
    """If anything other than approval is provided, it's an error."""
    filter_str = 'content = "x"'
    request = issues_pb2.ListCommentsRequest(
        parent=self.issue_1_resource_name, page_size=1, filter=filter_str)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    with self.assertRaises(exceptions.InputException):
      self.CallWrapped(self.issues_svcr.ListComments, mc, request)

  def testListComments_TwoApprovalsErrors(self):
    """If anything other than a single approval is provided, it's an error."""
    filter_str = (
        'approval = "projects/chicken/approvalDefs/404" OR '
        'approval = "projects/chicken/approvalDefs/405')
    request = issues_pb2.ListCommentsRequest(
        parent=self.issue_1_resource_name, page_size=1, filter=filter_str)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    with self.assertRaises(exceptions.InputException):
      self.CallWrapped(self.issues_svcr.ListComments, mc, request)

  def testListComments_FilterTypoError(self):
    """Even an extra space is an error."""
    filter_str = 'approval = "projects/chicken/approvalDefs/404" '
    request = issues_pb2.ListCommentsRequest(
        parent=self.issue_1_resource_name, page_size=1, filter=filter_str)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    with self.assertRaises(exceptions.InputException):
      self.CallWrapped(self.issues_svcr.ListComments, mc, request)

  def testListComments_UnknownApprovalInFilter(self):
    """Filter with unknown approval returns no error and no comments."""
    approval_comment = tracker_pb2.IssueComment(
        id=123,
        issue_id=self.issue_1.issue_id,
        project_id=self.issue_1.project_id,
        user_id=self.owner.user_id,
        content='comment 2 - approval 1',
        approval_id=1)
    self.services.issue.TestAddComment(approval_comment, self.issue_1.local_id)
    request = issues_pb2.ListCommentsRequest(
        parent=self.issue_1_resource_name, page_size=1,
        filter='approval = "projects/chicken/approvalDefs/404"')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    response = self.CallWrapped(self.issues_svcr.ListComments, mc, request)
    self.assertEqual(len(response.comments), 0)

  def testListComments_ApprovalInFilter(self):
    approval_comment = tracker_pb2.IssueComment(
        id=123,
        issue_id=self.issue_1.issue_id,
        project_id=self.issue_1.project_id,
        user_id=self.owner.user_id,
        content='comment 2 - approval 1',
        approval_id=1)
    self.services.issue.TestAddComment(approval_comment, self.issue_1.local_id)
    request = issues_pb2.ListCommentsRequest(
        parent=self.issue_1_resource_name, page_size=1,
        filter='approval = "projects/chicken/approvalDefs/1"')
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    response = self.CallWrapped(self.issues_svcr.ListComments, mc, request)
    self.assertEqual(len(response.comments), 1)
    self.assertEqual(response.comments[0].content, approval_comment.content)

  def testListApprovalValues(self):
    config = fake.MakeTestConfig(self.project_2.project_id, [], [])
    self.services.config.StoreConfig(self.cnxn, config)

    # Make regular field def and value
    fd_1 = fake.MakeTestFieldDef(
        1, self.project_2.project_id, tracker_pb2.FieldTypes.STR_TYPE,
        field_name='field1')
    self.services.config.TestAddFieldDef(fd_1)
    fv_1 = fake.MakeFieldValue(
        field_id=fd_1.field_id, str_value='value1', derived=False)

    # Make testing approval def and its associated field def
    approval_gate = fake.MakeTestFieldDef(
        2, self.project_2.project_id, tracker_pb2.FieldTypes.APPROVAL_TYPE,
        field_name='approval-gate-1')
    self.services.config.TestAddFieldDef(approval_gate)
    ad = fake.MakeTestApprovalDef(2, approver_ids=[self.user_2.user_id])
    self.services.config.TestAddApprovalDef(ad, self.project_2.project_id)

    # Make approval value
    av = fake.MakeApprovalValue(2, set_on=self.PAST_TIME,
          approver_ids=[self.user_2.user_id], setter_id=self.user_2.user_id)

    # Make field def that belongs to above approval_def
    fd_2 = fake.MakeTestFieldDef(
        3, self.project_2.project_id, tracker_pb2.FieldTypes.STR_TYPE,
        field_name='field2', approval_id=2)
    self.services.config.TestAddFieldDef(fd_2)
    fv_2 = fake.MakeFieldValue(
        field_id=fd_2.field_id, str_value='value2', derived=False)

    issue_resource_name = 'projects/cow/issues/1237'
    issue = fake.MakeTestIssue(
        self.project_2.project_id,
        1237,
        'sum',
        'New',
        self.user_2.user_id,
        project_name=self.project_2.project_name,
        field_values=[fv_1, fv_2],
        approval_values=[av])
    self.services.issue.TestAddIssue(issue)

    request = issues_pb2.ListApprovalValuesRequest(parent=issue_resource_name)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    actual_response = self.CallWrapped(
        self.issues_svcr.ListApprovalValues, mc, request)

    self.assertEqual(len(actual_response.approval_values), 1)
    expected_fv = issue_objects_pb2.FieldValue(
        field='projects/cow/fieldDefs/3',
        value='value2',
        derivation=issue_objects_pb2.Derivation.Value('EXPLICIT'))
    expected = issue_objects_pb2.ApprovalValue(
        name='projects/cow/issues/1237/approvalValues/2',
        status=issue_objects_pb2.ApprovalValue.ApprovalStatus.Value('NOT_SET'),
        approvers=['users/222'],
        approval_def='projects/cow/approvalDefs/2',
        set_time=timestamp_pb2.Timestamp(seconds=self.PAST_TIME),
        setter='users/222',
        field_values=[expected_fv])
    self.assertEqual(actual_response.approval_values[0], expected)

  def testListApprovalValues_Empty(self):
    request = issues_pb2.ListApprovalValuesRequest(
        parent=self.issue_1_resource_name)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    actual_response = self.CallWrapped(
        self.issues_svcr.ListApprovalValues, mc, request)
    self.assertEqual(len(actual_response.approval_values), 0)

  @mock.patch(
      'features.send_notifications.PrepareAndSendIssueChangeNotification')
  def testMakeIssue(self, _fake_pasicn):
    request_issue = issue_objects_pb2.Issue(
        summary='sum',
        status=issue_objects_pb2.Issue.StatusValue(status='New'),
        cc_users=[issue_objects_pb2.Issue.UserValue(user='users/222')],
        labels=[issue_objects_pb2.Issue.LabelValue(label='foo-bar')]
    )
    request = issues_pb2.MakeIssueRequest(
        parent='projects/chicken',
        issue=request_issue,
        description='description'
    )
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    response = self.CallWrapped(
        self.issues_svcr.MakeIssue, mc, request)
    self.assertEqual(response.summary, 'sum')
    self.assertEqual(response.status.status, 'New')
    self.assertEqual(response.cc_users[0].user, 'users/222')
    self.assertEqual(response.labels[0].label, 'foo-bar')
    self.assertEqual(response.star_count, 1)

  @mock.patch(
      'features.send_notifications.PrepareAndSendIssueChangeNotification')
  @mock.patch('time.time')
  def testModifyIssues(self, fake_time, fake_notify):
    fake_time.return_value = 12345

    issue = _Issue(780, 1)
    self.services.project.TestAddProject(
        issue.project_name, project_id=issue.project_id,
        owner_ids=[self.owner.user_id])

    issue.labels = ['keep-me', 'remove-me']
    self.services.issue.TestAddIssue(issue)
    exp_issue = copy.deepcopy(issue)

    self.services.issue.CreateIssueComment = mock.Mock()
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)

    request = issues_pb2.ModifyIssuesRequest(
        deltas=[
            issues_pb2.IssueDelta(
                issue=issue_objects_pb2.Issue(
                    name='projects/proj-780/issues/1',
                    labels=[issue_objects_pb2.Issue.LabelValue(
                        label='add-me')]),
                update_mask=field_mask_pb2.FieldMask(paths=['labels']),
                labels_remove=['remove-me'])],
        uploads=[issues_pb2.AttachmentUpload(
            filename='mowgli.gif', content='cute dog')],
        comment_content='Release the chicken.',
        notify_type=issues_pb2.NotifyType.Value('NO_NOTIFICATION'))

    response = self.CallWrapped(
        self.issues_svcr.ModifyIssues, mc, request)
    exp_issue.labels = ['keep-me', 'add-me']
    exp_issue.modified_timestamp = 12345
    exp_api_issue = self.issues_svcr.converter.ConvertIssue(exp_issue)
    self.assertEqual([iss for iss in response.issues], [exp_api_issue])

    # All updated issues should have been fetched from DB, skipping cache.
    # So we expect assume_stale=False was applied to all issues during the
    # the fetch.
    exp_issue.assume_stale = False
    # These derived values get set to the following when an issue goes through
    # the ApplyFilterRules path. (see filter_helpers._ComputeDerivedFields)
    exp_issue.derived_owner_id = 0
    exp_issue.derived_status = ''
    exp_attachments = [framework_helpers.AttachmentUpload(
        'mowgli.gif', 'cute dog', 'image/gif')]
    exp_amendments = [tracker_pb2.Amendment(
        field=tracker_pb2.FieldID.LABELS, newvalue='-remove-me add-me')]
    self.services.issue.CreateIssueComment.assert_called_once_with(
        self.cnxn, exp_issue, mc.auth.user_id, 'Release the chicken.',
        attachments=exp_attachments, amendments=exp_amendments, commit=False)
    fake_notify.assert_called_once_with(
        issue.issue_id, 'testing-app.appspot.com', self.owner.user_id,
        comment_id=mock.ANY, old_owner_id=None, send_email=False)

  def testModifyIssues_Empty(self):
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    request = issues_pb2.ModifyIssuesRequest()
    response = self.CallWrapped(self.issues_svcr.ModifyIssues, mc, request)
    self.assertEqual(response, issues_pb2.ModifyIssuesResponse())

  @mock.patch('api.v3.api_constants.MAX_MODIFY_ISSUES', 2)
  @mock.patch('api.v3.api_constants.MAX_MODIFY_IMPACTED_ISSUES', 4)
  def testModifyIssues_TooMany(self):
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    request = issues_pb2.ModifyIssuesRequest(
        deltas=[
            issues_pb2.IssueDelta(),
            issues_pb2.IssueDelta(),
            issues_pb2.IssueDelta()
        ])
    with self.assertRaisesRegexp(
        exceptions.InputException,
        'Requesting 3 updates when the allowed maximum is 2 updates.'):
      self.CallWrapped(self.issues_svcr.ModifyIssues, mc, request)

    issue_ref_list = [issue_objects_pb2.IssueRef()]
    request = issues_pb2.ModifyIssuesRequest(
        deltas=[
            issues_pb2.IssueDelta(
                issue=issue_objects_pb2.Issue(
                    blocked_on_issue_refs=issue_ref_list),
                blocked_on_issues_remove=issue_ref_list,
                update_mask=field_mask_pb2.FieldMask(
                    paths=['merged_into_issue_ref'])),
            issues_pb2.IssueDelta(
                issue=issue_objects_pb2.Issue(
                    blocking_issue_refs=issue_ref_list),
                blocking_issues_remove=issue_ref_list)
        ])
    with self.assertRaisesRegexp(
        exceptions.InputException,
        'Updates include 5 impacted issues when the allowed maximum is 4.'):
      self.CallWrapped(self.issues_svcr.ModifyIssues, mc, request)

  @mock.patch('time.time', mock.MagicMock(return_value=CURRENT_TIME))
  @mock.patch(
      'features.send_notifications.PrepareAndSendApprovalChangeNotification')
  def testModifyIssueApprovalValues(self, fake_notify):
    self.services.issue.DeltaUpdateIssueApproval = mock.Mock()
    config = fake.MakeTestConfig(self.project_1.project_id, [], [])
    self.services.config.StoreConfig(self.cnxn, config)

    # Make testing approval def and its associated field def
    field_id = 2
    approval_field_def = fake.MakeTestFieldDef(
        field_id,
        self.project_1.project_id,
        tracker_pb2.FieldTypes.APPROVAL_TYPE,
        field_name='approval-gate-1')
    self.services.config.TestAddFieldDef(approval_field_def)
    ad = fake.MakeTestApprovalDef(field_id, approver_ids=[self.owner.user_id])
    self.services.config.TestAddApprovalDef(ad, self.project_1.project_id)

    # Make approval value
    av = fake.MakeApprovalValue(
        field_id,
        status=tracker_pb2.ApprovalStatus.NEEDS_REVIEW,
        set_on=self.PAST_TIME,
        approver_ids=[self.owner.user_id],
        setter_id=self.user_2.user_id)

    issue = fake.MakeTestIssue(
        self.project_1.project_id,
        1237,
        'sum',
        'New',
        self.owner.user_id,
        project_name=self.project_1.project_name,
        approval_values=[av])
    self.services.issue.TestAddIssue(issue)

    av_name = 'projects/%s/issues/%d/approvalValues/%d' % (
        self.project_1.project_name, issue.local_id, ad.approval_id)
    delta = issues_pb2.ApprovalDelta(
        approval_value=issue_objects_pb2.ApprovalValue(
            name=av_name,
            status=issue_objects_pb2.ApprovalValue.ApprovalStatus.Value('NA')),
        update_mask=field_mask_pb2.FieldMask(paths=['status']))

    request = issues_pb2.ModifyIssueApprovalValuesRequest(deltas=[delta],)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    response = self.CallWrapped(
        self.issues_svcr.ModifyIssueApprovalValues, mc, request)
    expected_ingested_delta = tracker_pb2.ApprovalDelta(
        status=tracker_pb2.ApprovalStatus.NA,
        set_on=int(CURRENT_TIME),
        setter_id=self.owner.user_id,
    )
    # NOTE: Because we mock out DeltaUpdateIssueApproval, the ApprovalValues
    # returned haven't been changed in this test. We can't test that it was
    # changed correctly, but we can make sure it's for the right ApprovalValue.
    self.assertEqual(len(response.approval_values), 1)
    self.assertEqual(response.approval_values[0].name, av_name)
    self.services.issue.DeltaUpdateIssueApproval.assert_called_once_with(
        mc.cnxn,
        self.owner.user_id,
        config,
        issue,
        av,
        expected_ingested_delta,
        comment_content=u'',
        is_description=False,
        attachments=None,
        kept_attachments=None)
    fake_notify.assert_called_once_with(
        issue.issue_id,
        ad.approval_id,
        'testing-app.appspot.com',
        mock.ANY,
        send_email=True)

  @mock.patch('api.v3.api_constants.MAX_MODIFY_APPROVAL_VALUES', 2)
  def testModifyIssueApprovalValues_TooMany(self):
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    request = issues_pb2.ModifyIssueApprovalValuesRequest(
        deltas=[
            issues_pb2.ApprovalDelta(),
            issues_pb2.ApprovalDelta(),
            issues_pb2.ApprovalDelta()
        ])
    with self.assertRaises(exceptions.InputException):
      self.CallWrapped(self.issues_svcr.ModifyIssueApprovalValues, mc, request)

  def testModifyIssueApprovalValues_Empty(self):
    request = issues_pb2.ModifyIssueApprovalValuesRequest()
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    response = self.CallWrapped(
        self.issues_svcr.ModifyIssueApprovalValues, mc, request)
    self.assertEqual(len(response.approval_values), 0)

  @mock.patch(
      'businesslogic.work_env.WorkEnv.GetIssue',
      return_value=tracker_pb2.Issue(
          owner_id=0,
          project_name='chicken',
          project_id=789,
          local_id=1234,
          issue_id=80134))
  def testModifyCommentState(self, mocked_get_issue):
    name = self.issue_1_resource_name + '/comments/1'
    state = issue_objects_pb2.IssueContentState.Value('DELETED')
    request = issues_pb2.ModifyCommentStateRequest(name=name, state=state)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    with self.assertRaises(exceptions.NoSuchCommentException):
      self.CallWrapped(self.issues_svcr.ModifyCommentState, mc, request)
    mocked_get_issue.assert_any_call(self.issue_1.issue_id, use_cache=False)

  def testModifyCommentState_Delete(self):
    comment_1 = tracker_pb2.IssueComment(
        id=124,
        issue_id=self.issue_1.issue_id,
        project_id=self.issue_1.project_id,
        user_id=self.owner.user_id,
        content='first actual comment')
    self.services.issue.TestAddComment(comment_1, self.issue_1.local_id)

    name = self.issue_1_resource_name + '/comments/1'
    state = issue_objects_pb2.IssueContentState.Value('DELETED')
    request = issues_pb2.ModifyCommentStateRequest(name=name, state=state)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    response = self.CallWrapped(
        self.issues_svcr.ModifyCommentState, mc, request)
    self.assertEqual(response.comment.state, state)
    self.assertEqual(response.comment.content, 'first actual comment')

    # Test noop
    response = self.CallWrapped(
        self.issues_svcr.ModifyCommentState, mc, request)
    self.assertEqual(response.comment.state, state)

    # Test undelete
    state = issue_objects_pb2.IssueContentState.Value('ACTIVE')
    request = issues_pb2.ModifyCommentStateRequest(name=name, state=state)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    response = self.CallWrapped(
        self.issues_svcr.ModifyCommentState, mc, request)
    self.assertEqual(response.comment.state, state)

  @mock.patch(
      'framework.permissions.UpdateIssuePermissions',
      return_value=permissions.ADMIN_PERMISSIONSET)
  def testModifyCommentState_Spam(self, _mocked):
    comment_1 = tracker_pb2.IssueComment(
        id=124,
        issue_id=self.issue_1.issue_id,
        project_id=self.issue_1.project_id,
        user_id=self.owner.user_id,
        content='first actual comment')
    self.services.issue.TestAddComment(comment_1, self.issue_1.local_id)

    name = self.issue_1_resource_name + '/comments/1'
    state = issue_objects_pb2.IssueContentState.Value('SPAM')
    request = issues_pb2.ModifyCommentStateRequest(name=name, state=state)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    response = self.CallWrapped(
        self.issues_svcr.ModifyCommentState, mc, request)
    self.assertEqual(response.comment.state, state)

    # Test noop
    response = self.CallWrapped(
        self.issues_svcr.ModifyCommentState, mc, request)
    self.assertEqual(response.comment.state, state)

    # Test unflag as spam
    state = issue_objects_pb2.IssueContentState.Value('ACTIVE')
    request = issues_pb2.ModifyCommentStateRequest(name=name, state=state)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    response = self.CallWrapped(
        self.issues_svcr.ModifyCommentState, mc, request)
    self.assertEqual(response.comment.state, state)

  def testModifyCommentState_Active(self):
    comment_1 = tracker_pb2.IssueComment(
        id=124,
        issue_id=self.issue_1.issue_id,
        project_id=self.issue_1.project_id,
        user_id=self.owner.user_id,
        content='first actual comment')
    self.services.issue.TestAddComment(comment_1, self.issue_1.local_id)

    name = self.issue_1_resource_name + '/comments/1'
    state = issue_objects_pb2.IssueContentState.Value('ACTIVE')
    request = issues_pb2.ModifyCommentStateRequest(name=name, state=state)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    response = self.CallWrapped(
        self.issues_svcr.ModifyCommentState, mc, request)
    self.assertEqual(response.comment.state, state)

  def testModifyCommentState_Spam_ActionNotSupported(self):
    # Cannot transition from deleted to spam
    comment_1 = tracker_pb2.IssueComment(
        id=124,
        issue_id=self.issue_1.issue_id,
        project_id=self.issue_1.project_id,
        user_id=self.owner.user_id,
        content='first actual comment',
        deleted_by=self.owner.user_id)
    self.services.issue.TestAddComment(comment_1, self.issue_1.local_id)

    name = self.issue_1_resource_name + '/comments/1'
    state = issue_objects_pb2.IssueContentState.Value('SPAM')
    request = issues_pb2.ModifyCommentStateRequest(name=name, state=state)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    with self.assertRaises(exceptions.ActionNotSupported):
      self.CallWrapped(self.issues_svcr.ModifyCommentState, mc, request)

  def testModifyCommentState_Delete_ActionNotSupported(self):
    # Cannot transition from spam to deleted
    comment_1 = tracker_pb2.IssueComment(
        id=124,
        issue_id=self.issue_1.issue_id,
        project_id=self.issue_1.project_id,
        user_id=self.owner.user_id,
        content='first actual comment',
        is_spam=True)
    self.services.issue.TestAddComment(comment_1, self.issue_1.local_id)

    name = self.issue_1_resource_name + '/comments/1'
    state = issue_objects_pb2.IssueContentState.Value('DELETED')
    request = issues_pb2.ModifyCommentStateRequest(name=name, state=state)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    with self.assertRaises(exceptions.ActionNotSupported):
      self.CallWrapped(self.issues_svcr.ModifyCommentState, mc, request)

  def testModifyCommentState_NoSuchComment(self):
    name = self.issue_1_resource_name + '/comments/1'
    state = issue_objects_pb2.IssueContentState.Value('DELETED')
    request = issues_pb2.ModifyCommentStateRequest(name=name, state=state)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.owner.email)
    with self.assertRaises(exceptions.NoSuchCommentException):
      self.CallWrapped(self.issues_svcr.ModifyCommentState, mc, request)

  def testModifyCommentState_Delete_PermissionException(self):
    comment_1 = tracker_pb2.IssueComment(
        id=124,
        issue_id=self.issue_1.issue_id,
        project_id=self.issue_1.project_id,
        user_id=self.owner.user_id,
        content='first actual comment')
    self.services.issue.TestAddComment(comment_1, self.issue_1.local_id)

    name = self.issue_1_resource_name + '/comments/1'
    state = issue_objects_pb2.IssueContentState.Value('DELETED')
    request = issues_pb2.ModifyCommentStateRequest(name=name, state=state)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.user_2.email)
    with self.assertRaises(permissions.PermissionException):
      self.CallWrapped(self.issues_svcr.ModifyCommentState, mc, request)

  @mock.patch(
      'framework.permissions.UpdateIssuePermissions',
      return_value=permissions.READ_ONLY_PERMISSIONSET)
  def testModifyCommentState_Spam_PermissionException(self, _mocked):
    comment_1 = tracker_pb2.IssueComment(
        id=124,
        issue_id=self.issue_1.issue_id,
        project_id=self.issue_1.project_id,
        user_id=self.owner.user_id,
        content='first actual comment')
    self.services.issue.TestAddComment(comment_1, self.issue_1.local_id)

    name = self.issue_1_resource_name + '/comments/1'
    state = issue_objects_pb2.IssueContentState.Value('SPAM')
    request = issues_pb2.ModifyCommentStateRequest(name=name, state=state)
    mc = monorailcontext.MonorailContext(
        self.services, cnxn=self.cnxn, requester=self.user_2.email)
    with self.assertRaises(permissions.PermissionException):
      self.CallWrapped(self.issues_svcr.ModifyCommentState, mc, request)
