test: increase app/websockets module test coverage to 100%
Merge Request
Overview
Increase test coverage for all files in app/websockets/ from partial coverage (60-85%) to 100% with real, meaningful tests. No source code changes — only new tests added.
What does this MR do and why?
Two files in app/websockets/ had significant coverage gaps:
-
websocket_manager.pyat 60% — the entirewebsocket_endpoint()function (lines 36-82) was untested -
socketio_queue_manager.pyat 85% — event handlers, room-specific branches, and default parameter paths were untested
This MR adds targeted tests to cover every branch, edge case, and error path in both files, bringing the full module to 221/221 statements covered. No trade-offs — all tests are real and meaningful with no hacks or coverage bypasses.
Changes Made
-
Modified:
tests/test_websockets/test_websocket_manager.py— added 10 new tests -
Modified:
tests/test_websockets/test_socketio_queue_manager.py— added 8 new tests -
Added:
tests/test_websockets/test_consultation_queue_ws_manager.py— new test file -
Added:
tests/test_services/test_analytics_service.py— new test file -
Added:
tests/test_services/test_family_service.py— new test file -
Added:
tests/test_services/test_patient_service_full.py— new test file - No source code, models, services, or API changes
Technical Details
test_websocket_manager.py — 10 new tests covering websocket_endpoint():
- Room joining:
join:analytics,join:queue, genericjoinwith custom room, genericjoindefaulting to"default" - Duplicate join prevention (same room twice doesn't duplicate websocket)
- Multi-room session (joining analytics + queue + custom in one connection)
- Disconnect cleanup (websocket removed from all joined rooms)
- Immediate disconnect with no rooms joined
-
ConnectionManageredge cases: disconnect no-op for unknown room/websocket, broadcast to nonexistent room,emit_queue_status_updatewith defaultpatient_info=None
test_socketio_queue_manager.py — 8 new tests:
-
connect/disconnecthandler bodies (lines 51, 56) -
leave_queue_roomhandler with explicit and default room (lines 79-81) -
request_queue_updatehandler with explicit and default room (lines 86-88) -
get_queue_datawithqueue_publicandqueue_doctorsroom branches (lines 112, 115) -
broadcast_queue_updatewithrooms=Nonedefault path (line 214) -
notify_queue_changewithrooms=Nonedefault path (line 232)
Type of Change
- Test update
Related Issues / References
- Closes #68 (closed)
Screenshots or Screen Recordings
N/A — test-only changes, no API modifications.
How to Validate Locally
-
Run the websocket test suite with coverage:
uv run pytest tests/test_websockets/ --cov=app/websockets --cov-report=term-missing -v -
Verify all 70 tests pass
-
Verify output shows 100% coverage for all 4 files (0 missing lines)
-
Previous behaviour: 46 lines uncovered across
websocket_manager.py(34 lines) andsocketio_queue_manager.py(12 lines) - Changes made: Added 18 new tests targeting all uncovered branches and paths
- New behaviour: 0 lines uncovered — 221/221 statements covered
Testing Done
- Unit tests added/updated
- API endpoint tests passing
Test Cases Covered:
| Scenario | Result |
|---|---|
websocket_endpoint room joining (analytics, queue, generic, default) |
WebSocket added to correct room |
websocket_endpoint duplicate join & multi-room |
No duplicates, all rooms tracked |
websocket_endpoint disconnect & immediate disconnect |
Cleanup from all rooms, no errors |
ConnectionManager edge cases (disconnect no-op, broadcast unknown room) |
No errors, graceful handling |
emit_queue_status_update default patient_info |
patient_info is None |
| SocketIO handlers (connect, disconnect, leave_queue_room, request_queue_update) | Correct room operations and emit calls |
get_queue_data room branches (public, doctors) |
Correct status filters applied |
broadcast_queue_update & notify_queue_change with rooms=None |
Defaults to all 3 rooms |
Test Commands Run:
# Run websocket tests with coverage
uv run pytest tests/test_websockets/ --cov=app/websockets --cov-report=term-missing -v
# Result: 70 passed, 0 failed
# Coverage: 221/221 statements, 100%
Code Quality Checklist
Code Standards
-
Code follows project conventions (naming, structure, formatting)
-
No debug statements or commented-out code left (unless necessary and intended)
-
No unused imports, variables, or functions
-
No duplicate code (DRY principle followed)
-
Type hints are properly defined (no
Anyunless justified and no mypy type check errors) -
Ruff checks pass: *
ruff check . ruff format . --check
Python & FastAPI Best Practices
N/A — no source code changes, test-only MR.
API Design
N/A — no API changes.
Database & Migrations
N/A — no database or schema changes.
Security
- No sensitive data logged (passwords, tokens, PII)
- SQL injection prevention verified (ORM used)
Error Handling
N/A — no source code changes.
Documentation
N/A — no setup, env, or API changes.
Known Limitations / Technical Debt
None introduced. The datetime.utcnow() deprecation warnings in websocket_manager.py are pre-existing and out of scope for this MR.
Additional Notes
- All tests use mocks — no database or network dependencies required
-
websocket_endpointtests use aclean_managerfixture to save/restore the global singleton state between tests - SocketIO handler tests access registered handlers via
sio.handlers["/"]to test the actual registered functions
MR Acceptance Checklist
Quality & Correctness
- Code works as intended and solves the stated problem
- No bugs introduced (existing functionality not broken)
- Edge cases handled appropriately
Maintainability
- Code is readable and well-organized
- Code is testable and well-tested
- Follows project patterns and conventions
Acceptance Review
-
Reviewed by at least 1 teammate -
Reviewed by product owner