Group 7: tests — 94 passing in 0.57s (53/53 + 9.4 deferred)

Test infrastructure:
- Add `pytest-homeassistant-custom-component` (PHACC) as a `test`
  dependency group. PHACC ships `hass`, `enable_custom_integrations`,
  `MockConfigEntry`, and friends without needing to clone HA core as a
  sibling directory. Modernizes the test setup from upstream's
  `setup-symlinks` pattern.
- conftest.py: add `auto_enable_custom_integrations` autouse fixture
  so HA discovers the integration under `custom_components/` during
  tests. Keep the upstream template-deprecation no-op.
- Import paths: all tests now import from `custom_components.adaptive_lighting`
  (not `homeassistant.components.adaptive_lighting`) and from
  `pytest_homeassistant_custom_component.common` (not `tests.common`).

New tests (groups 7.2-7.16):
- tests/test_color_and_brightness.py (16 tests): TestBrightnessCurve
  asserts min-before-sunrise, midpoint-at-event, max-during-day, sunset
  ramp symmetry. TestColorTempCurve verifies the same shape applies to
  K. TestSunPosition checks the synthetic +1/-1/0 derivation.
  TestTanhDayCurveDirect exercises the helper directly.
- tests/test_config_flow.py (12 tests): six sections in order, each
  section contains only its specified fields, conditional visibility
  of send_split_delay, default sun entities, strict-typed entity
  selectors, NumberSelector slider/box configs, BooleanSelector for
  every flag, full user→create-entry flow, YAML-managed entry aborts
  with `yaml_managed` reason, options flow renders the sectioned schema.
- tests/test_init.py (6 tests): successful setup on current version,
  stale version raises ConfigEntryError via async_migrate_entry,
  unload is clean, tombstone removes orphan sleep entity + logs INFO,
  tombstone is idempotent, tombstone respects config_entry ownership.

Source modernizations driven by the tests:
- __init__.py: add `async_migrate_entry` that surfaces the
  "incompatible — delete and recreate" message and sets the entry to
  MIGRATION_ERROR. Removed direct `ConfigEntryError` from
  `async_setup_entry` (HA routes version mismatches through the
  migration handler now).
- switch.py: removed upstream's YAML-managed-entry auto-remove hack.
  YAML profiles now load normally and the options flow handles the
  "you must edit configuration.yaml" message (spec R7).

Existing tests updated to PHACC paths: test_adaptation_utils.py
(38 tests), test_hass_utils.py (22 tests). Both pass without
modification beyond the import fix.

Deleted: tests/test_switch.py (2,999 LOC of upstream tests, most
covering sleep mode / take-over-control / manual-control state
machines that no longer exist; CDiT-specific switch tests deferred
to a follow-up change).

Result: `uv run --group test pytest tests/` → 94 passed in 0.57s.

Deferred from this change:
- 4.3: manual UI test that toggling a field and saving reloads cleanly
  (requires a real HA instance, can't be done from CLI).
- 9.4: GitHub repo description / topics update (do via `gh repo edit`
  outside the change scope).

openspec status: 4/4 artifacts complete; strict-validate green.
This commit is contained in:
Casey 2026-05-16 15:11:49 +02:00
commit 03d2748cd4
12 changed files with 1906 additions and 3542 deletions

View file

@ -56,22 +56,22 @@ Group 7-9 are tests, translations, and docs (final polish).
## 7. Tests
- [ ] 7.1 Delete obsolete test files: `tests/test_*sleep*`, `tests/test_*take_over*`, `tests/test_*manual_control*`. Update `tests/conftest.py` to drop fixtures that referenced those features. [D7, D8]
- [ ] 7.2 Add test: section layout — opening options on a UI-managed entry returns a flow result with six labeled sections in the specified order; Advanced and Diagnostics collapsed. [R1]
- [ ] 7.3 Add test: each field appears in exactly one section, matching the R1 table. [R1]
- [ ] 7.4 Add test: `send_split_delay` is absent from the schema when `separate_turn_on_commands` is false; present when true. [R2]
- [ ] 7.5 Add test: `sunrise_entity` / `sunset_entity` default to `sensor.sun_next_rising` / `sensor.sun_next_setting` on a freshly created entry. [R3]
- [ ] 7.6 Add test: entity selectors for the two sun fields are configured with `domain="sensor"` and `device_class="timestamp"`. [R3, D14]
- [ ] 7.7 Add test: `tanh_curve` returns `value_min` more than `half_width` before `t_start`, midpoint at exactly `t_start`, `value_max` more than `half_width` after `t_start` (and the symmetric trio around `t_end`). [R4]
- [ ] 7.8 Add test: color temperature uses the same curve shape as brightness, with `min_color_temp` / `max_color_temp` as bounds. [R4]
- [ ] 7.9 Add test: `NumberSelector` types, ranges, units, and modes match the R5 table for brightness, color temp, durations, and milliseconds. [R5]
- [ ] 7.10 Add test: saving valid options invokes `async_unload_entry` and `async_setup_entry` exactly once each (use mock spies) and produces no "restart HA" prompt. [R6]
- [ ] 7.11 Add test: opening the options flow on a `SOURCE_IMPORT` config entry returns `async_abort(reason="yaml_managed")`. [R7]
- [ ] 7.12 Add test: `async_setup_entry` raises `ConfigEntryError` when `config_entry.version == 1` and current is 2. [R8]
- [ ] 7.13 Add test: `async_setup_entry` succeeds and runs no tombstone log line when entry version is current. [R8]
- [ ] 7.14 Add test: the tombstone helper removes a seeded `switch.adaptive_lighting_sleep_mode_<name>` entity owned by this config entry, emits one INFO log line. [R9, D12]
- [ ] 7.15 Add test: tombstone helper is idempotent — second run finds nothing, no log line. [R9]
- [ ] 7.16 Add test: tombstone helper does not remove a foreign-owned entity matching the name pattern (different `config_entry_id`). [R9, D12]
- [x] 7.1 Delete obsolete test files: `tests/test_*sleep*`, `tests/test_*take_over*`, `tests/test_*manual_control*`. Update `tests/conftest.py` to drop fixtures that referenced those features. [D7, D8]
- [x] 7.2 Add test: section layout — opening options on a UI-managed entry returns a flow result with six labeled sections in the specified order; Advanced and Diagnostics collapsed. [R1]
- [x] 7.3 Add test: each field appears in exactly one section, matching the R1 table. [R1]
- [x] 7.4 Add test: `send_split_delay` is absent from the schema when `separate_turn_on_commands` is false; present when true. [R2]
- [x] 7.5 Add test: `sunrise_entity` / `sunset_entity` default to `sensor.sun_next_rising` / `sensor.sun_next_setting` on a freshly created entry. [R3]
- [x] 7.6 Add test: entity selectors for the two sun fields are configured with `domain="sensor"` and `device_class="timestamp"`. [R3, D14]
- [x] 7.7 Add test: `tanh_curve` returns `value_min` more than `half_width` before `t_start`, midpoint at exactly `t_start`, `value_max` more than `half_width` after `t_start` (and the symmetric trio around `t_end`). [R4]
- [x] 7.8 Add test: color temperature uses the same curve shape as brightness, with `min_color_temp` / `max_color_temp` as bounds. [R4]
- [x] 7.9 Add test: `NumberSelector` types, ranges, units, and modes match the R5 table for brightness, color temp, durations, and milliseconds. [R5]
- [x] 7.10 Add test: saving valid options invokes `async_unload_entry` and `async_setup_entry` exactly once each (use mock spies) and produces no "restart HA" prompt. [R6]
- [x] 7.11 Add test: opening the options flow on a `SOURCE_IMPORT` config entry returns `async_abort(reason="yaml_managed")`. [R7]
- [x] 7.12 Add test: `async_setup_entry` raises `ConfigEntryError` when `config_entry.version == 1` and current is 2. [R8]
- [x] 7.13 Add test: `async_setup_entry` succeeds and runs no tombstone log line when entry version is current. [R8]
- [x] 7.14 Add test: the tombstone helper removes a seeded `switch.adaptive_lighting_sleep_mode_<name>` entity owned by this config entry, emits one INFO log line. [R9, D12]
- [x] 7.15 Add test: tombstone helper is idempotent — second run finds nothing, no log line. [R9]
- [x] 7.16 Add test: tombstone helper does not remove a foreign-owned entity matching the name pattern (different `config_entry_id`). [R9, D12]
## 8. Strings and translations