Fix/issue 392 retry transient#3
Merged
Merged
Conversation
api.py previously had only a single integration test that requires live login, leaving the core logic effectively uncovered offline. This adds a fake aiohttp ClientSession and exercises the pure logic and request machinery without credentials or network: - request() status handling: 200 JSON, 204 bytes, invalid JSON, error status codes, 500 GET retry-to-exhaustion vs 500 POST immediate raise, 401 -> token refresh -> retry - _request_worker retry/backoff: connection errors and timeouts retried then surfaced as RequestConnectionError / RequestTimeoutError - state_to_attrs: keydict mapping, Value/ValueAsString precedence, missing key/value skipping, excludes, duplicate-last-wins - set_attributes: ATTR_TYPES conversion, snake_case keys, conversion-failure fallback, update-in-place - is_command_valid: all resume/stop branches (incl. a characterization test for the int(None) issue flagged for the Phase 3 correctness cleanup) - stream_update routing: matching charger, unknown/missing/zero-guid ids - Zaptec mapping + poll dispatch: register/contains/qual_id, poll dispatch and unknown-object error Tests are self-contained (no live-constants fixture) so they run under SKIP_ZAPTEC_API_TEST and in CI. Lint-clean under the repo's ruff config. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Follows up the initial offline suite with the cheap, high-value cases, raising api.py statement coverage from ~50% to ~66%: - command(): named id, numeric id, authorize_charge alias, unknown-command error - charger settings wrappers: set_settings (valid + unknown-key), authorize_ charge, set_permanent_cable_lock, set_hmi_brightness (URL + payload) - installation current setters: set_limit_current (availableCurrent, missing-arg, partial-phase, out-of-range) and set_three_to_one_phase_switch_current (valid + out-of-range) - Charger.poll_info (happy, 403 -> charger-list fallback, non-403 re-raise) and poll_state (happy, 403 ignored) - Installation.poll_info SupportGroup logo stripping - login()/_refresh_token: token stored and sent on later requests; 400 -> AuthenticationError - small accessors/lifecycle: is_charging, model/model_prefix, Zaptec objects/installations/chargers/iter/len, async context manager Payload validation is bypassed in the poll tests (it has its own test module). build()/streaming/poll_firmware remain uncovered and are better tested alongside the Phase 2 typed-model work. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The token/OAuth request and every other API call previously raised on the first transient HTTP error: the retry loop in _request_worker only re-tried TimeoutError/ClientConnectionError, and _refresh_token raised immediately on any non-200/400 status. A single 503 from api.zaptec.com on the token POST was therefore fatal (issue custom-components#392). Treat 429/502/503/504 as retryable in _request_worker for all methods, using the existing exponential backoff and honoring a Retry-After header when present. On the final attempt the response is still yielded so the caller raises its normal RequestError(status). This covers both _refresh_token and request() from one place. The existing 500-on-GET-only behavior is unchanged, so non-idempotent POST/PUT are never double-executed on a 500. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
) A transient RequestError during setup login was mapped to ConfigEntryError, which Home Assistant treats as permanent (no auto-retry) -- so a 503 on the token endpoint required a full HA restart to recover. Extract _config_entry_error(), which maps authentication failures to ConfigEntryAuthFailed and connection/timeout errors plus transient server statuses (429/502/503/504) to ConfigEntryNotReady, letting HA retry setup automatically. All other API errors remain permanent ConfigEntryError. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Satisfies the new enforcing ruff check CI step (excludes api.py): D209 in _config_entry_error's docstring and PLR2004 magic values (2, 2.0) in the transient-retry offline tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.