from plone import api
from ploneintranet.search.solr.interfaces import IMaintenance
from ploneintranet.suite.testing import PLONEINTRANET_SUITE_INTEGRATION
from ploneintranet.suite.testing import PLONEINTRANET_SUITE_SOLR_INTEGRATION
from Products.CMFCore.indexing import processQueue
from zope.component import getUtility

import unittest


class TestTestFixture(unittest.TestCase):
    """
    Exercise the testing setup only.
    Handy if you're debugging the setup:
    bin/test -s ploneintranet.suite -t integration -D
    """

    layer = PLONEINTRANET_SUITE_INTEGRATION

    def test_integration(self):
        self.assertTrue(True)


class TestUserProfileSecurity(unittest.TestCase):
    """
    This test expands on userprofile and search/solr
    It needs complex test fixures which are not available in userprofile.
    Instead we use the existing suite test fixture.
    """

    layer = PLONEINTRANET_SUITE_SOLR_INTEGRATION

    def _make_utility(self, *args, **kw):
        from ploneintranet.search.solr.solr_search import SiteSearch

        return SiteSearch()

    def _query(self, util, *args, **kw):
        response = util.query(*args, **kw)
        return response

    def solr_commit(self):
        """On integration tests we need to commit on solr before searching"""
        processQueue()
        getUtility(IMaintenance).connection.commit()

    def setUp(self):
        portal = self.layer["portal"]
        self.profile1 = portal.profiles.robinson_crusoe
        self.profile2 = portal.profiles.ulysses_grant
        # set an email address that is distinct from the name
        self.profile1.email = "wrtlprmft@example.com"
        self.profile1.reindexObject()
        self.profile2.email = "dubliner@example.com"
        self.profile2.reindexObject()
        self.solr_commit()

    def test_profile_email_indexed(self):
        util = self._make_utility()
        # Search for Robinson by email address
        response = self._query(util, "wrtlprmft")
        self.assertEqual(response.total_results, 1)
        self.assertEqual(response.results[0]["email"], "wrtlprmft@example.com")
        self.profile1.hide_email = True
        self.profile1.reindexObject()
        self.solr_commit()
        # Searching by email address (SearchableText!) no longer yields a result
        response = self._query(util, "wrtlprmft")
        self.assertEqual(response.total_results, 0)
        # We can still find Robinson via name search, but we don't see his email
        response = self._query(util, "crusoe")
        self.assertEqual(response.total_results, 1)
        self.assertEqual(response.results[0]["email"], "")
        # We can still find other users via email search
        response = self._query(util, "dubliner")
        self.assertEqual(response.total_results, 1)
        self.assertEqual(response.results[0]["email"], "dubliner@example.com")
        # Set global default to "hide email"
        api.portal.set_registry_record(
            "ploneintranet.userprofile.hide_email_by_default", True
        )
        self.profile1.reindexObject()
        self.profile2.reindexObject()
        self.solr_commit()
        # Now Ulysses, the profile without individual preference, hides his email too
        response = self._query(util, "dubliner")
        self.assertEqual(response.total_results, 0)
        response = self._query(util, "ulysses")
        self.assertEqual(response.total_results, 1)
        self.assertEqual(response.results[0]["email"], "")
        # Robinson still cannot be found via email search
        response = self._query(util, "wrtlprmft")
        self.assertEqual(response.total_results, 0)
        # Robinson decides to show his email address again.
        self.profile1.hide_email = False
        self.profile1.reindexObject()
        self.solr_commit()
        # Searching by email yields a result again, and the email facet again
        # contains the actual email
        response = self._query(util, "wrtlprmft")
        self.assertEqual(response.total_results, 1)
        self.assertEqual(response.results[0]["email"], "wrtlprmft@example.com")

    def test_profile_email_default_hide(self):
        # If the default is set to "hide", we won't find users' email data
        # as long as they do not actively enable showing it
        api.portal.set_registry_record(
            "ploneintranet.userprofile.hide_email_by_default", True
        )
        self.profile1.reindexObject()
        self.profile2.reindexObject()
        self.solr_commit()
        util = self._make_utility()
        # Search for Robinson by email address - no result
        response = self._query(util, "wrtlprmft")
        self.assertEqual(response.total_results, 0)
        response = self._query(util, "crusoe")
        self.assertEqual(response.total_results, 1)
        self.assertEqual(response.results[0]["email"], "")
        # Search for Ulysses by email - no result
        response = self._query(util, "dubliner")
        self.assertEqual(response.total_results, 0)
        response = self._query(util, "ulysses")
        self.assertEqual(response.total_results, 1)
        self.assertEqual(response.results[0]["email"], "")

        # Robinson decides to show his - now we find him
        self.profile1.hide_email = False
        self.profile1.reindexObject()
        self.solr_commit()
        response = self._query(util, "wrtlprmft")
        self.assertEqual(response.total_results, 1)
        self.assertEqual(response.results[0]["email"], "wrtlprmft@example.com")

        # Switch site default to not hide
        api.portal.set_registry_record(
            "ploneintranet.userprofile.hide_email_by_default", False
        )
        self.profile2.reindexObject()
        self.solr_commit()
        # Ulysses can now be found via email
        response = self._query(util, "dubliner")
        self.assertEqual(response.total_results, 1)
        self.assertEqual(response.results[0]["email"], "dubliner@example.com")
