Spaces:
Running
Running
Download test_api.py from sihproject2007/oneNation: direct link, hf CLI and curl.
- Browser
- Download file 18 kB
-
https://huggingface.co/spaces/sihproject2007/oneNation/resolve/main/test_api.py
- Command line
-
hf download hf://spaces/sihproject2007/oneNation/test_api.py
-
curl -L -o test_api.py https://huggingface.co/spaces/sihproject2007/oneNation/resolve/main/test_api.py
18 kB
| """ | |
| DoctorKavach API Comprehensive Test Suite | |
| Validates all 5 functional modules using Flask's test client. | |
| """ | |
| import json | |
| from datetime import datetime | |
| from app import app, DB_PATH | |
| import db_setup | |
| def run_tests(): | |
| print("=" * 60) | |
| print(" RUNNING DOCTORKAVACH BACKEND API VERIFICATION SUITE") | |
| print("=" * 60) | |
| # Initialize and seed database | |
| db_setup.init_db(DB_PATH) | |
| db_setup.seed_database(DB_PATH) | |
| client = app.test_client() | |
| # ------------------------------------------------------------- | |
| # TEST 1: Health Check | |
| # ------------------------------------------------------------- | |
| res = client.get('/api/health') | |
| assert res.status_code == 200, f"Health check failed: {res.status_code}" | |
| data = res.get_json() | |
| assert data["status"] == "healthy" | |
| print("[PASS] 1. GET /api/health -- PASS (Status: Healthy, Doctors:", data["registered_doctors"], ")") | |
| # ------------------------------------------------------------- | |
| # TEST 2: Doctor Verification (Public Lookup) | |
| # ------------------------------------------------------------- | |
| # Valid NMC lookup | |
| res = client.get('/api/doctor/verify/NMC-2018-847291') | |
| assert res.status_code == 200 | |
| data = res.get_json() | |
| assert data["success"] is True | |
| assert data["doctor"]["verification_badge"] == "Verified Green Shield" | |
| assert data["doctor"]["clinic_establishment_license"] == "CEA-DL-2021-9921" | |
| print("[PASS] 2a. GET /api/doctor/verify/NMC-2018-847291 -- PASS (Verified Green Shield, CEA Verified)") | |
| # Fake/Unregistered lookup | |
| res = client.get('/api/doctor/verify/NMC-FAKE-000000') | |
| assert res.status_code == 404 | |
| data = res.get_json() | |
| assert "anti_quackery_warning" in data | |
| print("[PASS] 2b. GET /api/doctor/verify/NMC-FAKE-000000 -- PASS (Anti-Quackery Warning Triggered)") | |
| # ------------------------------------------------------------- | |
| # TEST 3: Doctor Registration & Audit | |
| # ------------------------------------------------------------- | |
| new_doc_payload = { | |
| "full_name": "Dr. Sneha Roy", | |
| "govt_id": "AADHAAR-5511-9922-3344", | |
| "nmc_reg_number": "NMC-2022-771122", | |
| "state_medical_council": "Delhi Medical Council", | |
| "degrees": "MBBS, MS (ENT)", | |
| "medical_college": "Lady Hardinge Medical College, New Delhi", | |
| "internship_hospital": "Safdarjung Hospital, New Delhi", | |
| "current_hospital_clinic": "Roy ENT Specialty Center, Saket, New Delhi", | |
| "clinic_establishment_license": "CEA-DL-2023-1122" | |
| } | |
| res = client.post('/api/doctor/register', json=new_doc_payload) | |
| assert res.status_code == 201 | |
| data = res.get_json() | |
| assert data["verification_badge"] == "Verified Green Shield" | |
| assert "clinic_qr_payload" in data | |
| print("[PASS] 3. POST /api/doctor/register -- PASS (Auto-Audit Verified & Clinic QR Generated)") | |
| # ------------------------------------------------------------- | |
| # TEST 4: Patient Registration & Offline Bundle | |
| # ------------------------------------------------------------- | |
| new_patient_payload = { | |
| "health_id": "ABHA-5544-3322-1100", | |
| "full_name": "Vikram Malhotra", | |
| "phone": "+91 98334 55667", | |
| "age": 34, | |
| "gender": "Male", | |
| "village_city": "Saket, New Delhi", | |
| "emergency_contact": "Sunita Malhotra (Spouse): +91 98334 55668" | |
| } | |
| res = client.post('/api/patient/register', json=new_patient_payload) | |
| assert res.status_code == 201 | |
| print("[PASS] 4a. POST /api/patient/register -- PASS (ABHA Enrolled)") | |
| # Retrieve offline bundle for seeded patient Riya Verma | |
| res = client.get('/api/patient/ABHA-9148-2910-4821/offline-bundle') | |
| assert res.status_code == 200 | |
| bundle = res.get_json()["offline_bundle"] | |
| assert len(bundle["active_prescriptions"]) > 0 | |
| assert "PENICILLIN" in bundle["critical_alerts"]["allergies"] | |
| print("[PASS] 4b. GET /api/patient/<health_id>/offline-bundle -- PASS (Active Meds:", len(bundle["active_prescriptions"]), "| Allergies:", bundle["critical_alerts"]["allergies"], ")") | |
| # ------------------------------------------------------------- | |
| # TEST 5: Consent Request (Doctor Switching Simulator) | |
| # ------------------------------------------------------------- | |
| res = client.post('/api/consent/request', json={ | |
| "patient_health_id": "ABHA-9148-2910-4821", | |
| "doctor_id": 2 # Dr. Priya Nair requesting access | |
| }) | |
| assert res.status_code == 201 | |
| data = res.get_json() | |
| consent_id = data["consent_id"] | |
| simulated_otp = data["notification_simulation"]["simulated_otp"] | |
| print(f"[PASS] 5. POST /api/consent/request -- PASS (Consent #{consent_id} Pending | OTP: {simulated_otp})") | |
| # ------------------------------------------------------------- | |
| # TEST 6: Consent Respond & 2-Hour Token Generation | |
| # ------------------------------------------------------------- | |
| res = client.post('/api/consent/respond', json={ | |
| "consent_id": consent_id, | |
| "decision": "APPROVED" | |
| }) | |
| assert res.status_code == 200 | |
| data = res.get_json() | |
| access_token = data["access_token"] | |
| assert access_token is not None | |
| print(f"[PASS] 6. POST /api/consent/respond -- PASS (Status: APPROVED | 2h Token: {access_token[:12]}...)") | |
| # ------------------------------------------------------------- | |
| # TEST 7: Patient History Access & Duplicate Test Prevention | |
| # ------------------------------------------------------------- | |
| # Unauthorized without token | |
| res = client.get('/api/patient/ABHA-9148-2910-4821/history') | |
| assert res.status_code in (401, 403) | |
| print(f"[PASS] 7a. GET /api/patient/<health_id>/history (No Token) -- PASS ({res.status_code} Access Blocked)") | |
| # Authorized with token | |
| res = client.get(f'/api/patient/ABHA-9148-2910-4821/history?token={access_token}') | |
| assert res.status_code == 200 | |
| data = res.get_json() | |
| assert len(data["clinical_timeline"]) > 0 | |
| assert len(data["duplicate_test_alerts"]) > 0 | |
| alert = data["duplicate_test_alerts"][0] | |
| assert alert["test_name"] == "Widal Tube Agglutination Test" | |
| assert alert["cost_saved_inr"] == 650 | |
| print(f"[PASS] 7b. GET /api/patient/<health_id>/history (With Token) -- PASS (Widal Duplicate Prevention Detected: INR {alert['cost_saved_inr']} Saved)") | |
| # ------------------------------------------------------------- | |
| # TEST 8: Clinical Visit Creation & 3-Day Refill Alert | |
| # ------------------------------------------------------------- | |
| visit_payload = { | |
| "patient_health_id": "ABHA-5544-3322-1100", | |
| "doctor_id": 1, | |
| "symptoms": "Acute pharyngitis with dry cough", | |
| "provisional_diagnosis": "Viral Upper Respiratory Tract Infection", | |
| "lab_tests_prescribed": "Throat Swab Culture", | |
| "lab_test_results": "Normal Flora", | |
| "recovery_status": "Improving", | |
| "recovery_percentage": 50, | |
| "efficacy_feedback": "Patient tolerated warm saline gargles and antiallergic well", | |
| "prescriptions": [ | |
| { | |
| "medicine_name": "Levocetirizine 5mg", | |
| "dosage": "5mg", | |
| "frequency_time": "10:00 PM (Bedtime)", | |
| "total_days": 5, | |
| "remaining_days": 2 # <= 3 days triggers refill alert! | |
| }, | |
| { | |
| "medicine_name": "Ambroxol Cough Syrup", | |
| "dosage": "10ml", | |
| "frequency_time": "TDS (Thrice Daily)", | |
| "total_days": 7, | |
| "remaining_days": 6 | |
| } | |
| ] | |
| } | |
| res = client.post('/api/visit/create', json=visit_payload) | |
| assert res.status_code == 201 | |
| data = res.get_json() | |
| assert len(data["refill_alerts_triggered"]) == 1 | |
| print("[PASS] 8. POST /api/visit/create -- PASS (Refill Alert Generated: 2 days Levocetirizine remaining)") | |
| # ------------------------------------------------------------- | |
| # TEST 9: Patient Outcome Feedback | |
| # ------------------------------------------------------------- | |
| res = client.post('/api/patient/feedback', json={ | |
| "patient_health_id": "ABHA-9148-2910-4821", | |
| "sentiment": "Yes", | |
| "notes": "Dawai se bukhar puri tarah utar gaya, koi allergy nahi hui" | |
| }) | |
| assert res.status_code == 200 | |
| print("[PASS] 9. POST /api/patient/feedback -- PASS (Efficacy & Side-Effect Feedback Synced)") | |
| # ------------------------------------------------------------- | |
| # TEST 10: Reminders & Daily Dosage Clocks | |
| # ------------------------------------------------------------- | |
| res = client.get('/api/patient/ABHA-9148-2910-4821/reminders') | |
| assert res.status_code == 200 | |
| data = res.get_json() | |
| assert len(data["dosage_clock"]) > 0 | |
| assert len(data["refill_alerts"]) > 0 | |
| reminder_id = data["dosage_clock"][0]["reminder_id"] | |
| print(f"[PASS] 10a. GET /api/patient/<health_id>/reminders -- PASS (Dosages: {len(data['dosage_clock'])}, Refill Alerts: {len(data['refill_alerts'])})") | |
| # ------------------------------------------------------------- | |
| # TEST 11: Multi-Role RBAC Authentication | |
| # ------------------------------------------------------------- | |
| # Doctor login | |
| res = client.post('/api/auth/login', json={"role": "doctor", "nmc_reg_number": "NMC-2018-847291", "password": "doctor123"}) | |
| assert res.status_code == 200, f"Doctor login failed: {res.status_code}" | |
| assert res.get_json()["role"] == "doctor" | |
| # Patient login | |
| res = client.post('/api/auth/login', json={"role": "patient", "identifier": "ABHA-9148-2910-4821"}) | |
| assert res.status_code == 200 | |
| assert res.get_json()["role"] == "patient" | |
| # Hospital admin login | |
| res = client.post('/api/auth/login', json={"role": "hospital", "cea_license": "CEA-DL-2021-9921", "admin_id": "ADMIN-SHARMA-01", "password": "admin123"}) | |
| assert res.status_code == 200 | |
| assert res.get_json()["role"] == "hospital" | |
| # Govt regulator login | |
| res = client.post('/api/auth/login', json={"role": "govt", "regulator_id": "GMO-DELHI-001", "password": "govt123"}) | |
| assert res.status_code == 200 | |
| assert res.get_json()["role"] == "govt" | |
| print("[PASS] 11. POST /api/auth/login -- PASS (4 Portals: Doctor, Patient, Hospital, Govt Verified)") | |
| # ------------------------------------------------------------- | |
| # TEST 12: Dual-Mode Smart Diet & Nutrition Engine | |
| # ------------------------------------------------------------- | |
| res = client.get('/api/diets/templates') | |
| assert res.status_code == 200 | |
| templates = res.get_json()["templates"] | |
| assert len(templates) >= 6 | |
| # Lookup Typhoid preset | |
| res = client.get('/api/diets/lookup/Typhoid') | |
| assert res.status_code == 200 | |
| diet = res.get_json()["diet"] | |
| assert "Boiled water" in diet["default_allowed"] | |
| assert "Deep-fried" in diet["default_restricted"] | |
| print(f"[PASS] 12. GET /api/diets/templates & lookup/Typhoid -- PASS ({len(templates)} Presets Loaded, Dietary Rules Found)") | |
| # ------------------------------------------------------------- | |
| # TEST 13: Live OPD Queue & Triage Pipeline | |
| # ------------------------------------------------------------- | |
| # 13a. Hospital Reception allocates token | |
| token_payload = { | |
| "patient_health_id": "ABHA-9148-2910-4821", | |
| "doctor_id": 1, | |
| "hospital_id": 1, | |
| "opd_counter": "OPD Counter 2", | |
| "priority": "URGENT", | |
| "vitals_bp": "120/80 mmHg", | |
| "vitals_pulse": 78, | |
| "vitals_temp": 99.1, | |
| "vitals_spo2": 99 | |
| } | |
| res = client.post('/api/queue/token/allocate', json=token_payload) | |
| assert res.status_code == 201 | |
| q_data = res.get_json() | |
| new_token_display = q_data["token_display"] | |
| new_queue_id = q_data["queue_id"] | |
| assert q_data["status"] == "WAITING" | |
| print(f"[PASS] 13a. POST /api/queue/token/allocate -- PASS (Allocated {new_token_display} for Dr. Sharma, Priority: URGENT)") | |
| # 13b. Doctor views waiting room | |
| res = client.get('/api/queue/doctor/1') | |
| assert res.status_code == 200 | |
| w_data = res.get_json() | |
| assert len(w_data["waiting_room"]) > 0 | |
| # 13c. Doctor calls next patient | |
| res = client.post('/api/queue/call-next', json={"doctor_id": 1, "queue_id": new_queue_id}) | |
| assert res.status_code == 200 | |
| call_data = res.get_json() | |
| assert call_data["consultation_patient"]["status"] == "IN_CONSULTATION" | |
| print(f"[PASS] 13b. POST /api/queue/call-next -- PASS (Patient Called into Consultation Desk)") | |
| # 13d. Complete consultation | |
| res = client.post('/api/queue/complete', json={"queue_id": new_queue_id}) | |
| assert res.status_code == 200 | |
| assert res.get_json()["status"] == "COMPLETED" | |
| print("[PASS] 13c. POST /api/queue/complete -- PASS (OPD Case Moved to Completed Queue)") | |
| # ------------------------------------------------------------- | |
| # TEST 14: Multi-Entity Audit Trail & Customized Diet Visit | |
| # ------------------------------------------------------------- | |
| audit_visit_payload = { | |
| "patient_health_id": "ABHA-9148-2910-4821", | |
| "doctor_id": 1, | |
| "hospital_id": 1, | |
| "hospital_name": "Sharma Health Clinic & Diagnostics", | |
| "doctor_name": "Dr. Arun Kumar Sharma", | |
| "specialization": "General Medicine & Diabetology", | |
| "symptoms": "Post-typhoid follow-up checkup", | |
| "provisional_diagnosis": "Convalescent Typhoid Recovery Phase", | |
| "treatments_performed": "Physical examination, Vitals evaluation, Dietary counseling", | |
| "tests_ordered": "CBC follow-up", | |
| "custom_diet_prescription": "ALLOWED: High protein khichdi, boiled eggs | RESTRICTED: Chillies, street food", | |
| "recovery_status": "Improving", | |
| "recovery_percentage": 90, | |
| "prescriptions": [ | |
| { | |
| "medicine_name": "B-Complex with Zinc", | |
| "dosage": "1 Capsule", | |
| "frequency_time": "02:00 PM (After Lunch)", | |
| "total_days": 10, | |
| "remaining_days": 10 | |
| } | |
| ] | |
| } | |
| res = client.post('/api/visit/create', json=audit_visit_payload) | |
| assert res.status_code == 201 | |
| audit_res = res.get_json() | |
| assert "audit_card_summary" in audit_res | |
| print(f"[PASS] 14a. POST /api/visit/create with Multi-Entity Audit -- PASS ({audit_res['audit_card_summary']})") | |
| # Verify history rendering multi-entity audit trail card | |
| res = client.get(f'/api/patient/ABHA-9148-2910-4821/history?token={access_token}') | |
| assert res.status_code == 200 | |
| latest_visit = res.get_json()["clinical_timeline"][0] | |
| assert "Treated on" in latest_visit["audit_trail_card"] | |
| assert "Dr. Arun Kumar Sharma" in latest_visit["audit_trail_card"] | |
| assert "Sharma Health Clinic" in latest_visit["audit_trail_card"] | |
| print(f"[PASS] 14b. Multi-Entity Timeline Card Verified: '{latest_visit['audit_trail_card'][:80]}...'") | |
| # ------------------------------------------------------------- | |
| # TEST 15: Dual-Feedback & Reputation Engine | |
| # ------------------------------------------------------------- | |
| feedback_payload = { | |
| "patient_health_id": "ABHA-9148-2910-4821", | |
| "doctor_id": 1, | |
| "hospital_id": 1, | |
| "visit_id": audit_res["visit_id"], | |
| "doctor_rating": 5, | |
| "doctor_review": "Exceptional diagnosis and patient care. Explained recovery diet clearly.", | |
| "hospital_rating": 5, | |
| "hospital_hygiene_facility_review": "Clean OPD chambers, spotless waiting lounge, very courteous staff." | |
| } | |
| res = client.post('/api/feedback/submit', json=feedback_payload) | |
| assert res.status_code == 201 | |
| f_data = res.get_json() | |
| assert f_data["doctor_rating"] == 5 | |
| assert f_data["hospital_rating"] == 5 | |
| # Check doctor feedback aggregation | |
| res = client.get('/api/feedback/doctor/1') | |
| assert res.status_code == 200 | |
| assert res.get_json()["average_rating"] >= 4.0 | |
| # Check hospital feedback aggregation | |
| res = client.get('/api/feedback/hospital/1') | |
| assert res.status_code == 200 | |
| assert res.get_json()["average_rating"] >= 4.0 | |
| print("[PASS] 15. POST /api/feedback/submit & GET /api/feedback/* -- PASS (Dual Rating & Independent Aggregations Verified)") | |
| # ------------------------------------------------------------- | |
| # TEST 16: Central Government / Regulator Command Dashboard | |
| # ------------------------------------------------------------- | |
| # 16a. Regional analytics | |
| res = client.get('/api/admin/govt-dashboard/analytics') | |
| assert res.status_code == 200 | |
| analytics = res.get_json()["analytics"] | |
| assert analytics["total_doctors"] >= 3 | |
| assert analytics["total_beds"] > 0 | |
| assert "daily_opd_footfall" in analytics | |
| # 16b. Quack / Fraud 1-click verify & revoke | |
| # Revoke Dr. 1 | |
| res = client.post('/api/admin/doctor/1/verify', json={"action": "revoke"}) | |
| assert res.status_code == 200 | |
| assert res.get_json()["verification_badge"] == "Rejected" | |
| # Re-grant Verified Green Shield | |
| res = client.post('/api/admin/doctor/1/verify', json={"action": "grant"}) | |
| assert res.status_code == 200 | |
| assert res.get_json()["verification_badge"] == "Verified Green Shield" | |
| # 16c. Doctor-Hospital Affiliation | |
| res = client.post('/api/admin/affiliations/assign', json={ | |
| "doctor_id": 2, | |
| "hospital_id": 2, | |
| "department": "Interventional Cardiology", | |
| "opd_room": "Cardiac OPD 3" | |
| }) | |
| assert res.status_code == 201 | |
| assert "affiliation_id" in res.get_json() | |
| res = client.get('/api/admin/affiliations') | |
| assert res.status_code == 200 | |
| assert len(res.get_json()["affiliations"]) >= 4 | |
| print("[PASS] 16. Central Government / Regulator API -- PASS (Regional Analytics, 1-Click Revocation/Shield, Affiliation Mapping)") | |
| print("=" * 60) | |
| print(" ALL 16 COMPREHENSIVE BACKEND API TESTS PASSED WITH 100% INTEGRITY") | |
| print("=" * 60) | |
| if __name__ == '__main__': | |
| run_tests() | |