Fix ETTN creation on live Checkbox

- prepayment as DISCOUNT: live API rejects PRE_PAYMENT with 400 third_party.generic
- normalize lowercase ETTN statuses returned by the live API
- show Checkbox error code instead of bare 'Internal Server Error'
- page size 50 for ETTN list, 429 rate limit is retryable, pause polling on it
- phone in 380XXXXXXXXX format like portal receipts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-24 13:49:50 +03:00
co-authored by Claude Opus 5.5
parent 912a37c00c
commit 3a6ad85d11
7 changed files with 73 additions and 26 deletions
+32
View File
@@ -148,3 +148,35 @@ async def test_bad_pin_raises() -> None:
)
with pytest.raises(CheckboxError, match="Невірний пін-код"):
await _client().sign_in(CREDS)
@respx.mock
async def test_lowercase_status_from_live_api_is_normalized() -> None:
_signin()
respx.get(f"{BASE}/api/v1/ettn/e-1").mock(
return_value=Response(200, json={**ETTN, "status": "done"})
)
ettn = await _client().get_ettn(CREDS, "e-1")
assert ettn.status == "DONE"
@respx.mock
async def test_third_party_error_code_is_shown() -> None:
_signin()
respx.post(f"{BASE}/api/v1/ettn").mock(
return_value=Response(
400, json={"code": "third_party.generic", "message": "Internal Server Error"}
)
)
with pytest.raises(CheckboxError, match=r"third_party\.generic"):
await _client().create_ettn(CREDS, {})
@respx.mock
async def test_rate_limit_is_retryable() -> None:
_signin()
respx.post(f"{BASE}/api/v1/ettn").mock(
return_value=Response(429, json={"message": "Занадто часто виконуються запити"})
)
with pytest.raises(CheckboxUnavailableError):
await _client().create_ettn(CREDS, {})