HH/docs/REAL_TIME_SLA_TESTING_GUIDE.md

517 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Real-Time SLA Testing Guide
This guide explains how to use the realistic SLA testing scenarios that simulate real-world complaint workflows with time compression.
## Overview
The SLA testing system uses **time-compressed simulation** to test real workflows in a fraction of the time:
- **Time Compression Ratio**: 1 second of real time = 1 hour of system time
- This allows testing a 48-hour SLA in just 48 seconds
- All actual system code is executed (no mocking)
- Real Celery tasks, email sending, and database operations
## Test Scripts
### 1. Scenario 1: Successful Explanation Submission
**File**: `test_scenario_1_successful_explanation.py`
Tests the happy path where a staff member submits their explanation before the SLA deadline. No escalation occurs.
**Duration**: ~7 seconds
**SLA Configuration**:
- Response deadline: 10 hours (10 seconds)
- First reminder: 5 hours before deadline
- Auto-escalation: Enabled (but not triggered)
**Workflow**:
```
T+0s Setup environment (hospital, department, staff)
T+2s Create complaint
T+1s Request explanation from staff
T+0s Verify initial state (pending, no reminders)
T+3s Staff submits explanation (before deadline)
T+0s Verify explanation submitted
T+0s Verify no escalation occurred
```
**Expected Results**:
- ✅ Explanation request email sent
- ✅ Staff submits explanation before deadline
- ✅ Explanation marked as used
- ✅ No reminders sent (not needed)
- ✅ No escalation occurred
- ✅ Complaint resolution process can proceed
**Key Database States**:
```python
# After completion
ComplaintExplanation.is_used = True
ComplaintExplanation.is_overdue = False
ComplaintExplanation.reminder_sent_at = None
ComplaintExplanation.escalated_to_manager = None
```
---
### 2. Scenario 2: Escalation with Reminders
**File**: `test_scenario_2_escalation_with_reminders.py`
Tests the case where a staff member doesn't submit their explanation, leading to reminders and automatic escalation through the management chain.
**Duration**: ~37 seconds
**SLA Configuration**:
- Response deadline: 12 hours (12 seconds)
- First reminder: 6 hours before deadline
- Second reminder: 3 hours before deadline
- Auto-escalation: Enabled, immediate
- Max escalation levels: 3
**Workflow**:
```
T+0s Setup environment (hospital, department, staff hierarchy)
- Staff (Omar Al-Harbi)
- Manager (Mohammed Al-Rashid)
- Department Head (Ahmed Al-Farsi)
- Hospital Admin
T+1s Create complaint (high severity, high priority)
T+1s Request explanation from staff
T+0s Verify initial state (pending)
T+4s Wait for first reminder check
- First reminder sent at T+6h (6 hours after request)
T+0s Verify first reminder sent
T+3s Wait for second reminder check
- Second reminder sent at T+9h (3 hours before deadline)
T+0s Verify second reminder sent
T+3s Wait for deadline (T+12h)
- Escalate to manager
T+0s Verify escalation to manager
T+12s Wait for manager deadline (T+24h total)
- Manager also doesn't respond
- Escalate to department head
T+0s Verify escalation to department head
T+0s Final verification (overdue state)
```
**Expected Results**:
- ✅ Explanation request email sent to staff
- ✅ First reminder sent at 6 hours before deadline
- ✅ Second reminder sent at 3 hours before deadline
- ✅ Deadline reached - escalated to manager
- ✅ Manager receives explanation request
- ✅ Manager deadline reached - escalated to department head
- ✅ Department head receives explanation request
- ✅ Explanation marked as overdue
- ✅ Escalation chain: Staff → Manager → Department Head
**Key Database States**:
```python
# After escalation to manager
ComplaintExplanation.is_used = False
ComplaintExplanation.is_overdue = True
ComplaintExplanation.reminder_sent_at = [timestamp]
ComplaintExplanation.second_reminder_sent_at = [timestamp]
ComplaintExplanation.escalated_to_manager = Manager instance
ComplaintExplanation.escalated_at = [timestamp]
ComplaintExplanation.escalation_level = 1
# After escalation to department head
ComplaintExplanation.escalated_to_dept_head = Department Head instance
ComplaintExplanation.escalation_level = 2
```
---
## Running the Tests
### Prerequisites
1. **Django Setup**: Make sure Django is properly configured
```bash
# Check your .env file has the correct settings
cat .env | grep DJANGO_SETTINGS_MODULE
```
2. **Database**: Ensure your database is accessible
```bash
# Run migrations if needed
python manage.py migrate
```
3. **Email Configuration**: Email service should be configured (or use console backend)
### Execute Scenario 1
```bash
# Make the script executable
chmod +x test_scenario_1_successful_explanation.py
# Run the test
python test_scenario_1_successful_explanation.py
```
**Expected Output**:
```
================================================================================
SCENARIO 1: SUCCESSFUL EXPLANATION SUBMISSION
================================================================================
[Step 1] Setting up test environment
→ Executing immediately
✓ Created hospital: Al Hammadi Hospital
✓ Created department: Emergency Department
✓ Created staff member: Omar Al-Harbi
✓ Created ExplanationSLAConfig: 10h response time
✓ Created ComplaintSLAConfig: medium/medium - 72h SLA
[Step 2] Creating complaint
→ Waiting 2s (simulates 2 hours)
[1/2s] Simulated time: 2 hours
[2/2s] Simulated time: 4 hours
✓ Created complaint: Poor response time in emergency... (ID: 1)
Severity: medium
Priority: medium
Status: open
Staff: Omar Al-Harbi
[Step 3] Requesting explanation from staff
→ Waiting 1s (simulates 1 hours)
[1/1s] Simulated time: 1 hours
✓ Created explanation request for Omar Al-Harbi
Token: abc123...
✓ Explanation request email sent
SLA Due At: 2026-01-14 17:04:00
Hours until deadline: 10.0
[Step 4] Verifying initial explanation state
→ Executing immediately
✓ Explanation pending correctly (is_used=False, is_overdue=False, reminder=False)
[Step 5] Staff submits explanation (before deadline)
→ Waiting 3s (simulates 3 hours)
[1/3s] Simulated time: 1 hours
[2/3s] Simulated time: 2 hours
[3/3s] Simulated time: 3 hours
✓ Staff submitted explanation
Response time: 2026-01-14 17:04:00
SLA deadline: 2026-01-15 03:04:00
✓ Submitted 7.0 hours BEFORE deadline ✓
[Step 6] Verifying explanation submitted successfully
→ Executing immediately
✓ Explanation submitted successfully (is_used=True, is_overdue=False)
[Step 7] Verifying no escalation occurred
→ Executing immediately
✓ No escalation occurred (as expected)
================================================================================
TEST SUMMARY
================================================================================
Total Steps: 7
Successful: 7
Failed: 0
Elapsed Time: 7.2s
✓✓✓ ALL TESTS PASSED ✓✓✓
================================================================================
✓ Scenario 1 completed successfully!
```
### Execute Scenario 2
```bash
# Make the script executable
chmod +x test_scenario_2_escalation_with_reminders.py
# Run the test
python test_scenario_2_escalation_with_reminders.py
```
**Expected Output**:
```
================================================================================
SCENARIO 2: ESCALATION WITH REMINDERS
================================================================================
[Step 1] Setting up test environment
→ Executing immediately
✓ Created hospital: Al Hammadi Hospital
✓ Created department: Emergency Department
✓ Created staff hierarchy: Omar Al-Harbi → Mohammed Al-Rashid → Ahmed Al-Farsi → Admin
✓ Created ExplanationSLAConfig: 12h response time
✓ Second reminder config: 3h before deadline
✓ Created ComplaintSLAConfig: high/high - 48h SLA
[Step 2] Creating complaint
→ Waiting 1s (simulates 1 hours)
[1/1s] Simulated time: 1 hours
✓ Created complaint: Patient left waiting for 3 hours... (ID: 2)
Severity: high
Priority: high
Status: open
Staff: Omar Al-Harbi
[Step 3] Requesting explanation from staff
→ Waiting 1s (simulates 1 hours)
[1/1s] Simulated time: 1 hours
✓ Created explanation request for Omar Al-Harbi
✓ Explanation request email sent
SLA Deadline: 12.0 hours from now
First reminder: 6.0 hours from now
Second reminder: 9.0 hours from now
[Step 4] Verifying initial explanation state
→ Executing immediately
✓ Explanation pending correctly (is_used=False, is_overdue=False, reminder=False)
[Step 5] Waiting for first reminder
→ Waiting 4s (simulates 4 hours)
[1/4s] Simulated time: 1 hours
[2/4s] Simulated time: 2 hours
[3/4s] Simulated time: 3 hours
[4/4s] Simulated time: 4 hours
Checking for first reminder...
✓ First reminder sent at 2026-01-14 16:09:00
✓ First reminder sent correctly
[Step 6] Verifying first reminder sent
→ Executing immediately
✓ Reminder sent correctly (is_used=False, has_reminder=True, escalated=False)
[Step 7] Waiting for second reminder
→ Waiting 3s (simulates 3 hours)
[1/3s] Simulated time: 1 hours
[2/3s] Simulated time: 2 hours
[3/3s] Simulated time: 3 hours
Checking for second reminder...
✓ Second reminder sent at 2026-01-14 16:12:00
✓ Second reminder sent correctly
[Step 8] Waiting for deadline (escalation to manager)
→ Waiting 3s (simulates 3 hours)
[1/3s] Simulated time: 1 hours
[2/3s] Simulated time: 2 hours
[3/3s] Simulated time: 3 hours
Checking for overdue explanations (escalate to manager)...
✓ Escalated to manager: Mohammed Al-Rashid
✓ Escalated to manager correctly
[Step 9] Verifying escalation to manager
→ Executing immediately
✓ Escalated to manager: Mohammed Al-Rashid
✓ Escalated correctly
[Step 10] Waiting for manager deadline (escalation to department head)
→ Waiting 12s (simulates 12 hours)
[1/12s] Simulated time: 1 hours
[5/12s] Simulated time: 5 hours
[10/12s] Simulated time: 10 hours
[12/12s] Simulated time: 12 hours
Checking for overdue manager explanations (escalate to department head)...
✓ Manager's explanation escalated to department head
✓ Escalated to department head correctly
[Step 11] Verifying escalation to department head
→ Executing immediately
✓ Escalated to department head: Ahmed Al-Farsi
✓ Escalated correctly
[Step 12] Final verification - explanation state
→ Executing immediately
✓ Explanation overdue and escalated correctly (is_used=False, is_overdue=True, escalated=True)
================================================================================
TEST SUMMARY
================================================================================
Total Steps: 12
Successful: 12
Failed: 0
Elapsed Time: 37.5s
✓✓✓ ALL TESTS PASSED ✓✓✓
================================================================================
✓ Scenario 2 completed successfully!
```
---
## Understanding the Test Results
### Success Indicators
✅ **Explanation Submitted**: Staff responded before deadline
✅ **No Escalation**: Workflow completed at staff level
✅ **Reminders Sent**: System sent timely reminders
✅ **Escalation Occurred**: System automatically escalated to manager
✅ **Multi-Level Escalation**: Escalation chain worked correctly
### Common Issues and Solutions
#### Issue: "Email failed to send"
**Cause**: Email service not configured
**Solution**:
- Check `.env` for email settings
- Use console backend for testing: `EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend`
#### Issue: "Escalation not triggered"
**Cause**: SLA configuration incorrect
**Solution**:
- Verify `auto_escalate_enabled=True`
- Check `response_hours` matches expected timing
- Ensure `escalation_hours_overdue` is set correctly
#### Issue: "Reminder not sent"
**Cause**: Reminder timing misconfiguration
**Solution**:
- Check `reminder_hours_before` in SLA config
- Verify `SecondReminderConfig` is enabled (for second reminder)
- Ensure sufficient time has passed
---
## Customizing Scenarios
### Adjust Time Compression
Modify the `time_compression_ratio` parameter:
```python
# 1 second = 1 hour (default)
test = Scenario1SuccessfulExplanation(time_compression_ratio=1)
# 1 second = 2 hours (faster testing)
test = Scenario1SuccessfulExplanation(time_compression_ratio=2)
# 1 second = 30 minutes (slower, more detailed)
test = Scenario1SuccessfulExplanation(time_compression_ratio=0.5)
```
### Change SLA Deadlines
Modify the SLA configuration in the test scripts:
```python
# In setup_environment()
self.create_explanation_sla_config(
hospital=hospital,
response_hours=24, # Change from 10 to 24 hours
reminder_hours_before=12, # Change from 5 to 12 hours
auto_escalate_enabled=True,
escalation_hours_overdue=0,
max_escalation_levels=3
)
```
### Test Different Severities
Create complaints with different severity/priority:
```python
# High severity, high priority
complaint = Complaint.objects.create(
hospital=hospital,
department=department,
staff=staff,
severity='high',
priority='high',
# ... other fields
)
# Low severity, low priority
complaint = Complaint.objects.create(
hospital=hospital,
department=department,
staff=staff,
severity='low',
priority='low',
# ... other fields
)
```
---
## Database Cleanup
After running tests, you may want to clean up test data:
```bash
# Delete test complaints and explanations
python manage.py shell
>>> from apps.complaints.models import Complaint, ComplaintExplanation
>>> Complaint.objects.filter(contact_name="Test Patient").delete()
>>> Complaint.objects.filter(contact_name="Concerned Family Member").delete()
# Delete test staff (be careful with real data!)
>>> from apps.organizations.models import Staff
>>> Staff.objects.filter(email__contains=".test").delete()
```
---
## Debugging Tips
### Enable Django Debug Mode
Make sure `DEBUG=True` in your settings to see detailed error messages.
### Check Celery Tasks
If Celery tasks aren't executing:
```bash
# Check if Celery worker is running
ps aux | grep celery
# Start Celery worker
celery -A config worker -l info
```
### Inspect Database State
```python
# Check explanation state
from apps.complaints.models import ComplaintExplanation
exp = ComplaintExplanation.objects.first()
print(f"is_used: {exp.is_used}")
print(f"is_overdue: {exp.is_overdue}")
print(f"sla_due_at: {exp.sla_due_at}")
print(f"escalated_to_manager: {exp.escalated_to_manager}")
```
### View Email Content
When using console email backend, emails will be printed to stdout. You can also check:
```python
from django.core.mail import outbox
print(len(outbox)) # Number of emails sent
print(outbox[0].subject) # Subject of first email
print(outbox[0].body) # Body of first email
```
---
## Next Steps
After successfully running the scenarios:
1. **Verify in Admin**: Check the Django admin interface to see the created complaints and explanations
2. **Review Emails**: Examine the email templates and content
3. **Test UI**: Manually test the complaint and explanation workflows in the web interface
4. **Customize Scenarios**: Modify the test scripts to match your specific use cases
5. **Integration Testing**: Run these tests as part of your CI/CD pipeline
---
## Support
For issues or questions:
- Check the logs in the `logs/` directory
- Review the SLA documentation in `docs/SLA_SYSTEM_OVERVIEW.md`
- Examine the Celery tasks in `apps/complaints/tasks.py`