diff --git a/src/backend/mailbox_manager/admin.py b/src/backend/mailbox_manager/admin.py index d17a67f..66454ba 100644 --- a/src/backend/mailbox_manager/admin.py +++ b/src/backend/mailbox_manager/admin.py @@ -101,6 +101,35 @@ def fetch_domain_status_from_dimail(modeladmin, request, queryset): # pylint: d ) +@admin.action(description=_("Fetch domain expected config from dimail")) +def fetch_domain_expected_config_from_dimail(modeladmin, request, queryset): # pylint: disable=unused-argument + """Admin action to fetch domain expected config from dimail.""" + client = DimailAPIClient() + excluded_domains = [] + for domain in queryset: + # do not check disabled domains + if domain.status == enums.MailDomainStatusChoices.DISABLED: + excluded_domains.append(domain.name) + continue + response = client.fetch_domain_expected_config(domain) + if response: + messages.success( + request, + _(f"Domain expected config fetched with success for {domain.name}."), + ) + else: + messages.error( + request, _(f"Failed to fetch domain expected config for {domain.name}.") + ) + if excluded_domains: + messages.warning( + request, + _( + f"Domains disabled are excluded from fetch: {', '.join(excluded_domains)}" + ), + ) + + class UserMailDomainAccessInline(admin.TabularInline): """Inline admin class for mail domain accesses.""" @@ -124,7 +153,11 @@ class MailDomainAdmin(admin.ModelAdmin): readonly_fields = ["created_at", "slug"] list_filter = ("status",) inlines = (UserMailDomainAccessInline,) - actions = (sync_mailboxes_from_dimail, fetch_domain_status_from_dimail) + actions = ( + sync_mailboxes_from_dimail, + fetch_domain_status_from_dimail, + fetch_domain_expected_config_from_dimail, + ) @admin.register(models.Mailbox) diff --git a/src/backend/mailbox_manager/tests/test_admin_actions.py b/src/backend/mailbox_manager/tests/test_admin_actions.py index ea836ce..e565eb5 100644 --- a/src/backend/mailbox_manager/tests/test_admin_actions.py +++ b/src/backend/mailbox_manager/tests/test_admin_actions.py @@ -18,6 +18,7 @@ from mailbox_manager import enums, factories, models from .fixtures.dimail import ( CHECK_DOMAIN_BROKEN, CHECK_DOMAIN_OK, + DOMAIN_SPEC, TOKEN_OK, response_mailbox_created, ) @@ -150,3 +151,56 @@ def test_fetch_domain_status__should_switch_to_enabled_when_domain_ok(client): assert "Check domains done with success" in response.content.decode("utf-8") for mailbox in models.Mailbox.objects.filter(domain=domain1): assert mailbox.status == enums.MailboxStatusChoices.ENABLED + + +@pytest.mark.parametrize( + "domain_status", + [ + enums.MailDomainStatusChoices.PENDING, + enums.MailDomainStatusChoices.FAILED, + enums.MailDomainStatusChoices.ENABLED, + ], +) +@responses.activate +@pytest.mark.django_db +def test_fetch_domain_expected_config(client, domain_status): + """Test admin action to fetch domain expected config from dimail.""" + admin = core_factories.UserFactory(is_staff=True, is_superuser=True) + client.force_login(admin) + domain = factories.MailDomainFactory(status=domain_status) + data = { + "action": "fetch_domain_expected_config_from_dimail", + "_selected_action": [domain.id], + } + responses.add( + responses.GET, + re.compile(rf".*/domains/{domain.name}/spec/"), + body=json.dumps(DOMAIN_SPEC), + status=status.HTTP_200_OK, + content_type="application/json", + ) + url = reverse("admin:mailbox_manager_maildomain_changelist") + response = client.post(url, data, follow=True) + assert response.status_code == status.HTTP_200_OK + domain.refresh_from_db() + assert domain.expected_config == DOMAIN_SPEC + + +@pytest.mark.django_db +def test_fetch_domain_expected_config__should_not_fetch_for_disabled_domain(client): + """Test admin action to fetch domain expected config from dimail.""" + admin = core_factories.UserFactory(is_staff=True, is_superuser=True) + client.force_login(admin) + domain = factories.MailDomainFactory(status=enums.MailDomainStatusChoices.DISABLED) + data = { + "action": "fetch_domain_expected_config_from_dimail", + "_selected_action": [domain.id], + } + url = reverse("admin:mailbox_manager_maildomain_changelist") + response = client.post(url, data, follow=True) + assert response.status_code == status.HTTP_200_OK + domain.refresh_from_db() + assert domain.expected_config is None + assert "Domains disabled are excluded from fetch" in response.content.decode( + "utf-8" + )