""" Contract test for GET /healthcare/patients endpoint. This test MUST fail before implementation. """ import pytest from django.test import TestCase from django.urls import reverse from rest_framework.test import APIClient from rest_framework import status import json class HealthcarePatientsGetContractTest(TestCase): def setUp(self): self.client = APIClient() self.patients_url = '/api/v1/healthcare/patients/' # Tenant authentication header self.tenant_auth = {'HTTP_AUTHORIZATION': 'Bearer tenant_token'} def test_get_patients_success(self): """Test successful retrieval of patients list.""" response = self.client.get( self.patients_url, **self.tenant_auth ) # This should fail before implementation assert response.status_code == status.HTTP_200_OK data = response.json() assert 'patients' in data assert isinstance(data['patients'], list) # Check pagination structure assert 'pagination' in data pagination = data['pagination'] assert 'page' in pagination assert 'limit' in pagination assert 'total' in pagination assert 'pages' in pagination def test_get_patients_unauthorized(self): """Test patients list retrieval without authentication.""" response = self.client.get(self.patients_url) assert response.status_code == status.HTTP_401_UNAUTHORIZED def test_get_patients_with_pagination(self): """Test patients list retrieval with pagination parameters.""" params = { 'page': 2, 'limit': 15 } response = self.client.get( self.patients_url, data=params, **self.tenant_auth ) assert response.status_code == status.HTTP_200_OK data = response.json() assert data['pagination']['page'] == 2 assert data['pagination']['limit'] == 15 def test_get_patients_with_search(self): """Test patients list retrieval with search parameter.""" params = { 'search': 'tan' } response = self.client.get( self.patients_url, data=params, **self.tenant_auth ) assert response.status_code == status.HTTP_200_OK data = response.json() # All returned patients should match search criteria for patient in data['patients']: search_match = ( 'tan' in patient['name'].lower() or 'tan' in patient['ic_number'].lower() or 'tan' in patient['email'].lower() ) assert search_match def test_get_patients_filter_by_gender(self): """Test patients list retrieval filtered by gender.""" params = { 'gender': 'FEMALE' } response = self.client.get( self.patients_url, data=params, **self.tenant_auth ) assert response.status_code == status.HTTP_200_OK data = response.json() # All returned patients should have the specified gender for patient in data['patients']: assert patient['gender'] == 'FEMALE' def test_get_patients_filter_by_status(self): """Test patients list retrieval filtered by status.""" params = { 'status': 'ACTIVE' } response = self.client.get( self.patients_url, data=params, **self.tenant_auth ) assert response.status_code == status.HTTP_200_OK data = response.json() # All returned patients should have the specified status for patient in data['patients']: assert patient['status'] == 'ACTIVE' def test_get_patients_filter_by_age_range(self): """Test patients list retrieval filtered by age range.""" params = { 'min_age': 25, 'max_age': 65 } response = self.client.get( self.patients_url, data=params, **self.tenant_auth ) assert response.status_code == status.HTTP_200_OK data = response.json() # All returned patients should be within the age range for patient in data['patients']: assert 25 <= patient['age'] <= 65 def test_get_patients_data_structure(self): """Test that patient data structure matches the contract.""" response = self.client.get( self.patients_url, **self.tenant_auth ) if response.status_code == status.HTTP_200_OK and len(response.json()['patients']) > 0: patient = response.json()['patients'][0] # Required fields according to contract required_fields = [ 'id', 'ic_number', 'name', 'gender', 'date_of_birth', 'age', 'phone', 'email', 'address', 'blood_type', 'allergies', 'medications', 'status', 'tenant_id', 'created_at', 'updated_at' ] for field in required_fields: assert field in patient # Field types and enums assert isinstance(patient['id'], str) assert isinstance(patient['ic_number'], str) assert isinstance(patient['name'], str) assert patient['gender'] in ['MALE', 'FEMALE', 'OTHER'] assert isinstance(patient['date_of_birth'], str) assert isinstance(patient['age'], int) assert isinstance(patient['phone'], str) assert isinstance(patient['email'], str) assert patient['blood_type'] in ['A+', 'A-', 'B+', 'B-', 'AB+', 'AB-', 'O+', 'O-', 'UNKNOWN'] assert patient['status'] in ['ACTIVE', 'INACTIVE', 'DECEASED'] def test_get_patients_with_medical_history(self): """Test that patient data includes medical history.""" response = self.client.get( self.patients_url, data={'include_medical_history': 'true'}, **self.tenant_auth ) if response.status_code == status.HTTP_200_OK and len(response.json()['patients']) > 0: patient = response.json()['patients'][0] # Should include medical history assert 'medical_history' in patient medical_history = patient['medical_history'] # Medical history should include relevant fields expected_medical_fields = ['conditions', 'surgeries', 'family_history', 'immunizations'] for field in expected_medical_fields: assert field in medical_history def test_get_patients_with_emergency_contacts(self): """Test that patient data includes emergency contacts.""" response = self.client.get( self.patients_url, data={'include_emergency_contacts': 'true'}, **self.tenant_auth ) if response.status_code == status.HTTP_200_OK and len(response.json()['patients']) > 0: patient = response.json()['patients'][0] # Should include emergency contacts assert 'emergency_contacts' in patient emergency_contacts = patient['emergency_contacts'] # Should be a list assert isinstance(emergency_contacts, list) if len(emergency_contacts) > 0: contact = emergency_contacts[0] expected_contact_fields = ['name', 'relationship', 'phone', 'email'] for field in expected_contact_fields: assert field in contact def test_get_patients_with_insurance_info(self): """Test that patient data includes insurance information.""" response = self.client.get( self.patients_url, data={'include_insurance': 'true'}, **self.tenant_auth ) if response.status_code == status.HTTP_200_OK and len(response.json()['patients']) > 0: patient = response.json()['patients'][0] # Should include insurance information assert 'insurance' in patient insurance = patient['insurance'] # Insurance should include relevant fields expected_insurance_fields = ['provider', 'policy_number', 'coverage_details', 'expiry_date'] for field in expected_insurance_fields: assert field in insurance def test_get_patients_sorting(self): """Test patients list retrieval with sorting.""" params = { 'sort_by': 'name', 'sort_order': 'asc' } response = self.client.get( self.patients_url, data=params, **self.tenant_auth ) assert response.status_code == status.HTTP_200_OK data = response.json() # Patients should be sorted by name in ascending order patient_names = [patient['name'] for patient in data['patients']] assert patient_names == sorted(patient_names) def test_get_patients_tenant_isolation(self): """Test that patients are isolated by tenant.""" response = self.client.get( self.patients_url, **self.tenant_auth ) if response.status_code == status.HTTP_200_OK: data = response.json() # All returned patients should belong to the authenticated tenant for patient in data['patients']: assert 'tenant_id' in patient # This will be validated once implementation exists def test_get_patients_with_visit_history(self): """Test that patient data includes visit history.""" response = self.client.get( self.patients_url, data={'include_visits': 'true'}, **self.tenant_auth ) if response.status_code == status.HTTP_200_OK and len(response.json()['patients']) > 0: patient = response.json()['patients'][0] # Should include visit history assert 'visit_history' in patient visit_history = patient['visit_history'] # Should be a list assert isinstance(visit_history, list) if len(visit_history) > 0: visit = visit_history[0] expected_visit_fields = ['date', 'doctor_id', 'diagnosis', 'treatment', 'notes'] for field in expected_visit_fields: assert field in visit def test_get_patients_data_compliance(self): """Test that patient data complies with healthcare data protection.""" response = self.client.get( self.patients_url, **self.tenant_auth ) if response.status_code == status.HTTP_200_OK and len(response.json()['patients']) > 0: patient = response.json()['patients'][0] # Sensitive medical data should be properly handled # Allergies and medications should be present for healthcare compliance assert 'allergies' in patient assert 'medications' in patient # Address should be structured for privacy compliance assert 'address' in patient address = patient['address'] expected_address_fields = ['street', 'city', 'state', 'postal_code', 'country'] for field in expected_address_fields: assert field in address