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

import unittest

from features import hotlist_views
from framework import authdata
from framework import framework_views
from framework import permissions
from services import service_manager
from testing import fake
from mrproto import user_pb2


class MemberViewTest(unittest.TestCase):

  def setUp(self):
    self.hotlist = fake.Hotlist('hotlistName', 123,
                                hotlist_item_fields=[
                                    (2, 0, None, None, ''),
                                    (1, 0, None, None, ''),
                                    (5, 0, None, None, '')],
                                is_private=False, owner_ids=[111])
    self.user1 = user_pb2.User(user_id=111)
    self.user1_view = framework_views.UserView(self.user1)

  def testMemberViewCorrect(self):
    member_view = hotlist_views.MemberView(111, 111, self.user1_view,
                                           self.hotlist)
    self.assertEqual(member_view.user, self.user1_view)
    self.assertEqual(member_view.detail_url, '/u/111/')
    self.assertEqual(member_view.role, 'Owner')
    self.assertTrue(member_view.viewing_self)


class HotlistViewTest(unittest.TestCase):

  def setUp(self):
    self.services = service_manager.Services(user=fake.UserService(),
    usergroup=fake.UserGroupService())
    self.user1 = self.services.user.TestAddUser('user1', 111)
    self.user1.obscure_email = True
    self.user1_view = framework_views.UserView(self.user1)
    self.user2 = self.services.user.TestAddUser('user2', 222)
    self.user2.obscure_email = False
    self.user2_view = framework_views.UserView(self.user2)
    self.user3 = self.services.user.TestAddUser('user3', 333)
    self.user3_view = framework_views.UserView(self.user3)
    self.user4 = self.services.user.TestAddUser('user4', 444, banned=True)
    self.user4_view = framework_views.UserView(self.user4)

    self.user_auth = authdata.AuthData.FromEmail(
        None, 'user3', self.services)
    self.user_auth.effective_ids = {3}
    self.user_auth.user_id = 3
    self.users_by_id = {1: self.user1_view, 2: self.user2_view,
        3: self.user3_view, 4: self.user4_view}
    self.perms = permissions.EMPTY_PERMISSIONSET

  def testNoOwner(self):
    hotlist = fake.Hotlist('unowned', 500, owner_ids=[])
    view = hotlist_views.HotlistView(hotlist, self.perms,
                                     self.user_auth, 1, self.users_by_id)
    self.assertFalse(view.url)

  def testBanned(self):
    # With a banned user
    hotlist = fake.Hotlist('userBanned', 423, owner_ids=[4])
    hotlist_view = hotlist_views.HotlistView(
        hotlist, self.perms, self.user_auth, 1, self.users_by_id)
    self.assertFalse(hotlist_view.visible)

    # With a user not banned
    hotlist = fake.Hotlist('userNotBanned', 453, owner_ids=[1])
    hotlist_view = hotlist_views.HotlistView(
        hotlist, self.perms, self.user_auth, 1, self.users_by_id)
    self.assertTrue(hotlist_view.visible)

  def testNoPermissions(self):
    hotlist = fake.Hotlist(
        'private', 333, is_private=True, owner_ids=[1], editor_ids=[2])
    hotlist_view = hotlist_views.HotlistView(
        hotlist, self.perms, self.user_auth, 1, self.users_by_id)
    self.assertFalse(hotlist_view.visible)
    self.assertEqual(hotlist_view.url, '/u/1/hotlists/private')

  def testFriendlyURL(self):
    # owner with obscure_email:false
    hotlist = fake.Hotlist(
        'noObscureHotlist', 133, owner_ids=[2], editor_ids=[3])
    hotlist_view = hotlist_views.HotlistView(
        hotlist, self.perms, self.user_auth,
        viewed_user_id=3, users_by_id=self.users_by_id)
    self.assertEqual(hotlist_view.url, '/u/user2/hotlists/noObscureHotlist')

    #owner with obscure_email:true
    hotlist = fake.Hotlist('ObscureHotlist', 133, owner_ids=[1], editor_ids=[3])
    hotlist_view = hotlist_views.HotlistView(
        hotlist, self.perms, self.user_auth, viewed_user_id=1,
        users_by_id=self.users_by_id)
    self.assertEqual(hotlist_view.url, '/u/1/hotlists/ObscureHotlist')

  def testOtherAttributes(self):
    hotlist = fake.Hotlist(
        'hotlistName', 123, hotlist_item_fields=[(2, 0, None, None, ''),
                                                (1, 0, None, None, ''),
                                                 (5, 0, None, None, '')],
                                is_private=False, owner_ids=[1],
                                editor_ids=[2, 3])
    hotlist_view = hotlist_views.HotlistView(
        hotlist, self.perms, self.user_auth, viewed_user_id=2,
        users_by_id=self.users_by_id, is_starred=True)
    self.assertTrue(hotlist_view.visible, True)
    self.assertEqual(hotlist_view.role_name, 'editor')
    self.assertEqual(hotlist_view.owners, [self.user1_view])
    self.assertEqual(hotlist_view.editors, [self.user2_view, self.user3_view])
    self.assertEqual(hotlist_view.num_issues, 3)
    self.assertTrue(hotlist_view.is_starred)
