From 225be65f71bf73e3981d6524259d15d16fe74588 Mon Sep 17 00:00:00 2001 From: Xiangxuan Qu Date: Wed, 7 Jan 2026 20:22:39 +0900 Subject: [PATCH] Fix IndexError in Israel Rail sensor when no departures available (#160351) Co-authored-by: Joostlek --- .../components/israel_rail/sensor.py | 2 + tests/components/israel_rail/test_sensor.py | 42 ++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/israel_rail/sensor.py b/homeassistant/components/israel_rail/sensor.py index 86b2e135cfb..6e3324de7ae 100644 --- a/homeassistant/components/israel_rail/sensor.py +++ b/homeassistant/components/israel_rail/sensor.py @@ -116,6 +116,8 @@ class IsraelRailEntitySensor( @property def native_value(self) -> StateType | datetime: """Return the state of the sensor.""" + if self.entity_description.index >= len(self.coordinator.data): + return None return self.entity_description.value_fn( self.coordinator.data[self.entity_description.index] ) diff --git a/tests/components/israel_rail/test_sensor.py b/tests/components/israel_rail/test_sensor.py index 08aed2bbc21..a1bf00472d9 100644 --- a/tests/components/israel_rail/test_sensor.py +++ b/tests/components/israel_rail/test_sensor.py @@ -7,7 +7,7 @@ from unittest.mock import AsyncMock from freezegun.api import FrozenDateTimeFactory from syrupy.assertion import SnapshotAssertion -from homeassistant.const import STATE_UNAVAILABLE +from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er @@ -66,3 +66,43 @@ async def test_fail_query( assert len(hass.states.async_entity_ids()) == 6 departure_sensor = hass.states.get("sensor.mock_title_departure") assert departure_sensor.state == STATE_UNAVAILABLE + + +async def test_no_departures( + hass: HomeAssistant, + freezer: FrozenDateTimeFactory, + mock_israelrail: AsyncMock, + mock_config_entry: MockConfigEntry, +) -> None: + """Test handling when there are no departures available.""" + await init_integration(hass, mock_config_entry) + assert len(hass.states.async_entity_ids()) == 6 + + # Simulate no departures (e.g., after-hours) + mock_israelrail.query.return_value = [] + + await goto_future(hass, freezer) + + # All sensors should still exist + assert len(hass.states.async_entity_ids()) == 6 + + # Departure sensors should have unknown state (None) + departure_sensor = hass.states.get("sensor.mock_title_departure") + assert departure_sensor.state == STATE_UNKNOWN + + departure_sensor_1 = hass.states.get("sensor.mock_title_departure_1") + assert departure_sensor_1.state == STATE_UNKNOWN + + departure_sensor_2 = hass.states.get("sensor.mock_title_departure_2") + assert departure_sensor_2.state == STATE_UNKNOWN + + # Non-departure sensors (platform, trains, train_number) also access index 0 + # and should have unknown state when no departures available + platform_sensor = hass.states.get("sensor.mock_title_platform") + assert platform_sensor.state == STATE_UNKNOWN + + trains_sensor = hass.states.get("sensor.mock_title_trains") + assert trains_sensor.state == STATE_UNKNOWN + + train_number_sensor = hass.states.get("sensor.mock_title_train_number") + assert train_number_sensor.state == STATE_UNKNOWN