diff --git a/homeassistant/components/shelly/quality_scale.yaml b/homeassistant/components/shelly/quality_scale.yaml index ac2a0756b5b..8fec824bcc1 100644 --- a/homeassistant/components/shelly/quality_scale.yaml +++ b/homeassistant/components/shelly/quality_scale.yaml @@ -6,9 +6,7 @@ rules: appropriate-polling: done brands: done common-modules: done - config-flow-test-coverage: - status: todo - comment: make sure flows end with created entry or abort + config-flow-test-coverage: done config-flow: done dependency-transparency: done docs-actions: diff --git a/tests/components/shelly/conftest.py b/tests/components/shelly/conftest.py index 2a386a1628c..be5e5749731 100644 --- a/tests/components/shelly/conftest.py +++ b/tests/components/shelly/conftest.py @@ -1,5 +1,6 @@ """Test configuration for Shelly.""" +from collections.abc import Generator from copy import deepcopy from unittest.mock import AsyncMock, Mock, PropertyMock, patch @@ -690,3 +691,21 @@ async def mock_sleepy_rpc_device(): rpc_device_mock.return_value.mock_initialized = Mock(side_effect=initialized) yield rpc_device_mock.return_value + + +@pytest.fixture +def mock_setup_entry() -> Generator[AsyncMock]: + """Override async_setup_entry.""" + with patch( + "homeassistant.components.shelly.async_setup_entry", return_value=True + ) as mock_setup_entry: + yield mock_setup_entry + + +@pytest.fixture +def mock_setup() -> Generator[AsyncMock]: + """Override async_setup_entry.""" + with patch( + "homeassistant.components.shelly.async_setup", return_value=True + ) as mock_setup: + yield mock_setup diff --git a/tests/components/shelly/test_config_flow.py b/tests/components/shelly/test_config_flow.py index 26944ab1f41..e093dcf11d2 100644 --- a/tests/components/shelly/test_config_flow.py +++ b/tests/components/shelly/test_config_flow.py @@ -82,6 +82,8 @@ async def test_form( port: int, mock_block_device: Mock, mock_rpc_device: Mock, + mock_setup_entry: AsyncMock, + mock_setup: AsyncMock, ) -> None: """Test we get the form.""" result = await hass.config_entries.flow.async_init( @@ -101,23 +103,15 @@ async def test_form( "port": port, }, ), - patch( - "homeassistant.components.shelly.async_setup", return_value=True - ) as mock_setup, - patch( - "homeassistant.components.shelly.async_setup_entry", - return_value=True, - ) as mock_setup_entry, ): - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], {CONF_HOST: "1.1.1.1", CONF_PORT: port}, ) - await hass.async_block_till_done() - assert result2["type"] is FlowResultType.CREATE_ENTRY - assert result2["title"] == "Test name" - assert result2["data"] == { + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == "Test name" + assert result["data"] == { CONF_HOST: "1.1.1.1", CONF_PORT: port, CONF_MODEL: model, @@ -131,26 +125,19 @@ async def test_form( async def test_user_flow_overrides_existing_discovery( hass: HomeAssistant, mock_rpc_device: Mock, + mock_setup_entry: AsyncMock, + mock_setup: AsyncMock, ) -> None: """Test setting up from the user flow when the devices is already discovered.""" - with ( - patch( - "homeassistant.components.shelly.config_flow.get_info", - return_value={ - "mac": "AABBCCDDEEFF", - "model": MODEL_PLUS_2PM, - "auth": False, - "gen": 2, - "port": 80, - }, - ), - patch( - "homeassistant.components.shelly.async_setup", return_value=True - ) as mock_setup, - patch( - "homeassistant.components.shelly.async_setup_entry", - return_value=True, - ) as mock_setup_entry, + with patch( + "homeassistant.components.shelly.config_flow.get_info", + return_value={ + "mac": "AABBCCDDEEFF", + "model": MODEL_PLUS_2PM, + "auth": False, + "gen": 2, + "port": 80, + }, ): discovery_result = await hass.config_entries.flow.async_init( DOMAIN, @@ -172,22 +159,21 @@ async def test_user_flow_overrides_existing_discovery( ) assert result["type"] is FlowResultType.FORM assert result["errors"] == {} - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], {CONF_HOST: "1.1.1.1", CONF_PORT: 80}, ) - await hass.async_block_till_done() - assert result2["type"] is FlowResultType.CREATE_ENTRY - assert result2["title"] == "Test name" - assert result2["data"] == { + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == "Test name" + assert result["data"] == { CONF_HOST: "1.1.1.1", CONF_PORT: 80, CONF_MODEL: MODEL_PLUS_2PM, CONF_SLEEP_PERIOD: 0, CONF_GEN: 2, } - assert result2["context"]["unique_id"] == "AABBCCDDEEFF" + assert result["context"]["unique_id"] == "AABBCCDDEEFF" assert len(mock_setup.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1 assert len(hass.config_entries.async_entries(DOMAIN)) == 1 @@ -198,6 +184,8 @@ async def test_user_flow_overrides_existing_discovery( async def test_form_gen1_custom_port( hass: HomeAssistant, mock_block_device: Mock, + mock_setup_entry: AsyncMock, + mock_setup: AsyncMock, ) -> None: """Test we get the form.""" result = await hass.config_entries.flow.async_init( @@ -216,13 +204,35 @@ async def test_form_gen1_custom_port( side_effect=CustomPortNotSupported, ), ): - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], - {"host": "1.1.1.1", "port": "1100"}, + {CONF_HOST: "1.1.1.1", CONF_PORT: "1100"}, ) - assert result2["type"] is FlowResultType.FORM - assert result2["errors"]["base"] == "custom_port_not_supported" + assert result["type"] is FlowResultType.FORM + assert result["errors"]["base"] == "custom_port_not_supported" + + with patch( + "homeassistant.components.shelly.config_flow.get_info", + return_value={"mac": "test-mac", "type": MODEL_1, "gen": 1}, + ): + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_HOST: "1.1.1.1", CONF_PORT: DEFAULT_HTTP_PORT}, + ) + + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == "Test name" + assert result["data"] == { + CONF_HOST: "1.1.1.1", + CONF_PORT: DEFAULT_HTTP_PORT, + CONF_MODEL: MODEL_1, + CONF_SLEEP_PERIOD: 0, + CONF_GEN: 1, + } + assert result["context"]["unique_id"] == "test-mac" + assert len(mock_setup.mock_calls) == 1 + assert len(mock_setup_entry.mock_calls) == 1 @pytest.mark.parametrize( @@ -256,6 +266,8 @@ async def test_form_auth( username: str, mock_block_device: Mock, mock_rpc_device: Mock, + mock_setup_entry: AsyncMock, + mock_setup: AsyncMock, ) -> None: """Test manual configuration if auth is required.""" result = await hass.config_entries.flow.async_init( @@ -268,31 +280,21 @@ async def test_form_auth( "homeassistant.components.shelly.config_flow.get_info", return_value={"mac": "test-mac", "type": MODEL_1, "auth": True, "gen": gen}, ): - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], {CONF_HOST: "1.1.1.1"}, ) - assert result2["type"] is FlowResultType.FORM + assert result["type"] is FlowResultType.FORM assert result["errors"] == {} - with ( - patch( - "homeassistant.components.shelly.async_setup", return_value=True - ) as mock_setup, - patch( - "homeassistant.components.shelly.async_setup_entry", - return_value=True, - ) as mock_setup_entry, - ): - result3 = await hass.config_entries.flow.async_configure( - result2["flow_id"], user_input - ) - await hass.async_block_till_done() + result = await hass.config_entries.flow.async_configure( + result["flow_id"], user_input + ) - assert result3["type"] is FlowResultType.CREATE_ENTRY - assert result3["title"] == "Test name" - assert result3["data"] == { + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == "Test name" + assert result["data"] == { CONF_HOST: "1.1.1.1", CONF_PORT: DEFAULT_HTTP_PORT, CONF_MODEL: model, @@ -314,7 +316,12 @@ async def test_form_auth( ], ) async def test_form_errors_get_info( - hass: HomeAssistant, exc: Exception, base_error: str + hass: HomeAssistant, + mock_block_device: Mock, + mock_setup: AsyncMock, + mock_setup_entry: AsyncMock, + exc: Exception, + base_error: str, ) -> None: """Test we handle errors.""" result = await hass.config_entries.flow.async_init( @@ -322,13 +329,35 @@ async def test_form_errors_get_info( ) with patch("homeassistant.components.shelly.config_flow.get_info", side_effect=exc): - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], {CONF_HOST: "1.1.1.1"}, ) - assert result2["type"] is FlowResultType.FORM - assert result2["errors"] == {"base": base_error} + assert result["type"] is FlowResultType.FORM + assert result["errors"] == {"base": base_error} + + with patch( + "homeassistant.components.shelly.config_flow.get_info", + return_value={"mac": "test-mac", "type": MODEL_1, "gen": 1}, + ): + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_HOST: "1.1.1.1"}, + ) + + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == "Test name" + assert result["data"] == { + CONF_HOST: "1.1.1.1", + CONF_PORT: DEFAULT_HTTP_PORT, + CONF_MODEL: MODEL_1, + CONF_SLEEP_PERIOD: 0, + CONF_GEN: 1, + } + assert result["context"]["unique_id"] == "test-mac" + assert len(mock_setup.mock_calls) == 1 + assert len(mock_setup_entry.mock_calls) == 1 async def test_form_missing_model_key( @@ -343,13 +372,13 @@ async def test_form_missing_model_key( "homeassistant.components.shelly.config_flow.get_info", return_value={"mac": "test-mac", "auth": False, "gen": "2"}, ): - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], {CONF_HOST: "1.1.1.1"}, ) - assert result2["type"] is FlowResultType.ABORT - assert result2["reason"] == "firmware_not_fully_provisioned" + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "firmware_not_fully_provisioned" async def test_form_missing_model_key_auth_enabled( @@ -366,20 +395,20 @@ async def test_form_missing_model_key_auth_enabled( "homeassistant.components.shelly.config_flow.get_info", return_value={"mac": "test-mac", "auth": True, "gen": 2}, ): - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], {CONF_HOST: "1.1.1.1"}, ) - assert result2["type"] is FlowResultType.FORM + assert result["type"] is FlowResultType.FORM assert result["errors"] == {} monkeypatch.setattr(mock_rpc_device, "shelly", {"gen": 2}) - result3 = await hass.config_entries.flow.async_configure( - result2["flow_id"], {CONF_PASSWORD: "1234"} + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_PASSWORD: "1234"} ) - assert result3["type"] is FlowResultType.ABORT - assert result3["reason"] == "firmware_not_fully_provisioned" + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "firmware_not_fully_provisioned" async def test_form_missing_model_key_zeroconf( @@ -398,6 +427,7 @@ async def test_form_missing_model_key_zeroconf( data=DISCOVERY_INFO, context={"source": config_entries.SOURCE_ZEROCONF}, ) + assert result["type"] is FlowResultType.ABORT assert result["reason"] == "firmware_not_fully_provisioned" @@ -411,7 +441,12 @@ async def test_form_missing_model_key_zeroconf( ], ) async def test_form_errors_test_connection( - hass: HomeAssistant, exc: Exception, base_error: str + hass: HomeAssistant, + mock_block_device: Mock, + mock_setup_entry: AsyncMock, + mock_setup: AsyncMock, + exc: Exception, + base_error: str, ) -> None: """Test we handle errors.""" result = await hass.config_entries.flow.async_init( @@ -427,13 +462,35 @@ async def test_form_errors_test_connection( "aioshelly.block_device.BlockDevice.create", new=AsyncMock(side_effect=exc) ), ): - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], {CONF_HOST: "1.1.1.1"}, ) - assert result2["type"] is FlowResultType.FORM - assert result2["errors"] == {"base": base_error} + assert result["type"] is FlowResultType.FORM + assert result["errors"] == {"base": base_error} + + with patch( + "homeassistant.components.shelly.config_flow.get_info", + return_value={"mac": "test-mac", "auth": False}, + ): + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_HOST: "1.1.1.1"}, + ) + + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == "Test name" + assert result["data"] == { + CONF_HOST: "1.1.1.1", + CONF_PORT: DEFAULT_HTTP_PORT, + CONF_MODEL: MODEL_1, + CONF_SLEEP_PERIOD: 0, + CONF_GEN: 1, + } + assert result["context"]["unique_id"] == "test-mac" + assert len(mock_setup.mock_calls) == 1 + assert len(mock_setup_entry.mock_calls) == 1 async def test_form_already_configured(hass: HomeAssistant) -> None: @@ -452,20 +509,23 @@ async def test_form_already_configured(hass: HomeAssistant) -> None: "homeassistant.components.shelly.config_flow.get_info", return_value={"mac": "test-mac", "type": MODEL_1, "auth": False}, ): - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], {CONF_HOST: "1.1.1.1"}, ) - assert result2["type"] is FlowResultType.ABORT - assert result2["reason"] == "already_configured" + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "already_configured" # Test config entry got updated with latest IP assert entry.data[CONF_HOST] == "1.1.1.1" async def test_user_setup_ignored_device( - hass: HomeAssistant, mock_block_device: Mock + hass: HomeAssistant, + mock_block_device: Mock, + mock_setup_entry: AsyncMock, + mock_setup: AsyncMock, ) -> None: """Test user can successfully setup an ignored device.""" @@ -481,25 +541,16 @@ async def test_user_setup_ignored_device( DOMAIN, context={"source": config_entries.SOURCE_USER} ) - with ( - patch( - "homeassistant.components.shelly.config_flow.get_info", - return_value={"mac": "test-mac", "type": MODEL_1, "auth": False}, - ), - patch( - "homeassistant.components.shelly.async_setup", return_value=True - ) as mock_setup, - patch( - "homeassistant.components.shelly.async_setup_entry", - return_value=True, - ) as mock_setup_entry, + with patch( + "homeassistant.components.shelly.config_flow.get_info", + return_value={"mac": "test-mac", "type": MODEL_1, "auth": False}, ): - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], {CONF_HOST: "1.1.1.1"}, ) - assert result2["type"] is FlowResultType.CREATE_ENTRY + assert result["type"] is FlowResultType.CREATE_ENTRY # Test config entry got updated with latest IP assert entry.data[CONF_HOST] == "1.1.1.1" @@ -517,7 +568,12 @@ async def test_user_setup_ignored_device( ], ) async def test_form_auth_errors_test_connection_gen1( - hass: HomeAssistant, exc: Exception, base_error: str + hass: HomeAssistant, + mock_block_device: Mock, + mock_setup: AsyncMock, + mock_setup_entry: AsyncMock, + exc: Exception, + base_error: str, ) -> None: """Test we handle errors in Gen1 authenticated devices.""" result = await hass.config_entries.flow.async_init( @@ -528,21 +584,45 @@ async def test_form_auth_errors_test_connection_gen1( "homeassistant.components.shelly.config_flow.get_info", return_value={"mac": "test-mac", "auth": True}, ): - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], {CONF_HOST: "1.1.1.1"}, ) with patch( "aioshelly.block_device.BlockDevice.create", - new=AsyncMock(side_effect=exc), + side_effect=exc, ): - result3 = await hass.config_entries.flow.async_configure( - result2["flow_id"], + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_USERNAME: "test username", CONF_PASSWORD: "test password"}, ) - assert result3["type"] is FlowResultType.FORM - assert result3["errors"] == {"base": base_error} + assert result["type"] is FlowResultType.FORM + assert result["errors"] == {"base": base_error} + + with patch( + "homeassistant.components.shelly.config_flow.get_info", + return_value={"mac": "test-mac", "auth": True}, + ): + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_USERNAME: "test username", CONF_PASSWORD: "test password"}, + ) + + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == "Test name" + assert result["data"] == { + CONF_HOST: "1.1.1.1", + CONF_PORT: DEFAULT_HTTP_PORT, + CONF_MODEL: MODEL_1, + CONF_SLEEP_PERIOD: 0, + CONF_GEN: 1, + CONF_USERNAME: "test username", + CONF_PASSWORD: "test password", + } + assert result["context"]["unique_id"] == "test-mac" + assert len(mock_setup.mock_calls) == 1 + assert len(mock_setup_entry.mock_calls) == 1 @pytest.mark.parametrize( @@ -555,7 +635,12 @@ async def test_form_auth_errors_test_connection_gen1( ], ) async def test_form_auth_errors_test_connection_gen2( - hass: HomeAssistant, exc: Exception, base_error: str + hass: HomeAssistant, + mock_rpc_device: Mock, + mock_setup: AsyncMock, + mock_setup_entry: AsyncMock, + exc: Exception, + base_error: str, ) -> None: """Test we handle errors in Gen2 authenticated devices.""" result = await hass.config_entries.flow.async_init( @@ -566,20 +651,44 @@ async def test_form_auth_errors_test_connection_gen2( "homeassistant.components.shelly.config_flow.get_info", return_value={"mac": "test-mac", "auth": True, "gen": 2}, ): - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], {CONF_HOST: "1.1.1.1"}, ) with patch( "aioshelly.rpc_device.RpcDevice.create", - new=AsyncMock(side_effect=exc), + side_effect=exc, ): - result3 = await hass.config_entries.flow.async_configure( - result2["flow_id"], {CONF_PASSWORD: "test password"} + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_PASSWORD: "test password"} ) - assert result3["type"] is FlowResultType.FORM - assert result3["errors"] == {"base": base_error} + assert result["type"] is FlowResultType.FORM + assert result["errors"] == {"base": base_error} + + with patch( + "homeassistant.components.shelly.config_flow.get_info", + return_value={"mac": "test-mac", "auth": True, "gen": 2}, + ): + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_PASSWORD: "test password"}, + ) + + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == "Test name" + assert result["data"] == { + CONF_HOST: "1.1.1.1", + CONF_PORT: DEFAULT_HTTP_PORT, + CONF_MODEL: "SNSW-002P16EU", + CONF_SLEEP_PERIOD: 0, + CONF_GEN: 2, + CONF_USERNAME: "admin", + CONF_PASSWORD: "test password", + } + assert result["context"]["unique_id"] == "test-mac" + assert len(mock_setup.mock_calls) == 1 + assert len(mock_setup_entry.mock_calls) == 1 @pytest.mark.parametrize( @@ -609,6 +718,8 @@ async def test_zeroconf( get_info: dict[str, Any], mock_block_device: Mock, mock_rpc_device: Mock, + mock_setup_entry: AsyncMock, + mock_setup: AsyncMock, ) -> None: """Test we get the form.""" @@ -629,24 +740,15 @@ async def test_zeroconf( ) assert context["title_placeholders"]["name"] == "shelly1pm-12345" assert context["confirm_only"] is True - with ( - patch( - "homeassistant.components.shelly.async_setup", return_value=True - ) as mock_setup, - patch( - "homeassistant.components.shelly.async_setup_entry", - return_value=True, - ) as mock_setup_entry, - ): - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - {}, - ) - await hass.async_block_till_done() - assert result2["type"] is FlowResultType.CREATE_ENTRY - assert result2["title"] == "Test name" - assert result2["data"] == { + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {}, + ) + + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == "Test name" + assert result["data"] == { CONF_HOST: "1.1.1.1", CONF_MODEL: model, CONF_SLEEP_PERIOD: 0, @@ -657,7 +759,11 @@ async def test_zeroconf( async def test_zeroconf_sleeping_device( - hass: HomeAssistant, mock_block_device: Mock, monkeypatch: pytest.MonkeyPatch + hass: HomeAssistant, + mock_block_device: Mock, + monkeypatch: pytest.MonkeyPatch, + mock_setup_entry: AsyncMock, + mock_setup: AsyncMock, ) -> None: """Test sleeping device configuration via zeroconf.""" monkeypatch.setitem( @@ -687,24 +793,15 @@ async def test_zeroconf_sleeping_device( if flow["flow_id"] == result["flow_id"] ) assert context["title_placeholders"]["name"] == "shelly1pm-12345" - with ( - patch( - "homeassistant.components.shelly.async_setup", return_value=True - ) as mock_setup, - patch( - "homeassistant.components.shelly.async_setup_entry", - return_value=True, - ) as mock_setup_entry, - ): - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - {}, - ) - await hass.async_block_till_done() - assert result2["type"] is FlowResultType.CREATE_ENTRY - assert result2["title"] == "Test name" - assert result2["data"] == { + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {}, + ) + + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == "Test name" + assert result["data"] == { CONF_HOST: "1.1.1.1", CONF_MODEL: MODEL_1, CONF_SLEEP_PERIOD: 600, @@ -736,8 +833,9 @@ async def test_zeroconf_sleeping_device_error(hass: HomeAssistant) -> None: data=DISCOVERY_INFO, context={"source": config_entries.SOURCE_ZEROCONF}, ) - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "cannot_connect" + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "cannot_connect" async def test_options_flow_abort_setup_retry( @@ -789,8 +887,9 @@ async def test_zeroconf_already_configured(hass: HomeAssistant) -> None: data=DISCOVERY_INFO, context={"source": config_entries.SOURCE_ZEROCONF}, ) - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "already_configured" + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "already_configured" # Test config entry got updated with latest IP assert entry.data[CONF_HOST] == "1.1.1.1" @@ -816,8 +915,9 @@ async def test_zeroconf_ignored(hass: HomeAssistant) -> None: data=DISCOVERY_INFO, context={"source": config_entries.SOURCE_ZEROCONF}, ) - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "already_configured" + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "already_configured" async def test_zeroconf_with_wifi_ap_ip(hass: HomeAssistant) -> None: @@ -839,8 +939,9 @@ async def test_zeroconf_with_wifi_ap_ip(hass: HomeAssistant) -> None: ), context={"source": config_entries.SOURCE_ZEROCONF}, ) - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "already_configured" + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "already_configured" # Test config entry was not updated with the wifi ap ip assert entry.data[CONF_HOST] == "2.2.2.2" @@ -857,12 +958,16 @@ async def test_zeroconf_cannot_connect(hass: HomeAssistant) -> None: data=DISCOVERY_INFO, context={"source": config_entries.SOURCE_ZEROCONF}, ) - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "cannot_connect" + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "cannot_connect" async def test_zeroconf_require_auth( - hass: HomeAssistant, mock_block_device: Mock + hass: HomeAssistant, + mock_block_device: Mock, + mock_setup_entry: AsyncMock, + mock_setup: AsyncMock, ) -> None: """Test zeroconf if auth is required.""" @@ -875,27 +980,18 @@ async def test_zeroconf_require_auth( data=DISCOVERY_INFO, context={"source": config_entries.SOURCE_ZEROCONF}, ) - assert result["type"] is FlowResultType.FORM - assert result["errors"] == {} - with ( - patch( - "homeassistant.components.shelly.async_setup", return_value=True - ) as mock_setup, - patch( - "homeassistant.components.shelly.async_setup_entry", - return_value=True, - ) as mock_setup_entry, - ): - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - {CONF_USERNAME: "test username", CONF_PASSWORD: "test password"}, - ) - await hass.async_block_till_done() + assert result["type"] is FlowResultType.FORM + assert result["errors"] == {} - assert result2["type"] is FlowResultType.CREATE_ENTRY - assert result2["title"] == "Test name" - assert result2["data"] == { + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_USERNAME: "test username", CONF_PASSWORD: "test password"}, + ) + + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == "Test name" + assert result["data"] == { CONF_HOST: "1.1.1.1", CONF_PORT: DEFAULT_HTTP_PORT, CONF_MODEL: MODEL_1, @@ -944,8 +1040,8 @@ async def test_reauth_successful( user_input=user_input, ) - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "reauth_successful" + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "reauth_successful" @pytest.mark.parametrize( @@ -1001,8 +1097,8 @@ async def test_reauth_unsuccessful( user_input=user_input, ) - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == abort_reason + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == abort_reason async def test_reauth_get_info_error(hass: HomeAssistant) -> None: @@ -1024,8 +1120,8 @@ async def test_reauth_get_info_error(hass: HomeAssistant) -> None: user_input={CONF_PASSWORD: "test2 password"}, ) - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "reauth_unsuccessful" + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "reauth_unsuccessful" async def test_options_flow_disabled_gen_1( @@ -1105,7 +1201,6 @@ async def test_options_flow_ble(hass: HomeAssistant, mock_rpc_device: Mock) -> N CONF_BLE_SCANNER_MODE: BLEScannerMode.DISABLED, }, ) - await hass.async_block_till_done() assert result["type"] is FlowResultType.CREATE_ENTRY assert result["data"][CONF_BLE_SCANNER_MODE] is BLEScannerMode.DISABLED @@ -1121,7 +1216,6 @@ async def test_options_flow_ble(hass: HomeAssistant, mock_rpc_device: Mock) -> N CONF_BLE_SCANNER_MODE: BLEScannerMode.ACTIVE, }, ) - await hass.async_block_till_done() assert result["type"] is FlowResultType.CREATE_ENTRY assert result["data"][CONF_BLE_SCANNER_MODE] is BLEScannerMode.ACTIVE @@ -1137,7 +1231,6 @@ async def test_options_flow_ble(hass: HomeAssistant, mock_rpc_device: Mock) -> N CONF_BLE_SCANNER_MODE: BLEScannerMode.PASSIVE, }, ) - await hass.async_block_till_done() assert result["type"] is FlowResultType.CREATE_ENTRY assert result["data"][CONF_BLE_SCANNER_MODE] is BLEScannerMode.PASSIVE @@ -1173,8 +1266,9 @@ async def test_zeroconf_already_configured_triggers_refresh_mac_in_name( data=DISCOVERY_INFO_WITH_MAC, context={"source": config_entries.SOURCE_ZEROCONF}, ) - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "already_configured" + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "already_configured" monkeypatch.setattr(mock_rpc_device, "connected", False) mock_rpc_device.mock_disconnected() @@ -1213,8 +1307,9 @@ async def test_zeroconf_already_configured_triggers_refresh( data=DISCOVERY_INFO, context={"source": config_entries.SOURCE_ZEROCONF}, ) - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "already_configured" + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "already_configured" monkeypatch.setattr(mock_rpc_device, "connected", False) mock_rpc_device.mock_disconnected() @@ -1263,8 +1358,9 @@ async def test_zeroconf_sleeping_device_not_triggers_refresh( data=DISCOVERY_INFO, context={"source": config_entries.SOURCE_ZEROCONF}, ) - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "already_configured" + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "already_configured" monkeypatch.setattr(mock_rpc_device, "connected", False) mock_rpc_device.mock_disconnected() @@ -1317,8 +1413,9 @@ async def test_zeroconf_sleeping_device_attempts_configure( data=DISCOVERY_INFO, context={"source": config_entries.SOURCE_ZEROCONF}, ) - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "already_configured" + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "already_configured" assert mock_rpc_device.update_outbound_websocket.mock_calls == [] @@ -1382,8 +1479,9 @@ async def test_zeroconf_sleeping_device_attempts_configure_ws_disabled( data=DISCOVERY_INFO, context={"source": config_entries.SOURCE_ZEROCONF}, ) - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "already_configured" + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "already_configured" assert mock_rpc_device.update_outbound_websocket.mock_calls == [] @@ -1447,8 +1545,9 @@ async def test_zeroconf_sleeping_device_attempts_configure_no_url_available( data=DISCOVERY_INFO, context={"source": config_entries.SOURCE_ZEROCONF}, ) - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "already_configured" + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "already_configured" assert mock_rpc_device.update_outbound_websocket.mock_calls == [] @@ -1493,8 +1592,8 @@ async def test_sleeping_device_gen2_with_new_firmware( result["flow_id"], {CONF_HOST: "1.1.1.1"}, ) - await hass.async_block_till_done() + assert result["type"] is FlowResultType.CREATE_ENTRY assert result["data"] == { CONF_HOST: "1.1.1.1", CONF_PORT: DEFAULT_HTTP_PORT, @@ -1608,6 +1707,19 @@ async def test_reconfigure_with_exception( assert result["errors"] == {"base": base_error} + with patch( + "homeassistant.components.shelly.config_flow.get_info", + return_value={"mac": "test-mac", "type": MODEL_1, "auth": False, "gen": 2}, + ): + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + user_input={CONF_HOST: "10.10.10.10", CONF_PORT: 99}, + ) + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "reconfigure_successful" + assert entry.data == {CONF_HOST: "10.10.10.10", CONF_PORT: 99, CONF_GEN: 2} + async def test_zeroconf_rejects_ipv6(hass: HomeAssistant) -> None: """Test zeroconf discovery rejects ipv6."""