Add test suite with mocked API, coverage CI and a pinned interpreter - #159
Open
LightD31 wants to merge 4 commits into
Open
Add test suite with mocked API, coverage CI and a pinned interpreter#159LightD31 wants to merge 4 commits into
LightD31 wants to merge 4 commits into
Conversation
This repository was started from a component template and some strings still name the components it was copied from: - pyproject.toml describes the project as the Google Home integration - the prettier pre-commit hook excludes custom_components/google_home/ manifest.json, a path that does not exist here, so glinet's manifest.json is not actually excluded - button.py and switch.py carry Pi-hole module and function docstrings No behaviour changes.
GLinetRouter dispatches signal_device_new when polling finds a client it has not seen before (router.py:368), but device_tracker.async_setup_entry never subscribed to it: it called update_router() once at setup and then nothing again. Devices that joined the network later got no tracker entity until the config entry was reloaded or Home Assistant restarted. Connect update_router to the signal, unsubscribing on unload.
…ations Bug fixes: - Fix sensor platform setup crash: the setup filter mutated the sensor list while iterating over it, and the uptime sensor raised KeyError when the router had not yet reported a system status (e.g. right after a router restart) - Fix interface type reporting: UNKNOWN2 duplicated UNKNOWN's enum value making it an alias excluded from list(), so integer interface types >= 8 were mislabelled and type 12 raised IndexError; replaced with an explicit int-to-member mapping with a safe fallback - Cancel the periodic polling timer on unload; previously every reload of the entry stacked another 30s polling loop - Register the config entry update listener so options changes actually apply; the options flow is slimmed down to consider_home only and no longer echoes credentials back to the user - Trigger the reauth flow from the polling loop; ConfigEntryAuthFailed raised inside a timer callback is not handled by Home Assistant - Log in once during setup instead of three times - Route tailscale_configured through the shared error handler so a timeout can no longer escape the update loop - Validate WireGuard client configs before building state and avoid logging their values (they contain private key material) - Remove duplicate wireguard_connections property, wrong @callback decorators on async methods and dead code New features: - Reauth flow: a changed router password can now be fixed from the UI instead of deleting and re-adding the integration - Reconfigure flow for changing host/username/password - Diagnostics support with credentials, MACs and SSIDs redacted Polish: - Entity names now use translation keys (display names unchanged) - Sensors, switches and the reboot button report unavailable while the router is unreachable (device trackers keep consider_home semantics) - Typed config entry (ConfigEntry[GLinetRouter]) and Platform enum - consider_home is stored in entry options for new entries, with fallback to entry data for existing ones (no migration needed) The manifest version is left alone so the release version stays the maintainer's call.
Adds the first tests to the repository (a README TODO item): 68 tests covering the config flow (user, DHCP, reauth, reconfigure, options), entry setup/unload, the router polling and error-recovery logic, all four entity platforms, diagnostics redaction and the adjust_mac utility. Overall coverage of custom_components/glinet is 93%. Test infrastructure: - pytest-homeassistant-custom-component pinned to 0.13.316, the release that pins homeassistant==2026.2.3 exactly and the last one supporting Python 3.13; it must be bumped in lockstep with homeassistant and homeassistant-stubs - gli4py added to the dev dependency group (matching the manifest pin) so the integration is importable in tests; the GLinet API client is mocked at the class seam in both router.py and config_flow.py - Canned API responses live in tests/const.py; every mocked API method carries a __name__ because the router's error handler logs it - Time-driven behavior (30s polling, consider_home aging, uptime smoothing) is tested with freezegun plus async_fire_time_changed - New tests.yml workflow runs pytest with coverage reporting on pushes and pull requests; mypy/pylint exclude tests/ for now The interpreter is pinned alongside: on a fresh runner uv picked Python 3.14 (the newest allowed by requires-python), where the locked homeassistant 2026.2.3 cannot even be imported (mashumaro fails to serialize RTCIceServer). A tracked .python-version file (previously gitignored) and a requires-python cap at <3.14 keep CI on the interpreter the lockfile was resolved for; both bounds should be raised together with the homeassistant pins above.
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.
Adds the first tests to the repository (a README TODO item): 68 tests, 93% coverage of
custom_components/glinet, covering the config flow (user, DHCP, reauth, reconfigure, options), entry setup/unload, the router polling and error-recovery logic, all four entity platforms, diagnostics redaction and theadjust_macutility.Test infrastructure
pytest-homeassistant-custom-componentpinned to 0.13.316 — the release that pinshomeassistant==2026.2.3exactly, and the last one supporting Python 3.13. It must be bumped in lockstep withhomeassistantandhomeassistant-stubsgli4pyadded to the dev dependency group (matching the manifest pin) so the integration is importable in tests; the GLinet API client is mocked at the class seam in bothrouter.pyandconfig_flow.pytests/const.py; every mocked API method carries a__name__because the router's error handler logs itconsider_homeaging, uptime smoothing) is tested with freezegun plusasync_fire_time_changedtests.ymlworkflow runs pytest with coverage on pushes and PRs; mypy/pylint excludetests/for nowPinned interpreter
On a fresh runner
uvpicked Python 3.14 (the newest allowed byrequires-python), where the lockedhomeassistant2026.2.3 cannot even be imported — mashumaro fails to serializeRTCIceServer. A tracked.python-versionfile (previously gitignored) and arequires-pythoncap at<3.14keep CI on the interpreter the lockfile was resolved for. Both bounds should be raised together with the homeassistant pins above.