from plone import api
from plone.app.testing import login
from plone.app.testing import logout
from plone.app.testing.interfaces import SITE_OWNER_NAME
from plone.testing import zope as zope_testing
from ploneintranet.todo.testing import IntegrationTestCase

MODIFY = "Modify portal content"


class TodoWorkflowBaseTestCase(IntegrationTestCase):
    def setUp(self):
        IntegrationTestCase.setUp(self)
        self.app = self.layer["app"]
        self.portal = self.layer["portal"]
        self.folder = api.content.create(self.portal, "Folder", "todofolder")
        # Revoke modify permission from Editor to check that it's granted
        # separately. This simulates that in a workspace an Editor does not
        # have modify permission.
        self.folder.manage_permission(
            "Modify portal content", roles=["Manager", "Owner", "Site Administrator"]
        )
        self.login_as_portal_owner()
        # Simulates a workspace member in the Admins group.
        api.user.create(
            username="wsadmin",
            email="admin@test.com",
            roles=["Contributor", "Editor", "Reviewer", "Reader", "TeamManager"],
        )
        # Simulates a workspace member in the Moderators group.
        api.user.create(
            username="wsmember",
            email="member@test.com",
            roles=["Contributor", "Editor", "Reviewer", "Reader"],
        )
        api.user.create(username="nonmember", email="user@test.com")
        self.todo = api.content.create(self.folder, "todo", "todo1")
        login(self.portal, "wsmember")
        # wsmember is owner of todo2
        self.todo2 = api.content.create(self.folder, "todo", "todo2")
        self.login_as_portal_owner()

    def login_as_portal_owner(self):
        """
        helper method to login as site admin
        """
        zope_testing.login(self.app["acl_users"], SITE_OWNER_NAME)

    def admin_permissions(self, permission):
        permissions = api.user.get_permissions(username="wsadmin", obj=self.todo)
        return permissions[permission]

    def member_permissions(self, permission):
        permissions = api.user.get_permissions(username="wsmember", obj=self.todo)
        return permissions[permission]

    def owner_permissions(self, permission):
        permissions = api.user.get_permissions(username="wsmember", obj=self.todo2)
        return permissions[permission]

    def nonmember_permissions(self, permission):
        permissions = api.user.get_permissions(username="nonmember", obj=self.todo)
        return permissions[permission]

    def anon_permissions(self, permission):
        logout()
        permissions = api.user.get_permissions(obj=self.todo)
        return permissions[permission]


class TestTodoWorkflow(TodoWorkflowBaseTestCase):
    def test_planned_state(self):
        """
        In planned state, todo can be modified by
        teammanager, teammember and owner.
        """
        api.content.transition(self.todo, "set_to_planned")
        api.content.transition(self.todo2, "set_to_planned")

        self.assertTrue(self.admin_permissions(MODIFY))
        self.assertTrue(self.member_permissions(MODIFY))
        self.assertTrue(self.owner_permissions(MODIFY))
        self.assertFalse(self.nonmember_permissions(MODIFY))
        self.assertFalse(self.anon_permissions(MODIFY))

    def test_open_state(self):
        """
        In open state, todo can be modified by
        teammanager, teammember and owner.
        """
        self.assertTrue(self.admin_permissions(MODIFY))
        self.assertTrue(self.member_permissions(MODIFY))
        self.assertTrue(self.owner_permissions(MODIFY))
        self.assertFalse(self.nonmember_permissions(MODIFY))
        self.assertFalse(self.anon_permissions(MODIFY))

    def test_done_state(self):
        """
        In done state, todo can be modified by
        teammanager, teammember and owner.
        """
        api.content.transition(self.todo, "finish")
        api.content.transition(self.todo2, "finish")

        self.assertTrue(self.admin_permissions(MODIFY))
        self.assertTrue(self.member_permissions(MODIFY))
        self.assertTrue(self.owner_permissions(MODIFY))
        self.assertFalse(self.nonmember_permissions(MODIFY))
        self.assertFalse(self.anon_permissions(MODIFY))
