from unittest.mock import Mock, patch

from django.test import SimpleTestCase

from corehq.apps.domain.exceptions import DomainDoesNotExist
from corehq.apps.linked_domain.exceptions import (
    DomainLinkAlreadyExists,
    DomainLinkError,
    DomainLinkNotAllowed,
)
from corehq.apps.linked_domain.views import link_domains


class LinkDomainsTests(SimpleTestCase):

    @classmethod
    def setUpClass(cls):
        super(LinkDomainsTests, cls).setUpClass()
        cls.upstream_domain = 'upstream'
        cls.downstream_domain = 'downstream'

    def test_exception_raised_if_domain_does_not_exist(self):
        def mock_handler(domain):
            return domain != self.downstream_domain

        with patch('corehq.apps.linked_domain.views.domain_exists') as mock_domainexists,\
             self.assertRaises(DomainDoesNotExist):
            mock_domainexists.side_effect = mock_handler
            link_domains(Mock(), self.upstream_domain, self.downstream_domain)

    def test_exception_raised_if_domain_link_already_exists(self):
        with patch('corehq.apps.linked_domain.views.domain_exists', return_value=True),\
             patch('corehq.apps.linked_domain.views.get_active_domain_link', return_value=Mock()),\
             self.assertRaises(DomainLinkAlreadyExists):
            link_domains(Mock(), self.upstream_domain, self.downstream_domain)

    def test_exception_raised_if_domain_link_error_raised(self):
        def mock_handler(downstream, upstream):
            raise DomainLinkError

        with patch('corehq.apps.linked_domain.views.domain_exists', return_value=True),\
             patch('corehq.apps.linked_domain.views.get_active_domain_link', return_value=None),\
             patch('corehq.apps.linked_domain.views.DomainLink.link_domains') as mock_linkdomains,\
             self.assertRaises(DomainLinkError):
            mock_linkdomains.side_effect = mock_handler
            link_domains(Mock(), self.upstream_domain, self.downstream_domain)

    def test_exception_raised_if_user_is_not_admin_in_both_domains(self):
        with patch('corehq.apps.linked_domain.views.domain_exists', return_value=True),\
             patch('corehq.apps.linked_domain.views.get_active_domain_link', return_value=None),\
             patch('corehq.apps.linked_domain.views.user_has_admin_access_in_all_domains', return_value=False),\
             self.assertRaises(DomainLinkNotAllowed):
            link_domains(Mock(), self.upstream_domain, self.downstream_domain)

    def test_successful(self):
        with patch('corehq.apps.linked_domain.views.domain_exists', return_value=True),\
             patch('corehq.apps.linked_domain.views.get_active_domain_link', return_value=None),\
             patch('corehq.apps.linked_domain.views.DomainLink.link_domains', return_value=True),\
             patch('corehq.apps.linked_domain.views.user_has_admin_access_in_all_domains', return_value=True):
            domain_link = link_domains(Mock(), self.upstream_domain, self.downstream_domain)

        self.assertIsNotNone(domain_link)

[((710, 764), 'unittest.mock.patch', 'patch', (['"""corehq.apps.linked_domain.views.domain_exists"""'], {}), "('corehq.apps.linked_domain.views.domain_exists')\n", (715, 764), False, 'from unittest.mock import Mock, patch\n'), ((1057, 1130), 'unittest.mock.patch', 'patch', (['"""corehq.apps.linked_domain.views.domain_exists"""'], {'return_value': '(True)'}), "('corehq.apps.linked_domain.views.domain_exists', return_value=True)\n", (1062, 1130), False, 'from unittest.mock import Mock, patch\n'), ((1531, 1604), 'unittest.mock.patch', 'patch', (['"""corehq.apps.linked_domain.views.domain_exists"""'], {'return_value': '(True)'}), "('corehq.apps.linked_domain.views.domain_exists', return_value=True)\n", (1536, 1604), False, 'from unittest.mock import Mock, patch\n'), ((1620, 1706), 'unittest.mock.patch', 'patch', (['"""corehq.apps.linked_domain.views.get_active_domain_link"""'], {'return_value': 'None'}), "('corehq.apps.linked_domain.views.get_active_domain_link',\n    return_value=None)\n", (1625, 1706), False, 'from unittest.mock import Mock, patch\n'), ((1718, 1782), 'unittest.mock.patch', 'patch', (['"""corehq.apps.linked_domain.views.DomainLink.link_domains"""'], {}), "('corehq.apps.linked_domain.views.DomainLink.link_domains')\n", (1723, 1782), False, 'from unittest.mock import Mock, patch\n'), ((2077, 2150), 'unittest.mock.patch', 'patch', (['"""corehq.apps.linked_domain.views.domain_exists"""'], {'return_value': '(True)'}), "('corehq.apps.linked_domain.views.domain_exists', return_value=True)\n", (2082, 2150), False, 'from unittest.mock import Mock, patch\n'), ((2166, 2252), 'unittest.mock.patch', 'patch', (['"""corehq.apps.linked_domain.views.get_active_domain_link"""'], {'return_value': 'None'}), "('corehq.apps.linked_domain.views.get_active_domain_link',\n    return_value=None)\n", (2171, 2252), False, 'from unittest.mock import Mock, patch\n'), ((2264, 2365), 'unittest.mock.patch', 'patch', (['"""corehq.apps.linked_domain.views.user_has_admin_access_in_all_domains"""'], {'return_value': '(False)'}), "('corehq.apps.linked_domain.views.user_has_admin_access_in_all_domains',\n    return_value=False)\n", (2269, 2365), False, 'from unittest.mock import Mock, patch\n'), ((2542, 2615), 'unittest.mock.patch', 'patch', (['"""corehq.apps.linked_domain.views.domain_exists"""'], {'return_value': '(True)'}), "('corehq.apps.linked_domain.views.domain_exists', return_value=True)\n", (2547, 2615), False, 'from unittest.mock import Mock, patch\n'), ((2631, 2717), 'unittest.mock.patch', 'patch', (['"""corehq.apps.linked_domain.views.get_active_domain_link"""'], {'return_value': 'None'}), "('corehq.apps.linked_domain.views.get_active_domain_link',\n    return_value=None)\n", (2636, 2717), False, 'from unittest.mock import Mock, patch\n'), ((2729, 2816), 'unittest.mock.patch', 'patch', (['"""corehq.apps.linked_domain.views.DomainLink.link_domains"""'], {'return_value': '(True)'}), "('corehq.apps.linked_domain.views.DomainLink.link_domains',\n    return_value=True)\n", (2734, 2816), False, 'from unittest.mock import Mock, patch\n'), ((2828, 2928), 'unittest.mock.patch', 'patch', (['"""corehq.apps.linked_domain.views.user_has_admin_access_in_all_domains"""'], {'return_value': '(True)'}), "('corehq.apps.linked_domain.views.user_has_admin_access_in_all_domains',\n    return_value=True)\n", (2833, 2928), False, 'from unittest.mock import Mock, patch\n'), ((922, 928), 'unittest.mock.Mock', 'Mock', ([], {}), '()\n', (926, 928), False, 'from unittest.mock import Mock, patch\n'), ((1315, 1321), 'unittest.mock.Mock', 'Mock', ([], {}), '()\n', (1319, 1321), False, 'from unittest.mock import Mock, patch\n'), ((1935, 1941), 'unittest.mock.Mock', 'Mock', ([], {}), '()\n', (1939, 1941), False, 'from unittest.mock import Mock, patch\n'), ((2443, 2449), 'unittest.mock.Mock', 'Mock', ([], {}), '()\n', (2447, 2449), False, 'from unittest.mock import Mock, patch\n'), ((2965, 2971), 'unittest.mock.Mock', 'Mock', ([], {}), '()\n', (2969, 2971), False, 'from unittest.mock import Mock, patch\n'), ((1223, 1229), 'unittest.mock.Mock', 'Mock', ([], {}), '()\n', (1227, 1229), False, 'from unittest.mock import Mock, patch\n')]