Stub Twilio imports in phone call router tests#7798
Conversation
Greptile SummaryThis PR makes
Confidence Score: 4/5Safe to merge — only test infrastructure changes; no production code is modified. The Twilio stubs and autouse fixture correctly isolate the tests from external dependencies, and the 17 existing tests pass. The one gap is that the autouse fixture always presents a paid-user profile, so the free-tier call-counting branch in the TwiML webhook is never exercised and a regression there would not be caught by this suite. backend/tests/unit/test_phone_calls.py — specifically the autouse quota snapshot fixture and the absence of any free-tier twiml test. Important Files Changed
Sequence DiagramsequenceDiagram
participant pytest
participant test_phone_calls.py
participant sys.modules
participant routers.phone_calls
participant monkeypatch
Note over test_phone_calls.py: Module-level setup (collection time)
test_phone_calls.py->>sys.modules: setdefault('twilio', stub)
test_phone_calls.py->>sys.modules: setdefault('twilio.base.exceptions', stub + TwilioRestException)
test_phone_calls.py->>sys.modules: setdefault('twilio.twiml.voice_response', stub + VoiceResponse/Dial)
test_phone_calls.py->>sys.modules: setdefault('twilio.rest', stub + Client)
test_phone_calls.py->>sys.modules: setdefault('twilio.jwt.access_token.grants', stub + VoiceGrant)
test_phone_calls.py->>routers.phone_calls: import router (uses stubs above)
Note over pytest: Per-test setup
pytest->>monkeypatch: autouse _stub_phone_call_plan_guards
monkeypatch->>routers.phone_calls: patch check_call_access → MagicMock
monkeypatch->>routers.phone_calls: "patch get_quota_snapshot → has_access=True, is_paid=True"
monkeypatch->>routers.phone_calls: patch check_destination_allowed → MagicMock
pytest->>test_phone_calls.py: run test
test_phone_calls.py->>routers.phone_calls: HTTP request
routers.phone_calls-->>test_phone_calls.py: response
Note over pytest: Per-test teardown
monkeypatch->>routers.phone_calls: revert all 3 patches automatically
Reviews (1): Last reviewed commit: "test(backend): stub twilio phone call te..." | Re-trigger Greptile |
| @pytest.fixture(autouse=True) | ||
| def _stub_phone_call_plan_guards(monkeypatch): | ||
| monkeypatch.setattr('routers.phone_calls.check_call_access', MagicMock()) | ||
| monkeypatch.setattr( | ||
| 'routers.phone_calls.get_quota_snapshot', | ||
| MagicMock(return_value=SimpleNamespace(has_access=True, is_paid=True, max_duration_seconds=None)), | ||
| ) | ||
| monkeypatch.setattr('routers.phone_calls.check_destination_allowed', MagicMock()) |
There was a problem hiding this comment.
Free-tier usage increment path is silently bypassed
The autouse fixture sets is_paid=True on every test's quota snapshot. In the router, phone_call_usage_db.increment_current_month(uid) is only executed when not snapshot.is_paid (line 312 of phone_calls.py). Because is_paid is always True here, that branch is never reached, and phone_call_usage_db is never patched in any test — meaning a regression that drops the increment call would pass undetected. Consider adding at least one test (or a parameterized variant of test_twiml_success) that passes is_paid=False and asserts the counter is incremented.
There was a problem hiding this comment.
Addressed in f041b7027 by adding test_twiml_free_tier_counts_successful_call.
That test overrides the default paid quota snapshot with is_paid=False, patches phone_call_usage_db, posts a successful TwiML request, and asserts:
mock_usage_db.increment_current_month.assert_called_once_with(TEST_UID)Revalidated on the Windows backend venv:
python -m pytest tests\unit\test_phone_calls.py -q-> 18 passedpython -m black --line-length 120 --skip-string-normalization tests\unit\test_phone_calls.py --checkpython -m py_compile tests\unit\test_phone_calls.py
tianmind-studio
left a comment
There was a problem hiding this comment.
Addressed the free-tier coverage gap in the latest commit. The new TwiML test overrides the quota snapshot with is_paid=False, patches phone_call_usage_db, and asserts increment_current_month(TEST_UID) is called after all dialing guards pass. Re-ran test_phone_calls.py (18 passed) plus black, py_compile, and diff check.
Summary
test_phone_calls.py, coveringTwilioRestException,VoiceResponse,Dial, REST client, JWT token, grants, and request validator imports.Why
In this Windows minimal backend venv,
test_phone_calls.pyfailed during collection because the optional Twilio SDK is not installed. After stubbing Twilio imports, endpoint tests reached real phone-call access/quota guards and could hang on external database-backed paths.These tests already patch the router's Twilio service and database collaborators; keeping the remaining Twilio/plan guard surface local makes the file self-contained and runnable without installing Twilio or connecting to backend services. The follow-up free-tier test keeps the permissive default fixture while explicitly covering the usage-counting branch with
is_paid=False.Testing
python -m pytest tests\unit\test_phone_calls.py -q-> 18 passedpython -m black --line-length 120 --skip-string-normalization tests\unit\test_phone_calls.py --checkpython -m py_compile tests\unit\test_phone_calls.pygit diff --check -- backend/tests/unit/test_phone_calls.py