#!/usr/bin/env python """ Test script to verify survey can be accessed multiple times until submission. Tests: 1. Survey can be opened multiple times 2. Survey shows error after completion 3. Survey shows error after token expiry """ import os import sys import django # Setup Django os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'PX360.settings') sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) django.setup() from django.test import Client from django.utils import timezone from datetime import timedelta from apps.surveys.models import SurveyInstance, SurveyTemplate from apps.patients.models import Patient from apps.hospitals.models import Hospital import uuid def print_header(text): """Print formatted header""" print("\n" + "="*70) print(f" {text}") print("="*70 + "\n") def print_success(text): """Print success message""" print(f"✓ {text}") def print_error(text): """Print error message""" print(f"✗ {text}") def test_multiple_access(): """Test that survey can be accessed multiple times""" print_header("TEST 1: Multiple Survey Access") # Get or create test data patient = Patient.objects.first() hospital = Hospital.objects.first() template = SurveyTemplate.objects.filter(is_active=True).first() if not all([patient, hospital, template]): print_error("Missing required test data (patient, hospital, or template)") return False # Create test survey survey = SurveyInstance.objects.create( survey_template=template, patient=patient, hospital=hospital, status='sent', sent_at=timezone.now(), token_expires_at=timezone.now() + timedelta(days=2), access_token=uuid.uuid4().hex ) print(f"Created test survey: {survey.survey_template.name}") print(f"Access token: {survey.access_token}") print(f"Initial status: {survey.status}") client = Client() # Access survey first time print("\n1. First access...") response = client.get(f'/surveys/s/{survey.access_token}/') if response.status_code == 200: print_success(f"First access successful (200)") else: print_error(f"First access failed ({response.status_code})") survey.delete() return False survey.refresh_from_db() print(f" Status after first access: {survey.status}") print(f" Open count: {survey.open_count}") # Access survey second time (refresh) print("\n2. Second access (refresh)...") response = client.get(f'/surveys/s/{survey.access_token}/') if response.status_code == 200: print_success(f"Second access successful (200)") else: print_error(f"Second access failed ({response.status_code})") survey.delete() return False survey.refresh_from_db() print(f" Status after second access: {survey.status}") print(f" Open count: {survey.open_count}") # Access survey third time print("\n3. Third access...") response = client.get(f'/surveys/s/{survey.access_token}/') if response.status_code == 200: print_success(f"Third access successful (200)") else: print_error(f"Third access failed ({response.status_code})") survey.delete() return False survey.refresh_from_db() print(f" Status after third access: {survey.status}") print(f" Open count: {survey.open_count}") # Verify open count increased if survey.open_count == 3: print_success(f"Open count correctly tracked: {survey.open_count}") else: print_error(f"Open count incorrect: {survey.open_count} (expected 3)") survey.delete() return False # Clean up survey.delete() print_success("Test survey cleaned up") return True def test_access_after_completion(): """Test that survey cannot be accessed after completion""" print_header("TEST 2: Access After Completion") # Get or create test data patient = Patient.objects.first() hospital = Hospital.objects.first() template = SurveyTemplate.objects.filter(is_active=True).first() if not all([patient, hospital, template]): print_error("Missing required test data") return False # Create and complete test survey survey = SurveyInstance.objects.create( survey_template=template, patient=patient, hospital=hospital, status='completed', sent_at=timezone.now(), opened_at=timezone.now(), completed_at=timezone.now(), token_expires_at=timezone.now() + timedelta(days=2), access_token=uuid.uuid4().hex ) print(f"Created completed survey") print(f"Status: {survey.status}") client = Client() # Try to access completed survey print("\nAttempting to access completed survey...") response = client.get(f'/surveys/s/{survey.access_token}/') if response.status_code == 200: print_error("Should not be able to access completed survey (200)") survey.delete() return False elif response.status_code == 404: print_success("Correctly rejected access to completed survey (404)") else: print_error(f"Unexpected status code: {response.status_code}") survey.delete() return False # Clean up survey.delete() print_success("Test survey cleaned up") return True def test_access_after_expiry(): """Test that survey cannot be accessed after token expiry""" print_header("TEST 3: Access After Token Expiry") # Get or create test data patient = Patient.objects.first() hospital = Hospital.objects.first() template = SurveyTemplate.objects.filter(is_active=True).first() if not all([patient, hospital, template]): print_error("Missing required test data") return False # Create expired survey now = timezone.now() survey = SurveyInstance.objects.create( survey_template=template, patient=patient, hospital=hospital, status='sent', sent_at=now - timedelta(days=3), token_expires_at=now - timedelta(hours=1), # Expired 1 hour ago access_token=uuid.uuid4().hex ) print(f"Created expired survey") print(f"Token expired at: {survey.token_expires_at}") print(f"Current time: {now}") client = Client() # Try to access expired survey print("\nAttempting to access expired survey...") response = client.get(f'/surveys/s/{survey.access_token}/') if response.status_code == 200: print_error("Should not be able to access expired survey (200)") survey.delete() return False else: print_success(f"Correctly rejected access to expired survey ({response.status_code})") # Clean up survey.delete() print_success("Test survey cleaned up") return True def main(): """Run all tests""" print_header("Survey Multiple Access Test Suite") print("This script verifies that:") print(" 1. Survey can be accessed multiple times until submission") print(" 2. Survey cannot be accessed after completion") print(" 3. Survey cannot be accessed after token expiry (2 days)") results = [] try: # Test 1: Multiple access results.append(('Multiple Access', test_multiple_access())) # Test 2: Access after completion results.append(('Access After Completion', test_access_after_completion())) # Test 3: Access after expiry results.append(('Access After Expiry', test_access_after_expiry())) except Exception as e: print_error(f"Test failed with error: {str(e)}") import traceback traceback.print_exc() # Print summary print_header("Test Summary") passed = sum(1 for _, result in results if result) total = len(results) for test_name, result in results: status = "✓ PASS" if result else "✗ FAIL" print(f"{status}: {test_name}") print(f"\nTotal: {passed}/{total} tests passed") if passed == total: print_success("All tests passed!") return 0 else: print_error(f"{total - passed} test(s) failed") return 1 if __name__ == '__main__': sys.exit(main())