core/tests/components/tuya/test_config_flow.py

245 lines
7.3 KiB
Python

"""Tests for the Tuya config flow."""
from __future__ import annotations
from unittest.mock import MagicMock
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.tuya.const import CONF_APP_TYPE, CONF_USER_CODE, DOMAIN
from homeassistant.config_entries import SOURCE_USER
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from tests.common import MockConfigEntry
pytestmark = pytest.mark.usefixtures("mock_setup_entry")
@pytest.mark.usefixtures("mock_tuya_login_control")
async def test_user_flow(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
) -> None:
"""Test the full happy path user flow from start to finish."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
)
assert result.get("type") is FlowResultType.FORM
assert result.get("step_id") == "user"
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={CONF_USER_CODE: "12345"},
)
assert result2.get("type") is FlowResultType.FORM
assert result2.get("step_id") == "scan"
result3 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={},
)
assert result3.get("type") is FlowResultType.CREATE_ENTRY
assert result3 == snapshot
async def test_user_flow_failed_qr_code(
hass: HomeAssistant,
mock_tuya_login_control: MagicMock,
) -> None:
"""Test an error occurring while retrieving the QR code."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
)
assert result.get("type") is FlowResultType.FORM
assert result.get("step_id") == "user"
# Something went wrong getting the QR code (like an invalid user code)
mock_tuya_login_control.qr_code.return_value["success"] = False
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={CONF_USER_CODE: "12345"},
)
assert result2.get("type") is FlowResultType.FORM
assert result2.get("errors") == {"base": "login_error"}
# This time it worked out
mock_tuya_login_control.qr_code.return_value["success"] = True
result3 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={CONF_USER_CODE: "12345"},
)
assert result3.get("step_id") == "scan"
result3 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={},
)
assert result3.get("type") is FlowResultType.CREATE_ENTRY
async def test_user_flow_failed_scan(
hass: HomeAssistant,
mock_tuya_login_control: MagicMock,
) -> None:
"""Test an error occurring while verifying login."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
)
assert result.get("type") is FlowResultType.FORM
assert result.get("step_id") == "user"
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={CONF_USER_CODE: "12345"},
)
assert result2.get("type") is FlowResultType.FORM
assert result2.get("step_id") == "scan"
# Access has been denied, or the code hasn't been scanned yet
good_values = mock_tuya_login_control.login_result.return_value
mock_tuya_login_control.login_result.return_value = (
False,
{"msg": "oops", "code": 42},
)
result3 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={},
)
assert result3.get("type") is FlowResultType.FORM
assert result3.get("errors") == {"base": "login_error"}
# This time it worked out
mock_tuya_login_control.login_result.return_value = good_values
result4 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={},
)
assert result4.get("type") is FlowResultType.CREATE_ENTRY
@pytest.mark.usefixtures("mock_tuya_login_control")
async def test_reauth_flow(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
snapshot: SnapshotAssertion,
) -> None:
"""Test the reauthentication configuration flow."""
mock_config_entry.add_to_hass(hass)
result = await mock_config_entry.start_reauth_flow(hass)
assert result.get("type") is FlowResultType.FORM
assert result.get("step_id") == "scan"
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={},
)
assert result2.get("type") is FlowResultType.ABORT
assert result2.get("reason") == "reauth_successful"
assert mock_config_entry == snapshot
@pytest.mark.usefixtures("mock_tuya_login_control")
async def test_reauth_flow_migration(
hass: HomeAssistant,
mock_old_config_entry: MockConfigEntry,
snapshot: SnapshotAssertion,
) -> None:
"""Test the reauthentication configuration flow.
This flow tests the migration from an old config entry.
"""
mock_old_config_entry.add_to_hass(hass)
# Ensure old data is there, new data is missing
assert CONF_APP_TYPE in mock_old_config_entry.data
assert CONF_USER_CODE not in mock_old_config_entry.data
result = await mock_old_config_entry.start_reauth_flow(hass)
assert result.get("type") is FlowResultType.FORM
assert result.get("step_id") == "reauth_user_code"
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={CONF_USER_CODE: "12345"},
)
assert result2.get("type") is FlowResultType.FORM
assert result2.get("step_id") == "scan"
result3 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={},
)
assert result3.get("type") is FlowResultType.ABORT
assert result3.get("reason") == "reauth_successful"
# Ensure the old data is gone, new data is present
assert CONF_APP_TYPE not in mock_old_config_entry.data
assert CONF_USER_CODE in mock_old_config_entry.data
assert mock_old_config_entry == snapshot
async def test_reauth_flow_failed_qr_code(
hass: HomeAssistant,
mock_tuya_login_control: MagicMock,
mock_old_config_entry: MockConfigEntry,
) -> None:
"""Test an error occurring while retrieving the QR code."""
mock_old_config_entry.add_to_hass(hass)
result = await mock_old_config_entry.start_reauth_flow(hass)
# Something went wrong getting the QR code (like an invalid user code)
mock_tuya_login_control.qr_code.return_value["success"] = False
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={CONF_USER_CODE: "12345"},
)
assert result2.get("type") is FlowResultType.FORM
assert result2.get("errors") == {"base": "login_error"}
# This time it worked out
mock_tuya_login_control.qr_code.return_value["success"] = True
result3 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={CONF_USER_CODE: "12345"},
)
assert result3.get("step_id") == "scan"
result3 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={},
)
assert result3.get("type") is FlowResultType.ABORT
assert result3.get("reason") == "reauth_successful"