diff --git a/custom_components/national_grid/config_flow.py b/custom_components/national_grid/config_flow.py index 42a9b5c..3683b9c 100644 --- a/custom_components/national_grid/config_flow.py +++ b/custom_components/national_grid/config_flow.py @@ -56,6 +56,9 @@ async def async_step_user( _LOGGER.exception(exception) _errors["base"] = "unknown" else: + if not self._accounts: + _LOGGER.error("Login succeeded but no accounts returned") + return self.async_abort(reason="no_accounts_found") await self.async_set_unique_id(slugify(self._username)) self._abort_if_unique_id_configured() @@ -135,6 +138,12 @@ async def async_step_reconfigure( except NationalGridError as exception: _LOGGER.exception(exception) _errors["base"] = "unknown" + else: + if not self._accounts: + _LOGGER.error( + "Reconfigure: login succeeded but no accounts returned" + ) + return self.async_abort(reason="no_accounts_found") current_selection = reconfigure_entry.data.get(CONF_SELECTED_ACCOUNTS, []) diff --git a/custom_components/national_grid/strings.json b/custom_components/national_grid/strings.json index 0b12e49..1986aad 100644 --- a/custom_components/national_grid/strings.json +++ b/custom_components/national_grid/strings.json @@ -36,6 +36,7 @@ }, "abort": { "already_configured": "This account is already configured.", + "no_accounts_found": "Login succeeded but no National Grid accounts were found on this profile.", "reauth_successful": "Re-authentication successful.", "reconfigure_successful": "Account selection updated successfully." } diff --git a/custom_components/national_grid/translations/en.json b/custom_components/national_grid/translations/en.json index 0b12e49..1986aad 100644 --- a/custom_components/national_grid/translations/en.json +++ b/custom_components/national_grid/translations/en.json @@ -36,6 +36,7 @@ }, "abort": { "already_configured": "This account is already configured.", + "no_accounts_found": "Login succeeded but no National Grid accounts were found on this profile.", "reauth_successful": "Re-authentication successful.", "reconfigure_successful": "Account selection updated successfully." } diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index fe54132..ff828c5 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -528,6 +528,43 @@ async def test_reconfigure_unknown_error(hass: HomeAssistant) -> None: assert result["errors"]["base"] == "unknown" +async def test_user_step_no_accounts_found(hass: HomeAssistant) -> None: + """Test user step aborts when login succeeds but no accounts are returned.""" + with patch(PATCH_CLIENT) as mock_cls: + client = mock_cls.return_value + client.__aenter__ = AsyncMock(return_value=client) + client.__aexit__ = AsyncMock(return_value=False) + client.get_linked_accounts = AsyncMock(return_value=[]) + + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": config_entries.SOURCE_USER}, + data={ + CONF_USERNAME: MOCK_USERNAME, + CONF_PASSWORD: MOCK_PASSWORD, + }, + ) + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "no_accounts_found" + + +async def test_reconfigure_no_accounts_found(hass: HomeAssistant) -> None: + """Test reconfigure aborts when login succeeds but no accounts are returned.""" + entry = _make_reconfigure_entry(hass) + + with patch(PATCH_CLIENT) as mock_cls: + client = mock_cls.return_value + client.__aenter__ = AsyncMock(return_value=client) + client.__aexit__ = AsyncMock(return_value=False) + client.get_linked_accounts = AsyncMock(return_value=[]) + + result = await entry.start_reconfigure_flow(hass) + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "no_accounts_found" + + async def test_already_configured(hass: HomeAssistant) -> None: """Test that duplicate unique_id aborts.""" entry = MockConfigEntry(