Skip to content

fix(tests): stop leaking test values into developer keyring#615

Merged
Orinks merged 2 commits intodevfrom
fix/pirate-weather-api-key-storage
Apr 21, 2026
Merged

fix(tests): stop leaking test values into developer keyring#615
Orinks merged 2 commits intodevfrom
fix/pirate-weather-api-key-storage

Conversation

@Orinks
Copy link
Copy Markdown
Owner

@Orinks Orinks commented Apr 21, 2026

New AccessiWeather installs on a machine that had run the test suite showed secret_key pre-filled in the Pirate Weather provider field. The Settings dialog was fine — the developer's Windows Credential Manager actually contained the literal string secret_key under service accessiweather, username pirate_weather_api_key, and the production load path (LazySecureStorage → keyring) faithfully read it back on every new install.

The source was tests/test_settings_operations.py: test_redacted_logging called operations.update_settings(pirate_weather_api_key="secret_key") without patching SecureStorage.set_password, so every local pytest run committed secret_key to the real keyring. Its sibling test_update_secure_setting right above it already used @patch("accessiweather.config.settings.SecureStorage.set_password") — the redaction test was a copy-paste miss. Visual Crossing and OpenRouter escaped only because no equivalent unmocked test ever ran for them.

The existing autouse _mock_keyring_available fixture in tests/conftest.py faked the availability probe but never intercepted writes, so it offered no protection.

This PR fixes both layers:

  • Add the missing @patch("accessiweather.config.settings.SecureStorage.set_password") to test_redacted_logging.
  • Add an autouse _isolate_keyring_from_real_backend fixture in tests/conftest.py that swaps accessiweather.config.secure_storage._keyring_module with an in-memory fake for every test. Explicit @patch of _get_keyring or SecureStorage.*_password in individual tests still wins, so test_secure_storage.py, test_portable_secrets.py, and the startup-guidance suite keep passing unchanged.

Impact is limited to developers who ran the test suite locally. CI runners use ephemeral backends and end users never run these tests, so published installers and fresh user installs were never affected. The already-polluted pirate_weather_api_key (and an unrelated avwx_api_key with a pasted `gh pr checkout 480` string) were cleared from the developer's keyring during investigation.

Test plan

  • `pytest tests/test_settings_operations.py` — 38 pass, including the newly-patched `test_redacted_logging`.
  • `pytest tests/test_secure_storage.py tests/test_portable_secrets.py tests/test_settings_dialog_api_key_guard.py tests/test_config_manager.py tests/test_startup_guidance_prompts.py` — 95 pass, confirming the autouse fixture does not interfere with tests that explicitly patch `_get_keyring` or `SecureStorage`.
  • After both test runs, `keyring.get_password("accessiweather", "pirate_weather_api_key")` still returns `None` — the isolation holds.

Compound Engineering
Claude Code

Orinks added 2 commits April 20, 2026 20:02
test_redacted_logging was missing @patch for SecureStorage.set_password,
so every run wrote the literal string "secret_key" to the real system
keyring under pirate_weather_api_key — which then surfaced in the
Settings dialog on fresh installs.

Fix the immediate test and add an autouse conftest fixture that routes
SecureStorage through an in-memory fake keyring for all tests. Explicit
@patch of _get_keyring or SecureStorage.*_password in individual tests
still wins, so existing secure-storage tests pass unchanged.
@Orinks Orinks merged commit 736dcad into dev Apr 21, 2026
3 checks passed
@Orinks Orinks deleted the fix/pirate-weather-api-key-storage branch April 21, 2026 00:10
@Orinks Orinks mentioned this pull request Apr 21, 2026
Orinks added a commit that referenced this pull request Apr 21, 2026
Routine sync of `dev` into `main`. Includes:

- fix(tests): stop leaking test values into developer keyring
([#615](#615))
- feat(products): Forecast Products dialog + HWO/SPS notifications
([#613](#613))
- feat(zones): NWS zone metadata on saved locations
([#612](#612))
- chore: remove unused html_formatters module
- feat(ui): add preference for location buttons near dropdown
([#611](#611))

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant