114 lines
4.9 KiB
Python
114 lines
4.9 KiB
Python
"""
|
|
Tests for the suggestion closed-loop communication fixes:
|
|
- Fix 2.1(a): public submission sends an acknowledgement SMS
|
|
- Fix 2.1(b): status change to acknowledged/closed notifies the suggester
|
|
"""
|
|
from unittest.mock import patch
|
|
|
|
from django.contrib.auth.models import Group
|
|
from django.test import TestCase
|
|
from django.urls import reverse
|
|
|
|
from apps.accounts.models import User
|
|
from apps.feedback.models import Feedback, FeedbackStatus, FeedbackType
|
|
from apps.organizations.models import Hospital
|
|
|
|
|
|
class PublicSuggestionAcknowledgementTests(TestCase):
|
|
"""Fix 2.1(a) — public suggestion submit sends an acknowledgement SMS."""
|
|
|
|
def setUp(self):
|
|
self.hospital = Hospital.objects.create(name="Ack Test Hospital", code="ACK", status="active")
|
|
|
|
@patch("apps.feedback.views.NotificationService.send_sms")
|
|
@patch("apps.feedback.tasks.analyze_suggestion_with_ai.delay")
|
|
@patch("apps.complaints.tasks.notify_staff_new_item.delay")
|
|
def test_public_suggestion_sends_acknowledgement(self, mock_notify_staff, mock_ai, mock_sms):
|
|
data = {
|
|
"contact_name": "Jane Doe",
|
|
"contact_phone": "0501234567",
|
|
"message": "Please add more seating in the waiting area.",
|
|
"hospital": str(self.hospital.id),
|
|
}
|
|
response = self.client.post(
|
|
reverse("feedback:public_suggestion_submit"),
|
|
data,
|
|
HTTP_X_REQUESTED_WITH="XMLHttpRequest",
|
|
)
|
|
self.assertEqual(response.status_code, 200)
|
|
result = response.json()
|
|
self.assertTrue(result["success"])
|
|
|
|
feedback = Feedback.objects.get()
|
|
self.assertEqual(feedback.feedback_type, FeedbackType.SUGGESTION)
|
|
# Acknowledgement SMS fired exactly once to the suggester's phone.
|
|
mock_sms.assert_called_once()
|
|
called_phone = mock_sms.call_args.args[0]
|
|
self.assertEqual(called_phone, "0501234567")
|
|
|
|
|
|
class SuggestionStatusChangeNotificationTests(TestCase):
|
|
"""Fix 2.1(b) — moving to ACKNOWLEDGED/CLOSED notifies the suggester."""
|
|
|
|
def setUp(self):
|
|
self.hospital = Hospital.objects.create(name="SC Test Hospital", code="SC", status="active")
|
|
px_group = Group.objects.create(name="PX Employee")
|
|
self.user = User.objects.create_user(email="px@example.com", password="pass12345")
|
|
self.user.groups.add(px_group)
|
|
self.client.force_login(self.user)
|
|
|
|
def _make_suggestion(self, status=FeedbackStatus.REVIEWED, phone="0509876543"):
|
|
return Feedback.objects.create(
|
|
hospital=self.hospital,
|
|
feedback_type=FeedbackType.SUGGESTION,
|
|
title="Improve signage",
|
|
message="The signage in the ER is confusing.",
|
|
status=status,
|
|
contact_name="Bob",
|
|
contact_phone=phone,
|
|
)
|
|
|
|
@patch("apps.feedback.views.NotificationService.send_sms")
|
|
def test_acknowledged_notifies_suggester(self, mock_sms):
|
|
feedback = self._make_suggestion(status=FeedbackStatus.REVIEWED, phone="0509876543")
|
|
response = self.client.post(
|
|
reverse("feedback:feedback_change_status", kwargs={"pk": feedback.pk}),
|
|
{"status": FeedbackStatus.ACKNOWLEDGED.value},
|
|
)
|
|
self.assertEqual(response.status_code, 302)
|
|
feedback.refresh_from_db()
|
|
self.assertEqual(feedback.status, FeedbackStatus.ACKNOWLEDGED.value)
|
|
mock_sms.assert_called_once()
|
|
self.assertEqual(mock_sms.call_args.args[0], "0509876543")
|
|
|
|
@patch("apps.feedback.views.NotificationService.send_sms")
|
|
def test_closed_notifies_suggester(self, mock_sms):
|
|
feedback = self._make_suggestion(status=FeedbackStatus.REVIEWED, phone="0501112233")
|
|
response = self.client.post(
|
|
reverse("feedback:feedback_change_status", kwargs={"pk": feedback.pk}),
|
|
{"status": FeedbackStatus.CLOSED.value},
|
|
)
|
|
self.assertEqual(response.status_code, 302)
|
|
feedback.refresh_from_db()
|
|
self.assertEqual(feedback.status, FeedbackStatus.CLOSED.value)
|
|
mock_sms.assert_called_once()
|
|
|
|
@patch("apps.feedback.views.NotificationService.send_sms")
|
|
def test_no_phone_skips_notification(self, mock_sms):
|
|
feedback = self._make_suggestion(status=FeedbackStatus.REVIEWED, phone="")
|
|
self.client.post(
|
|
reverse("feedback:feedback_change_status", kwargs={"pk": feedback.pk}),
|
|
{"status": FeedbackStatus.ACKNOWLEDGED.value},
|
|
)
|
|
mock_sms.assert_not_called()
|
|
|
|
@patch("apps.feedback.views.NotificationService.send_sms")
|
|
def test_reviewed_does_not_notify(self, mock_sms):
|
|
# Only acknowledged/closed notify — reviewed is an internal triage step.
|
|
feedback = self._make_suggestion(status=FeedbackStatus.SUBMITTED, phone="0509998877")
|
|
self.client.post(
|
|
reverse("feedback:feedback_change_status", kwargs={"pk": feedback.pk}),
|
|
{"status": FeedbackStatus.REVIEWED.value},
|
|
)
|
|
mock_sms.assert_not_called()
|