"""Setup/installation tests for this package."""

from plone import api
from ploneintranet import api as pi_api
from ploneintranet.userprofile.exc import CannotDeleteGroup
from ploneintranet.userprofile.tests.base import BaseTestCase
from ploneintranet.workspace.config import INTRANET_USERS_GROUP_ID
from Products.CMFPlone.utils import get_installer
from Products.PluggableAuthService.interfaces.plugins import IGroupsPlugin

PROJECTNAME = "ploneintranet.userprofile"


class TestInstall(BaseTestCase):
    """Test installation of ploneintranet.userprofile into Plone."""

    def setUp(self):
        """Custom shared utility setup for tests."""
        self.portal = self.layer["portal"]
        self.installer = get_installer(self.portal, self.layer["request"])

    def test_product_installed(self):
        """Test if ploneintranet.userprofile is installed with portal_quickinstaller."""
        self.assertTrue(self.installer.is_product_installed(PROJECTNAME))

    def test_types_installed(self):
        portal_types = api.portal.get_tool("portal_types")
        fti = portal_types.get("ploneintranet.userprofile.userprofile", None)
        self.assertEqual(fti.id, "ploneintranet.userprofile.userprofile")
        fti = portal_types.get("ploneintranet.userprofile.userprofilecontainer", None)
        self.assertEqual(fti.id, "ploneintranet.userprofile.userprofilecontainer")

    def test_allowed_types_installed(self):
        portal_types = api.portal.get_tool("portal_types")
        fti = portal_types.get("Plone Site", None)
        self.assertIn(
            "ploneintranet.userprofile.userprofilecontainer", fti.allowed_content_types
        )

    def test_userprofile_container_installed(self):
        self.assertIn("profiles", self.portal)
        self.assertEqual(
            "ploneintranet.userprofile.userprofilecontainer",
            self.portal.profiles.portal_type,
        )

    def test_workgroup_container_installed(self):
        self.assertIn("groups", self.portal)
        self.assertEqual(
            "ploneintranet.userprofile.workgroupcontainer",
            self.portal.groups.portal_type,
        )
        pt = api.portal.get_tool("portal_types")
        typ = pt["ploneintranet.userprofile.workgroupcontainer"]
        self.assertIn("ploneintranet.userprofile.workgroup", typ.allowed_content_types)

    def test_intranet_workgroup_installed(self):
        self.assertIn("groups", self.portal)
        self.assertIn("intranet", self.portal.groups)
        self.assertEqual(
            "ploneintranet.userprofile.workgroup",
            self.portal.groups.intranet.portal_type,
        )

    def test_intranet_workgroup_never_deleted(self):
        with self.assertRaises(CannotDeleteGroup):
            api.content.delete(self.portal.groups.intranet)

    def test_intranet_workgroup_never_renamed(self):
        with self.assertRaises(CannotDeleteGroup):
            api.content.rename(self.portal.groups.intranet, "foobar")

    def test_intranet_workgroup_has_role_member(self):
        self.assertIn("Member", api.group.get_roles(groupname=INTRANET_USERS_GROUP_ID))

    def test_group_plugins(self):
        au = api.portal.get_tool("acl_users")
        self.assertIn("pi_recursive_groups", au)
        self.assertTupleEqual(
            au.plugins.listPluginIds(IGroupsPlugin),
            ("source_groups", "auto_group", "pi_recursive_groups"),
        )

    def test_membrane_catalog(self):
        obj = pi_api.userprofile.create("johndoe", email="johndoe@exaple.com")
        mt = api.portal.get_tool("membrane_tool")
        self.assertEqual(
            [brain.getObject() for brain in mt(email="johndoe@exaple.com")], [obj]
        )

    def test_installed_behaviors(self):
        portal_types = api.portal.get_tool("portal_types")
        behavior_name = "plone.textindexer"

        for fti_id in (
            "ploneintranet.userprofile.userprofile",
            "ploneintranet.userprofile.workgroup",
        ):
            fti = portal_types.get(fti_id, None)
            self.assertIn(behavior_name, fti.behaviors, fti_id)


class TestUninstall(BaseTestCase):
    """Test that ploneintranet.userprofile is properly uninstalled."""

    def setUp(self):
        """Custom shared utility setup for tests."""
        self.portal = self.layer["portal"]
        self.installer = get_installer(self.portal, self.layer["request"])
        self.installer.uninstall_product("ploneintranet.userprofile")

    def test_uninstall(self):
        """Test if ploneintranet.userprofile is cleanly uninstalled."""
        self.assertFalse(self.installer.is_product_installed(PROJECTNAME))

    def test_types_removed(self):
        portal_types = api.portal.get_tool("portal_types")
        fti = portal_types.get("ploneintranet.userprofile.userprofile", None)
        self.assertIsNone(fti)
        fti = portal_types.get("ploneintranet.userprofile.userprofilecontainer", None)
        self.assertIsNone(fti)

    def test_allowed_types_removed(self):
        portal_types = api.portal.get_tool("portal_types")
        fti = portal_types.get("Plone Site", None)
        self.assertNotIn(
            "ploneintranet.userprofile.userprofilecontainer", fti.allowed_content_types
        )

    def test_userprofile_container_not_removed(self):
        self.assertIn("profiles", self.portal)
        self.assertEqual(
            "ploneintranet.userprofile.userprofilecontainer",
            self.portal.profiles.portal_type,
        )

    def test_group_plugins(self):
        au = api.portal.get_tool("acl_users")
        self.assertNotIn("pi_recursive_groups", au)
        self.assertTupleEqual(
            au.plugins.listPluginIds(IGroupsPlugin),
            ("source_groups", "auto_group", "membrane_groups", "recursive_groups"),
        )
