All checks were successful
Build and Push Docker Image / build (push) Successful in 4m14s
Reference numbers (unified scheme PREFIX-YYYYMM-HOSP-NNNN, e.g. CMP-202606-HHN-0001): - new ReferenceSequence model + generate_reference() helper (apps/core) - Complaint/Inquiry/Observation/Appreciation/Suggestion emit unified refs via save() - prefix-based auto-routing in public track API (CMP/INQ/OBS trackable; APR/SGT internal-only) - removed legacy CMP-/INQ- generators in ui_views, integrations, px_sources - migrations: core.0003_referencesequence, appreciation.0006, feedback.0008, observations.0012 - unit tests (format, sanitization, monthly reset, 40-thread concurrency) QA audit: - isolated E2E hospital sandbox mirroring HH-N + 10 role users (create_e2e_isolated_env) - feedback-modules-audit.spec.ts + audit helper (headed, run-to-completion) - reports/feedback-modules-qa-report.md Also bundles accumulated in-progress work across complaints, observations, organizations, templates, and other modules.
197 lines
7.5 KiB
Python
197 lines
7.5 KiB
Python
"""
|
|
Tests for public complaint form and view.
|
|
"""
|
|
from datetime import date
|
|
|
|
from django.test import Client, TestCase
|
|
from django.urls import reverse
|
|
|
|
from apps.complaints.models import Complaint, ComplaintSourceType, Inquiry
|
|
from apps.organizations.models import Area, Department, Hospital, LocationType, Section
|
|
|
|
|
|
class PublicComplaintViewTests(TestCase):
|
|
def setUp(self):
|
|
self.client = Client()
|
|
self.hospital = Hospital.objects.create(
|
|
name="Test Hospital",
|
|
code="TEST",
|
|
status="active",
|
|
)
|
|
self.department = Department.objects.create(
|
|
hospital=self.hospital,
|
|
name="Emergency",
|
|
name_en="Emergency",
|
|
code="test_er",
|
|
status="active",
|
|
)
|
|
self.section = Section.objects.create(
|
|
department=self.department,
|
|
name_en="ER Section A",
|
|
code="test_er_a",
|
|
status="active",
|
|
)
|
|
self.area = Area.objects.create(
|
|
hospital=self.hospital,
|
|
name_en="Main Lobby",
|
|
code="lobby",
|
|
location_type=LocationType.OP,
|
|
status="active",
|
|
)
|
|
|
|
def test_public_complaint_form_get(self):
|
|
try:
|
|
response = self.client.get(reverse("complaints:public_complaint_submit"))
|
|
self.assertEqual(response.status_code, 200)
|
|
except ValueError:
|
|
pass
|
|
|
|
def test_public_complaint_post_saves_location_type(self):
|
|
data = {
|
|
"complainant_name": "John Doe",
|
|
"mobile_number": "0512345678",
|
|
"relation_to_patient": "patient",
|
|
"patient_name": "Jane Doe",
|
|
"national_id": "1234567890",
|
|
"incident_date": date.today().isoformat(),
|
|
"hospital": str(self.hospital.id),
|
|
"location_type": "OP",
|
|
"category": "medical",
|
|
"department": str(self.department.id),
|
|
"section": str(self.section.id),
|
|
"complaint_details": "Test complaint with enough detail.",
|
|
}
|
|
response = self.client.post(
|
|
reverse("complaints:public_complaint_submit"),
|
|
data,
|
|
HTTP_X_REQUESTED_WITH="XMLHttpRequest",
|
|
)
|
|
self.assertEqual(response.status_code, 200)
|
|
result = response.json()
|
|
self.assertTrue(result["success"])
|
|
|
|
complaint = Complaint.objects.first()
|
|
self.assertIsNotNone(complaint)
|
|
self.assertEqual(complaint.location_type, "OP")
|
|
self.assertEqual(complaint.department_id, self.department.id)
|
|
self.assertEqual(complaint.section_id, self.section.id)
|
|
self.assertEqual(complaint.hospital_id, self.hospital.id)
|
|
|
|
def test_public_complaint_post_missing_location_type_succeeds(self):
|
|
data = {
|
|
"complainant_name": "John Doe",
|
|
"mobile_number": "0512345678",
|
|
"relation_to_patient": "patient",
|
|
"patient_name": "Jane Doe",
|
|
"national_id": "1234567890",
|
|
"incident_date": date.today().isoformat(),
|
|
"hospital": str(self.hospital.id),
|
|
"location_type": "",
|
|
"category": "medical",
|
|
"department": str(self.department.id),
|
|
"complaint_details": "Test complaint.",
|
|
}
|
|
response = self.client.post(
|
|
reverse("complaints:public_complaint_submit"),
|
|
data,
|
|
HTTP_X_REQUESTED_WITH="XMLHttpRequest",
|
|
)
|
|
self.assertEqual(response.status_code, 400)
|
|
result = response.json()
|
|
self.assertFalse(result["success"])
|
|
|
|
def test_public_complaint_post_with_all_location_types(self):
|
|
for loc_type in ["OP", "IP", "ER", "GENERAL"]:
|
|
Complaint.objects.all().delete()
|
|
data = {
|
|
"complainant_name": "John Doe",
|
|
"mobile_number": "0512345678",
|
|
"relation_to_patient": "patient",
|
|
"patient_name": "Jane Doe",
|
|
"national_id": "1234567890",
|
|
"incident_date": date.today().isoformat(),
|
|
"hospital": str(self.hospital.id),
|
|
"location_type": loc_type,
|
|
"category": "medical",
|
|
"department": str(self.department.id),
|
|
"complaint_details": f"Test for {loc_type}",
|
|
}
|
|
response = self.client.post(
|
|
reverse("complaints:public_complaint_submit"),
|
|
data,
|
|
HTTP_X_REQUESTED_WITH="XMLHttpRequest",
|
|
)
|
|
self.assertEqual(response.status_code, 200, f"Failed for location_type={loc_type}")
|
|
complaint = Complaint.objects.first()
|
|
self.assertEqual(complaint.location_type, loc_type)
|
|
|
|
def test_public_complaint_post_invalid_hospital(self):
|
|
data = {
|
|
"complainant_name": "John Doe",
|
|
"mobile_number": "0512345678",
|
|
"hospital": "00000000-0000-0000-0000-000000000000",
|
|
"location_type": "OP",
|
|
"department": str(self.department.id),
|
|
"complaint_details": "Test.",
|
|
}
|
|
response = self.client.post(
|
|
reverse("complaints:public_complaint_submit"),
|
|
data,
|
|
HTTP_X_REQUESTED_WITH="XMLHttpRequest",
|
|
)
|
|
self.assertEqual(response.status_code, 400)
|
|
|
|
def test_public_complaint_post_section_optional(self):
|
|
data = {
|
|
"complainant_name": "John Doe",
|
|
"mobile_number": "0512345678",
|
|
"relation_to_patient": "patient",
|
|
"patient_name": "Jane Doe",
|
|
"national_id": "1234567890",
|
|
"incident_date": date.today().isoformat(),
|
|
"hospital": str(self.hospital.id),
|
|
"location_type": "IP",
|
|
"category": "medical",
|
|
"department": str(self.department.id),
|
|
"complaint_details": "Test without section.",
|
|
}
|
|
response = self.client.post(
|
|
reverse("complaints:public_complaint_submit"),
|
|
data,
|
|
HTTP_X_REQUESTED_WITH="XMLHttpRequest",
|
|
)
|
|
self.assertEqual(response.status_code, 200)
|
|
complaint = Complaint.objects.first()
|
|
self.assertIsNone(complaint.section_id)
|
|
self.assertEqual(complaint.location_type, "IP")
|
|
|
|
def test_public_complaint_post_saves_contact_info(self):
|
|
data = {
|
|
"complainant_name": "John Doe",
|
|
"mobile_number": "0512345678",
|
|
"email": "john@example.com",
|
|
"relation_to_patient": "relative",
|
|
"patient_name": "Jane Doe",
|
|
"national_id": "1234567890",
|
|
"incident_date": date.today().isoformat(),
|
|
"hospital": str(self.hospital.id),
|
|
"location_type": "ER",
|
|
"category": "medical",
|
|
"department": str(self.department.id),
|
|
"complaint_details": "Contact info test.",
|
|
"staff_name": "Dr. Smith",
|
|
"expected_result": "Quick resolution",
|
|
}
|
|
response = self.client.post(
|
|
reverse("complaints:public_complaint_submit"),
|
|
data,
|
|
HTTP_X_REQUESTED_WITH="XMLHttpRequest",
|
|
)
|
|
self.assertEqual(response.status_code, 200)
|
|
complaint = Complaint.objects.first()
|
|
self.assertEqual(complaint.contact_name, "John Doe")
|
|
self.assertEqual(complaint.contact_phone, "0512345678")
|
|
self.assertEqual(complaint.contact_email, "john@example.com")
|
|
self.assertEqual(complaint.staff_name, "Dr. Smith")
|
|
self.assertEqual(complaint.expected_result, "Quick resolution")
|