Notify via matrix when a new membership application is submitted. (#87)
Reviewed-on: https://git.data.coop/data.coop/membersystem/pulls/87 Reviewed-by: benjaoming <benjaoming@data.coop> Co-authored-by: Víðir Valberg Guðmundsson <valberg@orn.li> Co-committed-by: Víðir Valberg Guðmundsson <valberg@orn.li>
This commit is contained in:
parent
5922c3245c
commit
0b2d6b9dc4
3 changed files with 89 additions and 0 deletions
4
Justfile
4
Justfile
|
@ -30,6 +30,10 @@ typecheck:
|
||||||
test:
|
test:
|
||||||
docker compose run --rm app pytest
|
docker compose run --rm app pytest
|
||||||
|
|
||||||
|
coverage *ARGS:
|
||||||
|
@echo "Running tests with coverage"
|
||||||
|
docker compose run --rm app pytest --cov --cov-report term-missing:skip-covered {{ARGS}}
|
||||||
|
|
||||||
# You need to install Stripe CLI from here to run this: https://github.com/stripe/stripe-cli/releases
|
# You need to install Stripe CLI from here to run this: https://github.com/stripe/stripe-cli/releases
|
||||||
stripe_cli:
|
stripe_cli:
|
||||||
stripe listen --forward-to 0.0.0.0:8000/order/stripe/webhook/
|
stripe listen --forward-to 0.0.0.0:8000/order/stripe/webhook/
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""Models for the membership app."""
|
"""Models for the membership app."""
|
||||||
|
|
||||||
import uuid
|
import uuid
|
||||||
|
from typing import Any
|
||||||
from typing import Self
|
from typing import Self
|
||||||
|
|
||||||
from dirtyfields import DirtyFieldsMixin
|
from dirtyfields import DirtyFieldsMixin
|
||||||
|
@ -9,11 +10,14 @@ from django.contrib.auth.models import UserManager
|
||||||
from django.contrib.postgres.constraints import ExclusionConstraint
|
from django.contrib.postgres.constraints import ExclusionConstraint
|
||||||
from django.contrib.postgres.fields import DateRangeField
|
from django.contrib.postgres.fields import DateRangeField
|
||||||
from django.contrib.postgres.fields import RangeOperators
|
from django.contrib.postgres.fields import RangeOperators
|
||||||
|
from django.contrib.sites.models import Site
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from djmoney.money import Money
|
from djmoney.money import Money
|
||||||
from services.models import ServiceRequest
|
from services.models import ServiceRequest
|
||||||
|
from utils.matrix import notify_admins
|
||||||
from utils.mixins import CreatedModifiedAbstract
|
from utils.mixins import CreatedModifiedAbstract
|
||||||
|
|
||||||
|
|
||||||
|
@ -287,3 +291,14 @@ class WaitingListEntry(CreatedModifiedAbstract):
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("waiting list entry")
|
verbose_name = _("waiting list entry")
|
||||||
verbose_name_plural = _("waiting list entries")
|
verbose_name_plural = _("waiting list entries")
|
||||||
|
|
||||||
|
def save(self, *args: Any, **kwargs: Any) -> None: # noqa: ANN401
|
||||||
|
"""Create notifications when new are added."""
|
||||||
|
is_new = not self.pk
|
||||||
|
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
if is_new:
|
||||||
|
base_domain = Site.objects.get_current()
|
||||||
|
change_url = reverse("admin:membership_waitinglistentry_change", kwargs={"object_id": self.pk})
|
||||||
|
notify_admins(f"Membership application: https://{base_domain}{change_url}")
|
||||||
|
|
70
tests/test_waitinglistentry.py
Normal file
70
tests/test_waitinglistentry.py
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
"""Tests for WaitingListEntry functionality."""
|
||||||
|
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from django.contrib.sites.models import Site
|
||||||
|
from django.urls import reverse
|
||||||
|
from membership.models import WaitingListEntry
|
||||||
|
|
||||||
|
|
||||||
|
class TestWaitingListEntryNotifications:
|
||||||
|
"""Tests for WaitingListEntry notification functionality."""
|
||||||
|
|
||||||
|
@pytest.mark.django_db()
|
||||||
|
def test_matrix_notification_on_create(self, membership_type):
|
||||||
|
"""Test that a Matrix notification is sent when a new WaitingListEntry is created."""
|
||||||
|
# Explicitly patch notify_admins to ensure we're testing the right function
|
||||||
|
with mock.patch("membership.models.notify_admins") as mock_notify:
|
||||||
|
# Create a new WaitingListEntry
|
||||||
|
entry = WaitingListEntry.objects.create(
|
||||||
|
name="Test User",
|
||||||
|
email="test@example.com",
|
||||||
|
membership_type=membership_type,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check that notify_admins was called
|
||||||
|
mock_notify.assert_called_once()
|
||||||
|
|
||||||
|
# Get the expected URL components
|
||||||
|
base_domain = Site.objects.get_current()
|
||||||
|
change_url = reverse("admin:membership_waitinglistentry_change", kwargs={"object_id": entry.pk})
|
||||||
|
expected_message = f"Membership application: https://{base_domain}{change_url}"
|
||||||
|
|
||||||
|
# Verify the message content
|
||||||
|
mock_notify.assert_called_with(expected_message)
|
||||||
|
|
||||||
|
@pytest.mark.django_db()
|
||||||
|
def test_no_matrix_notification_on_update(self, membership_type):
|
||||||
|
"""Test that no Matrix notification is sent when a WaitingListEntry is updated."""
|
||||||
|
# First create the entry
|
||||||
|
entry = WaitingListEntry.objects.create(
|
||||||
|
name="Test User",
|
||||||
|
email="test@example.com",
|
||||||
|
membership_type=membership_type,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Now update it with a patched notify_admins
|
||||||
|
with mock.patch("membership.models.notify_admins") as mock_notify:
|
||||||
|
entry.geography = "Some Location"
|
||||||
|
entry.save()
|
||||||
|
|
||||||
|
# Verify that notify_admins was not called
|
||||||
|
mock_notify.assert_not_called()
|
||||||
|
|
||||||
|
@pytest.mark.django_db()
|
||||||
|
def test_message_format(self, membership_type):
|
||||||
|
"""Test that the message has the expected format with 'Membership application:' prefix."""
|
||||||
|
with mock.patch("membership.models.notify_admins") as mock_notify:
|
||||||
|
# Create a new WaitingListEntry
|
||||||
|
WaitingListEntry.objects.create(
|
||||||
|
name="Test User",
|
||||||
|
email="test@example.com",
|
||||||
|
membership_type=membership_type,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check the message format
|
||||||
|
args, kwargs = mock_notify.call_args
|
||||||
|
message = args[0]
|
||||||
|
assert message.startswith("Membership application: ")
|
||||||
|
assert "https://" in message
|
Loading…
Add table
Reference in a new issue