From 99cdc3172c326cd3ad297340cb597d94ebe4bd7a Mon Sep 17 00:00:00 2001 From: moryoav Date: Thu, 3 Sep 2026 22:40:18 +0300 Subject: [PATCH] Fix Besen config flow schema serialization (#181223) --- homeassistant/components/besen/config_flow.py | 14 ++++----- tests/components/besen/test_config_flow.py | 31 ++++++++++++------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/homeassistant/components/besen/config_flow.py b/homeassistant/components/besen/config_flow.py index 755deaee5335..59f9dbded70f 100644 --- a/homeassistant/components/besen/config_flow.py +++ b/homeassistant/components/besen/config_flow.py @@ -34,13 +34,10 @@ def _normalize_address(address: str) -> str: return address.strip().upper() -PIN_SCHEMA = vol.All( - selector.TextSelector( - selector.TextSelectorConfig( - type=selector.TextSelectorType.PASSWORD, - ) - ), - vol.Match(r"^\d{6}$"), +PIN_SCHEMA = selector.TextSelector( + selector.TextSelectorConfig( + type=selector.TextSelectorType.PASSWORD, + ) ) PIN_ONLY_SCHEMA = vol.Schema( @@ -77,6 +74,9 @@ async def _async_validate_input( ) -> str: """Validate setup by logging into the charger.""" + if len(pin) != 6 or not pin.isdecimal(): + raise InvalidAuth("PIN must be exactly 6 digits") + def _ble_device_provider() -> BLEDevice | None: return bluetooth.async_ble_device_from_address( hass, diff --git a/tests/components/besen/test_config_flow.py b/tests/components/besen/test_config_flow.py index a1bbcdc69ab9..d7ac7ddca709 100644 --- a/tests/components/besen/test_config_flow.py +++ b/tests/components/besen/test_config_flow.py @@ -3,8 +3,8 @@ from unittest.mock import Mock from besen.exceptions import CannotConnect, InvalidAuth +from probatio import to_field_list import pytest -import voluptuous as vol from homeassistant.components.besen.const import DOMAIN from homeassistant.components.bluetooth import BluetoothServiceInfoBleak @@ -12,6 +12,7 @@ from homeassistant.config_entries import SOURCE_BLUETOOTH, SOURCE_USER from homeassistant.const import CONF_ADDRESS, CONF_NAME, CONF_PIN from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType +from homeassistant.helpers import config_validation as cv from .conftest import ( FIXTURE_ADDRESS, @@ -91,6 +92,7 @@ async def test_bluetooth_step_sets_discovered_context( assert result["type"] is FlowResultType.FORM assert result["step_id"] == "bluetooth_confirm" + assert to_field_list(result["data_schema"], custom_serializer=cv.custom_serializer) result = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -243,25 +245,32 @@ async def test_user_step_success( _assert_create_entry(result) -@pytest.mark.usefixtures("mock_besen_client", "mock_setup_entry") +@pytest.mark.parametrize("invalid_pin", ["12345", "¹²³⁴⁵⁶"]) +@pytest.mark.usefixtures("mock_setup_entry") async def test_user_step_rejects_invalid_pin( hass: HomeAssistant, + mock_besen_client: Mock, + invalid_pin: str, ) -> None: - """Test the user step PIN schema rejects invalid values.""" + """Test the user step rejects invalid PIN values.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER}, ) - with pytest.raises(vol.Invalid): - await hass.config_entries.flow.async_configure( - result["flow_id"], - { - CONF_ADDRESS: FIXTURE_ADDRESS, - CONF_PIN: "12345", - }, - ) + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + { + CONF_ADDRESS: FIXTURE_ADDRESS, + CONF_PIN: invalid_pin, + }, + ) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + assert result["errors"] == {"base": "invalid_auth"} + mock_besen_client.async_start.assert_not_awaited() result = await hass.config_entries.flow.async_configure( result["flow_id"],