# 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.

"""Unittest for the dateaction module."""

from __future__ import division
from __future__ import print_function
from __future__ import absolute_import

import logging
import mock
import time
import unittest

from features import dateaction
from framework import cloud_tasks_helpers
from framework import framework_constants
from framework import framework_views
from framework import timestr
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 tracker_bizobj


NOW = 1492120863


class DateActionCronTest(unittest.TestCase):

  def setUp(self):
    self.services = service_manager.Services(
        user=fake.UserService(),
        issue=fake.IssueService())
    self.servlet = dateaction.DateActionCron(services=self.services)
    self.TIMESTAMP_MIN = (
        NOW // framework_constants.SECS_PER_DAY *
        framework_constants.SECS_PER_DAY)
    self.TIMESTAMP_MAX = self.TIMESTAMP_MIN + framework_constants.SECS_PER_DAY
    self.left_joins = [
        ('Issue2FieldValue ON Issue.id = Issue2FieldValue.issue_id', []),
        ('FieldDef ON Issue2FieldValue.field_id = FieldDef.id', []),
    ]
    self.where = [
        ('FieldDef.field_type = %s', ['date_type']),
        (
            'FieldDef.date_action IN (%s,%s)',
            ['ping_owner_only', 'ping_participants']),
        ('Issue2FieldValue.date_value >= %s', [self.TIMESTAMP_MIN]),
        ('Issue2FieldValue.date_value < %s', [self.TIMESTAMP_MAX]),
    ]
    self.order_by = [
        ('Issue.id', []),
    ]

  @mock.patch('time.time', return_value=NOW)
  def testHandleRequest_NoMatches(self, _mock_time):
    _request, mr = testing_helpers.GetRequestObjects(
        path=urls.DATE_ACTION_CRON)
    self.services.issue.RunIssueQuery = mock.MagicMock(return_value=([], False))

    self.servlet.HandleRequest(mr)

    self.services.issue.RunIssueQuery.assert_called_with(
        mr.cnxn, self.left_joins, self.where + [('Issue.id > %s', [0])],
        self.order_by)

  @mock.patch('framework.cloud_tasks_helpers._get_client')
  @mock.patch('time.time', return_value=NOW)
  def testHandleRequest_OneMatche(self, _mock_time, get_client_mock):
    _request, mr = testing_helpers.GetRequestObjects(
        path=urls.DATE_ACTION_CRON)
    self.services.issue.RunIssueQuery = mock.MagicMock(
        return_value=([78901], False))

    self.servlet.HandleRequest(mr)

    self.services.issue.RunIssueQuery.assert_called_with(
        mr.cnxn, self.left_joins, self.where + [('Issue.id > %s', [0])],
        self.order_by)
    expected_task = {
        'app_engine_http_request':
            {
                'relative_uri': urls.ISSUE_DATE_ACTION_TASK + '.do',
                'body': b'issue_id=78901',
                'headers': {
                    'Content-type': 'application/x-www-form-urlencoded'
                }
            }
    }
    get_client_mock().create_task.assert_any_call(
        parent=get_client_mock().queue_path(),
        task=expected_task,
        retry=cloud_tasks_helpers._DEFAULT_RETRY)

  @mock.patch('framework.cloud_tasks_helpers._get_client')
  def testEnqueueDateAction(self, get_client_mock):
    self.servlet.EnqueueDateAction(78901)
    expected_task = {
        'app_engine_http_request':
            {
                'relative_uri': urls.ISSUE_DATE_ACTION_TASK + '.do',
                'body': b'issue_id=78901',
                'headers': {
                    'Content-type': 'application/x-www-form-urlencoded'
                }
            }
    }
    get_client_mock().create_task.assert_any_call(
        parent=get_client_mock().queue_path(),
        task=expected_task,
        retry=cloud_tasks_helpers._DEFAULT_RETRY)


class IssueDateActionTaskTest(unittest.TestCase):

  def setUp(self):
    self.services = service_manager.Services(
        user=fake.UserService(),
        usergroup=fake.UserGroupService(),
        features=fake.FeaturesService(),
        issue=fake.IssueService(),
        project=fake.ProjectService(),
        config=fake.ConfigService(),
        issue_star=fake.IssueStarService())
    self.servlet = dateaction.IssueDateActionTask(services=self.services)

    self.config = self.services.config.GetProjectConfig('cnxn', 789)
    self.config.field_defs = [
        tracker_bizobj.MakeFieldDef(
            123, 789, 'NextAction', tracker_pb2.FieldTypes.DATE_TYPE,
            '', '', False, False, False, None, None, None, False, '',
            None, None, tracker_pb2.DateAction.PING_OWNER_ONLY,
            'Date of next expected progress update', False),
        tracker_bizobj.MakeFieldDef(
            124, 789, 'EoL', tracker_pb2.FieldTypes.DATE_TYPE,
            '', '', False, False, False, None, None, None, False, '',
            None, None, tracker_pb2.DateAction.PING_OWNER_ONLY, 'doc', False),
        tracker_bizobj.MakeFieldDef(
            125, 789, 'TLsBirthday', tracker_pb2.FieldTypes.DATE_TYPE,
            '', '', False, False, False, None, None, None, False, '',
            None, None, tracker_pb2.DateAction.NO_ACTION, 'doc', False),
        ]
    self.services.config.StoreConfig('cnxn', self.config)
    self.project = self.services.project.TestAddProject('proj', project_id=789)
    self.owner = self.services.user.TestAddUser('owner@example.com', 111)
    self.date_action_user = self.services.user.TestAddUser(
        'date-action-user@example.com', 555)

  def testHandleRequest_IssueHasNoArrivedDates(self):
    _request, mr = testing_helpers.GetRequestObjects(
        path=urls.ISSUE_DATE_ACTION_TASK + '.do?issue_id=78901')
    self.services.issue.TestAddIssue(fake.MakeTestIssue(
        789, 1, 'summary', 'New', 111, issue_id=78901))
    self.assertEqual(1, len(self.services.issue.GetCommentsForIssue(
        mr.cnxn, 78901)))

    self.servlet.HandleRequest(mr)
    self.assertEqual(1, len(self.services.issue.GetCommentsForIssue(
        mr.cnxn, 78901)))

  @mock.patch('framework.cloud_tasks_helpers.create_task')
  def testHandleRequest_IssueHasOneArriveDate(self, create_task_mock):
    _request, mr = testing_helpers.GetRequestObjects(
        path=urls.ISSUE_DATE_ACTION_TASK + '.do?issue_id=78901')

    now = int(time.time())
    date_str = timestr.TimestampToDateWidgetStr(now)
    issue = fake.MakeTestIssue(789, 1, 'summary', 'New', 111, issue_id=78901)
    self.services.issue.TestAddIssue(issue)
    issue.field_values = [
        tracker_bizobj.MakeFieldValue(123, None, None, None, now, None, False)]
    self.assertEqual(1, len(self.services.issue.GetCommentsForIssue(
        mr.cnxn, 78901)))

    self.servlet.HandleRequest(mr)
    comments = self.services.issue.GetCommentsForIssue(mr.cnxn, 78901)
    self.assertEqual(2, len(comments))
    self.assertEqual(
      'The NextAction date has arrived: %s' % date_str,
      comments[1].content)

    self.assertEqual(create_task_mock.call_count, 1)

    (args, kwargs) = create_task_mock.call_args
    self.assertEqual(
        args[0]['app_engine_http_request']['relative_uri'],
        urls.OUTBOUND_EMAIL_TASK + '.do')
    self.assertEqual(kwargs['queue'], 'outboundemail')

  def SetUpFieldValues(self, issue, now):
    issue.field_values = [
        tracker_bizobj.MakeFieldValue(123, None, None, None, now, None, False),
        tracker_bizobj.MakeFieldValue(124, None, None, None, now, None, False),
        tracker_bizobj.MakeFieldValue(125, None, None, None, now, None, False),
        ]

  @mock.patch('framework.cloud_tasks_helpers.create_task')
  def testHandleRequest_IssueHasTwoArriveDates(self, create_task_mock):
    _request, mr = testing_helpers.GetRequestObjects(
        path=urls.ISSUE_DATE_ACTION_TASK + '.do?issue_id=78901')

    now = int(time.time())
    date_str = timestr.TimestampToDateWidgetStr(now)
    issue = fake.MakeTestIssue(789, 1, 'summary', 'New', 111, issue_id=78901)
    self.services.issue.TestAddIssue(issue)
    self.SetUpFieldValues(issue, now)
    self.assertEqual(1, len(self.services.issue.GetCommentsForIssue(
        mr.cnxn, 78901)))

    self.servlet.HandleRequest(mr)
    comments = self.services.issue.GetCommentsForIssue(mr.cnxn, 78901)
    self.assertEqual(2, len(comments))
    self.assertEqual(
      'The EoL date has arrived: %s\n'
      'The NextAction date has arrived: %s' % (date_str, date_str),
      comments[1].content)

    self.assertEqual(create_task_mock.call_count, 1)

    (args, kwargs) = create_task_mock.call_args
    self.assertEqual(
        args[0]['app_engine_http_request']['relative_uri'],
        urls.OUTBOUND_EMAIL_TASK + '.do')
    self.assertEqual(kwargs['queue'], 'outboundemail')

  def MakePingComment(self):
    comment = tracker_pb2.IssueComment()
    comment.project_id = self.project.project_id
    comment.user_id = self.date_action_user.user_id
    comment.content = 'Some date(s) arrived...'
    return comment

  def testMakeEmailTasks_Owner(self):
    """The issue owner gets pinged and the email has expected content."""
    issue = fake.MakeTestIssue(
        789, 1, 'summary', 'New', self.owner.user_id, issue_id=78901)
    self.services.issue.TestAddIssue(issue)
    now = int(time.time())
    self.SetUpFieldValues(issue, now)
    issue.project_name = 'proj'
    comment = self.MakePingComment()
    next_action_field_def = self.config.field_defs[0]
    pings = [(next_action_field_def, now)]
    users_by_id = framework_views.MakeAllUserViews(
        'fake cnxn', self.services.user,
        [self.owner.user_id, self.date_action_user.user_id])

    tasks = self.servlet._MakeEmailTasks(
        'fake cnxn', issue, self.project, self.config, comment,
        [], 'example-app.appspot.com', users_by_id, pings)
    self.assertEqual(1, len(tasks))
    notify_owner_task = tasks[0]
    self.assertEqual('owner@example.com', notify_owner_task['to'])
    self.assertEqual(
        'Follow up on issue 1 in proj: summary',
        notify_owner_task['subject'])
    body = notify_owner_task['body']
    self.assertIn(comment.content, body)
    self.assertIn(next_action_field_def.docstring, body)

  def testMakeEmailTasks_Starrer(self):
    """Users who starred the issue are notified iff they opt in."""
    issue = fake.MakeTestIssue(
        789, 1, 'summary', 'New', 0, issue_id=78901)
    self.services.issue.TestAddIssue(issue)
    now = int(time.time())
    self.SetUpFieldValues(issue, now)
    issue.project_name = 'proj'
    comment = self.MakePingComment()
    next_action_field_def = self.config.field_defs[0]
    pings = [(next_action_field_def, now)]

    starrer_333 = self.services.user.TestAddUser('starrer333@example.com', 333)
    starrer_333.notify_starred_ping = True
    self.services.user.TestAddUser('starrer444@example.com', 444)
    starrer_ids = [333, 444]
    users_by_id = framework_views.MakeAllUserViews(
        'fake cnxn', self.services.user,
        [self.owner.user_id, self.date_action_user.user_id],
        starrer_ids)

    tasks = self.servlet._MakeEmailTasks(
        'fake cnxn', issue, self.project, self.config, comment,
        starrer_ids, 'example-app.appspot.com', users_by_id, pings)
    self.assertEqual(1, len(tasks))
    notify_owner_task = tasks[0]
    self.assertEqual('starrer333@example.com', notify_owner_task['to'])
