"""Define tests for the 17Track config flow.""" from unittest.mock import AsyncMock from py17track.errors import SeventeenTrackError import pytest from homeassistant import config_entries, data_entry_flow from homeassistant.components.seventeentrack import DOMAIN from homeassistant.components.seventeentrack.const import ( CONF_SHOW_ARCHIVED, CONF_SHOW_DELIVERED, ) from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_USER from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType from tests.common import MockConfigEntry ACCOUNT_ID = "1234" VALID_CONFIG = { CONF_USERNAME: "someemail@gmail.com", CONF_PASSWORD: "edc3eee7330e4fdda04489e3fbc283d0", } VALID_CONFIG_OLD = { CONF_USERNAME: "someemail@gmail.com", CONF_PASSWORD: "edc3eee7330e4fdda04489e3fbc283d0", } async def test_create_entry( hass: HomeAssistant, mock_setup_entry: AsyncMock, mock_seventeentrack: AsyncMock ) -> None: """Test that the user step works.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} ) assert result["type"] == FlowResultType.FORM assert result["errors"] == {} result2 = await hass.config_entries.flow.async_configure( result["flow_id"], VALID_CONFIG, ) await hass.async_block_till_done() assert result2["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY assert result2["title"] == "someemail@gmail.com" assert result2["data"] == { CONF_PASSWORD: "edc3eee7330e4fdda04489e3fbc283d0", CONF_USERNAME: "someemail@gmail.com", } @pytest.mark.parametrize( ("return_value", "side_effect", "error"), [ ( False, None, "invalid_auth", ), ( True, SeventeenTrackError(), "cannot_connect", ), ], ) async def test_flow_fails( hass: HomeAssistant, mock_seventeentrack: AsyncMock, return_value, side_effect, error, ) -> None: """Test that the user step fails.""" mock_seventeentrack.return_value.profile.login.return_value = return_value mock_seventeentrack.return_value.profile.login.side_effect = side_effect failed_result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER}, data=VALID_CONFIG, ) assert failed_result["errors"] == {"base": error} mock_seventeentrack.return_value.profile.login.return_value = True mock_seventeentrack.return_value.profile.login.side_effect = None result = await hass.config_entries.flow.async_configure( failed_result["flow_id"], VALID_CONFIG, ) await hass.async_block_till_done() assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY assert result["title"] == "someemail@gmail.com" assert result["data"] == { CONF_PASSWORD: "edc3eee7330e4fdda04489e3fbc283d0", CONF_USERNAME: "someemail@gmail.com", } async def test_import_flow(hass: HomeAssistant, mock_seventeentrack: AsyncMock) -> None: """Test the import configuration flow.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_IMPORT}, data=VALID_CONFIG_OLD, ) assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY assert result["title"] == "someemail@gmail.com" assert result["data"][CONF_USERNAME] == "someemail@gmail.com" assert result["data"][CONF_PASSWORD] == "edc3eee7330e4fdda04489e3fbc283d0" @pytest.mark.parametrize( ("return_value", "side_effect", "error"), [ ( False, None, "invalid_credentials", ), ( True, SeventeenTrackError(), "cannot_connect", ), ], ) async def test_import_flow_cannot_connect_error( hass: HomeAssistant, mock_seventeentrack: AsyncMock, return_value, side_effect, error, ) -> None: """Test the import configuration flow with error.""" mock_seventeentrack.return_value.profile.login.return_value = return_value mock_seventeentrack.return_value.profile.login.side_effect = side_effect result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_IMPORT}, data=VALID_CONFIG_OLD, ) assert result["type"] == data_entry_flow.FlowResultType.ABORT assert result["reason"] == error async def test_option_flow(hass: HomeAssistant, mock_seventeentrack: AsyncMock) -> None: """Test option flow.""" entry = MockConfigEntry( domain=DOMAIN, data=VALID_CONFIG, options={ CONF_SHOW_ARCHIVED: False, CONF_SHOW_DELIVERED: False, }, ) entry.add_to_hass(hass) await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() result = await hass.config_entries.options.async_init(entry.entry_id) assert result["type"] == data_entry_flow.FlowResultType.FORM assert result["step_id"] == "init" result = await hass.config_entries.options.async_configure( result["flow_id"], user_input={CONF_SHOW_ARCHIVED: True, CONF_SHOW_DELIVERED: False}, ) assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY assert result["data"][CONF_SHOW_ARCHIVED] assert not result["data"][CONF_SHOW_DELIVERED] async def test_import_flow_already_configured( hass: HomeAssistant, mock_seventeentrack: AsyncMock ) -> None: """Test the import configuration flow with error.""" entry = MockConfigEntry( domain=DOMAIN, data=VALID_CONFIG, unique_id=ACCOUNT_ID, ) entry.add_to_hass(hass) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} ) result_aborted = await hass.config_entries.flow.async_configure( result["flow_id"], VALID_CONFIG, ) await hass.async_block_till_done() assert result_aborted["type"] == data_entry_flow.FlowResultType.ABORT assert result_aborted["reason"] == "already_configured"