# 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 issueattachmenttext."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import mock
import unittest

import ezt
from google.appengine.ext import testbed
from google.cloud import storage

from framework import permissions
from mrproto import tracker_pb2
from services import service_manager
from testing import fake
from testing import testing_helpers
from tracker import issueattachmenttext


class IssueAttachmentTextTest(unittest.TestCase):

  def setUp(self):
    self.testbed = testbed.Testbed()
    self.testbed.activate()
    self.testbed.init_app_identity_stub()

    services = service_manager.Services(
        project=fake.ProjectService(),
        config=fake.ConfigService(),
        issue=fake.IssueService(),
        user=fake.UserService())
    self.project = services.project.TestAddProject('proj')
    self.servlet = issueattachmenttext.AttachmentText(services=services)

    services.user.TestAddUser('commenter@example.com', 111)

    self.issue = tracker_pb2.Issue()
    self.issue.local_id = 1
    self.issue.issue_id = 1
    self.issue.summary = 'sum'
    self.issue.project_name = 'proj'
    self.issue.project_id = self.project.project_id
    services.issue.TestAddIssue(self.issue)

    self.comment0 = tracker_pb2.IssueComment()
    self.comment0.content = 'this is the description'
    self.comment0.user_id = 111
    self.comment1 = tracker_pb2.IssueComment()
    self.comment1.content = 'this is a comment'
    self.comment1.user_id = 111

    self.attach0 = tracker_pb2.Attachment(
        attachment_id=4567, filename='b.txt', mimetype='text/plain',
        gcs_object_id='/pid/attachments/abcd')
    self.comment0.attachments.append(self.attach0)

    self.attach1 = tracker_pb2.Attachment(
        attachment_id=1234, filename='a.txt', mimetype='text/plain',
        gcs_object_id='/pid/attachments/abcdefg')
    self.comment0.attachments.append(self.attach1)

    self.bin_attach = tracker_pb2.Attachment(
        attachment_id=2468, mimetype='application/octets',
        gcs_object_id='/pid/attachments/\0\0\0\0\0\1\2\3')
    self.comment1.attachments.append(self.bin_attach)

    self.comment0.project_id = self.project.project_id
    services.issue.TestAddComment(self.comment0, self.issue.local_id)
    self.comment1.project_id = self.project.project_id
    services.issue.TestAddComment(self.comment1, self.issue.local_id)
    services.issue.TestAddAttachment(
        self.attach0, self.comment0.id, self.issue.issue_id)
    services.issue.TestAddAttachment(
        self.attach1, self.comment1.id, self.issue.issue_id)
    # TODO(jrobbins): add tests for binary content

    self.client = mock.MagicMock()
    self.bucket = mock.MagicMock()
    self.blob = mock.MagicMock()
    self.client.get_bucket = mock.MagicMock(return_value=self.bucket)
    self.bucket.get_blob = mock.MagicMock(return_value=self.blob)
    self.blob.download_as_bytes = mock.MagicMock(return_value=b'')
    mock.patch.object(storage, 'Client', return_value=self.client).start()

  def tearDown(self):
    self.testbed.deactivate()
    mock.patch.stopall()

  def testGatherPageData_CommentDeleted(self):
    """If the attachment's comment was deleted, give a 403."""
    _request, mr = testing_helpers.GetRequestObjects(
        project=self.project,
        path='/a/d.com/p/proj/issues/attachmentText?aid=1234',
        perms=permissions.READ_ONLY_PERMISSIONSET)
    self.servlet.GatherPageData(mr)  # OK
    self.comment1.deleted_by = 111
    self.assertRaises(  # 403
        permissions.PermissionException,
        self.servlet.GatherPageData, mr)

  def testGatherPageData_IssueNotViewable(self):
    """If the attachment's issue is not viewable, give a 403."""
    _request, mr = testing_helpers.GetRequestObjects(
        project=self.project,
        path='/p/proj/issues/attachment?aid=1234',
        perms=permissions.EMPTY_PERMISSIONSET)  # No VIEW
    self.assertRaises(
        permissions.PermissionException,
        self.servlet.GatherPageData, mr)

  def testGatherPageData_IssueDeleted(self):
    _request, mr = testing_helpers.GetRequestObjects(
        project=self.project,
        path='/p/proj/issues/attachment?aid=1234',
        perms=permissions.READ_ONLY_PERMISSIONSET)
    self.issue.deleted = True
    self.assertRaises(  # Issue was deleted
        permissions.PermissionException,
        self.servlet.GatherPageData, mr)

  def testGatherPageData_IssueRestricted(self):
    _request, mr = testing_helpers.GetRequestObjects(
        project=self.project,
        path='/p/proj/issues/attachment?aid=1234',
        perms=permissions.READ_ONLY_PERMISSIONSET)
    self.issue.labels.append('Restrict-View-Nobody')
    self.assertRaises(  # Issue is restricted
        permissions.PermissionException,
        self.servlet.GatherPageData, mr)

  def testGatherPageData_NoSuchAttachment(self):
    _request, mr = testing_helpers.GetRequestObjects(
        project=self.project,
        path='/p/proj/issues/attachmentText?aid=9999',
        perms=permissions.READ_ONLY_PERMISSIONSET)
    with self.assertRaises(Exception) as cm:
      self.servlet.GatherPageData(mr)
    self.assertEqual(404, cm.exception.code)

  def testGatherPageData_AttachmentDeleted(self):
    """If the attachment was deleted, give a 404."""
    _request, mr = testing_helpers.GetRequestObjects(
        project=self.project,
        path='/p/proj/issues/attachmentText?aid=1234',
        perms=permissions.READ_ONLY_PERMISSIONSET)
    self.attach1.deleted = True
    with self.assertRaises(Exception) as cm:
      self.servlet.GatherPageData(mr)
      self.assertEqual(404, cm.exception.code)

  def testGatherPageData_Normal(self):
    self.blob.download_as_bytes = mock.MagicMock(
        return_value=b'/app_default_bucket/pid/attachments/abcdefg')

    _request, mr = testing_helpers.GetRequestObjects(
        project=self.project,
        path='/p/proj/issues/attachmentText?id=1&aid=1234',
        perms=permissions.READ_ONLY_PERMISSIONSET)
    page_data = self.servlet.GatherPageData(mr)
    self.assertEqual(1, page_data['local_id'])
    self.assertEqual('a.txt', page_data['filename'])
    self.assertEqual('43 bytes', page_data['filesize'])
    self.assertEqual(ezt.boolean(False), page_data['should_prettify'])
    self.assertEqual(ezt.boolean(False), page_data['is_binary'])
    self.assertEqual(ezt.boolean(False), page_data['too_large'])

    file_lines = page_data['file_lines']
    self.assertEqual(1, len(file_lines))
    self.assertEqual(1, file_lines[0].num)
    self.assertEqual(
        '/app_default_bucket/pid/attachments/abcdefg', file_lines[0].line)

    self.assertEqual(None, page_data['code_reviews'])

  @mock.patch('framework.filecontent.DecodeFileContents')
  def testGatherPageData_HugeFile(self, mock_DecodeFileContents):
    _request, mr = testing_helpers.GetRequestObjects(
        project=self.project,
        path='/p/proj/issues/attachmentText?id=1&aid=1234',
        perms=permissions.READ_ONLY_PERMISSIONSET)
    mock_DecodeFileContents.return_value = (
        'too large text', False, True)

    page_data = self.servlet.GatherPageData(mr)

    self.assertEqual(ezt.boolean(False), page_data['should_prettify'])
    self.assertEqual(ezt.boolean(False), page_data['is_binary'])
    self.assertEqual(ezt.boolean(True), page_data['too_large'])
