mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 12:17:07 +00:00
Refactor tests for Shelly config flow (#143517)
* Add mock_setup_entry * Add mock_setup * Improve test_form_gen1_custom_port * Improve test_form_errors_get_info * Improve test_form_errors_test_connection * Improve test_reconfigure_with_exception * Improve test_form_auth_errors_test_connection_gen1 * Improve test_form_auth_errors_test_connection_gen2 * Cleaning * Upate quality scale * Always use result variable * Remove unnecessary async_block_till_done
This commit is contained in:
parent
f5d3495c62
commit
f1b3b0c155
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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."""
|
||||
|
Loading…
x
Reference in New Issue
Block a user