import unittest
from unittest.mock import MagicMock, patch
import pytest

from rhodecode.authentication.views import AuthnPluginViewBase
from rhodecode.lib.celerylib import tasks


class TestAuthPluginView:
    @pytest.mark.parametrize(
        "sync_active_directory_users, expected_celery_task",
        [
            (
                True,
                tasks.schedule_sync_ldap_ad_users_producer,
            ),
            (
                False,
                tasks.unschedule_sync_ldap_ad_users_producer,
            ),
        ],
    )
    @patch("rhodecode.apps._base.BaseAppView.__init__", return_value=None)
    @patch("rhodecode.authentication.views.h")
    @patch("rhodecode.authentication.views.SettingsModel")
    @patch.object(AuthnPluginViewBase, "load_default_context")
    @patch("rhodecode.authentication.views.run_task")
    def test_enable_ad_sync_schedule(
        self,
        run_task_mock,
        load_default_context,
        settings_model,
        h,
        _init_,
        sync_active_directory_users,
        expected_celery_task,
    ):
        view = self._get_instance()

        settings_post = AuthnPluginViewBase.__dict__[  # ignore decorators
            "settings_post"
        ].__wrapped__.__wrapped__.__wrapped__

        schema = MagicMock()
        schema.deserialize.return_value = {"sync_active_directory_users": sync_active_directory_users}

        self._plugin.get_settings_schema.return_value = schema

        settings_post(view)

        run_task_mock.assert_called_once_with(expected_celery_task)

    def _get_instance(self):
        # since base __init__ was patched, there is a need to inject mocks manually
        self._context = MagicMock()
        self._request = MagicMock()
        self._plugin = MagicMock()

        view = AuthnPluginViewBase(self._context, self._request)
        view.request = self._request
        view.plugin = self._plugin
        view.context = self._context
        return view
