from plone import api
from ploneintranet.userprofile.tests.base import BaseTestCase
from unittest import mock


class FakeUser:

    source = "source_users"


class TestAuth(BaseTestCase):
    def setUp(self):
        super().setUp()
        self.login_as_portal_owner()
        params = {
            "username": "franknfurter",
            "first_name": "Frank N",
            "last_name": "Furter",
            "email": "frankn@furter.com",
            "password": "secret",
            "confirm_password": "secret",
        }
        api.content.create(
            container=self.profiles,
            type="ploneintranet.userprofile.userprofile",
            id="franknfurter",
            **params,
        )

    def test_profile_is_membrane_type(self):
        self.assertIn(
            "ploneintranet.userprofile.userprofile",
            self.membrane_tool.listMembraneTypes(),
        )

    def test_user_login(self):
        params = {
            "username": "johndoe",
            "first_name": "John",
            "last_name": "Doe",
            "email": "johndoe@example.com",
            "password": "secret",
            "confirm_password": "secret",
        }
        profile = api.content.create(
            container=self.profiles,
            type="ploneintranet.userprofile.userprofile",
            id="johndoe",
            **params,
        )

        self.logout()
        self.login("johndoe")
        user = api.user.get_current()
        self.assertEqual(profile.username, user.getId())

        self.logout()
        with self.assertRaises(ValueError):
            self.login("janedoe")

    def test_mail_password_form(self):
        self.login("franknfurter")
        view = self.portal.restrictedTraverse(
            "{}/change-password".format("/".join(self.portal.getPhysicalPath()))
        )
        contents = view()
        self.assertIn("Change password", contents)

    def test_mail_password_form_disabled_globally(self):
        """
        If the respective registry entry is set to False, the form for changing
        the password is not enabled.
        """
        self.login_as_portal_owner()
        api.portal.set_registry_record(
            "ploneintranet.userprofile.enable_password_reset", False
        )
        self.logout()
        self.login("franknfurter")
        view = api.content.get_view(
            "change-password", self.portal, self.request.clone()
        )
        view()
        self.assertDictEqual(
            view.request.response.headers, {"location": "http://nohost/plone"}
        )

    def test_mail_password_form_disabled_per_user(self):
        """Users that have a source field that corresponds to an authentication plugin
        are not allowed to changed their password
        """
        self.login("franknfurter")

        fake_user = FakeUser()
        api.portal.set_registry_record(
            "ploneintranet.userprofile.primary_external_user_source", fake_user.source
        )

        view = api.content.get_view(
            "change-password", self.portal, self.request.clone()
        )
        with mock.patch(
            "ploneintranet.api.userprofile.get_current",
            return_value=fake_user,
        ):
            view()

        self.assertDictEqual(
            view.request.response.headers, {"location": "http://nohost/plone"}
        )
