mirror of
https://github.com/home-assistant/core.git
synced 2025-07-14 08:47:10 +00:00
Workday create repair if named holiday missing (#101201)
This commit is contained in:
parent
c87f2027d4
commit
c64c1c8f08
@ -21,7 +21,8 @@ from homeassistant.helpers.entity_platform import (
|
|||||||
AddEntitiesCallback,
|
AddEntitiesCallback,
|
||||||
async_get_current_platform,
|
async_get_current_platform,
|
||||||
)
|
)
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
||||||
|
from homeassistant.util import dt as dt_util, slugify
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ALLOWED_DAYS,
|
ALLOWED_DAYS,
|
||||||
@ -122,6 +123,25 @@ async def async_setup_entry(
|
|||||||
LOGGER.debug("Removed %s by name '%s'", holiday, remove_holiday)
|
LOGGER.debug("Removed %s by name '%s'", holiday, remove_holiday)
|
||||||
except KeyError as unmatched:
|
except KeyError as unmatched:
|
||||||
LOGGER.warning("No holiday found matching %s", unmatched)
|
LOGGER.warning("No holiday found matching %s", unmatched)
|
||||||
|
async_create_issue(
|
||||||
|
hass,
|
||||||
|
DOMAIN,
|
||||||
|
f"bad_named_holiday-{entry.entry_id}-{slugify(remove_holiday)}",
|
||||||
|
is_fixable=True,
|
||||||
|
is_persistent=False,
|
||||||
|
severity=IssueSeverity.WARNING,
|
||||||
|
translation_key="bad_named_holiday",
|
||||||
|
translation_placeholders={
|
||||||
|
CONF_COUNTRY: country if country else "-",
|
||||||
|
"title": entry.title,
|
||||||
|
CONF_REMOVE_HOLIDAYS: remove_holiday,
|
||||||
|
},
|
||||||
|
data={
|
||||||
|
"entry_id": entry.entry_id,
|
||||||
|
"country": country,
|
||||||
|
"named_holiday": remove_holiday,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
LOGGER.debug("Found the following holidays for your configuration:")
|
LOGGER.debug("Found the following holidays for your configuration:")
|
||||||
for holiday_date, name in sorted(obj_holidays.items()):
|
for holiday_date, name in sorted(obj_holidays.items()):
|
||||||
|
@ -18,7 +18,8 @@ from homeassistant.helpers.selector import (
|
|||||||
SelectSelectorMode,
|
SelectSelectorMode,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .const import CONF_PROVINCE
|
from .config_flow import validate_custom_dates
|
||||||
|
from .const import CONF_PROVINCE, CONF_REMOVE_HOLIDAYS
|
||||||
|
|
||||||
|
|
||||||
class CountryFixFlow(RepairsFlow):
|
class CountryFixFlow(RepairsFlow):
|
||||||
@ -108,6 +109,76 @@ class CountryFixFlow(RepairsFlow):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class HolidayFixFlow(RepairsFlow):
|
||||||
|
"""Handler for an issue fixing flow."""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, entry: ConfigEntry, country: str | None, named_holiday: str
|
||||||
|
) -> None:
|
||||||
|
"""Create flow."""
|
||||||
|
self.entry = entry
|
||||||
|
self.country: str | None = country
|
||||||
|
self.named_holiday: str = named_holiday
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
async def async_step_init(
|
||||||
|
self, user_input: dict[str, str] | None = None
|
||||||
|
) -> data_entry_flow.FlowResult:
|
||||||
|
"""Handle the first step of a fix flow."""
|
||||||
|
return await self.async_step_named_holiday()
|
||||||
|
|
||||||
|
async def async_step_named_holiday(
|
||||||
|
self, user_input: dict[str, Any] | None = None
|
||||||
|
) -> data_entry_flow.FlowResult:
|
||||||
|
"""Handle the options step of a fix flow."""
|
||||||
|
errors: dict[str, str] = {}
|
||||||
|
if user_input:
|
||||||
|
options = dict(self.entry.options)
|
||||||
|
new_options = {**options, **user_input}
|
||||||
|
try:
|
||||||
|
await self.hass.async_add_executor_job(
|
||||||
|
validate_custom_dates, new_options
|
||||||
|
)
|
||||||
|
except Exception: # pylint: disable=broad-except
|
||||||
|
errors["remove_holidays"] = "remove_holiday_error"
|
||||||
|
else:
|
||||||
|
self.hass.config_entries.async_update_entry(
|
||||||
|
self.entry, options=new_options
|
||||||
|
)
|
||||||
|
await self.hass.config_entries.async_reload(self.entry.entry_id)
|
||||||
|
return self.async_create_entry(data={})
|
||||||
|
|
||||||
|
remove_holidays = self.entry.options[CONF_REMOVE_HOLIDAYS]
|
||||||
|
removed_named_holiday = [
|
||||||
|
value for value in remove_holidays if value != self.named_holiday
|
||||||
|
]
|
||||||
|
new_schema = self.add_suggested_values_to_schema(
|
||||||
|
vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Optional(CONF_REMOVE_HOLIDAYS, default=[]): SelectSelector(
|
||||||
|
SelectSelectorConfig(
|
||||||
|
options=[],
|
||||||
|
multiple=True,
|
||||||
|
custom_value=True,
|
||||||
|
mode=SelectSelectorMode.DROPDOWN,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
{CONF_REMOVE_HOLIDAYS: removed_named_holiday},
|
||||||
|
)
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id="named_holiday",
|
||||||
|
data_schema=new_schema,
|
||||||
|
description_placeholders={
|
||||||
|
CONF_COUNTRY: self.country if self.country else "-",
|
||||||
|
CONF_REMOVE_HOLIDAYS: self.named_holiday,
|
||||||
|
"title": self.entry.title,
|
||||||
|
},
|
||||||
|
errors=errors,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def async_create_fix_flow(
|
async def async_create_fix_flow(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
issue_id: str,
|
issue_id: str,
|
||||||
@ -119,6 +190,10 @@ async def async_create_fix_flow(
|
|||||||
entry_id = cast(str, entry_id)
|
entry_id = cast(str, entry_id)
|
||||||
entry = hass.config_entries.async_get_entry(entry_id)
|
entry = hass.config_entries.async_get_entry(entry_id)
|
||||||
|
|
||||||
|
if data and (holiday := data.get("named_holiday")) and entry:
|
||||||
|
# Bad named holiday in configuration
|
||||||
|
return HolidayFixFlow(entry, data.get("country"), holiday)
|
||||||
|
|
||||||
if data and entry:
|
if data and entry:
|
||||||
# Country or province does not exist
|
# Country or province does not exist
|
||||||
return CountryFixFlow(entry, data.get("country"))
|
return CountryFixFlow(entry, data.get("country"))
|
||||||
|
@ -132,6 +132,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"bad_named_holiday": {
|
||||||
|
"title": "Configured named holiday {remove_holidays} for {title} does not exist",
|
||||||
|
"fix_flow": {
|
||||||
|
"step": {
|
||||||
|
"named_holiday": {
|
||||||
|
"title": "[%key:component::workday::issues::bad_named_holiday::title%]",
|
||||||
|
"description": "Remove named holiday `{remove_holidays}` as it can't be found in country {country}.",
|
||||||
|
"data": {
|
||||||
|
"remove_holidays": "[%key:component::workday::config::step::options::data::remove_holidays%]"
|
||||||
|
},
|
||||||
|
"data_description": {
|
||||||
|
"remove_holidays": "[%key:component::workday::config::step::options::data_description::remove_holidays%]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"remove_holiday_error": "[%key:component::workday::config::error::remove_holiday_error%]"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"entity": {
|
"entity": {
|
||||||
|
@ -7,7 +7,7 @@ from homeassistant.components.repairs.websocket_api import (
|
|||||||
RepairsFlowIndexView,
|
RepairsFlowIndexView,
|
||||||
RepairsFlowResourceView,
|
RepairsFlowResourceView,
|
||||||
)
|
)
|
||||||
from homeassistant.components.workday.const import DOMAIN
|
from homeassistant.components.workday.const import CONF_REMOVE_HOLIDAYS, DOMAIN
|
||||||
from homeassistant.const import CONF_COUNTRY
|
from homeassistant.const import CONF_COUNTRY
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.issue_registry import async_create_issue
|
from homeassistant.helpers.issue_registry import async_create_issue
|
||||||
@ -16,6 +16,7 @@ from homeassistant.setup import async_setup_component
|
|||||||
from . import (
|
from . import (
|
||||||
TEST_CONFIG_INCORRECT_COUNTRY,
|
TEST_CONFIG_INCORRECT_COUNTRY,
|
||||||
TEST_CONFIG_INCORRECT_PROVINCE,
|
TEST_CONFIG_INCORRECT_PROVINCE,
|
||||||
|
TEST_CONFIG_REMOVE_NAMED,
|
||||||
init_integration,
|
init_integration,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -324,6 +325,83 @@ async def test_bad_province_none(
|
|||||||
assert not issue
|
assert not issue
|
||||||
|
|
||||||
|
|
||||||
|
async def test_bad_named_holiday(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
hass_client: ClientSessionGenerator,
|
||||||
|
hass_ws_client: WebSocketGenerator,
|
||||||
|
) -> None:
|
||||||
|
"""Test fixing bad province selecting none."""
|
||||||
|
assert await async_setup_component(hass, "repairs", {})
|
||||||
|
entry = await init_integration(hass, TEST_CONFIG_REMOVE_NAMED)
|
||||||
|
|
||||||
|
state = hass.states.get("binary_sensor.workday_sensor")
|
||||||
|
assert state
|
||||||
|
|
||||||
|
ws_client = await hass_ws_client(hass)
|
||||||
|
client = await hass_client()
|
||||||
|
|
||||||
|
await ws_client.send_json({"id": 1, "type": "repairs/list_issues"})
|
||||||
|
msg = await ws_client.receive_json()
|
||||||
|
|
||||||
|
assert msg["success"]
|
||||||
|
assert len(msg["result"]["issues"]) > 0
|
||||||
|
issue = None
|
||||||
|
for i in msg["result"]["issues"]:
|
||||||
|
if i["issue_id"] == "bad_named_holiday-1-not_a_holiday":
|
||||||
|
issue = i
|
||||||
|
assert issue is not None
|
||||||
|
|
||||||
|
url = RepairsFlowIndexView.url
|
||||||
|
resp = await client.post(
|
||||||
|
url,
|
||||||
|
json={"handler": DOMAIN, "issue_id": "bad_named_holiday-1-not_a_holiday"},
|
||||||
|
)
|
||||||
|
assert resp.status == HTTPStatus.OK
|
||||||
|
data = await resp.json()
|
||||||
|
|
||||||
|
flow_id = data["flow_id"]
|
||||||
|
assert data["description_placeholders"] == {
|
||||||
|
CONF_COUNTRY: "US",
|
||||||
|
CONF_REMOVE_HOLIDAYS: "Not a Holiday",
|
||||||
|
"title": entry.title,
|
||||||
|
}
|
||||||
|
assert data["step_id"] == "named_holiday"
|
||||||
|
|
||||||
|
url = RepairsFlowResourceView.url.format(flow_id=flow_id)
|
||||||
|
resp = await client.post(
|
||||||
|
url, json={"remove_holidays": ["Christmas", "Not exist 2"]}
|
||||||
|
)
|
||||||
|
assert resp.status == HTTPStatus.OK
|
||||||
|
data = await resp.json()
|
||||||
|
|
||||||
|
assert data["errors"] == {
|
||||||
|
CONF_REMOVE_HOLIDAYS: "remove_holiday_error",
|
||||||
|
}
|
||||||
|
|
||||||
|
url = RepairsFlowResourceView.url.format(flow_id=flow_id)
|
||||||
|
resp = await client.post(
|
||||||
|
url, json={"remove_holidays": ["Christmas", "Thanksgiving"]}
|
||||||
|
)
|
||||||
|
assert resp.status == HTTPStatus.OK
|
||||||
|
data = await resp.json()
|
||||||
|
|
||||||
|
assert data["type"] == "create_entry"
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("binary_sensor.workday_sensor")
|
||||||
|
assert state
|
||||||
|
|
||||||
|
await ws_client.send_json({"id": 2, "type": "repairs/list_issues"})
|
||||||
|
msg = await ws_client.receive_json()
|
||||||
|
|
||||||
|
assert msg["success"]
|
||||||
|
issue = None
|
||||||
|
for i in msg["result"]["issues"]:
|
||||||
|
if i["issue_id"] == "bad_named_holiday-1-not_a_holiday":
|
||||||
|
issue = i
|
||||||
|
assert not issue
|
||||||
|
|
||||||
|
|
||||||
async def test_other_fixable_issues(
|
async def test_other_fixable_issues(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
hass_client: ClientSessionGenerator,
|
hass_client: ClientSessionGenerator,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user