# Copyright 2016 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 notify.py."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import flask
import json
import mock
import six
import unittest

from google.appengine.ext import testbed

from features import notify
from features import notify_reasons
from framework import emailfmt
from framework import urls
from mrproto import tracker_pb2
from services import service_manager
from testing import fake
from testing import testing_helpers
from tracker import attachment_helpers
from tracker import tracker_bizobj


def MakeTestIssue(project_id, local_id, owner_id, reporter_id, is_spam=False):
  issue = tracker_pb2.Issue()
  issue.project_id = project_id
  issue.local_id = local_id
  issue.issue_id = 1000 * project_id + local_id
  issue.owner_id = owner_id
  issue.reporter_id = reporter_id
  issue.is_spam = is_spam
  return issue


class NotifyTaskHandleRequestTest(unittest.TestCase):

  def setUp(self):
    self.services = service_manager.Services(
        user=fake.UserService(),
        usergroup=fake.UserGroupService(),
        project=fake.ProjectService(),
        config=fake.ConfigService(),
        issue=fake.IssueService(),
        issue_star=fake.IssueStarService(),
        features=fake.FeaturesService())
    self.requester = self.services.user.TestAddUser('requester@example.com', 1)
    self.nonmember = self.services.user.TestAddUser('user@example.com', 2)
    self.member = self.services.user.TestAddUser('member@example.com', 3)
    self.project = self.services.project.TestAddProject(
        'test-project', owner_ids=[1, 3], project_id=12345)
    self.issue1 = MakeTestIssue(
        project_id=12345, local_id=1, owner_id=2, reporter_id=1)
    self.issue2 = MakeTestIssue(
        project_id=12345, local_id=2, owner_id=2, reporter_id=1)
    self.services.issue.TestAddIssue(self.issue1)

    self.orig_sign_attachment_id = attachment_helpers.SignAttachmentID
    attachment_helpers.SignAttachmentID = (
        lambda aid: 'signed_%d' % aid)
    self.servlet = notify.OutboundEmailTask(services=self.services)
    self.app = flask.Flask('test_app')
    self.app.config['TESTING'] = True
    self.app.add_url_rule(
        '/_task/outboundEmail.do',
        view_func=self.servlet.PostOutboundEmailTask,
        methods=['POST'])
    self.testbed = testbed.Testbed()
    self.testbed.activate()
    self.testbed.init_memcache_stub()
    self.testbed.init_datastore_v3_stub()

  def tearDown(self):
    attachment_helpers.SignAttachmentID = self.orig_sign_attachment_id

  def get_filtered_task_call_args(self, create_task_mock, relative_uri):
    return [
        (args, kwargs)
        for (args, kwargs) in create_task_mock.call_args_list
        if args[0]['app_engine_http_request']['relative_uri'] == relative_uri
    ]

  def VerifyParams(self, result, params):
    self.assertEqual(
        bool(params['send_email']), result['params']['send_email'])
    if 'issue_id' in params:
      self.assertEqual(params['issue_id'], result['params']['issue_id'])
    if 'issue_ids' in params:
      self.assertEqual([int(p) for p in params['issue_ids'].split(',')],
                       result['params']['issue_ids'])

  def testNotifyIssueChangeTask_Normal(self):
    task = notify.NotifyIssueChangeTask(services=self.services)
    params = {'send_email': 1, 'issue_id': 12345001, 'seq': 0,
              'commenter_id': 2}
    mr = testing_helpers.MakeMonorailRequest(
        user_info={'user_id': 1},
        params=params,
        method='POST',
        services=self.services)
    result = task.HandleRequest(mr)
    self.VerifyParams(result, params)

  @mock.patch('framework.cloud_tasks_helpers.create_task')
  def testNotifyIssueChangeTask_Spam(self, _create_task_mock):
    issue = MakeTestIssue(
        project_id=12345, local_id=1, owner_id=1, reporter_id=1,
        is_spam=True)
    self.services.issue.TestAddIssue(issue)
    task = notify.NotifyIssueChangeTask(services=self.services)
    params = {'send_email': 0, 'issue_id': issue.issue_id, 'seq': 0,
              'commenter_id': 2}
    mr = testing_helpers.MakeMonorailRequest(
        user_info={'user_id': 1},
        params=params,
        method='POST',
        services=self.services)
    result = task.HandleRequest(mr)
    self.assertEqual(0, len(result['notified']))

  @mock.patch('framework.cloud_tasks_helpers.create_task')
  def testNotifyBlockingChangeTask_Normal(self, _create_task_mock):
    issue2 = MakeTestIssue(
        project_id=12345, local_id=2, owner_id=2, reporter_id=1)
    self.services.issue.TestAddIssue(issue2)
    task = notify.NotifyBlockingChangeTask(services=self.services)
    params = {
        'send_email': 1, 'issue_id': issue2.issue_id, 'seq': 0,
        'delta_blocker_iids': str(self.issue1.issue_id), 'commenter_id': 1,
        'hostport': 'bugs.chromium.org'}
    mr = testing_helpers.MakeMonorailRequest(
        user_info={'user_id': 1},
        params=params,
        method='POST',
        services=self.services)
    result = task.HandleRequest(mr)
    self.VerifyParams(result, params)

  def testNotifyBlockingChangeTask_Spam(self):
    issue2 = MakeTestIssue(
        project_id=12345, local_id=2, owner_id=2, reporter_id=1,
        is_spam=True)
    self.services.issue.TestAddIssue(issue2)
    task = notify.NotifyBlockingChangeTask(services=self.services)
    params = {
        'send_email': 1, 'issue_id': issue2.issue_id, 'seq': 0,
        'delta_blocker_iids': str(self.issue1.issue_id), 'commenter_id': 1}
    mr = testing_helpers.MakeMonorailRequest(
        user_info={'user_id': 1},
        params=params,
        method='POST',
        services=self.services)
    result = task.HandleRequest(mr)
    self.assertEqual(0, len(result['notified']))

  @mock.patch('framework.cloud_tasks_helpers.create_task')
  def testNotifyBulkChangeTask_Normal(self, create_task_mock):
    """We generate email tasks for each user involved in the issues."""
    issue2 = MakeTestIssue(
        project_id=12345, local_id=2, owner_id=2, reporter_id=1)
    issue2.cc_ids = [3]
    self.services.issue.TestAddIssue(issue2)
    task = notify.NotifyBulkChangeTask(services=self.services)
    params = {
        'send_email': 1, 'seq': 0,
        'issue_ids': '%d,%d' % (self.issue1.issue_id, issue2.issue_id),
        'old_owner_ids': '1,1', 'commenter_id': 1}
    mr = testing_helpers.MakeMonorailRequest(
        user_info={'user_id': 1},
        params=params,
        method='POST',
        services=self.services)
    result = task.HandleRequest(mr)
    self.VerifyParams(result, params)

    call_args_list = self.get_filtered_task_call_args(
        create_task_mock, urls.OUTBOUND_EMAIL_TASK + '.do')
    self.assertEqual(2, len(call_args_list))

    for (args, _kwargs) in call_args_list:
      task = args[0]
      body = json.loads(task['app_engine_http_request']['body'].decode())
      if 'user' in body['to']:
        self.assertIn(u'\u2026', body['from_addr'])
      # Full email for members
      if 'member' in body['to']:
        self.assertNotIn(u'\u2026', body['from_addr'])

  @mock.patch('framework.cloud_tasks_helpers.create_task')
  def testNotifyBulkChangeTask_AlsoNotify(self, create_task_mock):
    """We generate email tasks for also-notify addresses."""
    self.issue1.derived_notify_addrs = [
        'mailing-list@example.com', 'member@example.com']
    task = notify.NotifyBulkChangeTask(services=self.services)
    params = {
        'send_email': 1, 'seq': 0,
        'issue_ids': '%d' % (self.issue1.issue_id),
        'old_owner_ids': '1', 'commenter_id': 1}
    mr = testing_helpers.MakeMonorailRequest(
        user_info={'user_id': 1},
        params=params,
        method='POST',
        services=self.services)
    result = task.HandleRequest(mr)
    self.VerifyParams(result, params)

    call_args_list = self.get_filtered_task_call_args(
        create_task_mock, urls.OUTBOUND_EMAIL_TASK + '.do')
    self.assertEqual(3, len(call_args_list))

    six.assertCountEqual(
        self,
        ['user@example.com', 'mailing-list@example.com', 'member@example.com'],
        result['notified'])
    for (args, _kwargs) in call_args_list:
      task = args[0]
      body = json.loads(task['app_engine_http_request']['body'].decode())
      # obfuscated email for non-members
      if 'user' in body['to']:
        self.assertIn(u'\u2026', body['from_addr'])
      # Full email for members
      if 'member' in body['to']:
        self.assertNotIn(u'\u2026', body['from_addr'])

  @mock.patch('framework.cloud_tasks_helpers.create_task')
  def testNotifyBulkChangeTask_ProjectNotify(self, create_task_mock):
    """We generate email tasks for project.issue_notify_address."""
    self.project.issue_notify_address = 'mailing-list@example.com'
    task = notify.NotifyBulkChangeTask(services=self.services)
    params = {
        'send_email': 1, 'seq': 0,
        'issue_ids': '%d' % (self.issue1.issue_id),
        'old_owner_ids': '1', 'commenter_id': 1}
    mr = testing_helpers.MakeMonorailRequest(
        user_info={'user_id': 1},
        params=params,
        method='POST',
        services=self.services)
    result = task.HandleRequest(mr)
    self.VerifyParams(result, params)

    call_args_list = self.get_filtered_task_call_args(
        create_task_mock, urls.OUTBOUND_EMAIL_TASK + '.do')
    self.assertEqual(2, len(call_args_list))

    six.assertCountEqual(
        self, ['user@example.com', 'mailing-list@example.com'],
        result['notified'])

    for (args, _kwargs) in call_args_list:
      task = args[0]
      body = json.loads(task['app_engine_http_request']['body'].decode())
      # obfuscated email for non-members
      if 'user' in body['to']:
        self.assertIn(u'\u2026', body['from_addr'])
      # Full email for members
      if 'member' in body['to']:
        self.assertNotIn(u'\u2026', body['from_addr'])

  @mock.patch('framework.cloud_tasks_helpers.create_task')
  def testNotifyBulkChangeTask_SubscriberGetsEmail(self, create_task_mock):
    """If a user subscription matches the issue, notify that user."""
    task = notify.NotifyBulkChangeTask(services=self.services)
    params = {
        'send_email': 1,
        'issue_ids': '%d' % (self.issue1.issue_id),
        'seq': 0,
        'old_owner_ids': '1', 'commenter_id': 1}
    mr = testing_helpers.MakeMonorailRequest(
        user_info={'user_id': 1},
        params=params,
        method='POST',
        services=self.services)
    self.services.user.TestAddUser('subscriber@example.com', 4)
    sq = tracker_bizobj.MakeSavedQuery(
        1, 'all open issues', 2, '', subscription_mode='immediate',
        executes_in_project_ids=[self.issue1.project_id])
    self.services.features.UpdateUserSavedQueries('cnxn', 4, [sq])
    result = task.HandleRequest(mr)
    self.VerifyParams(result, params)

    call_args_list = self.get_filtered_task_call_args(
        create_task_mock, urls.OUTBOUND_EMAIL_TASK + '.do')
    self.assertEqual(2, len(call_args_list))

  @mock.patch('framework.cloud_tasks_helpers.create_task')
  def testNotifyBulkChangeTask_CCAndSubscriberListsIssueOnce(
      self, create_task_mock):
    """If a user both CCs and subscribes, include issue only once."""
    task = notify.NotifyBulkChangeTask(services=self.services)
    params = {
        'send_email': 1,
        'issue_ids': '%d' % (self.issue1.issue_id),
        'seq': 0,
        'old_owner_ids': '1', 'commenter_id': 1}
    mr = testing_helpers.MakeMonorailRequest(
        user_info={'user_id': 1},
        params=params,
        method='POST',
        services=self.services)
    self.services.user.TestAddUser('subscriber@example.com', 4)
    self.issue1.cc_ids = [4]
    sq = tracker_bizobj.MakeSavedQuery(
        1, 'all open issues', 2, '', subscription_mode='immediate',
        executes_in_project_ids=[self.issue1.project_id])
    self.services.features.UpdateUserSavedQueries('cnxn', 4, [sq])
    result = task.HandleRequest(mr)
    self.VerifyParams(result, params)

    call_args_list = self.get_filtered_task_call_args(
        create_task_mock, urls.OUTBOUND_EMAIL_TASK + '.do')
    self.assertEqual(2, len(call_args_list))

    found = False
    for (args, _kwargs) in call_args_list:
      task = args[0]
      body = json.loads(task['app_engine_http_request']['body'].decode())
      if body['to'] == 'subscriber@example.com':
        found = True
        task_body = body['body']
        self.assertEqual(1, task_body.count('Issue %d' % self.issue1.local_id))
    self.assertTrue(found)

  @mock.patch('framework.cloud_tasks_helpers.create_task')
  def testNotifyBulkChangeTask_Spam(self, _create_task_mock):
    """A spam issue is excluded from notification emails."""
    issue2 = MakeTestIssue(
        project_id=12345, local_id=2, owner_id=2, reporter_id=1,
        is_spam=True)
    self.services.issue.TestAddIssue(issue2)
    task = notify.NotifyBulkChangeTask(services=self.services)
    params = {
        'send_email': 1,
        'issue_ids': '%d,%d' % (self.issue1.issue_id, issue2.issue_id),
        'seq': 0,
        'old_owner_ids': '1,1', 'commenter_id': 1}
    mr = testing_helpers.MakeMonorailRequest(
        user_info={'user_id': 1},
        params=params,
        method='POST',
        services=self.services)
    result = task.HandleRequest(mr)
    self.assertEqual(1, len(result['notified']))

  def testFormatBulkIssues_Normal_Single(self):
    """A user may see full notification details for all changed issues."""
    self.issue1.summary = 'one summary'
    task = notify.NotifyBulkChangeTask(services=self.services)
    users_by_id = {}
    commenter_view = None
    config = self.services.config.GetProjectConfig('cnxn', 12345)
    addrperm = notify_reasons.AddrPerm(
        False, 'nonmember@example.com', self.nonmember,
        notify_reasons.REPLY_NOT_ALLOWED, None)

    subject, body = task._FormatBulkIssues(
      [self.issue1], users_by_id, commenter_view, 'localhost:8080',
      'test comment', [], config, addrperm)

    self.assertIn('one summary', subject)
    self.assertIn('one summary', body)
    self.assertIn('test comment', body)

  def testFormatBulkIssues_Normal_Multiple(self):
    """A user may see full notification details for all changed issues."""
    self.issue1.summary = 'one summary'
    self.issue2.summary = 'two summary'
    task = notify.NotifyBulkChangeTask(services=self.services)
    users_by_id = {}
    commenter_view = None
    config = self.services.config.GetProjectConfig('cnxn', 12345)
    addrperm = notify_reasons.AddrPerm(
        False, 'nonmember@example.com', self.nonmember,
        notify_reasons.REPLY_NOT_ALLOWED, None)

    subject, body = task._FormatBulkIssues(
      [self.issue1, self.issue2], users_by_id, commenter_view, 'localhost:8080',
      'test comment', [], config, addrperm)

    self.assertIn('2 issues changed', subject)
    self.assertIn('one summary', body)
    self.assertIn('two summary', body)
    self.assertIn('test comment', body)

  def testFormatBulkIssues_LinkOnly_Single(self):
    """A user may not see full notification details for some changed issue."""
    self.issue1.summary = 'one summary'
    self.issue1.labels = ['Restrict-View-Google']
    task = notify.NotifyBulkChangeTask(services=self.services)
    users_by_id = {}
    commenter_view = None
    config = self.services.config.GetProjectConfig('cnxn', 12345)
    addrperm = notify_reasons.AddrPerm(
        False, 'nonmember@example.com', self.nonmember,
        notify_reasons.REPLY_NOT_ALLOWED, None)

    subject, body = task._FormatBulkIssues(
      [self.issue1], users_by_id, commenter_view, 'localhost:8080',
      'test comment', [], config, addrperm)

    self.assertIn('issue 1', subject)
    self.assertNotIn('one summary', subject)
    self.assertNotIn('one summary', body)
    self.assertNotIn('test comment', body)

  def testFormatBulkIssues_LinkOnly_Multiple(self):
    """A user may not see full notification details for some changed issue."""
    self.issue1.summary = 'one summary'
    self.issue1.labels = ['Restrict-View-Google']
    self.issue2.summary = 'two summary'
    task = notify.NotifyBulkChangeTask(services=self.services)
    users_by_id = {}
    commenter_view = None
    config = self.services.config.GetProjectConfig('cnxn', 12345)
    addrperm = notify_reasons.AddrPerm(
        False, 'nonmember@example.com', self.nonmember,
        notify_reasons.REPLY_NOT_ALLOWED, None)

    subject, body = task._FormatBulkIssues(
      [self.issue1, self.issue2], users_by_id, commenter_view, 'localhost:8080',
      'test comment', [], config, addrperm)

    self.assertIn('2 issues', subject)
    self.assertNotIn('summary', subject)
    self.assertNotIn('one summary', body)
    self.assertIn('two summary', body)
    self.assertNotIn('test comment', body)

  @mock.patch('framework.cloud_tasks_helpers.create_task')
  def testNotifyApprovalChangeTask_Normal(self, _create_task_mock):
    config = self.services.config.GetProjectConfig('cnxn', 12345)
    config.field_defs = [
        # issue's User field with any_comment is notified.
        tracker_bizobj.MakeFieldDef(
            121, 12345, 'TL', tracker_pb2.FieldTypes.USER_TYPE,
            '', '', False, False, False, None, None, None, False, '',
            None, tracker_pb2.NotifyTriggers.ANY_COMMENT, 'no_action',
            'TL, notified on everything', False),
        # issue's User field with never is not notified.
        tracker_bizobj.MakeFieldDef(
            122, 12345, 'silentTL', tracker_pb2.FieldTypes.USER_TYPE,
            '', '', False, False, False, None, None, None, False, '',
            None, tracker_pb2.NotifyTriggers.NEVER, 'no_action',
            'TL, notified on nothing', False),
        # approval's User field with any_comment is notified.
        tracker_bizobj.MakeFieldDef(
            123, 12345, 'otherapprovalTL', tracker_pb2.FieldTypes.USER_TYPE,
            '', '', False, False, False, None, None, None, False, '',
            None, tracker_pb2.NotifyTriggers.ANY_COMMENT, 'no_action',
            'TL on the approvers team', False, approval_id=3),
        # another approval's User field with any_comment is not notified.
        tracker_bizobj.MakeFieldDef(
            124, 12345, 'otherapprovalTL', tracker_pb2.FieldTypes.USER_TYPE,
            '', '', False, False, False, None, None, None, False, '',
            None, tracker_pb2.NotifyTriggers.ANY_COMMENT, 'no_action',
            'TL on another approvers team', False, approval_id=4),
        tracker_bizobj.MakeFieldDef(
            3, 12345, 'Goat-Approval', tracker_pb2.FieldTypes.APPROVAL_TYPE,
            '', '', False, False, False, None, None, None, False, '',
            None, tracker_pb2.NotifyTriggers.NEVER, 'no_action',
            'Get Approval from Goats', False)
    ]
    self.services.config.StoreConfig('cnxn', config)

    # Custom user_type field TLs
    self.services.user.TestAddUser('TL@example.com', 111)
    self.services.user.TestAddUser('silentTL@example.com', 222)
    self.services.user.TestAddUser('approvalTL@example.com', 333)
    self.services.user.TestAddUser('otherapprovalTL@example.com', 444)

    # Approvers
    self.services.user.TestAddUser('approver_old@example.com', 777)
    self.services.user.TestAddUser('approver_new@example.com', 888)
    self.services.user.TestAddUser('approver_still@example.com', 999)
    self.services.user.TestAddUser('approver_group@example.com', 666)
    self.services.user.TestAddUser('group_mem1@example.com', 661)
    self.services.user.TestAddUser('group_mem2@example.com', 662)
    self.services.user.TestAddUser('group_mem3@example.com', 663)
    self.services.usergroup.TestAddGroupSettings(
        666, 'approver_group@example.com')
    self.services.usergroup.TestAddMembers(666, [661, 662, 663])
    canary_phase = tracker_pb2.Phase(
        name='Canary', phase_id=1, rank=1)
    approval_values = [
        tracker_pb2.ApprovalValue(approval_id=3,
                                  approver_ids=[888, 999, 666, 661])]
    approval_issue = MakeTestIssue(
        project_id=12345, local_id=2, owner_id=2, reporter_id=1,
        is_spam=True)
    approval_issue.phases = [canary_phase]
    approval_issue.approval_values = approval_values
    approval_issue.field_values = [
        tracker_bizobj.MakeFieldValue(121, None, None, 111, None, None, False),
        tracker_bizobj.MakeFieldValue(122, None, None, 222, None, None, False),
        tracker_bizobj.MakeFieldValue(123, None, None, 333, None, None, False),
        tracker_bizobj.MakeFieldValue(124, None, None, 444, None, None, False),
    ]
    self.services.issue.TestAddIssue(approval_issue)

    amend = tracker_bizobj.MakeApprovalApproversAmendment([888], [777])

    comment = tracker_pb2.IssueComment(
        project_id=12345, user_id=999, issue_id=approval_issue.issue_id,
        amendments=[amend], timestamp=1234567890, content='just a comment.')
    attach = tracker_pb2.Attachment(
        attachment_id=4567, filename='sploot.jpg', mimetype='image/png',
        gcs_object_id='/pid/attachments/abcd', filesize=(1024 * 1023))
    comment.attachments.append(attach)
    self.services.issue.TestAddComment(comment, approval_issue.local_id)
    self.services.issue.TestAddAttachment(
        attach, comment.id, approval_issue.issue_id)

    task = notify.NotifyApprovalChangeTask(services=self.services)
    params = {
        'send_email': 1,
        'issue_id': approval_issue.issue_id,
        'approval_id': 3,
        'comment_id': comment.id,
    }
    mr = testing_helpers.MakeMonorailRequest(
        user_info={'user_id': 1},
        params=params,
        method='POST',
        services=self.services)
    result = task.HandleRequest(mr)
    self.assertTrue('just a comment' in result['tasks'][0]['body'])
    self.assertTrue('Approvers: -appro...' in result['tasks'][0]['body'])
    self.assertTrue('sploot.jpg' in result['tasks'][0]['body'])
    self.assertTrue(
        '/issues/attachment?aid=4567' in result['tasks'][0]['body'])
    six.assertCountEqual(
        self, [
            'user@example.com', 'approver_old@example.com',
            'approver_new@example.com', 'TL@example.com',
            'approvalTL@example.com', 'group_mem1@example.com',
            'group_mem2@example.com', 'group_mem3@example.com'
        ], result['notified'])

    # Test no approvers/groups notified
    # Status change to NEED_INFO does not email approvers.
    amend2 = tracker_bizobj.MakeApprovalStatusAmendment(
        tracker_pb2.ApprovalStatus.NEED_INFO)
    comment2 = tracker_pb2.IssueComment(
        project_id=12345, user_id=999, issue_id=approval_issue.issue_id,
        amendments=[amend2], timestamp=1234567891, content='')
    self.services.issue.TestAddComment(comment2, approval_issue.local_id)
    task = notify.NotifyApprovalChangeTask(services=self.services)
    params = {
        'send_email': 1,
        'issue_id': approval_issue.issue_id,
        'approval_id': 3,
        'comment_id': comment2.id,
    }
    mr = testing_helpers.MakeMonorailRequest(
        user_info={'user_id': 1},
        params=params,
        method='POST',
        services=self.services)
    result = task.HandleRequest(mr)

    self.assertIsNotNone(result['tasks'][0].get('references'))
    self.assertEqual(result['tasks'][0]['reply_to'], emailfmt.NoReplyAddress())
    self.assertTrue('Status: need_info' in result['tasks'][0]['body'])
    six.assertCountEqual(
        self, ['user@example.com', 'TL@example.com', 'approvalTL@example.com'],
        result['notified'])

  def testNotifyApprovalChangeTask_GetApprovalEmailRecipients(self):
    task = notify.NotifyApprovalChangeTask(services=self.services)
    issue = fake.MakeTestIssue(789, 1, 'summary', 'New', 111)
    approval_value = tracker_pb2.ApprovalValue(
        approver_ids=[222, 333],
        status=tracker_pb2.ApprovalStatus.APPROVED)
    comment = tracker_pb2.IssueComment(
        project_id=789, user_id=1, issue_id=78901)

    # Comment with not amendments notifies everyone.
    rids = task._GetApprovalEmailRecipients(
        approval_value, comment, issue, [777, 888])
    six.assertCountEqual(self, rids, [111, 222, 333, 777, 888])

    # New APPROVED status notifies owners and any_comment users.
    amendment = tracker_bizobj.MakeApprovalStatusAmendment(
        tracker_pb2.ApprovalStatus.APPROVED)
    comment.amendments = [amendment]
    rids = task._GetApprovalEmailRecipients(
        approval_value, comment, issue, [777, 888])
    six.assertCountEqual(self, rids, [111, 777, 888])

    # New REVIEW_REQUESTED status notifies approvers.
    approval_value.status = tracker_pb2.ApprovalStatus.REVIEW_REQUESTED
    amendment = tracker_bizobj.MakeApprovalStatusAmendment(
        tracker_pb2.ApprovalStatus.REVIEW_REQUESTED)
    comment.amendments = [amendment]
    rids = task._GetApprovalEmailRecipients(
        approval_value, comment, issue, [777, 888])
    six.assertCountEqual(self, rids, [222, 333])

    # Approvers change notifies everyone.
    amendment = tracker_bizobj.MakeApprovalApproversAmendment(
        [222], [555])
    comment.amendments = [amendment]
    approval_value.approver_ids = [222]
    rids = task._GetApprovalEmailRecipients(
        approval_value, comment, issue, [777], omit_ids=[444, 333])
    six.assertCountEqual(self, rids, [111, 222, 555, 777])

  @mock.patch('framework.cloud_tasks_helpers.create_task')
  def testNotifyRulesDeletedTask(self, _create_task_mock):
    self.services.project.TestAddProject(
        'proj', owner_ids=[777, 888], project_id=789)
    self.services.user.TestAddUser('owner1@test.com', 777)
    self.services.user.TestAddUser('cow@test.com', 888)
    task = notify.NotifyRulesDeletedTask(services=self.services)
    params = {'project_id': 789,
              'filter_rules': 'if green make yellow,if orange make blue'}
    mr = testing_helpers.MakeMonorailRequest(
        params=params,
        method='POST',
        services=self.services)
    result = task.HandleRequest(mr)
    self.assertEqual(len(result['tasks']), 2)
    body = result['tasks'][0]['body']
    self.assertTrue('if green make yellow' in body)
    self.assertTrue('if green make yellow' in body)
    self.assertTrue('/p/proj/adminRules' in body)
    six.assertCountEqual(
        self, ['cow@test.com', 'owner1@test.com'], result['notified'])

  def testOutboundEmailTask_Normal(self):
    """We can send an email."""
    params = {
        'from_addr': 'requester@example.com',
        'reply_to': 'user@example.com',
        'to': 'user@example.com',
        'subject': 'Test subject'}
    data = json.dumps(params)
    res = self.app.test_client().post('/_task/outboundEmail.do', data=data)
    res_string = res.get_data()[5:]
    res_json = json.loads(res_string)
    self.assertEqual(params['from_addr'], res_json['sender'])
    self.assertEqual(params['subject'], res_json['subject'])

  def testOutboundEmailTask_MissingTo(self):
    """We skip emails that don't specify the To-line."""
    params = {
        'from_addr': 'requester@example.com',
        'reply_to': 'user@example.com',
        'subject': 'Test subject'}
    data = json.dumps(params)
    res = self.app.test_client().post('/_task/outboundEmail.do', data=data)
    res_string = res.get_data()[5:]
    res_json = json.loads(res_string)
    self.assertEqual(
        'Skipping because no "to" address found.', res_json['note'])
    self.assertNotIn(b'from_addr', res_string)

  def testOutboundEmailTask_BannedUser(self):
    """We don't send emails to banned users.."""
    self.servlet.services.user.TestAddUser(
        'banned@example.com', 404, banned=True)
    params = {
        'from_addr': 'requester@example.com',
        'reply_to': 'user@example.com',
        'to': 'banned@example.com',
        'subject': 'Test subject'}
    data = json.dumps(params)
    res = self.app.test_client().post('/_task/outboundEmail.do', data=data)
    res_string = res.get_data()[5:]
    res_json = json.loads(res_string)
    self.assertEqual('Skipping because user is banned.', res_json['note'])
    self.assertNotIn(b'from_addr', res_string)
