Skip to content

Commit 6dd31fc

Browse files
committed
Add reauth testing as in core
1 parent c14b03e commit 6dd31fc

1 file changed

Lines changed: 200 additions & 18 deletions

File tree

tests/test_config_flow.py

Lines changed: 200 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
DEFAULT_UPDATE_FREQUENCY_SECONDS,
2020
DOMAIN,
2121
)
22-
from homeassistant.config_entries import SOURCE_SSDP, SOURCE_USER
22+
from homeassistant.config_entries import SOURCE_REAUTH, SOURCE_SSDP, SOURCE_USER
2323
from homeassistant.const import (
2424
CONF_HOST,
2525
CONF_PASSWORD,
@@ -29,8 +29,10 @@
2929
)
3030
from homeassistant.core import HomeAssistant
3131
from homeassistant.data_entry_flow import FlowResultType
32+
from homeassistant.exceptions import ConfigEntryAuthFailed
3233
from homeassistant.helpers.service_info.ssdp import SsdpServiceInfo
3334
from pytest_homeassistant_custom_component.common import MockConfigEntry
35+
from victron_mqtt import AuthenticationError
3436

3537
pytestmark = pytest.mark.usefixtures("mock_setup_entry", "enable_custom_integrations")
3638
MOCK_INSTALLATION_ID = "d41243d9b9c6"
@@ -153,23 +155,6 @@ async def test_user_flow_cannot_connect(
153155
assert result["type"] is FlowResultType.FORM
154156
assert result["errors"] == {"base": "cannot_connect"}
155157

156-
# Recover from error
157-
mock_victron_hub.return_value.connect.side_effect = None
158-
mock_victron_hub.return_value.installation_id = MOCK_INSTALLATION_ID
159-
160-
result = await hass.config_entries.flow.async_configure(
161-
result["flow_id"],
162-
{
163-
CONF_HOST: MOCK_HOST,
164-
CONF_PORT: DEFAULT_PORT,
165-
CONF_SSL: False,
166-
CONF_SIMPLE_NAMING: False,
167-
CONF_UPDATE_FREQUENCY_SECONDS: DEFAULT_UPDATE_FREQUENCY_SECONDS,
168-
},
169-
)
170-
171-
assert result["type"] is FlowResultType.CREATE_ENTRY
172-
173158

174159
async def test_user_flow_unknown_error(
175160
hass: HomeAssistant, mock_victron_hub: MagicMock
@@ -440,3 +425,200 @@ async def test_options_flow_cannot_connect(
440425

441426
assert result["type"] is FlowResultType.FORM
442427
assert result["errors"] == {"base": "cannot_connect"}
428+
429+
430+
@pytest.mark.usefixtures("mock_victron_hub")
431+
async def test_reauth_flow_success(hass: HomeAssistant) -> None:
432+
"""Test successful reauthentication flow."""
433+
mock_config_entry = MockConfigEntry(
434+
domain=DOMAIN,
435+
unique_id=MOCK_INSTALLATION_ID,
436+
data={
437+
CONF_HOST: MOCK_HOST,
438+
CONF_PORT: DEFAULT_PORT,
439+
CONF_USERNAME: "old-username",
440+
CONF_PASSWORD: "old-password",
441+
CONF_INSTALLATION_ID: MOCK_INSTALLATION_ID,
442+
CONF_SSL: False,
443+
CONF_UPDATE_FREQUENCY_SECONDS: 42,
444+
},
445+
)
446+
mock_config_entry.add_to_hass(hass)
447+
448+
result = await hass.config_entries.flow.async_init(
449+
DOMAIN,
450+
context={"source": SOURCE_REAUTH, "entry_id": mock_config_entry.entry_id},
451+
data=mock_config_entry.data,
452+
)
453+
454+
assert result["type"] is FlowResultType.FORM
455+
assert result["step_id"] == "reauth_confirm"
456+
457+
result = await hass.config_entries.flow.async_configure(
458+
result["flow_id"],
459+
user_input={
460+
CONF_USERNAME: "new-username",
461+
CONF_PASSWORD: "new-password",
462+
},
463+
)
464+
465+
assert result["type"] is FlowResultType.ABORT
466+
assert result["reason"] == "reauth_successful"
467+
assert mock_config_entry.data[CONF_USERNAME] == "new-username"
468+
assert mock_config_entry.data[CONF_PASSWORD] == "new-password"
469+
assert mock_config_entry.data[CONF_UPDATE_FREQUENCY_SECONDS] == 42
470+
471+
472+
async def test_reauth_flow_cannot_connect(
473+
hass: HomeAssistant, mock_victron_hub: MagicMock
474+
) -> None:
475+
"""Test reauthentication flow handles connection errors."""
476+
mock_config_entry = MockConfigEntry(
477+
domain=DOMAIN,
478+
unique_id=MOCK_INSTALLATION_ID,
479+
data={
480+
CONF_HOST: MOCK_HOST,
481+
CONF_PORT: DEFAULT_PORT,
482+
CONF_USERNAME: "old-username",
483+
CONF_PASSWORD: "old-password",
484+
CONF_INSTALLATION_ID: MOCK_INSTALLATION_ID,
485+
CONF_SSL: False,
486+
CONF_UPDATE_FREQUENCY_SECONDS: DEFAULT_UPDATE_FREQUENCY_SECONDS,
487+
},
488+
)
489+
mock_config_entry.add_to_hass(hass)
490+
491+
result = await hass.config_entries.flow.async_init(
492+
DOMAIN,
493+
context={"source": SOURCE_REAUTH, "entry_id": mock_config_entry.entry_id},
494+
data=mock_config_entry.data,
495+
)
496+
497+
assert result["type"] is FlowResultType.FORM
498+
assert result["step_id"] == "reauth_confirm"
499+
500+
mock_victron_hub.return_value.connect.side_effect = CannotConnectError
501+
502+
result = await hass.config_entries.flow.async_configure(
503+
result["flow_id"],
504+
user_input={
505+
CONF_USERNAME: "new-username",
506+
CONF_PASSWORD: "new-password",
507+
},
508+
)
509+
510+
assert result["type"] is FlowResultType.FORM
511+
assert result["errors"] == {"base": "cannot_connect"}
512+
513+
# Test recovery from error
514+
mock_victron_hub.return_value.connect.side_effect = None
515+
mock_victron_hub.return_value.installation_id = MOCK_INSTALLATION_ID
516+
517+
result = await hass.config_entries.flow.async_configure(
518+
result["flow_id"],
519+
user_input={
520+
CONF_USERNAME: "new-username",
521+
CONF_PASSWORD: "new-password",
522+
},
523+
)
524+
525+
assert result["type"] is FlowResultType.ABORT
526+
assert result["reason"] == "reauth_successful"
527+
528+
529+
async def test_reauth_flow_unknown_error(
530+
hass: HomeAssistant, mock_victron_hub: MagicMock
531+
) -> None:
532+
"""Test reauthentication flow handles unknown errors."""
533+
mock_config_entry = MockConfigEntry(
534+
domain=DOMAIN,
535+
unique_id=MOCK_INSTALLATION_ID,
536+
data={
537+
CONF_HOST: MOCK_HOST,
538+
CONF_PORT: DEFAULT_PORT,
539+
CONF_USERNAME: "old-username",
540+
CONF_PASSWORD: "old-password",
541+
CONF_INSTALLATION_ID: MOCK_INSTALLATION_ID,
542+
CONF_SSL: False,
543+
CONF_UPDATE_FREQUENCY_SECONDS: DEFAULT_UPDATE_FREQUENCY_SECONDS,
544+
},
545+
)
546+
mock_config_entry.add_to_hass(hass)
547+
548+
result = await hass.config_entries.flow.async_init(
549+
DOMAIN,
550+
context={"source": SOURCE_REAUTH, "entry_id": mock_config_entry.entry_id},
551+
data=mock_config_entry.data,
552+
)
553+
554+
mock_victron_hub.return_value.connect.side_effect = Exception("Test error")
555+
556+
result = await hass.config_entries.flow.async_configure(
557+
result["flow_id"],
558+
user_input={
559+
CONF_USERNAME: "new-username",
560+
CONF_PASSWORD: "new-password",
561+
},
562+
)
563+
564+
assert result["type"] is FlowResultType.FORM
565+
assert result["errors"] == {"base": "unknown"}
566+
567+
568+
async def test_reauth_flow_invalid_auth(
569+
hass: HomeAssistant, mock_victron_hub: MagicMock
570+
) -> None:
571+
"""Test reauthentication flow handles authentication errors."""
572+
mock_config_entry = MockConfigEntry(
573+
domain=DOMAIN,
574+
unique_id=MOCK_INSTALLATION_ID,
575+
data={
576+
CONF_HOST: MOCK_HOST,
577+
CONF_PORT: DEFAULT_PORT,
578+
CONF_USERNAME: "old-username",
579+
CONF_PASSWORD: "old-password",
580+
CONF_INSTALLATION_ID: MOCK_INSTALLATION_ID,
581+
CONF_SSL: False,
582+
CONF_UPDATE_FREQUENCY_SECONDS: DEFAULT_UPDATE_FREQUENCY_SECONDS,
583+
},
584+
)
585+
mock_config_entry.add_to_hass(hass)
586+
587+
result = await hass.config_entries.flow.async_init(
588+
DOMAIN,
589+
context={"source": SOURCE_REAUTH, "entry_id": mock_config_entry.entry_id},
590+
data=mock_config_entry.data,
591+
)
592+
593+
assert result["type"] is FlowResultType.FORM
594+
assert result["step_id"] == "reauth_confirm"
595+
596+
mock_victron_hub.return_value.connect.side_effect = AuthenticationError(
597+
"Invalid credentials"
598+
)
599+
600+
result = await hass.config_entries.flow.async_configure(
601+
result["flow_id"],
602+
user_input={
603+
CONF_USERNAME: "new-username",
604+
CONF_PASSWORD: "wrong-password",
605+
},
606+
)
607+
608+
assert result["type"] is FlowResultType.FORM
609+
assert result["errors"] == {"base": "invalid_auth"}
610+
611+
# Test recovery with correct credentials
612+
mock_victron_hub.return_value.connect.side_effect = None
613+
mock_victron_hub.return_value.installation_id = MOCK_INSTALLATION_ID
614+
615+
result = await hass.config_entries.flow.async_configure(
616+
result["flow_id"],
617+
user_input={
618+
CONF_USERNAME: "new-username",
619+
CONF_PASSWORD: "correct-password",
620+
},
621+
)
622+
623+
assert result["type"] is FlowResultType.ABORT
624+
assert result["reason"] == "reauth_successful"

0 commit comments

Comments
 (0)