from AccessControl import Unauthorized
from collective.workspace.interfaces import IHasWorkspace
from collective.workspace.interfaces import IWorkspace
from plone import api
from ploneintranet import api as pi_api
from ploneintranet.workspace.tests.base import BaseTestCase
from zope.component import getMultiAdapter


class TestRoster(BaseTestCase):
    """
    tests for the roster tab/view
    """

    def test_roster_access(self):
        """
        test who can access the roster tab
        and that members can see users who are part of the workspace
        """
        self.login_as_portal_owner()
        pi_api.userprofile.create(username="wsmember", email="member@test.com")
        pi_api.userprofile.create(username="wsmember2", email="member2@test.com")
        workspace_folder = api.content.create(
            self.workspace_container,
            "ploneintranet.workspace.workspacefolder",
            "example-workspace",
        )
        self.add_user_to_workspace("wsmember", workspace_folder)
        self.add_user_to_workspace("wsmember2", workspace_folder)

        self.login("wsmember")
        self.assertTrue(IHasWorkspace.providedBy(workspace_folder))
        html = workspace_folder.restrictedTraverse("@@team-roster")()

        self.assertIn("wsmember", html)
        self.assertIn("wsmember2", html)


class TestEditRoster(BaseTestCase):
    """
    tests of the roster edit view
    """

    def setUp(self):
        super().setUp()
        self.login_as_portal_owner()
        pi_api.userprofile.create(username="wsadmin", email="admin@test.com")
        pi_api.userprofile.create(username="wsmember", email="member@test.com")
        pi_api.userprofile.create(username="wsmember2", email="member@test.com")
        workspace_folder = api.content.create(
            self.workspace_container,
            "ploneintranet.workspace.workspacefolder",
            "example-workspace",
        )
        self.add_user_to_workspace("wsadmin", workspace_folder, {"Admins"})
        self.add_user_to_workspace("wsmember", workspace_folder)
        self.workspace = workspace_folder

    def test_index(self):
        view = getMultiAdapter(
            (self.workspace, self.request), name="sidebar.settings.members"
        )
        html = view.__call__()
        self.assertIn("member-list-items", html)

    def test_existing_users(self):
        users = self.workspace.existing_users()
        wsadmin = {
            "id": "wsadmin",
            "member": True,
            "admin": True,
            "title": "wsadmin",
            "description": "",
            "cls": "has-no-description",
        }

        wsadmin = {
            "id": "wsadmin",
            "member": True,
            "admin": True,
            "title": "wsadmin",
            "description": "",
            "cls": "user has-no-description has-label",
            "absolute_url": "http://nohost/plone/profiles/wsadmin",
            "portrait": "http://nohost/plone/@@avatars/wsadmin",
            "role": "Admin",
            "typ": "user",
        }

        users_by_id = {user["id"]: user for user in users}

        self.assertTrue("wsadmin" in users_by_id)
        self.assertTrue(
            set(wsadmin.items()).issubset(set(users_by_id["wsadmin"].items()))
        )

        wsmember = {
            "id": "wsmember",
            "member": True,
            "admin": False,
            "title": "wsmember",
            "description": "",
            "cls": "user has-no-description",
        }
        self.assertTrue("wsmember" in users_by_id)
        self.assertTrue(
            set(wsmember.items()).issubset(set(users_by_id["wsmember"].items()))
        )

        self.assertTrue("wsmember2" not in users_by_id)

    def test_update_users_remove_admin(self):
        """
        Remove admin role from workspace as manager
        """
        params = {"user_id": "wsadmin", "batch-function": "role"}
        request = self.layer["request"].clone()
        request.form.update(params)
        view = getMultiAdapter(
            (self.workspace, request), name="sidebar.settings.members"
        )

        view.execute_batch_function()
        members = IWorkspace(self.workspace).members
        self.assertIn("wsadmin", members)
        self.assertNotIn("Admins", IWorkspace(self.workspace).get("wsadmin").groups)

    def test_update_users_remove_member(self):
        self.login("wsadmin")
        params = {"user_id": ["wsmember"], "batch-function": "remove"}
        request = self.layer["request"].clone()
        request.form.update(params)
        view = getMultiAdapter(
            (self.workspace, request), name="sidebar.settings.members"
        )

        view.execute_batch_function()
        members = IWorkspace(self.workspace).members
        self.assertNotIn("wsmember", members)

    def test_cannot_remove_member_as_member(self):
        """
        only admins can remove members
        """
        self.workspace.join_policy = "team"

        self.login("wsmember")

        params = {"user_id": ["wsmember"], "batch-function": "remove"}
        request = self.layer["request"].clone()
        request.form.update(params)
        view = getMultiAdapter(
            (self.workspace, request), name="sidebar.settings.members"
        )
        self.assertRaises(Unauthorized, view.execute_batch_function)

    def test_update_users_add_member(self):
        params = {"user_id": ["wsmember2"], "batch-function": "add"}
        request = self.layer["request"].clone()
        request.form.update(params)
        view = getMultiAdapter(
            (self.workspace, request), name="sidebar.settings.members"
        )

        view.execute_batch_function()
        members = IWorkspace(self.workspace).members
        self.assertIn("wsmember2", members)

    def test_can_add_users_member(self):
        """
        admins can add users, and members can add users in
        self/team managed workspaces
        """
        self.workspace.join_policy = "team"

        self.login("wsmember")
        view = api.content.get_view(
            context=self.workspace, request=self.request, name="view"
        )
        self.assertTrue(view.can_add_users())
