diff --git a/temba/channels/tests.py b/temba/channels/tests.py index f602afd3640..196a0d3d7b5 100644 --- a/temba/channels/tests.py +++ b/temba/channels/tests.py @@ -1319,6 +1319,37 @@ def test_log_counts(self): mock.assert_called_with(self.admin, "temba.ivr_outgoing", {"count": 1}) +class ChannelEventCRUDLTest(CRUDLTestMixin, TembaTest): + def test_read(self): + contact = self.create_contact("Joe", phone="+250788111222") + e1 = ChannelEvent.objects.create( + org=self.org, + channel=self.channel, + event_type=ChannelEvent.TYPE_STOP_CONTACT, + contact=contact, + created_on=timezone.now() - timedelta(days=3), + occurred_on=timezone.now() - timedelta(days=3), + ) + e2 = ChannelEvent.objects.create( + org=self.org, + channel=self.channel, + event_type=ChannelEvent.TYPE_DELETE_CONTACT, + contact=contact, + created_on=timezone.now() - timedelta(days=2), + occurred_on=timezone.now() - timedelta(days=3), + ) + self.assertEqual(2, ChannelEvent.objects.all().count()) + + # 404 for non delete request event type + response = self.client.get(reverse("channels.channelevent_read", args=[e1.uuid])) + self.assertEqual(404, response.status_code) + + # success for event of type delete request + response = self.client.get(reverse("channels.channelevent_read", args=[e2.uuid])) + self.assertEqual(200, response.status_code) + self.assertContains(response, f"Confirmation code: {e2.uuid}") + + class ChannelEventTest(TembaTest): def test_trim_task(self): contact = self.create_contact("Joe", phone="+250788111222") diff --git a/temba/channels/urls.py b/temba/channels/urls.py index eb226e67e43..132d8310d63 100644 --- a/temba/channels/urls.py +++ b/temba/channels/urls.py @@ -5,7 +5,7 @@ from .android.views import register, sync from .models import Channel -from .views import ChannelCRUDL, ChannelLogCRUDL +from .views import ChannelCRUDL, ChannelEventCRUDL, ChannelLogCRUDL # we iterate all our channel types, finding all the URLs they want to wire in courier_urls = [] @@ -27,7 +27,12 @@ urlpatterns = [ - re_path(r"^channels/", include(ChannelCRUDL().as_urlpatterns() + ChannelLogCRUDL().as_urlpatterns())), + re_path( + r"^channels/", + include( + ChannelCRUDL().as_urlpatterns() + ChannelLogCRUDL().as_urlpatterns() + ChannelEventCRUDL().as_urlpatterns() + ), + ), re_path(r"^c/", include(courier_urls)), re_path(r"^channels/types/", include(type_urls)), re_path(r"^relayers/relayer/sync/(\d+)/$", sync, {}, "sync"), diff --git a/temba/channels/views.py b/temba/channels/views.py index 3a1373855b0..418141c3b67 100644 --- a/temba/channels/views.py +++ b/temba/channels/views.py @@ -43,7 +43,7 @@ from temba.utils.models import patch_queryset_count from temba.utils.views.mixins import ComponentFormMixin, ContextMenuMixin, ModalFormMixin, SpaMixin -from .models import Channel, ChannelCount, ChannelLog +from .models import Channel, ChannelCount, ChannelEvent, ChannelLog logger = logging.getLogger(__name__) @@ -850,6 +850,28 @@ def get_context_data(self, **kwargs): return context +class ChannelEventCRUDL(SmartCRUDL): + model = ChannelEvent + path = "events" # urls like /channels/events/ + actions = ("read",) + + class Read(SpaMixin, SmartReadView): + """ + Detail view for a single channel event that is a delete request event type + """ + + permission = None + slug_url_kwarg = "uuid" + + def derive_queryset(self, **kwargs): + return ChannelEvent.objects.filter(event_type=ChannelEvent.TYPE_DELETE_CONTACT) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["event"] = self.object + return context + + class ChannelLogCRUDL(SmartCRUDL): model = ChannelLog path = "logs" # urls like /channels/logs/ diff --git a/templates/channels/channelevent_read.html b/templates/channels/channelevent_read.html new file mode 100644 index 00000000000..9c1ff3817cb --- /dev/null +++ b/templates/channels/channelevent_read.html @@ -0,0 +1,17 @@ +{% extends "no_nav.html" %} +{% load smartmin compress temba %} +{% load i18n %} + +{% block head-title %} + {% trans "Data deletion request" %} +{% endblock head-title %} +{% block page-top %} +{% endblock page-top %} +{% block content %} +
+
+
{% trans "Data deletion request received" %}
+
{% trans "Confirmation code" %}: {{ event.uuid }}
+
+
+{% endblock content %}