# -*- coding: utf-8 -*-
from plone.app.testing import SITE_OWNER_NAME, SITE_OWNER_PASSWORD
from Products.CMFCore.utils import getToolByName
from plone.testing.z2 import Browser
from Products.CMFPlone.utils import normalizeString

from Products.CMFPlone.testing import \
    PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING

import unittest2 as unittest
import transaction


class UserGroupsControlPanelFunctionalTest(unittest.TestCase):
    """Test that changes in the user groups control panel are actually
    creating and changing users and groups.
    """

    layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING

    def _generateGroups(self):
        groupsTool = getToolByName(self.portal, 'portal_groups')
        self.groups = [
            {'id': 'group1', 'title': "Group 1"},
            {'id': 'group2', 'title': "Group 2"},
            {'id': 'group3', 'title': "Group 3 accentué"}
        ]
        for group in self.groups:
            groupsTool.addGroup(group['id'], [], [], title=group['title'])

    def _generateUsers(self):
        self.members = [
            {'username': 'DIispfuF', 'fullname': 'Kevin Hughes', 'email': 'DIispfuF@example.com'},
            {'username': 'enTHXigm', 'fullname': 'Richard Ramirez', 'email': 'enTHXigm@example.com'},
            {'username': 'q7UsYcrT', 'fullname': 'Kyle Brown', 'email': 'q7UsYcrT@example.com'},
            {'username': 'j5g0xPmr', 'fullname': 'Julian Green', 'email': 'j5g0xPmr@example.com'},
            {'username': 'o6Sx4It3', 'fullname': 'Makayla Coleman', 'email': 'o6Sx4It3@example.com'},
            {'username': 'SLUhquYa', 'fullname': 'Sean Foster', 'email': 'SLUhquYa@example.com'},
            {'username': 'nHWl3Ita', 'fullname': 'Molly Martin', 'email': 'nHWl3Ita@example.com'},
            {'username': 'xdkpCKmX', 'fullname': 'Jordan Thompson', 'email': 'xdkpCKmX@example.com'},
            {'username': 'p8H6CicB', 'fullname': 'Tyler Rivera', 'email': 'p8H6CicB@example.com'},
            {'username': 'T6vdBXbD', 'fullname': 'Megan Murphy', 'email': 'T6vdBXbD@example.com'},
            {'username': 'DohPmgIa', 'fullname': 'Gracie Diaz', 'email': 'DohPmgIa@example.com'},
            {'username': 'CqHWi65B', 'fullname': 'Rachel Morgan', 'email': 'CqHWi65B@example.com'},
            {'username': 'uHFQ7qk4', 'fullname': 'Maya Price', 'email': 'uHFQ7qk4@example.com'},
            {'username': 'BlXLQh7r', 'fullname': 'Blake Jenkins', 'email': 'BlXLQh7r@example.com'},
            {'username': 'FCrWUiSY', 'fullname': 'Owen Ramirez', 'email': 'FCrWUiSY@example.com'},
            {'username': 'bX3PqgHK', 'fullname': 'Owen Cook', 'email': 'bX3PqgHK@example.com'},
            {'username': 'sD35vVl0', 'fullname': 'Jayden Hill', 'email': 'sD35vVl0@example.com'},
            {'username': 'mfOcjXAG', 'fullname': 'Joseph Ramirez', 'email': 'mfOcjXAG@example.com'},
            {'username': 'GAJtdYbM', 'fullname': 'Nathan Young', 'email': 'GAJtdYbM@example.com'},
            {'username': 'E1OWG6bv', 'fullname': 'Kaitlyn Hernandez', 'email': 'E1OWG6bv@example.com'},
            {'username': 'BqOX2sCm', 'fullname': 'Faith Price', 'email': 'BqOX2sCm@example.com'},
            {'username': 'tyOxRnml', 'fullname': 'Sofia Williams', 'email': '5yOxRjtl@example.com'},
            {'username': 'fVcumDNl', 'fullname': 'David Sanders', 'email': 'fVcumDNl@example.com'},
            {'username': 'Ge1hqdEI', 'fullname': 'Jack Simmons', 'email': 'Ge1hqdEI@example.com'},
            {'username': 'o2CqT7kG', 'fullname': 'Cole Howard', 'email': 'o2CqT7kG@example.com'},
            {'username': 'mpGtfNl6', 'fullname': 'Rachel Miller', 'email': 'mpGtfNl6@example.com'},
            {'username': 'RGrpWiBg', 'fullname': 'Henry Patterson', 'email': 'RGrpWiBg@example.com'},
            {'username': 'Bufmi0YS', 'fullname': 'Avery Cooper', 'email': 'Bufmi0YS@example.com'},
            {'username': 'J7NvbjYd', 'fullname': 'Sydney Bennett', 'email': 'J7NvbjYd@example.com'},
            {'username': 'u5Xem8U1', 'fullname': 'Daniel Johnson', 'email': 'u5Xem8U1@example.com'},
            {'username': 'TWrMCLIo', 'fullname': 'Autumn Brooks', 'email': '0VrMCLIo@example.com'},
            {'username': 'FElYwiIr', 'fullname': 'Alexandra Nelson', 'email': 'FElYwiIr@example.com'},
            {'username': 'teK6pkhc', 'fullname': 'Brian Simmons', 'email': '0eK6pkhc@example.com'},
            {'username': 'RwAO2YPa', 'fullname': 'Kevin Hughes', 'email': 'gracie@example.com'},
            {'username': 'nlBMw26i', 'fullname': 'Sydney Evans', 'email': 'nlBMw26i@example.com'},
            {'username': 'Ahr3EiRC', 'fullname': 'Emma Brown', 'email': 'Ahr3EiRC@example.com'},
            {'username': 'NhuU0Y5x', 'fullname': 'Lauren Martin', 'email': 'NhuU0Y5x@example.com'},
            {'username': 'j2R3mKQg', 'fullname': 'Isabelle Russell', 'email': 'j2R3mKQg@example.com'},
            {'username': 'qOmK0iCN', 'fullname': 'Anna Baker', 'email': 'qOmK0iCN@example.com'},
            {'username': 'uQbVOgo7', 'fullname': 'Brady Watson', 'email': 'uQbVOgo7@example.com'},
            {'username': 'oLDCaQfW', 'fullname': 'Kaitlyn Robinson', 'email': 'oLDCaQfW@example.com'},
            {'username': 'osYHeFD1', 'fullname': 'Riley Richardson', 'email': 'osYHeFD1@example.com'},
            {'username': 'i4pHduDY', 'fullname': 'Kayla Sanders', 'email': 'i4pHduDY@example.com'},
            {'username': 'BvyX6qF3', 'fullname': 'Sara Richardson', 'email': 'BvyX6qF3@example.com'},
            {'username': 'a3EpwDYj', 'fullname': 'Trinity Gonzales', 'email': 'a3EpwDYj@example.com'},
            {'username': 'JDMseWdt', 'fullname': 'Madeline Garcia', 'email': 'JDMseWdt@example.com'},
            {'username': 'lPCYBvoi', 'fullname': 'Brian Gray', 'email': 'lPCYBvoi@example.com'},
            {'username': 'AByCsRQ3', 'fullname': 'Victoria Perez', 'email': 'AByCsRQ3@example.com'},
            {'username': 'CH7uVlNy', 'fullname': 'Charles Rodriguez', 'email': '5H7uVlNy@example.com'},
            {'username': 'XYsmd7ux', 'fullname': 'Abigail Simmons', 'email': 'XYsmd7ux@example.com'},
            {'username': 'DfaA1wqC3', 'fullname': 'Émilie Richard', 'email': 'DfaA1wqC3@example.com'},
        ]
        rtool = getToolByName(self.portal, 'portal_registration')
        for member in self.members:
            rtool.addMember(member['username'], 'somepassword', properties=member)

    def setUp(self):
        self.app = self.layer['app']
        self.portal = self.layer['portal']
        self.portal_url = self.portal.absolute_url()
        self.usergroups_url = "%s/@@usergroup-userprefs" % self.portal_url
        self.groups_url = "%s/@@usergroup-groupprefs" % self.portal_url
        self._generateGroups()
        self._generateUsers()
        transaction.commit()

        self.browser = Browser(self.app)
        self.browser.handleErrors = False
        self.browser.addHeader(
            'Authorization',
            'Basic %s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD,)
        )

    def test_usergroups_control_panel_link(self):
        self.browser.open(
            "%s/@@overview-controlpanel" % self.portal_url)
        self.browser.getLink('Users and Groups').click()
        self.assertEqual(
            self.browser.url,
            self.usergroups_url
        )

    def test_usergroups_groups_link(self):
        self.browser.open(self.usergroups_url)
        self.browser.getLink('Groups', index=0).click()
        self.assertEqual(
            self.browser.url,
            "%s/@@usergroup-groupprefs" % self.portal_url
        )

    def test_usergroups_settings_link(self):
        self.browser.open(self.usergroups_url)
        self.browser.getLink('Settings').click()
        self.assertEqual(
            self.browser.url,
            "%s/@@usergroup-controlpanel" % self.portal_url
        )

    def test_usergroups_memberfields_link(self):
        self.browser.open(self.usergroups_url)
        self.browser.getLink('Member fields').click()
        self.assertEqual(
            self.browser.url,
            "%s/@@member-fields" % self.portal_url
        )

    def test_user_search_by_name(self):
        self.browser.open(self.usergroups_url)
        self.browser.getControl(name='searchstring').value = 'Richard'
        self.browser.getControl(name='form.button.Search').click()
        self.assertIn('Richard Ramirez', self.browser.contents)
        self.assertIn('Sara Richardson', self.browser.contents)
        self.assertIn('Émilie Richard', self.browser.contents)

    def test_user_search_by_name_accent(self):
        self.browser.open(self.usergroups_url)
        self.browser.getControl(name='searchstring').value = 'Émilie'
        self.browser.getControl(name='form.button.Search').click()
        self.assertIn('Émilie Richard', self.browser.contents)

    def test_user_search_by_id(self):
        self.browser.open(self.usergroups_url)
        self.browser.getControl(name='searchstring').value = 'TWrMCLIo'
        self.browser.getControl(name='form.button.Search').click()
        self.assertIn('Autumn Brooks', self.browser.contents)

    def test_user_search_by_mail(self):
        self.browser.open(self.usergroups_url)
        self.browser.getControl(name='searchstring').value = 'DohPmgIa@'
        self.browser.getControl(name='form.button.Search').click()
        self.assertIn('Gracie Diaz', self.browser.contents)

    def test_user_show_all(self):
        self.browser.open(self.usergroups_url)
        self.browser.getControl(name='form.button.FindAll').click()

        # Check that first 10 members (sorted by fullname) are shown.
        for member in sorted(
            self.members, key=lambda k: normalizeString(k['fullname'])
        )[:10]:
            self.assertIn(member['fullname'], self.browser.contents)

    def test_user_show_all_with_search_term(self):
        self.browser.open(self.usergroups_url)
        self.browser.getControl(name='searchstring').value = 'no-user'
        self.browser.getControl(name='form.button.FindAll').click()

        # Check that all members is shown and search term is ignored
        self.assertIn('Avery Cooper', self.browser.contents)

    def test_user_add_new_link(self):
        self.browser.open(self.usergroups_url)
        self.browser.getLink(id='add-user').click()
        self.assertEqual(
            self.browser.url,
            "%s/@@new-user" % self.portal_url
        )

    def test_user_modify_roles(self):
        self.browser.open(self.usergroups_url)
        self.browser.getControl(name='searchstring').value = 'TWrMCLIo'
        self.browser.getControl(name='form.button.Search').click()

        # Check that contributor role is not enabled and enable it
        self.assertFalse(self.browser.getControl(
            name='users.roles:list:records'
        ).getControl(value='Contributor').selected)
        self.browser.getControl(
            name='users.roles:list:records'
        ).getControl(value='Contributor').selected = True
        self.browser.getControl(name='form.button.Modify').click()

        # Check that contributor role is now enabled for this user
        self.browser.open(self.usergroups_url)
        self.browser.getControl(name='searchstring').value = 'TWrMCLIo'
        self.browser.getControl(name='form.button.Search').click()
        self.assertTrue(self.browser.getControl(
            name='users.roles:list:records'
        ).getControl(value='Contributor').selected)

    def test_user_delete(self):
        self.browser.open(self.usergroups_url)
        self.browser.getControl(name='searchstring').value = 'TWrMCLIo'
        self.browser.getControl(name='form.button.Search').click()
        self.assertIn('Autumn Brooks', self.browser.contents)

        # Delete user
        self.browser.getControl(name='delete:list').getControl(
            value='TWrMCLIo').selected = True
        self.browser.getControl(name='form.button.Modify').click()

        # Check that user does not exist anymore
        self.browser.getControl(name='searchstring').value = 'TWrMCLIo'
        self.browser.getControl(name='form.button.Search').click()
        self.assertNotIn('Autumn Brooks', self.browser.contents)

    def test_groups_search_by_id(self):
        self.browser.open(self.groups_url)
        self.browser.getControl(name='searchstring').value = 'group1'
        self.browser.getControl(name='form.button.Search').click()
        self.assertIn('Group 1', self.browser.contents)

    def test_groups_search_by_name(self):
        self.browser.open(self.groups_url)
        self.browser.getControl(name='searchstring').value = 'Group 3 accentué'
        self.browser.getControl(name='form.button.Search').click()
        self.assertIn('Group 3 accentué', self.browser.contents)

    def test_groups_modify_roles(self):
        self.browser.open(self.groups_url)
        self.browser.getControl(name='searchstring').value = 'group1'

        # Check that role is not selected yet and then select it and apply it.
        self.assertFalse(self.browser.getControl(
            name='group_group1:list', index=1
        ).getControl(value='Contributor').selected)
        self.browser.getControl(
            name='group_group1:list', index=1
        ).getControl(value='Contributor').selected = True
        self.browser.getControl('Save').click()

        # Check that role is now selected
        self.browser.getControl(
            name='group_group1:list', index=1
        ).getControl(value='Contributor').selected

    def test_groups_delete_group(self):
        self.browser.open(self.groups_url)
        self.browser.getControl(name='searchstring').value = 'group1'

        # Delete a group
        self.browser.getControl(
            name='delete:list'
        ).getControl(value='group1').selected = True
        self.browser.getControl(name='form.button.Modify').click()

        # Check that group doesn't exist anymore
        self.browser.getControl(name='searchstring').value = 'group1'
        self.assertNotIn('Group 1', self.browser.contents)

    def test_groups_show_all(self):
        self.browser.open(self.groups_url)
        self.browser.getControl(name='form.button.FindAll').click()

        for group in self.groups:
            self.assertIn(group['title'], self.browser.contents)

    def test_group_add_users(self):
        self.browser.open(self.groups_url)
        self.browser.getLink('Group 1 (group1)').click()
        self.assertIn(
            'There is no group or user attached to this group.',
            self.browser.contents
        )

        # Add user (Autumn Brooks) to selected group (Group 1)
        self.browser.getControl(name='searchstring').value = 'TWrMCLIo'
        self.browser.getControl(name='form.button.Search').click()
        self.browser.getControl(name='add:list').getControl(
            value='TWrMCLIo').selected = True

        # Check that user is now part of the group
        self.browser.getControl(
            'Add selected groups and users to this group').click()
        self.assertIn('Autumn Brooks', self.browser.contents)

    def test_group_add_group(self):
        self.browser.open(self.groups_url)
        self.browser.getLink('Group 1 (group1)').click()
        self.assertIn(
            'There is no group or user attached to this group.',
            self.browser.contents
        )

        # Add group2 to selected  group 1
        self.browser.getControl(name='searchstring').value = 'group2'
        self.browser.getControl(name='form.button.Search').click()
        self.browser.getControl(name='add:list').getControl(
            value='group2').selected = True

        # Check that group is now part of the group
        self.browser.getControl(
            'Add selected groups and users to this group').click()
        self.assertIn('Group 2', self.browser.contents)

    def test_usergroups_settings_many_users(self):
        self.browser.open("%s/@@usergroup-controlpanel" % self.portal_url)
        self.browser.getControl(
            name='form.widgets.many_users:list'
        ).controls[0].selected = True
        self.browser.getControl('Save').click()

        # Check that show all button for users is no longer available
        self.browser.open(self.usergroups_url)
        self.assertNotIn('Show all', self.browser.contents)

        # Check that empty search does not trigger show all
        self.browser.open(self.usergroups_url)
        self.browser.getControl(name='searchstring').value = ''

    def test_usergroups_settings_many_groups(self):
        self.browser.open("%s/@@usergroup-controlpanel" % self.portal_url)
        self.browser.getControl(
            name='form.widgets.many_groups:list'
        ).controls[0].selected = True
        self.browser.getControl('Save').click()

        # Check that show all button for groups is no longer available
        self.browser.open(self.groups_url)
        self.assertNotIn('Show all', self.browser.contents)
        self.assertNotIn('DIispfuF', self.browser.contents)
