Some checks failed
System Monitoring / Health Checks (push) Has been cancelled
System Monitoring / Performance Monitoring (push) Has been cancelled
System Monitoring / Database Monitoring (push) Has been cancelled
System Monitoring / Cache Monitoring (push) Has been cancelled
System Monitoring / Log Monitoring (push) Has been cancelled
System Monitoring / Resource Monitoring (push) Has been cancelled
System Monitoring / Uptime Monitoring (push) Has been cancelled
System Monitoring / Backup Monitoring (push) Has been cancelled
System Monitoring / Security Monitoring (push) Has been cancelled
System Monitoring / Monitoring Dashboard (push) Has been cancelled
System Monitoring / Alerting (push) Has been cancelled
Security Scanning / Dependency Scanning (push) Has been cancelled
Security Scanning / Code Security Scanning (push) Has been cancelled
Security Scanning / Secrets Scanning (push) Has been cancelled
Security Scanning / Container Security Scanning (push) Has been cancelled
Security Scanning / Compliance Checking (push) Has been cancelled
Security Scanning / Security Dashboard (push) Has been cancelled
Security Scanning / Security Remediation (push) Has been cancelled
326 lines
11 KiB
Python
326 lines
11 KiB
Python
"""
|
|
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 |