444 lines
13 KiB
Python
444 lines
13 KiB
Python
"""Test the Holiday config flow."""
|
|
|
|
from datetime import datetime
|
|
from unittest.mock import AsyncMock
|
|
|
|
from freezegun.api import FrozenDateTimeFactory
|
|
from holidays import UNOFFICIAL
|
|
import pytest
|
|
|
|
from homeassistant import config_entries
|
|
from homeassistant.components.holiday.const import (
|
|
CONF_CATEGORIES,
|
|
CONF_PROVINCE,
|
|
DOMAIN,
|
|
)
|
|
from homeassistant.const import CONF_COUNTRY, STATE_OFF, STATE_ON
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.data_entry_flow import FlowResultType
|
|
from homeassistant.util import dt as dt_util
|
|
|
|
from tests.common import MockConfigEntry
|
|
|
|
|
|
async def test_form(hass: HomeAssistant, mock_setup_entry: AsyncMock) -> None:
|
|
"""Test we get the form."""
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
assert result["type"] is FlowResultType.FORM
|
|
|
|
result2 = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_COUNTRY: "DE",
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result2["type"] is FlowResultType.FORM
|
|
|
|
result3 = await hass.config_entries.flow.async_configure(
|
|
result2["flow_id"],
|
|
{
|
|
CONF_PROVINCE: "BW",
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result3["type"] is FlowResultType.CREATE_ENTRY
|
|
assert result3["title"] == "Germany, BW"
|
|
assert result3["data"] == {
|
|
"country": "DE",
|
|
"province": "BW",
|
|
}
|
|
assert len(mock_setup_entry.mock_calls) == 1
|
|
|
|
|
|
@pytest.mark.usefixtures("mock_setup_entry")
|
|
async def test_form_no_subdivision(hass: HomeAssistant) -> None:
|
|
"""Test we get the forms correctly without subdivision."""
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
assert result["type"] is FlowResultType.FORM
|
|
|
|
result2 = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_COUNTRY: "SE",
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result2["type"] is FlowResultType.CREATE_ENTRY
|
|
assert result2["title"] == "Sweden"
|
|
assert result2["data"] == {
|
|
"country": "SE",
|
|
}
|
|
|
|
|
|
@pytest.mark.usefixtures("mock_setup_entry")
|
|
async def test_form_translated_title(hass: HomeAssistant) -> None:
|
|
"""Test the title gets translated."""
|
|
hass.config.language = "de"
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
|
|
result2 = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_COUNTRY: "SE",
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result2["title"] == "Schweden"
|
|
|
|
|
|
@pytest.mark.usefixtures("mock_setup_entry")
|
|
async def test_single_combination_country_province(hass: HomeAssistant) -> None:
|
|
"""Test that configuring more than one instance is rejected."""
|
|
data_de = {
|
|
CONF_COUNTRY: "DE",
|
|
CONF_PROVINCE: "BW",
|
|
}
|
|
data_se = {
|
|
CONF_COUNTRY: "SE",
|
|
}
|
|
MockConfigEntry(domain=DOMAIN, data=data_de).add_to_hass(hass)
|
|
MockConfigEntry(domain=DOMAIN, data=data_se).add_to_hass(hass)
|
|
|
|
# Test for country without subdivisions
|
|
result_se = await hass.config_entries.flow.async_init(
|
|
DOMAIN,
|
|
context={"source": config_entries.SOURCE_USER},
|
|
data=data_se,
|
|
)
|
|
assert result_se["type"] is FlowResultType.ABORT
|
|
assert result_se["reason"] == "already_configured"
|
|
|
|
# Test for country with subdivisions
|
|
result_de_step1 = await hass.config_entries.flow.async_init(
|
|
DOMAIN,
|
|
context={"source": config_entries.SOURCE_USER},
|
|
data=data_de,
|
|
)
|
|
assert result_de_step1["type"] is FlowResultType.FORM
|
|
|
|
result_de_step2 = await hass.config_entries.flow.async_configure(
|
|
result_de_step1["flow_id"],
|
|
{
|
|
CONF_PROVINCE: data_de[CONF_PROVINCE],
|
|
},
|
|
)
|
|
assert result_de_step2["type"] is FlowResultType.ABORT
|
|
assert result_de_step2["reason"] == "already_configured"
|
|
|
|
|
|
@pytest.mark.usefixtures("mock_setup_entry")
|
|
async def test_form_babel_unresolved_language(hass: HomeAssistant) -> None:
|
|
"""Test the config flow if using not babel supported language."""
|
|
hass.config.language = "en-XX"
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_COUNTRY: "SE",
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result["title"] == "Sweden"
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_COUNTRY: "DE",
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_PROVINCE: "BW",
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
|
assert result["title"] == "Germany, BW"
|
|
assert result["data"] == {
|
|
"country": "DE",
|
|
"province": "BW",
|
|
}
|
|
|
|
|
|
@pytest.mark.usefixtures("mock_setup_entry")
|
|
async def test_form_babel_replace_dash_with_underscore(hass: HomeAssistant) -> None:
|
|
"""Test the config flow if using language with dash."""
|
|
hass.config.language = "en-GB"
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_COUNTRY: "SE",
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result["title"] == "Sweden"
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_COUNTRY: "DE",
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_PROVINCE: "BW",
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
|
assert result["title"] == "Germany, BW"
|
|
assert result["data"] == {
|
|
"country": "DE",
|
|
"province": "BW",
|
|
}
|
|
|
|
|
|
@pytest.mark.usefixtures("mock_setup_entry")
|
|
async def test_reconfigure(hass: HomeAssistant) -> None:
|
|
"""Test reconfigure flow."""
|
|
entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
title="Germany, BW",
|
|
data={"country": "DE", "province": "BW"},
|
|
)
|
|
entry.add_to_hass(hass)
|
|
|
|
result = await entry.start_reconfigure_flow(hass)
|
|
assert result["type"] is FlowResultType.FORM
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_PROVINCE: "NW",
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result["type"] is FlowResultType.ABORT
|
|
assert result["reason"] == "reconfigure_successful"
|
|
entry = hass.config_entries.async_get_entry(entry.entry_id)
|
|
assert entry.title == "Germany, NW"
|
|
assert entry.data == {"country": "DE", "province": "NW"}
|
|
|
|
|
|
@pytest.mark.usefixtures("mock_setup_entry")
|
|
async def test_reconfigure_with_categories(hass: HomeAssistant) -> None:
|
|
"""Test reconfigure flow with categories."""
|
|
entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
title="Unites States, TX",
|
|
data={"country": "US", "province": "TX"},
|
|
)
|
|
entry.add_to_hass(hass)
|
|
|
|
result = await entry.start_reconfigure_flow(hass)
|
|
assert result["type"] is FlowResultType.FORM
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_PROVINCE: "AL",
|
|
CONF_CATEGORIES: [UNOFFICIAL],
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result["type"] is FlowResultType.ABORT
|
|
assert result["reason"] == "reconfigure_successful"
|
|
entry = hass.config_entries.async_get_entry(entry.entry_id)
|
|
assert entry.title == "United States, AL"
|
|
assert entry.data == {CONF_COUNTRY: "US", CONF_PROVINCE: "AL"}
|
|
assert entry.options == {CONF_CATEGORIES: ["unofficial"]}
|
|
|
|
|
|
@pytest.mark.usefixtures("mock_setup_entry")
|
|
async def test_reconfigure_incorrect_language(hass: HomeAssistant) -> None:
|
|
"""Test reconfigure flow default to English."""
|
|
hass.config.language = "en-XX"
|
|
|
|
entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
title="Germany, BW",
|
|
data={"country": "DE", "province": "BW"},
|
|
)
|
|
entry.add_to_hass(hass)
|
|
|
|
result = await entry.start_reconfigure_flow(hass)
|
|
assert result["type"] is FlowResultType.FORM
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_PROVINCE: "NW",
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result["type"] is FlowResultType.ABORT
|
|
assert result["reason"] == "reconfigure_successful"
|
|
entry = hass.config_entries.async_get_entry(entry.entry_id)
|
|
assert entry.title == "Germany, NW"
|
|
assert entry.data == {"country": "DE", "province": "NW"}
|
|
|
|
|
|
@pytest.mark.usefixtures("mock_setup_entry")
|
|
async def test_reconfigure_entry_exists(hass: HomeAssistant) -> None:
|
|
"""Test reconfigure flow stops if other entry already exist."""
|
|
entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
title="Germany, BW",
|
|
data={"country": "DE", "province": "BW"},
|
|
)
|
|
entry.add_to_hass(hass)
|
|
entry2 = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
title="Germany, NW",
|
|
data={"country": "DE", "province": "NW"},
|
|
)
|
|
entry2.add_to_hass(hass)
|
|
|
|
result = await entry.start_reconfigure_flow(hass)
|
|
assert result["type"] is FlowResultType.FORM
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_PROVINCE: "NW",
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result["type"] is FlowResultType.ABORT
|
|
assert result["reason"] == "already_configured"
|
|
entry = hass.config_entries.async_get_entry(entry.entry_id)
|
|
assert entry.title == "Germany, BW"
|
|
assert entry.data == {"country": "DE", "province": "BW"}
|
|
|
|
|
|
async def test_form_with_options(
|
|
hass: HomeAssistant,
|
|
freezer: FrozenDateTimeFactory,
|
|
) -> None:
|
|
"""Test the flow with configuring options."""
|
|
await hass.config.async_set_time_zone("America/Chicago")
|
|
zone = await dt_util.async_get_time_zone("America/Chicago")
|
|
# Oct 31st is a Friday. Unofficial holiday as Halloween
|
|
freezer.move_to(datetime(2024, 10, 31, 12, 0, 0, tzinfo=zone))
|
|
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
assert result["type"] is FlowResultType.FORM
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_COUNTRY: "US",
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result["type"] is FlowResultType.FORM
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
CONF_PROVINCE: "TX",
|
|
CONF_CATEGORIES: [UNOFFICIAL],
|
|
},
|
|
)
|
|
await hass.async_block_till_done(wait_background_tasks=True)
|
|
|
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
|
assert result["title"] == "United States, TX"
|
|
assert result["data"] == {
|
|
CONF_COUNTRY: "US",
|
|
CONF_PROVINCE: "TX",
|
|
}
|
|
assert result["options"] == {
|
|
CONF_CATEGORIES: ["unofficial"],
|
|
}
|
|
|
|
state = hass.states.get("calendar.united_states_tx")
|
|
assert state
|
|
assert state.state == STATE_ON
|
|
|
|
entries = hass.config_entries.async_entries(DOMAIN)
|
|
entry = entries[0]
|
|
result = await hass.config_entries.options.async_init(entry.entry_id)
|
|
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["step_id"] == "init"
|
|
|
|
result = await hass.config_entries.options.async_configure(
|
|
result["flow_id"],
|
|
{CONF_CATEGORIES: []},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
|
assert result["data"] == {
|
|
CONF_CATEGORIES: [],
|
|
}
|
|
|
|
state = hass.states.get("calendar.united_states_tx")
|
|
assert state
|
|
assert state.state == STATE_OFF
|
|
|
|
|
|
@pytest.mark.usefixtures("mock_setup_entry")
|
|
async def test_options_abort_no_categories(hass: HomeAssistant) -> None:
|
|
"""Test the options flow abort if no categories to select."""
|
|
config_entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
data={CONF_COUNTRY: "SE"},
|
|
title="Sweden",
|
|
)
|
|
config_entry.add_to_hass(hass)
|
|
|
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
|
assert result["type"] is FlowResultType.ABORT
|
|
assert result["reason"] == "no_categories"
|