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

import datetime
import mock
import unittest

from dashboard.api import api_auth
from dashboard.api import bugs
from dashboard.common import testing_common
from dashboard.common import utils
from dashboard.models import try_job


class MockIssueTrackerService(object):
  """A fake version of IssueTrackerService that returns expected data."""
  def __init__(self, http=None):
    pass

  @classmethod
  def GetIssue(cls, _):
    return {
        'cc': [
            {
                'kind': 'monorail#issuePerson',
                'htmlLink': 'https://bugs.chromium.org/u/1253971105',
                'name': 'user@chromium.org',
            }, {
                'kind': 'monorail#issuePerson',
                'name': 'hello@world.org',
            }
        ],
        'labels': [
            'Type-Bug',
            'Pri-3',
            'M-61',
        ],
        'owner': {
            'kind': 'monorail#issuePerson',
            'htmlLink': 'https://bugs.chromium.org/u/49586776',
            'name': 'owner@chromium.org',
        },
        'id': 737355,
        'author': {
            'kind': 'monorail#issuePerson',
            'htmlLink': 'https://bugs.chromium.org/u/49586776',
            'name': 'author@chromium.org',
        },
        'state': 'closed',
        'status': 'Fixed',
        'summary': 'The bug title',
        'components': [
            'Blink>ServiceWorker',
            'Foo>Bar',
        ],
        'published': '2017-06-28T01:26:53',
        'updated': '2018-03-01T16:16:22',
    }

  @classmethod
  def GetIssueComments(cls, _):
    return [{
        'content': 'Comment one',
        'published': '2017-06-28T04:42:55',
        'author': 'comment-one-author@company.com',
    }, {
        'content': 'Comment two',
        'published': '2017-06-28T10:16:14',
        'author': 'author-two@chromium.org'
    }]


class BugsTest(testing_common.TestCase):

  def setUp(self):
    super(BugsTest, self).setUp()
    self.SetUpApp([(r'/api/bugs/(.*)', bugs.BugsHandler)])
    # Add a fake issue tracker service that we can get call values from.
    self.original_service = bugs.issue_tracker_service.IssueTrackerService
    bugs.issue_tracker_service = mock.MagicMock()
    self.service = MockIssueTrackerService
    bugs.issue_tracker_service.IssueTrackerService = self.service
    self.SetCurrentClientIdOAuth(api_auth.OAUTH_CLIENT_ID_WHITELIST[0])

  def tearDown(self):
    super(BugsTest, self).tearDown()
    bugs.issue_tracker_service.IssueTrackerService = self.original_service

  @mock.patch.object(utils, 'ServiceAccountHttp', mock.MagicMock())
  def testPost_WithValidBug_ShowsData(self):
    self.SetCurrentUserOAuth(testing_common.INTERNAL_USER)
    try_job.TryJob(
        bug_id=123456, status='started', bot='win_perf',
        results_data={}, config='config = {"command": "cmd"}',
        last_ran_timestamp=datetime.datetime(2017, 01, 01)).put()
    try_job.TryJob(
        bug_id=123456, status='failed', bot='android_bisect',
        results_data={'metric': 'foo'},
        config='config = {"command": "cmd"}').put()
    try_job.TryJob(
        bug_id=99999, status='failed', bot='win_perf',
        results_data={'metric': 'foo'},
        config='config = {"command": "cmd"}').put()
    response = self.Post('/api/bugs/123456?include_comments=true')
    bug = self.GetJsonValue(response, 'bug')
    self.assertEqual('The bug title', bug.get('summary'))
    self.assertEqual(2, len(bug.get('cc')))
    self.assertEqual('hello@world.org', bug.get('cc')[1])
    self.assertEqual('Fixed', bug.get('status'))
    self.assertEqual('closed', bug.get('state'))
    self.assertEqual('author@chromium.org', bug.get('author'))
    self.assertEqual('owner@chromium.org', bug.get('owner'))
    self.assertEqual('2017-06-28T01:26:53', bug.get('published'))
    self.assertEqual('2018-03-01T16:16:22', bug.get('updated'))
    self.assertEqual(2, len(bug.get('comments')))
    self.assertEqual('Comment two', bug.get('comments')[1].get('content'))
    self.assertEqual(
        'author-two@chromium.org', bug.get('comments')[1].get('author'))
    self.assertEqual(2, len(bug.get('legacy_bisects')))
    self.assertEqual('started', bug.get('legacy_bisects')[0].get('status'))
    self.assertEqual('cmd', bug.get('legacy_bisects')[0].get('command'))
    self.assertEqual('2017-01-01T00:00:00', bug.get('legacy_bisects')[0].get(
        'started_timestamp'))
    self.assertEqual('', bug.get('legacy_bisects')[1].get(
        'started_timestamp'))

  @mock.patch.object(utils, 'ServiceAccountHttp', mock.MagicMock())
  def testPost_WithValidBugButNoComments(self):
    self.SetCurrentUserOAuth(testing_common.INTERNAL_USER)

    try_job.TryJob(
        bug_id=123456, status='started', bot='win_perf',
        results_data={}, config='config = {"command": "cmd"}',
        last_ran_timestamp=datetime.datetime(2017, 01, 01)).put()
    try_job.TryJob(
        bug_id=123456, status='failed', bot='android_bisect',
        results_data={'metric': 'foo'},
        config='config = {"command": "cmd"}').put()
    try_job.TryJob(
        bug_id=99999, status='failed', bot='win_perf',
        results_data={'metric': 'foo'},
        config='config = {"command": "cmd"}').put()
    response = self.Post('/api/bugs/123456')
    bug = self.GetJsonValue(response, 'bug')
    self.assertNotIn('comments', bug)


  @mock.patch.object(utils, 'ServiceAccountHttp', mock.MagicMock())
  def testPost_WithInvalidBugIdParameter_ShowsError(self):
    self.SetCurrentUserOAuth(testing_common.INTERNAL_USER)
    response = self.Post('/api/bugs/foo', status=400)
    self.assertIn('Invalid bug ID \\"foo\\".', response.body)

  @mock.patch.object(utils, 'ServiceAccountHttp', mock.MagicMock())
  def testPost_NoAccess_ShowsError(self):
    self.SetCurrentUserOAuth(testing_common.EXTERNAL_USER)
    response = self.Post('/api/bugs/foo', status=403)
    self.assertIn('Access denied', response.body)

  def testPost_NoOauthUser(self):
    self.SetCurrentUserOAuth(None)
    self.Post('/api/bugs/12345', status=401)

  def testPost_BadOauthClientId(self):
    self.SetCurrentUserOAuth(testing_common.INTERNAL_USER)
    self.SetCurrentClientIdOAuth('invalid')
    self.Post('/api/bugs/12345', status=403)


if __name__ == '__main__':
  unittest.main()
