mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Add custom validator for countries (#30280)
This commit is contained in:
parent
33738cc83a
commit
d0c9a42b81
@ -367,6 +367,7 @@ homeassistant/components/websocket_api/* @home-assistant/core
|
||||
homeassistant/components/wemo/* @sqldiablo
|
||||
homeassistant/components/withings/* @vangorra
|
||||
homeassistant/components/wled/* @frenck
|
||||
homeassistant/components/workday/* @fabaff
|
||||
homeassistant/components/worldclock/* @fabaff
|
||||
homeassistant/components/wwlln/* @bachya
|
||||
homeassistant/components/xbox_live/* @MartinHjelmare
|
||||
|
@ -1,6 +1,7 @@
|
||||
"""Sensor to indicate whether the current day is a workday."""
|
||||
from datetime import datetime, timedelta
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
import holidays
|
||||
import voluptuous as vol
|
||||
@ -11,111 +12,6 @@ import homeassistant.helpers.config_validation as cv
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
# List of all countries currently supported by holidays
|
||||
# Source: https://github.com/dr-prodigy/python-holidays#available-countries
|
||||
# There seems to be no way to get the list out at runtime
|
||||
ALL_COUNTRIES = [
|
||||
"Argentina",
|
||||
"AR",
|
||||
"Aruba",
|
||||
"AW",
|
||||
"Australia",
|
||||
"AU",
|
||||
"Austria",
|
||||
"AT",
|
||||
"Brazil",
|
||||
"BR",
|
||||
"Belarus",
|
||||
"BY",
|
||||
"Belgium",
|
||||
"BE",
|
||||
"Bulgaria",
|
||||
"BG",
|
||||
"Canada",
|
||||
"CA",
|
||||
"Colombia",
|
||||
"CO",
|
||||
"Croatia",
|
||||
"HR",
|
||||
"Czech",
|
||||
"CZ",
|
||||
"Denmark",
|
||||
"DK",
|
||||
"England",
|
||||
"Estonia",
|
||||
"EE",
|
||||
"EuropeanCentralBank",
|
||||
"ECB",
|
||||
"TAR",
|
||||
"Finland",
|
||||
"FI",
|
||||
"France",
|
||||
"FRA",
|
||||
"Germany",
|
||||
"DE",
|
||||
"Hungary",
|
||||
"HU",
|
||||
"Honduras",
|
||||
"HND",
|
||||
"Iceland",
|
||||
"IS",
|
||||
"India",
|
||||
"IND",
|
||||
"Ireland",
|
||||
"IE",
|
||||
"Isle of Man",
|
||||
"Italy",
|
||||
"IT",
|
||||
"Japan",
|
||||
"JP",
|
||||
"Kenya",
|
||||
"KE",
|
||||
"Lithuania",
|
||||
"LT",
|
||||
"Luxembourg",
|
||||
"LU",
|
||||
"Mexico",
|
||||
"MX",
|
||||
"Netherlands",
|
||||
"NL",
|
||||
"NewZealand",
|
||||
"NZ",
|
||||
"Northern Ireland",
|
||||
"Norway",
|
||||
"NO",
|
||||
"Peru",
|
||||
"PE",
|
||||
"Poland",
|
||||
"Polish",
|
||||
"PL",
|
||||
"Portugal",
|
||||
"PT",
|
||||
"PortugalExt",
|
||||
"PTE",
|
||||
"Russia",
|
||||
"RU",
|
||||
"Scotland",
|
||||
"Slovenia",
|
||||
"SI",
|
||||
"Slovakia",
|
||||
"SK",
|
||||
"South Africa",
|
||||
"ZA",
|
||||
"Spain",
|
||||
"ES",
|
||||
"Sweden",
|
||||
"SE",
|
||||
"Switzerland",
|
||||
"CH",
|
||||
"Ukraine",
|
||||
"UA",
|
||||
"UnitedKingdom",
|
||||
"UK",
|
||||
"UnitedStates",
|
||||
"US",
|
||||
"Wales",
|
||||
]
|
||||
|
||||
ALLOWED_DAYS = WEEKDAYS + ["holiday"]
|
||||
|
||||
CONF_COUNTRY = "country"
|
||||
@ -132,9 +28,28 @@ DEFAULT_EXCLUDES = ["sat", "sun", "holiday"]
|
||||
DEFAULT_NAME = "Workday Sensor"
|
||||
DEFAULT_OFFSET = 0
|
||||
|
||||
|
||||
def valid_country(value: Any) -> str:
|
||||
"""Validate that the given country is supported."""
|
||||
value = cv.string(value)
|
||||
all_supported_countries = holidays.list_supported_countries()
|
||||
|
||||
try:
|
||||
raw_value = value.encode("utf-8")
|
||||
except UnicodeError:
|
||||
raise vol.Invalid(
|
||||
"The country name or the abbreviation must be a valid UTF-8 string."
|
||||
)
|
||||
if not raw_value:
|
||||
raise vol.Invalid("Country name or the abbreviation must not be empty.")
|
||||
if value not in all_supported_countries:
|
||||
raise vol.Invalid("Country is not supported.")
|
||||
return value
|
||||
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
{
|
||||
vol.Required(CONF_COUNTRY): vol.In(ALL_COUNTRIES),
|
||||
vol.Required(CONF_COUNTRY): valid_country,
|
||||
vol.Optional(CONF_EXCLUDES, default=DEFAULT_EXCLUDES): vol.All(
|
||||
cv.ensure_list, [vol.In(ALLOWED_DAYS)]
|
||||
),
|
||||
@ -151,13 +66,13 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Set up the Workday sensor."""
|
||||
sensor_name = config.get(CONF_NAME)
|
||||
country = config.get(CONF_COUNTRY)
|
||||
province = config.get(CONF_PROVINCE)
|
||||
workdays = config.get(CONF_WORKDAYS)
|
||||
excludes = config.get(CONF_EXCLUDES)
|
||||
days_offset = config.get(CONF_OFFSET)
|
||||
add_holidays = config.get(CONF_ADD_HOLIDAYS)
|
||||
country = config[CONF_COUNTRY]
|
||||
days_offset = config[CONF_OFFSET]
|
||||
excludes = config[CONF_EXCLUDES]
|
||||
province = config.get(CONF_PROVINCE)
|
||||
sensor_name = config[CONF_NAME]
|
||||
workdays = config[CONF_WORKDAYS]
|
||||
|
||||
year = (get_date(datetime.today()) + timedelta(days=days_offset)).year
|
||||
obj_holidays = getattr(holidays, country)(years=year)
|
||||
@ -259,7 +174,7 @@ class IsWorkdaySensor(BinarySensorDevice):
|
||||
# Default is no workday
|
||||
self._state = False
|
||||
|
||||
# Get iso day of the week (1 = Monday, 7 = Sunday)
|
||||
# Get ISO day of the week (1 = Monday, 7 = Sunday)
|
||||
date = get_date(datetime.today()) + timedelta(days=self._days_offset)
|
||||
day = date.isoweekday() - 1
|
||||
day_of_week = day_to_string(day)
|
||||
|
@ -3,8 +3,8 @@
|
||||
"name": "Workday",
|
||||
"documentation": "https://www.home-assistant.io/integrations/workday",
|
||||
"requirements": [
|
||||
"holidays==0.9.11"
|
||||
"holidays==0.9.12"
|
||||
],
|
||||
"dependencies": [],
|
||||
"codeowners": []
|
||||
"codeowners": ["@fabaff"]
|
||||
}
|
@ -663,7 +663,7 @@ hlk-sw16==0.0.7
|
||||
hole==0.5.0
|
||||
|
||||
# homeassistant.components.workday
|
||||
holidays==0.9.11
|
||||
holidays==0.9.12
|
||||
|
||||
# homeassistant.components.frontend
|
||||
home-assistant-frontend==20191204.1
|
||||
|
@ -228,7 +228,7 @@ herepy==2.0.0
|
||||
hole==0.5.0
|
||||
|
||||
# homeassistant.components.workday
|
||||
holidays==0.9.11
|
||||
holidays==0.9.12
|
||||
|
||||
# homeassistant.components.frontend
|
||||
home-assistant-frontend==20191204.1
|
||||
|
@ -2,7 +2,10 @@
|
||||
from datetime import date
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.components.workday.binary_sensor import day_to_string
|
||||
import pytest
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.components.workday.binary_sensor as binary_sensor
|
||||
from homeassistant.setup import setup_component
|
||||
|
||||
from tests.common import assert_setup_component, get_test_home_assistant
|
||||
@ -68,6 +71,20 @@ class TestWorkdaySetup:
|
||||
"""Stop everything that was started."""
|
||||
self.hass.stop()
|
||||
|
||||
def test_valid_country(self):
|
||||
"""Test topic name/filter validation."""
|
||||
# Invalid UTF-8, must not contain U+D800 to U+DFFF
|
||||
with pytest.raises(vol.Invalid):
|
||||
binary_sensor.valid_country("\ud800")
|
||||
with pytest.raises(vol.Invalid):
|
||||
binary_sensor.valid_country("\udfff")
|
||||
# Country MUST NOT be empty
|
||||
with pytest.raises(vol.Invalid):
|
||||
binary_sensor.valid_country("")
|
||||
# Country must be supported by holidays
|
||||
with pytest.raises(vol.Invalid):
|
||||
binary_sensor.valid_country("HomeAssistantLand")
|
||||
|
||||
def test_setup_component_province(self):
|
||||
"""Set up workday component."""
|
||||
with assert_setup_component(1, "binary_sensor"):
|
||||
@ -214,7 +231,7 @@ class TestWorkdaySetup:
|
||||
|
||||
def test_day_to_string(self):
|
||||
"""Test if day_to_string is behaving correctly."""
|
||||
assert day_to_string(0) == "mon"
|
||||
assert day_to_string(1) == "tue"
|
||||
assert day_to_string(7) == "holiday"
|
||||
assert day_to_string(8) is None
|
||||
assert binary_sensor.day_to_string(0) == "mon"
|
||||
assert binary_sensor.day_to_string(1) == "tue"
|
||||
assert binary_sensor.day_to_string(7) == "holiday"
|
||||
assert binary_sensor.day_to_string(8) is None
|
||||
|
Loading…
x
Reference in New Issue
Block a user