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

"""Unit tests for helpers module."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import unittest

from mock import patch

from framework import framework_views
from framework import permissions
from project import project_constants
from project import project_helpers
from mrproto import project_pb2
from services import service_manager
from testing import fake


class HelpersUnitTest(unittest.TestCase):

  def setUp(self):
    self.cnxn = 'fake sql connection'
    self.services = service_manager.Services(
        project=fake.ProjectService(),
        user=fake.UserService())
    self.services.user.TestAddUser('a@example.com', 111)
    self.services.user.TestAddUser('b@example.com', 222)
    self.services.user.TestAddUser('c@example.com', 333)
    self.users_by_id = framework_views.MakeAllUserViews(
        'cnxn', self.services.user, [111, 222, 333])
    self.effective_ids_by_user = {user: set() for user in {111, 222, 333}}

  def testBuildProjectMembers(self):
    project = project_pb2.MakeProject(
        'proj', owner_ids=[111], committer_ids=[222],
        contributor_ids=[333])
    page_data = project_helpers.BuildProjectMembers(
        self.cnxn, project, self.services.user)
    self.assertEqual(111, page_data['owners'][0].user_id)
    self.assertEqual(222, page_data['committers'][0].user_id)
    self.assertEqual(333, page_data['contributors'][0].user_id)
    self.assertEqual(3, len(page_data['all_members']))

  def testParseUsernames(self):
    # Form field was not present in post data.
    id_set = project_helpers.ParseUsernames(
        self.cnxn, self.services.user, None)
    self.assertEqual(set(), id_set)

    # Form field was present, but empty.
    id_set = project_helpers.ParseUsernames(
        self.cnxn, self.services.user, '')
    self.assertEqual(set(), id_set)

    # Parsing valid user names.
    id_set = project_helpers.ParseUsernames(
        self.cnxn, self.services.user, 'a@example.com, c@example.com')
    self.assertEqual({111, 333}, id_set)

  def testParseProjectAccess_NotOffered(self):
    project = project_pb2.MakeProject('proj')
    access = project_helpers.ParseProjectAccess(project, None)
    self.assertEqual(None, access)

  def testParseProjectAccess_AllowedChoice(self):
    project = project_pb2.MakeProject('proj')
    access = project_helpers.ParseProjectAccess(project, '1')
    self.assertEqual(project_pb2.ProjectAccess.ANYONE, access)

    access = project_helpers.ParseProjectAccess(project, '3')
    self.assertEqual(project_pb2.ProjectAccess.MEMBERS_ONLY, access)

  def testParseProjectAccess_BogusChoice(self):
    project = project_pb2.MakeProject('proj')
    access = project_helpers.ParseProjectAccess(project, '9')
    self.assertEqual(None, access)

  def testUsersWithPermsInProject_StandardPermission(self):
    project = project_pb2.MakeProject('proj', committer_ids=[111])
    perms_needed = {permissions.VIEW, permissions.EDIT_ISSUE}
    actual = project_helpers.UsersWithPermsInProject(
        project, perms_needed, self.users_by_id, self.effective_ids_by_user)
    self.assertEqual(
        {permissions.VIEW: {111, 222, 333},
         permissions.EDIT_ISSUE: {111}},
        actual)

  def testUsersWithPermsInProject_IndirectPermission(self):
    perms_needed = {permissions.EDIT_ISSUE}
    # User 111 has the EDIT_ISSUE permission.
    project = project_pb2.MakeProject('proj', committer_ids=[111])
    # User 222 has the EDIT_ISSUE permission, because 111 is included in its
    # effective IDs.
    self.effective_ids_by_user[222] = {111}
    # User 333 doesn't have the EDIT_ISSUE permission, since only direct
    # effective IDs are taken into account.
    self.effective_ids_by_user[333] = {222}
    actual = project_helpers.UsersWithPermsInProject(
        project, perms_needed, self.users_by_id, self.effective_ids_by_user)
    self.assertEqual(
        {permissions.EDIT_ISSUE: {111, 222}},
        actual)

  def testUsersWithPermsInProject_CustomPermission(self):
    project = project_pb2.MakeProject('proj')
    project.extra_perms = [
        project_pb2.Project.ExtraPerms(
            member_id=111,
            perms=['FooPerm', 'BarPerm']),
        project_pb2.Project.ExtraPerms(
            member_id=222,
            perms=['BarPerm'])]
    perms_needed = {'FooPerm', 'BarPerm'}
    actual = project_helpers.UsersWithPermsInProject(
        project, perms_needed, self.users_by_id, self.effective_ids_by_user)
    self.assertEqual(
        {'FooPerm': {111},
         'BarPerm': {111, 222}},
        actual)

  @patch('google.appengine.api.app_identity.get_default_gcs_bucket_name')
  @patch('framework.gcs_helpers.SignUrl')
  def testGetThumbnailUrl(self, mock_SignUrl, mock_get_default_gcs_bucket_name):
    bucket_name = 'testbucket'
    expected_url = 'signed/url'

    mock_get_default_gcs_bucket_name.return_value = bucket_name
    mock_SignUrl.return_value = expected_url

    self.assertEqual(expected_url, project_helpers.GetThumbnailUrl('xyz'))
    mock_get_default_gcs_bucket_name.assert_called_once()
    mock_SignUrl.assert_called_once_with(bucket_name, 'xyz' + '-thumbnail')

  def testIsValidProjectName_BadChars(self):
    self.assertFalse(project_helpers.IsValidProjectName('spa ce'))
    self.assertFalse(project_helpers.IsValidProjectName('under_score'))
    self.assertFalse(project_helpers.IsValidProjectName('name.dot'))
    self.assertFalse(project_helpers.IsValidProjectName('pie#sign$'))
    self.assertFalse(project_helpers.IsValidProjectName('(who?)'))

  def testIsValidProjectName_BadHyphen(self):
    self.assertFalse(project_helpers.IsValidProjectName('name-'))
    self.assertFalse(project_helpers.IsValidProjectName('-name'))
    self.assertTrue(project_helpers.IsValidProjectName('project-name'))

  def testIsValidProjectName_MinimumLength(self):
    self.assertFalse(project_helpers.IsValidProjectName('x'))
    self.assertTrue(project_helpers.IsValidProjectName('xy'))

  def testIsValidProjectName_MaximumLength(self):
    self.assertFalse(
        project_helpers.IsValidProjectName(
            'x' * (project_constants.MAX_PROJECT_NAME_LENGTH + 1)))
    self.assertTrue(
        project_helpers.IsValidProjectName(
            'x' * (project_constants.MAX_PROJECT_NAME_LENGTH)))

  def testIsValidProjectName_InvalidName(self):
    self.assertFalse(project_helpers.IsValidProjectName(''))
    self.assertFalse(project_helpers.IsValidProjectName('000'))

  def testIsValidProjectName_ValidName(self):
    self.assertTrue(project_helpers.IsValidProjectName('098asd'))
    self.assertTrue(project_helpers.IsValidProjectName('one-two-three'))

  def testAllProjectMembers(self):
    p = project_pb2.Project()
    self.assertEqual(project_helpers.AllProjectMembers(p), [])

    p.owner_ids.extend([1, 2, 3])
    p.committer_ids.extend([4, 5, 6])
    p.contributor_ids.extend([7, 8, 9])
    self.assertEqual(
        project_helpers.AllProjectMembers(p), [1, 2, 3, 4, 5, 6, 7, 8, 9])
