5959 SERVICE_VOLUME_SET ,
6060 SERVICE_VOLUME_UP ,
6161 STATE_OFF ,
62+ STATE_UNAVAILABLE ,
6263)
6364from homeassistant .core import HomeAssistant , State
6465from homeassistant .exceptions import HomeAssistantError
7374from tests .typing import ClientSessionGenerator
7475
7576
77+ async def mock_scan_interval (
78+ hass : HomeAssistant ,
79+ freezer : FrozenDateTimeFactory ,
80+ ) -> None :
81+ """Mock update interval to force an update."""
82+ freezer .tick (timedelta (seconds = 11 ))
83+ async_fire_time_changed (hass )
84+ await hass .async_block_till_done ()
85+ 86+ 7687@pytest .mark .parametrize (
7788 ("service" , "attr_data" , "client_call" ),
7889 [
@@ -488,9 +499,7 @@ async def test_client_disconnected(
488499 client .is_connected .return_value = False
489500 client .connect .side_effect = TimeoutError
490501
491- freezer .tick (timedelta (seconds = 20 ))
492- async_fire_time_changed (hass )
493- await hass .async_block_till_done ()
502+ await mock_scan_interval (hass , freezer )
494503
495504 assert "TimeoutError" not in caplog .text
496505
@@ -506,9 +515,7 @@ async def test_client_key_update_on_connect(
506515 client .is_connected .return_value = False
507516 client .client_key = "new_key"
508517
509- freezer .tick (timedelta (seconds = 20 ))
510- async_fire_time_changed (hass )
511- await hass .async_block_till_done ()
518+ await mock_scan_interval (hass , freezer )
512519
513520 assert config_entry .data [CONF_CLIENT_SECRET ] == client .client_key
514521
@@ -849,9 +856,7 @@ async def test_reauth_reconnect(
849856
850857 assert entry .state is ConfigEntryState .LOADED
851858
852- freezer .tick (timedelta (seconds = 20 ))
853- async_fire_time_changed (hass )
854- await hass .async_block_till_done ()
859+ await mock_scan_interval (hass , freezer )
855860
856861 assert entry .state is ConfigEntryState .LOADED
857862
@@ -886,3 +891,82 @@ async def test_update_media_state(hass: HomeAssistant, client) -> None:
886891 client .tv_state .is_on = False
887892 await client .mock_state_update ()
888893 assert hass .states .get (ENTITY_ID ).state == STATE_OFF
894+ 895+ 896+ async def test_availability (
897+ hass : HomeAssistant ,
898+ client ,
899+ caplog : pytest .LogCaptureFixture ,
900+ freezer : FrozenDateTimeFactory ,
901+ ) -> None :
902+ """Test that availability status changes are set and logged correctly."""
903+ await setup_webostv (hass )
904+ 905+ # Initially available
906+ assert hass .states .get (ENTITY_ID ).state == MediaPlayerState .ON
907+ 908+ # Make the entity go offline - should log unavailable message
909+ client .connect .side_effect = TimeoutError
910+ client .is_connected .return_value = False
911+ await mock_scan_interval (hass , freezer )
912+ 913+ assert hass .states .get (ENTITY_ID ).state == STATE_UNAVAILABLE
914+ unavailable_log = f"LG webOS TV entity { ENTITY_ID } is unavailable"
915+ assert unavailable_log in caplog .text
916+ 917+ # Clear logs and update the offline entity again - should NOT log again
918+ caplog .clear ()
919+ await mock_scan_interval (hass , freezer )
920+ 921+ assert unavailable_log not in caplog .text
922+ 923+ # Bring the entity back online - should log back online message
924+ client .connect .side_effect = None
925+ await mock_scan_interval (hass , freezer )
926+ 927+ assert hass .states .get (ENTITY_ID ).state == MediaPlayerState .ON
928+ available_log = f"LG webOS TV entity { ENTITY_ID } is back online"
929+ assert available_log in caplog .text
930+ 931+ # Clear logs and make update again - should NOT log again
932+ caplog .clear ()
933+ await mock_scan_interval (hass , freezer )
934+ 935+ assert hass .states .get (ENTITY_ID ).state == MediaPlayerState .ON
936+ assert available_log not in caplog .text
937+ 938+ # Test offline again to ensure the flag resets properly
939+ client .connect .side_effect = TimeoutError
940+ await mock_scan_interval (hass , freezer )
941+ 942+ assert hass .states .get (ENTITY_ID ).state == STATE_UNAVAILABLE
943+ assert unavailable_log in caplog .text
944+ 945+ # Test entity that supports turn on are considered available
946+ assert await async_setup_component (
947+ hass ,
948+ automation .DOMAIN ,
949+ {
950+ automation .DOMAIN : [
951+ {
952+ "trigger" : {
953+ "platform" : "webostv.turn_on" ,
954+ "entity_id" : ENTITY_ID ,
955+ },
956+ "action" : {
957+ "service" : "test.automation" ,
958+ "data_template" : {
959+ "some" : ENTITY_ID ,
960+ "id" : "{{ trigger.id }}" ,
961+ },
962+ },
963+ },
964+ ],
965+ },
966+ )
967+ 968+ await mock_scan_interval (hass , freezer )
969+ 970+ assert hass .states .get (ENTITY_ID ).state == MediaPlayerState .ON
971+ available_log = f"LG webOS TV entity { ENTITY_ID } is back online"
972+ assert available_log in caplog .text
0 commit comments