# Copyright 2016 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 or at
# https://developers.google.com/open-source/licenses/bsd

"""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 proto 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])
