|
7 | 7 |
|
8 | 8 | import pytest |
9 | 9 |
|
10 | | -from homeassistant.const import STATE_OFF, STATE_ON |
| 10 | +from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNKNOWN |
11 | 11 | from homeassistant.core import HomeAssistant |
12 | 12 | from homeassistant.helpers.issue_registry import ( |
13 | 13 | IssueSeverity, |
|
25 | 25 | from custom_components.lock_code_manager.models import SlotCode, SyncState |
26 | 26 | from custom_components.lock_code_manager.sync import SlotState, SlotSyncManager |
27 | 27 |
|
28 | | -from .common import SLOT_1_IN_SYNC_ENTITY |
| 28 | +from .common import SLOT_1_ACTIVE_ENTITY, SLOT_1_IN_SYNC_ENTITY, SLOT_1_PIN_ENTITY |
29 | 29 | from .conftest import async_trigger_sync_tick, get_in_sync_entity_obj |
30 | 30 |
|
31 | 31 |
|
@@ -426,6 +426,64 @@ async def test_loading_to_out_of_sync( |
426 | 426 | await async_trigger_sync_tick(hass, SLOT_1_IN_SYNC_ENTITY, set_dirty=False) |
427 | 427 | assert manager._state is SyncState.OUT_OF_SYNC |
428 | 428 |
|
| 429 | + async def test_disabled_slot_with_unknown_pin_exits_loading( |
| 430 | + self, |
| 431 | + hass: HomeAssistant, |
| 432 | + mock_lock_config_entry, |
| 433 | + lock_code_manager_config_entry, |
| 434 | + ) -> None: |
| 435 | + """Disabled slot with unknown PIN/code transitions out of LOADING.""" |
| 436 | + entity_obj = get_in_sync_entity_obj(hass, SLOT_1_IN_SYNC_ENTITY) |
| 437 | + manager = entity_obj._sync_manager |
| 438 | + manager._state = SyncState.LOADING |
| 439 | + |
| 440 | + # Simulate disabled slot: active=off, PIN unknown |
| 441 | + hass.states.async_set(SLOT_1_ACTIVE_ENTITY, STATE_OFF) |
| 442 | + hass.states.async_set(SLOT_1_PIN_ENTITY, STATE_UNKNOWN) |
| 443 | + # Coordinator has slot as EMPTY (no code on lock) |
| 444 | + manager._coordinator.data[1] = SlotCode.EMPTY |
| 445 | + |
| 446 | + await async_trigger_sync_tick(hass, SLOT_1_IN_SYNC_ENTITY, set_dirty=False) |
| 447 | + |
| 448 | + # Should transition to IN_SYNC (slot off, code empty = in sync) |
| 449 | + assert manager._state is SyncState.IN_SYNC |
| 450 | + |
| 451 | + async def test_active_unknown_stays_in_loading( |
| 452 | + self, |
| 453 | + hass: HomeAssistant, |
| 454 | + mock_lock_config_entry, |
| 455 | + lock_code_manager_config_entry, |
| 456 | + ) -> None: |
| 457 | + """Slot stays in LOADING when active entity is STATE_UNKNOWN.""" |
| 458 | + entity_obj = get_in_sync_entity_obj(hass, SLOT_1_IN_SYNC_ENTITY) |
| 459 | + manager = entity_obj._sync_manager |
| 460 | + manager._state = SyncState.LOADING |
| 461 | + |
| 462 | + hass.states.async_set(SLOT_1_ACTIVE_ENTITY, STATE_UNKNOWN) |
| 463 | + manager._coordinator.data[1] = SlotCode.EMPTY |
| 464 | + |
| 465 | + await async_trigger_sync_tick(hass, SLOT_1_IN_SYNC_ENTITY, set_dirty=False) |
| 466 | + assert manager._state is SyncState.LOADING |
| 467 | + |
| 468 | + async def test_enabled_slot_with_unknown_pin_stays_in_loading( |
| 469 | + self, |
| 470 | + hass: HomeAssistant, |
| 471 | + mock_lock_config_entry, |
| 472 | + lock_code_manager_config_entry, |
| 473 | + ) -> None: |
| 474 | + """Enabled slot with unknown PIN stays in LOADING (needs PIN to sync).""" |
| 475 | + entity_obj = get_in_sync_entity_obj(hass, SLOT_1_IN_SYNC_ENTITY) |
| 476 | + manager = entity_obj._sync_manager |
| 477 | + manager._state = SyncState.LOADING |
| 478 | + |
| 479 | + # Active=on but PIN unknown — can't sync without knowing what PIN to set |
| 480 | + hass.states.async_set(SLOT_1_ACTIVE_ENTITY, STATE_ON) |
| 481 | + hass.states.async_set(SLOT_1_PIN_ENTITY, STATE_UNKNOWN) |
| 482 | + manager._coordinator.data[1] = SlotCode.EMPTY |
| 483 | + |
| 484 | + await async_trigger_sync_tick(hass, SLOT_1_IN_SYNC_ENTITY, set_dirty=False) |
| 485 | + assert manager._state is SyncState.LOADING |
| 486 | + |
429 | 487 | async def test_loading_to_synced( |
430 | 488 | self, |
431 | 489 | hass: HomeAssistant, |
|
0 commit comments