from plone import api
from plone.browserlayer.utils import registered_layers
from ploneintranet.microblog.testing import PLONEINTRANET_MICROBLOG_INTEGRATION_TESTING
from Products.CMFPlone.utils import get_installer

import unittest

PROJECTNAME = "ploneintranet.microblog"

PERMISSIONS_GRANTED_TO_ALL_MEMBERS = (
    "Plone Social: Modify Own Microblog Status Update",
    "Plone Social: Delete Own Microblog Status Update",
)
PERMISSIONS_GRANTED_TO_INTRANET_MEMBERS = (
    "Plone Social: Add Microblog Status Update",
    "Plone Social: View Microblog Status Update",
)
PERMISSIONS_REQUIRING_MANAGER_ROLE = (
    "Plone Social: Modify Microblog Status Update",
    "Plone Social: Delete Microblog Status Update",
)


class TestInstall(unittest.TestCase):

    layer = PLONEINTRANET_MICROBLOG_INTEGRATION_TESTING

    def setUp(self):
        self.portal = self.layer["portal"]

    def test_product_is_installed(self):
        self.installer = get_installer(self.portal, self.layer["request"])
        self.assertTrue(self.installer.is_product_installed(PROJECTNAME))

    def test_addon_layer(self):
        layers = [layer.getName() for layer in registered_layers()]
        self.assertIn("IPloneIntranetMicroblogLayer", layers)

    def test_permissions_all_members(self):
        expected = {"Authenticated", "Manager", "Site Administrator"}
        for permission in PERMISSIONS_GRANTED_TO_ALL_MEMBERS:
            roles = self.portal.rolesOfPermission(permission)
            roles = {r["name"] for r in roles if r["selected"]}
            self.assertEqual(roles, expected)

    def test_permissions_intranet_members(self):
        expected = {"Manager", "Site Administrator", "Member"}
        for permission in PERMISSIONS_GRANTED_TO_INTRANET_MEMBERS:
            roles = self.portal.rolesOfPermission(permission)
            roles = {r["name"] for r in roles if r["selected"]}
            self.assertEqual(roles, expected)

    def test_permissions_manager(self):
        expected = {"Manager", "Site Administrator"}
        for permission in PERMISSIONS_REQUIRING_MANAGER_ROLE:
            roles = self.portal.rolesOfPermission(permission)
            roles = {r["name"] for r in roles if r["selected"]}
            self.assertEqual(roles, expected)

    def test_add_folder(self):
        testfolder = api.content.create(
            type="Folder", title="testfolder", container=self.portal
        )
        self.assertIn(testfolder.id, self.portal.objectIds())

    def test_tool_added(self):
        self.assertIn("ploneintranet_microblog", self.portal)


class TestUninstall(unittest.TestCase):

    layer = PLONEINTRANET_MICROBLOG_INTEGRATION_TESTING

    def setUp(self):
        self.portal = self.layer["portal"]
        self.installer = get_installer(self.portal, self.layer["request"])
        with api.env.adopt_roles(["Manager"]):
            self.installer.uninstall_product(PROJECTNAME)

    def test_uninstalled(self):
        self.assertFalse(self.installer.is_product_installed(PROJECTNAME))

    def test_addon_layer_removed(self):
        layers = [layer.getName() for layer in registered_layers()]
        self.assertNotIn("IPloneIntranetMicroblogLayer", layers)

    def test_tool_removed(self):
        self.assertNotIn("ploneintranet_microblog", self.portal)
