# 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_helpers
from features import notify_reasons
from framework import emailfmt
from framework import urls
from mrproto import tracker_pb2
from mrproto import project_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('features.notify_helpers.AddAllEmailTasks')
  def testNotifyIssueChangeTask_ArchivedProject(self, _AddAllEmailTasksMock):
    project = self.services.project.TestAddProject(
        'archived-project',
        owner_ids=[1, 3],
        state=project_pb2.ProjectState.ARCHIVED)
    issue = MakeTestIssue(
        project.project_id, local_id=3, owner_id=3, reporter_id=1)
    self.services.issue.TestAddIssue(issue)
    task = notify.NotifyIssueChangeTask(services=self.services)
    params = {
        'send_email': 1,
        '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.VerifyParams(result, params)
    _AddAllEmailTasksMock.assert_not_called()


  @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)

  @mock.patch('features.notify_helpers.AddAllEmailTasks')
  def testNotifyBlockingChangeTask_ArchivedProject(self, _AddAllEmailTasksMock):
    project = self.services.project.TestAddProject(
        'archived-project',
        owner_ids=[1, 3],
        state=project_pb2.ProjectState.ARCHIVED)
    issue = MakeTestIssue(
        project.project_id, local_id=3, owner_id=3, reporter_id=1)
    self.services.issue.TestAddIssue(issue)
    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(issue.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)
    _AddAllEmailTasksMock.assert_called_once_with([])

  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('features.notify_helpers.AddAllEmailTasks')
  def testNotifyBulkChangeTask_ArchivedProject(self, _AddAllEmailTasksMock):
    project = self.services.project.TestAddProject(
        'archived-project',
        owner_ids=[1, 3],
        state=project_pb2.ProjectState.ARCHIVED)
    issue = MakeTestIssue(
        project.project_id, local_id=3, owner_id=3, reporter_id=1)
    issue.cc_ids = [3]
    self.services.issue.TestAddIssue(issue)
    task = notify.NotifyBulkChangeTask(services=self.services)
    params = {
        'send_email': 1,
        'seq': 0,
        'issue_ids': '%d' % (issue.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)
    _AddAllEmailTasksMock.assert_not_called()

  @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'])

  @mock.patch('features.notify_helpers.AddAllEmailTasks')
  def testNotifyApprovalChangeTask_ArchivedProject(self, _AddAllEmailTasksMock):
    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])
    ]
    project = self.services.project.TestAddProject(
        'archived-project',
        owner_ids=[1, 3],
        state=project_pb2.ProjectState.ARCHIVED)
    issue = MakeTestIssue(
        project.project_id, local_id=3, owner_id=3, reporter_id=1)
    issue.phases = [canary_phase]
    issue.approval_values = approval_values
    issue.field_values = [
        tracker_bizobj.MakeFieldValue(121, None, None, 111, None, None, False),
    ]
    self.services.issue.TestAddIssue(issue)

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

    comment = tracker_pb2.IssueComment(
        project_id=12345,
        user_id=999,
        issue_id=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, issue.local_id)
    self.services.issue.TestAddAttachment(attach, comment.id, issue.issue_id)

    task = notify.NotifyApprovalChangeTask(services=self.services)
    params = {
        'send_email': 1,
        'issue_id': 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)
    task.HandleRequest(mr)
    _AddAllEmailTasksMock.assert_not_called()

  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'])

  @mock.patch('features.notify_helpers.AddAllEmailTasks')
  def testNotifyRulesDeletedTask_ArchivedProject(self, _AddAllEmailTasksMock):
    project = self.services.project.TestAddProject(
        'archived-project',
        owner_ids=[1, 3],
        state=project_pb2.ProjectState.ARCHIVED)
    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': project.project_id,
        'filter_rules': 'if green make yellow,if orange make blue'
    }
    mr = testing_helpers.MakeMonorailRequest(
        params=params, method='POST', services=self.services)
    task.HandleRequest(mr)
    _AddAllEmailTasksMock.assert_not_called()

  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)
