From fe94dea1db709f4201172a0d3c68ac20dc7bce07 Mon Sep 17 00:00:00 2001 From: Jordan Harvey Date: Tue, 16 Dec 2025 16:12:36 +0000 Subject: [PATCH] Add missing tests for Nintendo parental controls code coverage (#159210) Co-authored-by: Joost Lekkerkerker --- .../nintendo_parental_controls/services.py | 14 ++++++--- .../nintendo_parental_controls/strings.json | 3 ++ .../nintendo_parental_controls/test_init.py | 27 ++++++++++++++++ .../test_services.py | 31 +++++++++++++++++-- 4 files changed, 68 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/nintendo_parental_controls/services.py b/homeassistant/components/nintendo_parental_controls/services.py index fb23ff14e5a..b50ac07b0f8 100644 --- a/homeassistant/components/nintendo_parental_controls/services.py +++ b/homeassistant/components/nintendo_parental_controls/services.py @@ -7,7 +7,7 @@ import voluptuous as vol from homeassistant.const import ATTR_DEVICE_ID from homeassistant.core import HomeAssistant, ServiceCall, callback -from homeassistant.exceptions import HomeAssistantError +from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import config_validation as cv, device_registry as dr from .const import ATTR_BONUS_TIME, DOMAIN @@ -56,7 +56,7 @@ async def async_add_bonus_time(call: ServiceCall) -> None: bonus_time: int = data[ATTR_BONUS_TIME] device = dr.async_get(call.hass).async_get(device_id) if device is None: - raise HomeAssistantError( + raise ServiceValidationError( translation_domain=DOMAIN, translation_key="device_not_found", ) @@ -66,6 +66,10 @@ async def async_add_bonus_time(call: ServiceCall) -> None: break nintendo_device_id = _get_nintendo_device_id(device) if config_entry and nintendo_device_id: - await config_entry.runtime_data.api.devices[nintendo_device_id].add_extra_time( - bonus_time - ) + return await config_entry.runtime_data.api.devices[ + nintendo_device_id + ].add_extra_time(bonus_time) + raise ServiceValidationError( + translation_domain=DOMAIN, + translation_key="invalid_device", + ) diff --git a/homeassistant/components/nintendo_parental_controls/strings.json b/homeassistant/components/nintendo_parental_controls/strings.json index 6c503254424..aa959cd2537 100644 --- a/homeassistant/components/nintendo_parental_controls/strings.json +++ b/homeassistant/components/nintendo_parental_controls/strings.json @@ -69,6 +69,9 @@ "device_not_found": { "message": "Device not found." }, + "invalid_device": { + "message": "The specified device is not a Nintendo device." + }, "no_devices_found": { "message": "No Nintendo devices found for this account." } diff --git a/tests/components/nintendo_parental_controls/test_init.py b/tests/components/nintendo_parental_controls/test_init.py index 7182e2350ec..a6383edb12d 100644 --- a/tests/components/nintendo_parental_controls/test_init.py +++ b/tests/components/nintendo_parental_controls/test_init.py @@ -2,6 +2,8 @@ from unittest.mock import AsyncMock +from pynintendoauth.exceptions import InvalidOAuthConfigurationException + from homeassistant.config_entries import ConfigEntryState from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er @@ -28,3 +30,28 @@ async def test_invalid_authentication( assert len(entries) == 0 # Ensure the config entry is marked as error assert mock_config_entry.state is ConfigEntryState.SETUP_ERROR + + +async def test_reauth_flow( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_nintendo_authenticator: AsyncMock, + entity_registry: er.EntityRegistry, +) -> None: + """Test the reauth flow is triggered.""" + mock_nintendo_authenticator.async_complete_login.side_effect = ( + InvalidOAuthConfigurationException( + status_code=401, message="Authentication failed" + ) + ) + await setup_integration(hass, mock_config_entry) + + # Ensure no entities are created + entries = er.async_entries_for_config_entry( + entity_registry, mock_config_entry.entry_id + ) + assert len(entries) == 0 + # Ensure the config entry is marked as needing reauth + assert mock_config_entry.state is ConfigEntryState.SETUP_ERROR + + assert mock_config_entry.error_reason_translation_key == "auth_expired" diff --git a/tests/components/nintendo_parental_controls/test_services.py b/tests/components/nintendo_parental_controls/test_services.py index 970adeaa4ad..45fbdcdd46e 100644 --- a/tests/components/nintendo_parental_controls/test_services.py +++ b/tests/components/nintendo_parental_controls/test_services.py @@ -13,7 +13,7 @@ from homeassistant.components.nintendo_parental_controls.services import ( ) from homeassistant.const import ATTR_DEVICE_ID from homeassistant.core import HomeAssistant -from homeassistant.exceptions import HomeAssistantError +from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import device_registry as dr from . import setup_integration @@ -51,7 +51,7 @@ async def test_add_bonus_time_invalid_device( ) -> None: """Test add bonus time service.""" await setup_integration(hass, mock_config_entry) - with pytest.raises(HomeAssistantError) as err: + with pytest.raises(ServiceValidationError) as err: await hass.services.async_call( DOMAIN, NintendoParentalServices.ADD_BONUS_TIME, @@ -63,3 +63,30 @@ async def test_add_bonus_time_invalid_device( ) assert err.value.translation_domain == DOMAIN assert err.value.translation_key == "device_not_found" + + +async def test_add_bonus_time_device_id_not_nintendo( + hass: HomeAssistant, + device_registry: dr.DeviceRegistry, + mock_config_entry: MockConfigEntry, + mock_nintendo_client: AsyncMock, +) -> None: + """Test add bonus time service with a device that is not a valid Nintendo device.""" + await setup_integration(hass, mock_config_entry) + # Create a device that does not have a Nintendo identifier + device_entry = device_registry.async_get_or_create( + config_entry_id=mock_config_entry.entry_id, + connections={(dr.CONNECTION_NETWORK_MAC, "00:11:22:33:44:55")}, + ) + with pytest.raises(ServiceValidationError) as err: + await hass.services.async_call( + DOMAIN, + NintendoParentalServices.ADD_BONUS_TIME, + { + ATTR_DEVICE_ID: device_entry.id, + ATTR_BONUS_TIME: 15, + }, + blocking=True, + ) + assert err.value.translation_domain == DOMAIN + assert err.value.translation_key == "invalid_device"