Skip to content

Commit

Permalink
✨(dashboard) add admin actions for updating consent statuses
Browse files Browse the repository at this point in the history
Introduce `make_revoked` and `make_awaiting` actions to simplify updating consent status directly from the admin interface.
Updates include relevant timestamps and user feedback via success messages.
  • Loading branch information
ssorin committed Jan 13, 2025
1 parent a6a8949 commit 813d72f
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/dashboard/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ and this project adheres to
- add internationalization and language switcher
- add dashboard homepage
- add consent form to manage consents of one or many entities
- add admin integration for Entity, DeliveryPoint and Consent
- add mass admin action (make revoked and make awaiting) for consents
- integration of custom 403, 404 and 500 pages
- sentry integration
- added a signal on the creation of a delivery point. This signal allows the creation
Expand Down
27 changes: 26 additions & 1 deletion src/dashboard/apps/consent/admin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
"""Dashboard consent admin."""

from django.contrib import admin
from django.contrib import admin, messages
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

from . import AWAITING, REVOKED
from .models import Consent


Expand All @@ -23,3 +26,25 @@ class ConsentAdmin(admin.ModelAdmin):
]
list_filter = ["status"]
date_hierarchy = "start"
actions = ["make_revoked", "make_awaiting"]

@admin.action(description=_("Mark selected consents as revoked"))
def make_revoked(self, request, queryset):
"""Mark selected consents as revoked."""
now = timezone.now()
queryset.update(status=REVOKED, revoked_at=now, updated_at=now)
self.message_user(
request,
_("Selected consents have been marked as revoked."),
messages.SUCCESS,
)

@admin.action(description=_("Mark selected consents as awaiting"))
def make_awaiting(self, request, queryset):
"""Mark selected consents as awaiting."""
queryset.update(status=AWAITING, updated_at=timezone.now(), revoked_at=None)
self.message_user(
request,
_("Selected consents have been marked as awaiting."),
messages.SUCCESS,
)
11 changes: 11 additions & 0 deletions src/dashboard/apps/consent/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import datetime

import pytest
from django.utils import timezone

FAKE_TIME = datetime.datetime(2025, 1, 6, 17, 5, 55, 0, tzinfo=datetime.timezone.utc)

Expand All @@ -17,3 +18,13 @@ def now(cls, tz=datetime.timezone.utc):
return FAKE_TIME

monkeypatch.setattr(datetime, "datetime", FakeDatetime)


@pytest.fixture
def patch_timezone_now(monkeypatch):
"""Monkeypatch timezone.now to return a frozen date (`FAKE_TIME`)."""

def mock_now():
return FAKE_TIME

monkeypatch.setattr(timezone, "now", mock_now)
66 changes: 66 additions & 0 deletions src/dashboard/apps/consent/tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
from django.contrib.admin.sites import AdminSite
from django.urls import reverse

from apps.auth.factories import AdminUserFactory
from apps.consent import AWAITING, REVOKED, VALIDATED
from apps.consent.admin import ConsentAdmin
from apps.consent.models import Consent
from apps.consent.tests.conftest import FAKE_TIME
from apps.core.factories import DeliveryPointFactory


@pytest.mark.django_db
Expand All @@ -29,3 +33,65 @@ def test_admin_manager_name(rf):
# The manager name must be the default Django manager: `objects`.
manager_name = queryset.model._default_manager.name
assert manager_name == "objects"


@pytest.mark.django_db
def test_make_revoked_action(client, patch_timezone_now):
"""Tests the 'make_revoked' action for ConsentAdmin."""
# Initialize admin user
admin_user = AdminUserFactory()

# create a consent
assert Consent.objects.count() == 0
DeliveryPointFactory()
assert Consent.objects.count() == 1

# Post action with selected consent
consent = Consent.objects.first()
assert consent.status == AWAITING
data = {
"action": "make_revoked",
"_selected_action": [
consent.id,
],
}
client.force_login(admin_user)
client.post(reverse("admin:qcd_consent_consent_changelist"), data)

consent.refresh_from_db()
assert consent.status == REVOKED
assert consent.revoked_at == FAKE_TIME
assert consent.updated_at == FAKE_TIME


@pytest.mark.django_db
def test_make_awaiting_action(client, patch_timezone_now):
"""Tests the 'make_awaiting' action for ConsentAdmin."""
# Initialize admin user
admin_user = AdminUserFactory()

# create a consent
assert Consent.objects.count() == 0
DeliveryPointFactory()
assert Consent.objects.count() == 1

# Select and update consent status to AWAITING
consent = Consent.objects.first()
consent.status = VALIDATED
consent.save()
assert consent.status == VALIDATED

# Post action with selected consent
data = {
"action": "make_awaiting",
"_selected_action": [
consent.id,
],
}
client.force_login(admin_user)
client.post(reverse("admin:qcd_consent_consent_changelist"), data)

consent.refresh_from_db()
assert consent.status == AWAITING
assert consent.revoked_at is None
assert consent.updated_at == FAKE_TIME

0 comments on commit 813d72f

Please sign in to comment.