fix: resolve comprehensive review findings (security, concurrency, perf, Android, UI)
Multi-dimension review of v0.8.2. Excludes the deliberately deferred default_config.yaml weak-default-key item (C1). Backend: - calibration: create_default_calibration no longer exceeds led_count for small odd counts (bounded trim + regression test) - game-integration: generic webhook now requires auth_token; constant-time compare_digest in all adapters; per-IP failed-auth rate limit on the ingest route; auth_token encrypted at rest via secret_box (migration-safe) - playlist engine: serialize _state/_task under the lifecycle lock to close a delete-mid-play race (+ concurrency tests) - main: stop the calibration session on shutdown (restore prior target) - home_assistant: validate HA host via the LAN classifier on create/update - perf: drop slow preview-WS clients instead of blocking the send loop; cache composite full-strip resize linspaces; effect_stream lava reuses scratch Frontend: - setup/auto-calibration wizard: guard _state after awaits (cancel-safe), await session teardown before output start, busy-gate skip-calibration, manual display input keeps focus, move focus on step change - calibration: destroy EntitySelect on modal close - color-strips test: dirty-flag-gated render + cached ctx/ImageData - a11y/TV: focus-visible for new wizard/auto-cal/corner controls, aria-labels on the spatial corner/edge picker; theme-aware syntax tokens; dead/undefined CSS tokens removed; .modal-error styled; i18n titles (en/ru/zh) Android: - ApiKeyManager: EncryptedSharedPreferences with verified, data-safe legacy migration that never rotates an existing key - CaptureService: validate MediaProjection token before promoting; satisfy the startForeground 5s contract on the bail path - NotificationListener: connection-scoped executor with lazy fallback - BLE: request BLUETOOTH_SCAN/CONNECT at runtime + guard handler-thread SecurityExceptions - Root: cancellation-aware su grant probe Adds 14 tests. Gate: ruff + tsc 5.9.3 + esbuild + pytest (2185 passed) + compileDebugKotlin all green.
This commit is contained in:
@@ -291,6 +291,22 @@ def test_create_default_calibration_small_count():
|
||||
assert config.get_total_leds() == 4
|
||||
|
||||
|
||||
@pytest.mark.parametrize("led_count", [4, 5, 6, 7, 9, 11, 13, 60, 144, 300])
|
||||
def test_create_default_calibration_total_matches_count(led_count):
|
||||
"""Total LED count must equal led_count exactly, with every edge >= 1.
|
||||
|
||||
Regression for small odd counts where the per-edge max(1, ...) floor used
|
||||
to push the total above led_count (e.g. led_count=5 produced a total of 6).
|
||||
"""
|
||||
config = create_default_calibration(led_count)
|
||||
|
||||
assert config.get_total_leds() == led_count
|
||||
assert config.leds_top >= 1
|
||||
assert config.leds_right >= 1
|
||||
assert config.leds_bottom >= 1
|
||||
assert config.leds_left >= 1
|
||||
|
||||
|
||||
def test_create_default_calibration_invalid():
|
||||
"""Test default calibration with invalid LED count."""
|
||||
with pytest.raises(ValueError):
|
||||
|
||||
Reference in New Issue
Block a user