diff --git a/tests/components/ridwell/conftest.py b/tests/components/ridwell/conftest.py new file mode 100644 index 00000000000..35b4ddded4e --- /dev/null +++ b/tests/components/ridwell/conftest.py @@ -0,0 +1,85 @@ +"""Define test fixtures for Ridwell.""" +from datetime import date +from unittest.mock import AsyncMock, Mock, patch + +from aioridwell.model import EventState, RidwellPickup, RidwellPickupEvent +import pytest + +from homeassistant.components.ridwell.const import DOMAIN +from homeassistant.const import CONF_PASSWORD, CONF_USERNAME +from homeassistant.setup import async_setup_component + +from tests.common import MockConfigEntry + +ACCOUNT_ID = "12345" + + +@pytest.fixture(name="account") +def account_fixture(): + """Define a Ridwell account.""" + return Mock( + account_id=ACCOUNT_ID, + address={ + "street1": "123 Main Street", + "city": "New York", + "state": "New York", + "postal_code": "10001", + }, + async_get_next_pickup_event=AsyncMock( + return_value=RidwellPickupEvent( + AsyncMock(), + "event_123", + date(2022, 1, 24), + [RidwellPickup("Plastic Film", "offer_123", 1, "product_123", 1)], + EventState.INITIALIZED, + ) + ), + ) + + +@pytest.fixture(name="client") +def client_fixture(account): + """Define an aioridwell client.""" + return Mock( + async_authenticate=AsyncMock(), + async_get_accounts=AsyncMock(return_value={ACCOUNT_ID: account}), + ) + + +@pytest.fixture(name="config_entry") +def config_entry_fixture(hass, config, unique_id): + """Define a config entry fixture.""" + entry = MockConfigEntry(domain=DOMAIN, unique_id=unique_id, data=config) + entry.add_to_hass(hass) + return entry + + +@pytest.fixture(name="config") +def config_fixture(hass): + """Define a config entry data fixture.""" + return { + CONF_USERNAME: "user@email.com", + CONF_PASSWORD: "password", + } + + +@pytest.fixture(name="setup_ridwell") +async def setup_ridwell_fixture(hass, client, config): + """Define a fixture to set up Ridwell.""" + with patch( + "homeassistant.components.ridwell.config_flow.async_get_client", + return_value=client, + ), patch( + "homeassistant.components.ridwell.async_get_client", return_value=client + ), patch( + "homeassistant.components.ridwell.PLATFORMS", [] + ): + assert await async_setup_component(hass, DOMAIN, config) + await hass.async_block_till_done() + yield + + +@pytest.fixture(name="unique_id") +def unique_id_fixture(hass): + """Define a config entry unique ID fixture.""" + return "user@email.com" diff --git a/tests/components/ridwell/test_config_flow.py b/tests/components/ridwell/test_config_flow.py index 957ad31affb..358ac6783ad 100644 --- a/tests/components/ridwell/test_config_flow.py +++ b/tests/components/ridwell/test_config_flow.py @@ -1,5 +1,5 @@ """Test the Ridwell config flow.""" -from unittest.mock import AsyncMock, patch +from unittest.mock import patch from aioridwell.errors import InvalidCredentialsError, RidwellError import pytest @@ -14,114 +14,66 @@ from homeassistant.data_entry_flow import ( RESULT_TYPE_FORM, ) -from tests.common import MockConfigEntry - -@pytest.fixture(name="client") -def client_fixture(): - """Define a fixture for an aioridwell client.""" - return AsyncMock(return_value=None) - - -@pytest.fixture(name="client_login") -def client_login_fixture(client): - """Define a fixture for patching the aioridwell coroutine to get a client.""" - with patch( - "homeassistant.components.ridwell.config_flow.async_get_client" - ) as mock_client: - mock_client.side_effect = client - yield mock_client - - -async def test_duplicate_error(hass: HomeAssistant): +async def test_duplicate_error(hass: HomeAssistant, config, config_entry): """Test that errors are shown when duplicate entries are added.""" - MockConfigEntry( - domain=DOMAIN, - unique_id="user@email.com", - data={CONF_USERNAME: "user@email.com", CONF_PASSWORD: "password"}, - ).add_to_hass(hass) - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": config_entries.SOURCE_USER}, - data={CONF_USERNAME: "user@email.com", CONF_PASSWORD: "password"}, + DOMAIN, context={"source": config_entries.SOURCE_USER}, data=config ) - assert result["type"] == RESULT_TYPE_ABORT assert result["reason"] == "already_configured" +@pytest.mark.parametrize( + "exc,error", + [ + (InvalidCredentialsError, "invalid_auth"), + (RidwellError, "unknown"), + ], +) +async def test_errors(hass: HomeAssistant, config, error, exc) -> None: + """Test that various exceptions show the correct error.""" + with patch( + "homeassistant.components.ridwell.config_flow.async_get_client", side_effect=exc + ): + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": config_entries.SOURCE_USER}, data=config + ) + assert result["type"] == RESULT_TYPE_FORM + assert result["errors"]["base"] == error + + async def test_show_form_user(hass: HomeAssistant) -> None: """Test showing the form to input credentials.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} ) - assert result["type"] == RESULT_TYPE_FORM assert result["step_id"] == "user" assert result["errors"] is None -async def test_step_reauth(hass: HomeAssistant, client_login) -> None: +async def test_step_reauth( + hass: HomeAssistant, config, config_entry, setup_ridwell +) -> None: """Test a full reauth flow.""" - MockConfigEntry( - domain=DOMAIN, - unique_id="user@email.com", + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": config_entries.SOURCE_REAUTH}, data={CONF_USERNAME: "user@email.com", CONF_PASSWORD: "password"}, - ).add_to_hass(hass) - - with patch( - "homeassistant.components.ridwell.async_setup_entry", - return_value=True, - ): - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": config_entries.SOURCE_REAUTH}, - data={CONF_USERNAME: "user@email.com", CONF_PASSWORD: "password"}, - ) - result = await hass.config_entries.flow.async_configure( - result["flow_id"], - user_input={CONF_PASSWORD: "password"}, - ) - await hass.async_block_till_done() - + ) + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + user_input={CONF_PASSWORD: "password"}, + ) assert result["type"] == RESULT_TYPE_ABORT assert result["reason"] == "reauth_successful" assert len(hass.config_entries.async_entries()) == 1 -async def test_step_user(hass: HomeAssistant, client_login) -> None: +async def test_step_user(hass: HomeAssistant, config, setup_ridwell) -> None: """Test that the full user step succeeds.""" - with patch( - "homeassistant.components.ridwell.async_setup_entry", - return_value=True, - ): - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": config_entries.SOURCE_USER}, - data={CONF_USERNAME: "user@email.com", CONF_PASSWORD: "password"}, - ) - await hass.async_block_till_done() - - assert result["type"] == RESULT_TYPE_CREATE_ENTRY - - -@pytest.mark.parametrize( - "client,error", - [ - (AsyncMock(side_effect=InvalidCredentialsError), "invalid_auth"), - (AsyncMock(side_effect=RidwellError), "unknown"), - ], -) -async def test_step_user_invalid_credentials( - hass: HomeAssistant, client_login, error -) -> None: - """Test that invalid credentials are handled correctly.""" result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": config_entries.SOURCE_USER}, - data={CONF_USERNAME: "user@email.com", CONF_PASSWORD: "password"}, + DOMAIN, context={"source": config_entries.SOURCE_USER}, data=config ) - - assert result["type"] == RESULT_TYPE_FORM - assert result["errors"]["base"] == error + assert result["type"] == RESULT_TYPE_CREATE_ENTRY