mirror of
https://github.com/home-assistant/core.git
synced 2025-07-10 06:47:09 +00:00
Add update_daily action to Habitica integration (#140328)
* add update_daily action * day strings
This commit is contained in:
parent
324f208d68
commit
78a04776e4
@ -52,6 +52,11 @@ ATTR_REMINDER = "reminder"
|
|||||||
ATTR_REMOVE_REMINDER = "remove_reminder"
|
ATTR_REMOVE_REMINDER = "remove_reminder"
|
||||||
ATTR_CLEAR_REMINDER = "clear_reminder"
|
ATTR_CLEAR_REMINDER = "clear_reminder"
|
||||||
ATTR_CLEAR_DATE = "clear_date"
|
ATTR_CLEAR_DATE = "clear_date"
|
||||||
|
ATTR_REPEAT = "repeat"
|
||||||
|
ATTR_INTERVAL = "every_x"
|
||||||
|
ATTR_START_DATE = "start_date"
|
||||||
|
ATTR_REPEAT_MONTHLY = "repeat_monthly"
|
||||||
|
ATTR_STREAK = "streak"
|
||||||
|
|
||||||
SERVICE_CAST_SKILL = "cast_skill"
|
SERVICE_CAST_SKILL = "cast_skill"
|
||||||
SERVICE_START_QUEST = "start_quest"
|
SERVICE_START_QUEST = "start_quest"
|
||||||
@ -73,6 +78,7 @@ SERVICE_UPDATE_HABIT = "update_habit"
|
|||||||
SERVICE_CREATE_HABIT = "create_habit"
|
SERVICE_CREATE_HABIT = "create_habit"
|
||||||
SERVICE_UPDATE_TODO = "update_todo"
|
SERVICE_UPDATE_TODO = "update_todo"
|
||||||
SERVICE_CREATE_TODO = "create_todo"
|
SERVICE_CREATE_TODO = "create_todo"
|
||||||
|
SERVICE_UPDATE_DAILY = "update_daily"
|
||||||
|
|
||||||
DEVELOPER_ID = "4c4ca53f-c059-4ffa-966e-9d29dd405daf"
|
DEVELOPER_ID = "4c4ca53f-c059-4ffa-966e-9d29dd405daf"
|
||||||
X_CLIENT = f"{DEVELOPER_ID} - {APPLICATION_NAME} {__version__}"
|
X_CLIENT = f"{DEVELOPER_ID} - {APPLICATION_NAME} {__version__}"
|
||||||
@ -80,3 +86,5 @@ X_CLIENT = f"{DEVELOPER_ID} - {APPLICATION_NAME} {__version__}"
|
|||||||
SECTION_REAUTH_LOGIN = "reauth_login"
|
SECTION_REAUTH_LOGIN = "reauth_login"
|
||||||
SECTION_REAUTH_API_KEY = "reauth_api_key"
|
SECTION_REAUTH_API_KEY = "reauth_api_key"
|
||||||
SECTION_DANGER_ZONE = "danger_zone"
|
SECTION_DANGER_ZONE = "danger_zone"
|
||||||
|
|
||||||
|
WEEK_DAYS = ["m", "t", "w", "th", "f", "s", "su"]
|
||||||
|
@ -259,6 +259,17 @@
|
|||||||
"sections": {
|
"sections": {
|
||||||
"developer_options": "mdi:test-tube"
|
"developer_options": "mdi:test-tube"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"update_daily": {
|
||||||
|
"service": "mdi:calendar-month",
|
||||||
|
"sections": {
|
||||||
|
"checklist_options": "mdi:format-list-checks",
|
||||||
|
"tag_options": "mdi:tag",
|
||||||
|
"developer_options": "mdi:test-tube",
|
||||||
|
"reminder_options": "mdi:reminder",
|
||||||
|
"repeat_weekly_options": "mdi:calendar-refresh",
|
||||||
|
"repeat_monthly_options": "mdi:calendar-refresh"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import asdict
|
from dataclasses import asdict
|
||||||
from datetime import datetime, time
|
from datetime import UTC, date, datetime, time
|
||||||
import logging
|
import logging
|
||||||
from typing import TYPE_CHECKING, Any, cast
|
from typing import TYPE_CHECKING, Any, cast
|
||||||
from uuid import UUID, uuid4
|
from uuid import UUID, uuid4
|
||||||
@ -17,6 +17,7 @@ from habiticalib import (
|
|||||||
NotAuthorizedError,
|
NotAuthorizedError,
|
||||||
NotFoundError,
|
NotFoundError,
|
||||||
Reminders,
|
Reminders,
|
||||||
|
Repeat,
|
||||||
Skill,
|
Skill,
|
||||||
Task,
|
Task,
|
||||||
TaskData,
|
TaskData,
|
||||||
@ -39,6 +40,7 @@ from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
|
|||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
||||||
from homeassistant.helpers.selector import ConfigEntrySelector
|
from homeassistant.helpers.selector import ConfigEntrySelector
|
||||||
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ATTR_ADD_CHECKLIST_ITEM,
|
ATTR_ADD_CHECKLIST_ITEM,
|
||||||
@ -53,6 +55,7 @@ from .const import (
|
|||||||
ATTR_DATA,
|
ATTR_DATA,
|
||||||
ATTR_DIRECTION,
|
ATTR_DIRECTION,
|
||||||
ATTR_FREQUENCY,
|
ATTR_FREQUENCY,
|
||||||
|
ATTR_INTERVAL,
|
||||||
ATTR_ITEM,
|
ATTR_ITEM,
|
||||||
ATTR_KEYWORD,
|
ATTR_KEYWORD,
|
||||||
ATTR_NOTES,
|
ATTR_NOTES,
|
||||||
@ -62,8 +65,12 @@ from .const import (
|
|||||||
ATTR_REMOVE_CHECKLIST_ITEM,
|
ATTR_REMOVE_CHECKLIST_ITEM,
|
||||||
ATTR_REMOVE_REMINDER,
|
ATTR_REMOVE_REMINDER,
|
||||||
ATTR_REMOVE_TAG,
|
ATTR_REMOVE_TAG,
|
||||||
|
ATTR_REPEAT,
|
||||||
|
ATTR_REPEAT_MONTHLY,
|
||||||
ATTR_SCORE_CHECKLIST_ITEM,
|
ATTR_SCORE_CHECKLIST_ITEM,
|
||||||
ATTR_SKILL,
|
ATTR_SKILL,
|
||||||
|
ATTR_START_DATE,
|
||||||
|
ATTR_STREAK,
|
||||||
ATTR_TAG,
|
ATTR_TAG,
|
||||||
ATTR_TARGET,
|
ATTR_TARGET,
|
||||||
ATTR_TASK,
|
ATTR_TASK,
|
||||||
@ -87,9 +94,11 @@ from .const import (
|
|||||||
SERVICE_SCORE_REWARD,
|
SERVICE_SCORE_REWARD,
|
||||||
SERVICE_START_QUEST,
|
SERVICE_START_QUEST,
|
||||||
SERVICE_TRANSFORMATION,
|
SERVICE_TRANSFORMATION,
|
||||||
|
SERVICE_UPDATE_DAILY,
|
||||||
SERVICE_UPDATE_HABIT,
|
SERVICE_UPDATE_HABIT,
|
||||||
SERVICE_UPDATE_REWARD,
|
SERVICE_UPDATE_REWARD,
|
||||||
SERVICE_UPDATE_TODO,
|
SERVICE_UPDATE_TODO,
|
||||||
|
WEEK_DAYS,
|
||||||
)
|
)
|
||||||
from .coordinator import HabiticaConfigEntry
|
from .coordinator import HabiticaConfigEntry
|
||||||
|
|
||||||
@ -152,13 +161,24 @@ BASE_TASK_SCHEMA = vol.Schema(
|
|||||||
vol.Optional(ATTR_FREQUENCY): vol.Coerce(Frequency),
|
vol.Optional(ATTR_FREQUENCY): vol.Coerce(Frequency),
|
||||||
vol.Optional(ATTR_DATE): cv.date,
|
vol.Optional(ATTR_DATE): cv.date,
|
||||||
vol.Optional(ATTR_CLEAR_DATE): cv.boolean,
|
vol.Optional(ATTR_CLEAR_DATE): cv.boolean,
|
||||||
vol.Optional(ATTR_REMINDER): vol.All(cv.ensure_list, [cv.datetime]),
|
vol.Optional(ATTR_REMINDER): vol.All(
|
||||||
vol.Optional(ATTR_REMOVE_REMINDER): vol.All(cv.ensure_list, [cv.datetime]),
|
cv.ensure_list, [vol.Any(cv.datetime, cv.time)]
|
||||||
|
),
|
||||||
|
vol.Optional(ATTR_REMOVE_REMINDER): vol.All(
|
||||||
|
cv.ensure_list, [vol.Any(cv.datetime, cv.time)]
|
||||||
|
),
|
||||||
vol.Optional(ATTR_CLEAR_REMINDER): cv.boolean,
|
vol.Optional(ATTR_CLEAR_REMINDER): cv.boolean,
|
||||||
vol.Optional(ATTR_ADD_CHECKLIST_ITEM): vol.All(cv.ensure_list, [str]),
|
vol.Optional(ATTR_ADD_CHECKLIST_ITEM): vol.All(cv.ensure_list, [str]),
|
||||||
vol.Optional(ATTR_REMOVE_CHECKLIST_ITEM): vol.All(cv.ensure_list, [str]),
|
vol.Optional(ATTR_REMOVE_CHECKLIST_ITEM): vol.All(cv.ensure_list, [str]),
|
||||||
vol.Optional(ATTR_SCORE_CHECKLIST_ITEM): vol.All(cv.ensure_list, [str]),
|
vol.Optional(ATTR_SCORE_CHECKLIST_ITEM): vol.All(cv.ensure_list, [str]),
|
||||||
vol.Optional(ATTR_UNSCORE_CHECKLIST_ITEM): vol.All(cv.ensure_list, [str]),
|
vol.Optional(ATTR_UNSCORE_CHECKLIST_ITEM): vol.All(cv.ensure_list, [str]),
|
||||||
|
vol.Optional(ATTR_START_DATE): cv.date,
|
||||||
|
vol.Optional(ATTR_INTERVAL): vol.All(int, vol.Range(0)),
|
||||||
|
vol.Optional(ATTR_REPEAT): vol.All(cv.ensure_list, [vol.In(WEEK_DAYS)]),
|
||||||
|
vol.Optional(ATTR_REPEAT_MONTHLY): vol.All(
|
||||||
|
cv.string, vol.In({"day_of_month", "day_of_week"})
|
||||||
|
),
|
||||||
|
vol.Optional(ATTR_STREAK): vol.All(int, vol.Range(0)),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -175,6 +195,12 @@ SERVICE_CREATE_TASK_SCHEMA = BASE_TASK_SCHEMA.extend(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SERVICE_DAILY_SCHEMA = {
|
||||||
|
vol.Optional(ATTR_REMINDER): vol.All(cv.ensure_list, [cv.time]),
|
||||||
|
vol.Optional(ATTR_REMOVE_REMINDER): vol.All(cv.ensure_list, [cv.time]),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SERVICE_GET_TASKS_SCHEMA = vol.Schema(
|
SERVICE_GET_TASKS_SCHEMA = vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Required(ATTR_CONFIG_ENTRY): ConfigEntrySelector({"integration": DOMAIN}),
|
vol.Required(ATTR_CONFIG_ENTRY): ConfigEntrySelector({"integration": DOMAIN}),
|
||||||
@ -216,6 +242,7 @@ SERVICE_TASK_TYPE_MAP = {
|
|||||||
SERVICE_CREATE_HABIT: TaskType.HABIT,
|
SERVICE_CREATE_HABIT: TaskType.HABIT,
|
||||||
SERVICE_UPDATE_TODO: TaskType.TODO,
|
SERVICE_UPDATE_TODO: TaskType.TODO,
|
||||||
SERVICE_CREATE_TODO: TaskType.TODO,
|
SERVICE_CREATE_TODO: TaskType.TODO,
|
||||||
|
SERVICE_UPDATE_DAILY: TaskType.DAILY,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -605,7 +632,9 @@ def async_setup_services(hass: HomeAssistant) -> None: # noqa: C901
|
|||||||
SERVICE_UPDATE_HABIT,
|
SERVICE_UPDATE_HABIT,
|
||||||
SERVICE_UPDATE_REWARD,
|
SERVICE_UPDATE_REWARD,
|
||||||
SERVICE_UPDATE_TODO,
|
SERVICE_UPDATE_TODO,
|
||||||
|
SERVICE_UPDATE_DAILY,
|
||||||
)
|
)
|
||||||
|
task_type = SERVICE_TASK_TYPE_MAP[call.service]
|
||||||
current_task = None
|
current_task = None
|
||||||
|
|
||||||
if is_update:
|
if is_update:
|
||||||
@ -614,7 +643,7 @@ def async_setup_services(hass: HomeAssistant) -> None: # noqa: C901
|
|||||||
task
|
task
|
||||||
for task in coordinator.data.tasks
|
for task in coordinator.data.tasks
|
||||||
if call.data[ATTR_TASK] in (str(task.id), task.alias, task.text)
|
if call.data[ATTR_TASK] in (str(task.id), task.alias, task.text)
|
||||||
and task.Type is SERVICE_TASK_TYPE_MAP[call.service]
|
and task.Type is task_type
|
||||||
)
|
)
|
||||||
except StopIteration as e:
|
except StopIteration as e:
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
@ -626,7 +655,7 @@ def async_setup_services(hass: HomeAssistant) -> None: # noqa: C901
|
|||||||
data = Task()
|
data = Task()
|
||||||
|
|
||||||
if not is_update:
|
if not is_update:
|
||||||
data["type"] = SERVICE_TASK_TYPE_MAP[call.service]
|
data["type"] = task_type
|
||||||
|
|
||||||
if (text := call.data.get(ATTR_RENAME)) or (text := call.data.get(ATTR_NAME)):
|
if (text := call.data.get(ATTR_RENAME)) or (text := call.data.get(ATTR_NAME)):
|
||||||
data["text"] = text
|
data["text"] = text
|
||||||
@ -702,6 +731,8 @@ def async_setup_services(hass: HomeAssistant) -> None: # noqa: C901
|
|||||||
|
|
||||||
if frequency := call.data.get(ATTR_FREQUENCY):
|
if frequency := call.data.get(ATTR_FREQUENCY):
|
||||||
data["frequency"] = frequency
|
data["frequency"] = frequency
|
||||||
|
else:
|
||||||
|
frequency = current_task.frequency if current_task else Frequency.WEEKLY
|
||||||
|
|
||||||
if up_down := call.data.get(ATTR_UP_DOWN):
|
if up_down := call.data.get(ATTR_UP_DOWN):
|
||||||
data["up"] = "up" in up_down
|
data["up"] = "up" in up_down
|
||||||
@ -752,23 +783,46 @@ def async_setup_services(hass: HomeAssistant) -> None: # noqa: C901
|
|||||||
reminders = current_task.reminders if current_task else []
|
reminders = current_task.reminders if current_task else []
|
||||||
|
|
||||||
if add_reminders := call.data.get(ATTR_REMINDER):
|
if add_reminders := call.data.get(ATTR_REMINDER):
|
||||||
existing_reminder_datetimes = {
|
if task_type is TaskType.TODO:
|
||||||
r.time.replace(tzinfo=None) for r in reminders
|
existing_reminder_datetimes = {
|
||||||
}
|
r.time.replace(tzinfo=None) for r in reminders
|
||||||
|
}
|
||||||
|
|
||||||
reminders.extend(
|
reminders.extend(
|
||||||
Reminders(id=uuid4(), time=r)
|
Reminders(id=uuid4(), time=r)
|
||||||
for r in add_reminders
|
for r in add_reminders
|
||||||
if r not in existing_reminder_datetimes
|
if r not in existing_reminder_datetimes
|
||||||
)
|
)
|
||||||
|
if task_type is TaskType.DAILY:
|
||||||
|
existing_reminder_times = {
|
||||||
|
r.time.time().replace(microsecond=0, second=0) for r in reminders
|
||||||
|
}
|
||||||
|
|
||||||
|
reminders.extend(
|
||||||
|
Reminders(
|
||||||
|
id=uuid4(),
|
||||||
|
time=datetime.combine(date.today(), r, tzinfo=UTC),
|
||||||
|
)
|
||||||
|
for r in add_reminders
|
||||||
|
if r not in existing_reminder_times
|
||||||
|
)
|
||||||
|
|
||||||
if remove_reminder := call.data.get(ATTR_REMOVE_REMINDER):
|
if remove_reminder := call.data.get(ATTR_REMOVE_REMINDER):
|
||||||
reminders = list(
|
if task_type is TaskType.TODO:
|
||||||
filter(
|
reminders = list(
|
||||||
lambda r: r.time.replace(tzinfo=None) not in remove_reminder,
|
filter(
|
||||||
reminders,
|
lambda r: r.time.replace(tzinfo=None) not in remove_reminder,
|
||||||
|
reminders,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if task_type is TaskType.DAILY:
|
||||||
|
reminders = list(
|
||||||
|
filter(
|
||||||
|
lambda r: r.time.time().replace(second=0, microsecond=0)
|
||||||
|
not in remove_reminder,
|
||||||
|
reminders,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
if clear_reminders := call.data.get(ATTR_CLEAR_REMINDER):
|
if clear_reminders := call.data.get(ATTR_CLEAR_REMINDER):
|
||||||
reminders = []
|
reminders = []
|
||||||
@ -776,6 +830,47 @@ def async_setup_services(hass: HomeAssistant) -> None: # noqa: C901
|
|||||||
if add_reminders or remove_reminder or clear_reminders:
|
if add_reminders or remove_reminder or clear_reminders:
|
||||||
data["reminders"] = reminders
|
data["reminders"] = reminders
|
||||||
|
|
||||||
|
if start_date := call.data.get(ATTR_START_DATE):
|
||||||
|
data["startDate"] = datetime.combine(start_date, time())
|
||||||
|
else:
|
||||||
|
start_date = (
|
||||||
|
current_task.startDate
|
||||||
|
if current_task and current_task.startDate
|
||||||
|
else dt_util.start_of_local_day()
|
||||||
|
)
|
||||||
|
if repeat := call.data.get(ATTR_REPEAT):
|
||||||
|
if frequency is Frequency.WEEKLY:
|
||||||
|
data["repeat"] = Repeat(**{d: d in repeat for d in WEEK_DAYS})
|
||||||
|
else:
|
||||||
|
raise ServiceValidationError(
|
||||||
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="frequency_not_weekly",
|
||||||
|
)
|
||||||
|
if repeat_monthly := call.data.get(ATTR_REPEAT_MONTHLY):
|
||||||
|
if frequency is not Frequency.MONTHLY:
|
||||||
|
raise ServiceValidationError(
|
||||||
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="frequency_not_monthly",
|
||||||
|
)
|
||||||
|
|
||||||
|
if repeat_monthly == "day_of_week":
|
||||||
|
weekday = start_date.weekday()
|
||||||
|
data["weeksOfMonth"] = [(start_date.day - 1) // 7]
|
||||||
|
data["repeat"] = Repeat(
|
||||||
|
**{day: i == weekday for i, day in enumerate(WEEK_DAYS)}
|
||||||
|
)
|
||||||
|
data["daysOfMonth"] = []
|
||||||
|
|
||||||
|
else:
|
||||||
|
data["daysOfMonth"] = [start_date.day]
|
||||||
|
data["weeksOfMonth"] = []
|
||||||
|
|
||||||
|
if interval := call.data.get(ATTR_INTERVAL):
|
||||||
|
data["everyX"] = interval
|
||||||
|
|
||||||
|
if streak := call.data.get(ATTR_STREAK):
|
||||||
|
data["streak"] = streak
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if is_update:
|
if is_update:
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@ -805,7 +900,12 @@ def async_setup_services(hass: HomeAssistant) -> None: # noqa: C901
|
|||||||
else:
|
else:
|
||||||
return response.data.to_dict(omit_none=True)
|
return response.data.to_dict(omit_none=True)
|
||||||
|
|
||||||
for service in (SERVICE_UPDATE_TODO, SERVICE_UPDATE_REWARD, SERVICE_UPDATE_HABIT):
|
for service in (
|
||||||
|
SERVICE_UPDATE_DAILY,
|
||||||
|
SERVICE_UPDATE_HABIT,
|
||||||
|
SERVICE_UPDATE_REWARD,
|
||||||
|
SERVICE_UPDATE_TODO,
|
||||||
|
):
|
||||||
hass.services.async_register(
|
hass.services.async_register(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
service,
|
service,
|
||||||
|
@ -268,7 +268,7 @@ update_todo:
|
|||||||
task: *task
|
task: *task
|
||||||
rename: *rename
|
rename: *rename
|
||||||
notes: *notes
|
notes: *notes
|
||||||
checklist_options:
|
checklist_options: &checklist_options
|
||||||
collapsed: true
|
collapsed: true
|
||||||
fields:
|
fields:
|
||||||
add_checklist_item: &add_checklist_item
|
add_checklist_item: &add_checklist_item
|
||||||
@ -320,7 +320,7 @@ update_todo:
|
|||||||
text:
|
text:
|
||||||
type: datetime-local
|
type: datetime-local
|
||||||
multiple: true
|
multiple: true
|
||||||
clear_reminder:
|
clear_reminder: &clear_reminder
|
||||||
required: false
|
required: false
|
||||||
selector:
|
selector:
|
||||||
constant:
|
constant:
|
||||||
@ -339,3 +339,93 @@ create_todo:
|
|||||||
reminder: *reminder
|
reminder: *reminder
|
||||||
tag: *tag
|
tag: *tag
|
||||||
developer_options: *developer_options
|
developer_options: *developer_options
|
||||||
|
update_daily:
|
||||||
|
fields:
|
||||||
|
config_entry: *config_entry
|
||||||
|
task: *task
|
||||||
|
rename: *rename
|
||||||
|
notes: *notes
|
||||||
|
checklist_options: *checklist_options
|
||||||
|
priority: *priority
|
||||||
|
start_date:
|
||||||
|
required: false
|
||||||
|
selector:
|
||||||
|
date:
|
||||||
|
frequency:
|
||||||
|
required: false
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "daily"
|
||||||
|
- "weekly"
|
||||||
|
- "monthly"
|
||||||
|
- "yearly"
|
||||||
|
translation_key: "frequency"
|
||||||
|
mode: dropdown
|
||||||
|
every_x:
|
||||||
|
required: false
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
step: 1
|
||||||
|
unit_of_measurement: "🔃"
|
||||||
|
mode: box
|
||||||
|
repeat_weekly_options:
|
||||||
|
collapsed: true
|
||||||
|
fields:
|
||||||
|
repeat:
|
||||||
|
required: false
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "m"
|
||||||
|
- "t"
|
||||||
|
- "w"
|
||||||
|
- "th"
|
||||||
|
- "f"
|
||||||
|
- "s"
|
||||||
|
- "su"
|
||||||
|
mode: list
|
||||||
|
translation_key: repeat
|
||||||
|
multiple: true
|
||||||
|
repeat_monthly_options:
|
||||||
|
collapsed: true
|
||||||
|
fields:
|
||||||
|
repeat_monthly:
|
||||||
|
required: false
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "day_of_month"
|
||||||
|
- "day_of_week"
|
||||||
|
translation_key: repeat_monthly
|
||||||
|
mode: list
|
||||||
|
reminder_options:
|
||||||
|
collapsed: true
|
||||||
|
fields:
|
||||||
|
reminder:
|
||||||
|
required: false
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
type: time
|
||||||
|
multiple: true
|
||||||
|
remove_reminder:
|
||||||
|
required: false
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
type: time
|
||||||
|
multiple: true
|
||||||
|
clear_reminder: *clear_reminder
|
||||||
|
tag_options: *tag_options
|
||||||
|
developer_options:
|
||||||
|
collapsed: true
|
||||||
|
fields:
|
||||||
|
streak:
|
||||||
|
required: false
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
step: 1
|
||||||
|
unit_of_measurement: "▶▶"
|
||||||
|
mode: box
|
||||||
|
alias: *alias
|
||||||
|
@ -51,7 +51,8 @@
|
|||||||
"reminder_options_name": "Reminders",
|
"reminder_options_name": "Reminders",
|
||||||
"reminder_options_description": "Add, remove or clear reminders of a Habitica task.",
|
"reminder_options_description": "Add, remove or clear reminders of a Habitica task.",
|
||||||
"date_name": "Due date",
|
"date_name": "Due date",
|
||||||
"date_description": "The to-do's due date."
|
"date_description": "The to-do's due date.",
|
||||||
|
"repeat_name": "Repeat on"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
@ -1037,6 +1038,122 @@
|
|||||||
"description": "[%key:component::habitica::common::developer_options_description%]"
|
"description": "[%key:component::habitica::common::developer_options_description%]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"update_daily": {
|
||||||
|
"name": "Update a daily",
|
||||||
|
"description": "Updates a specific daily for a selected Habitica character",
|
||||||
|
"fields": {
|
||||||
|
"config_entry": {
|
||||||
|
"name": "[%key:component::habitica::common::config_entry_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::config_entry_description%]"
|
||||||
|
},
|
||||||
|
"task": {
|
||||||
|
"name": "[%key:component::habitica::common::task_name%]",
|
||||||
|
"description": "The name (or task ID) of the daily you want to update."
|
||||||
|
},
|
||||||
|
"rename": {
|
||||||
|
"name": "[%key:component::habitica::common::rename_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::rename_description%]"
|
||||||
|
},
|
||||||
|
"notes": {
|
||||||
|
"name": "[%key:component::habitica::common::notes_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::notes_description%]"
|
||||||
|
},
|
||||||
|
"tag": {
|
||||||
|
"name": "[%key:component::habitica::common::tag_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::tag_description%]"
|
||||||
|
},
|
||||||
|
"remove_tag": {
|
||||||
|
"name": "[%key:component::habitica::common::remove_tag_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::remove_tag_description%]"
|
||||||
|
},
|
||||||
|
"alias": {
|
||||||
|
"name": "[%key:component::habitica::common::alias_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::alias_description%]"
|
||||||
|
},
|
||||||
|
"priority": {
|
||||||
|
"name": "[%key:component::habitica::common::priority_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::priority_description%]"
|
||||||
|
},
|
||||||
|
"start_date": {
|
||||||
|
"name": "Start date",
|
||||||
|
"description": "Defines when the daily task becomes active and specifies the exact weekday or day of the month it repeats on."
|
||||||
|
},
|
||||||
|
"frequency": {
|
||||||
|
"name": "Repeat interval",
|
||||||
|
"description": "The repetition interval of a daily."
|
||||||
|
},
|
||||||
|
"every_x": {
|
||||||
|
"name": "Repeat every X",
|
||||||
|
"description": "The number of intervals (days, weeks, months, or years) after which the daily repeats, based on the chosen repetition interval. A value of 0 makes the daily inactive ('Grey Daily')."
|
||||||
|
},
|
||||||
|
"repeat": {
|
||||||
|
"name": "[%key:component::habitica::common::repeat_name%]",
|
||||||
|
"description": "The days of the week the daily repeats."
|
||||||
|
},
|
||||||
|
"repeat_monthly": {
|
||||||
|
"name": "[%key:component::habitica::common::repeat_name%]",
|
||||||
|
"description": "Whether a monthly recurring task repeats on the same calendar day each month or on the same weekday and week of the month, based on the start date."
|
||||||
|
},
|
||||||
|
"add_checklist_item": {
|
||||||
|
"name": "[%key:component::habitica::common::add_checklist_item_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::add_checklist_item_description%]"
|
||||||
|
},
|
||||||
|
"remove_checklist_item": {
|
||||||
|
"name": "[%key:component::habitica::common::remove_checklist_item_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::remove_checklist_item_description%]"
|
||||||
|
},
|
||||||
|
"score_checklist_item": {
|
||||||
|
"name": "[%key:component::habitica::common::score_checklist_item_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::score_checklist_item_description%]"
|
||||||
|
},
|
||||||
|
"unscore_checklist_item": {
|
||||||
|
"name": "[%key:component::habitica::common::unscore_checklist_item_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::unscore_checklist_item_description%]"
|
||||||
|
},
|
||||||
|
"streak": {
|
||||||
|
"name": "Adjust streak",
|
||||||
|
"description": "Adjust or reset the streak counter of the daily."
|
||||||
|
},
|
||||||
|
"reminder": {
|
||||||
|
"name": "[%key:component::habitica::common::reminder_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::reminder_description%]"
|
||||||
|
},
|
||||||
|
"remove_reminder": {
|
||||||
|
"name": "[%key:component::habitica::common::remove_reminder_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::remove_reminder_description%]"
|
||||||
|
},
|
||||||
|
"clear_reminder": {
|
||||||
|
"name": "[%key:component::habitica::common::clear_reminder_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::clear_reminder_description%]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sections": {
|
||||||
|
"checklist_options": {
|
||||||
|
"name": "[%key:component::habitica::common::checklist_options_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::checklist_options_description%]"
|
||||||
|
},
|
||||||
|
"repeat_weekly_options": {
|
||||||
|
"name": "Weekly repeat days",
|
||||||
|
"description": "Options related to weekly repetition, applicable when the repetition interval is set to weekly."
|
||||||
|
},
|
||||||
|
"repeat_monthly_options": {
|
||||||
|
"name": "Monthly repeat day",
|
||||||
|
"description": "Options related to monthly repetition, applicable when the repetition interval is set to monthly."
|
||||||
|
},
|
||||||
|
"tag_options": {
|
||||||
|
"name": "[%key:component::habitica::common::tag_options_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::tag_options_description%]"
|
||||||
|
},
|
||||||
|
"developer_options": {
|
||||||
|
"name": "[%key:component::habitica::common::developer_options_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::developer_options_description%]"
|
||||||
|
},
|
||||||
|
"reminder_options": {
|
||||||
|
"name": "[%key:component::habitica::common::reminder_options_name%]",
|
||||||
|
"description": "[%key:component::habitica::common::reminder_options_description%]"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"selector": {
|
"selector": {
|
||||||
@ -1079,6 +1196,23 @@
|
|||||||
"monthly": "Monthly",
|
"monthly": "Monthly",
|
||||||
"yearly": "Yearly"
|
"yearly": "Yearly"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"repeat": {
|
||||||
|
"options": {
|
||||||
|
"m": "[%key:common::time::monday%]",
|
||||||
|
"t": "[%key:common::time::tuesday%]",
|
||||||
|
"w": "[%key:common::time::wednesday%]",
|
||||||
|
"th": "[%key:common::time::thursday%]",
|
||||||
|
"f": "[%key:common::time::friday%]",
|
||||||
|
"s": "[%key:common::time::saturday%]",
|
||||||
|
"su": "[%key:common::time::sunday%]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"repeat_monthly": {
|
||||||
|
"options": {
|
||||||
|
"day_of_month": "Day of the month",
|
||||||
|
"day_of_week": "Day of the week"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -605,7 +605,18 @@
|
|||||||
"startDate": "2024-09-20T23:00:00.000Z",
|
"startDate": "2024-09-20T23:00:00.000Z",
|
||||||
"daysOfMonth": [],
|
"daysOfMonth": [],
|
||||||
"weeksOfMonth": [3],
|
"weeksOfMonth": [3],
|
||||||
"checklist": [],
|
"checklist": [
|
||||||
|
{
|
||||||
|
"completed": false,
|
||||||
|
"id": "a2a6702d-58e1-46c2-a3ce-422d525cc0b6",
|
||||||
|
"text": "Checklist-item1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"completed": true,
|
||||||
|
"id": "9f64e1cd-b0ab-4577-8344-c7a5e1827997",
|
||||||
|
"text": "Checklist-item2"
|
||||||
|
}
|
||||||
|
],
|
||||||
"reminders": [],
|
"reminders": [],
|
||||||
"createdAt": "2024-10-10T15:57:14.304Z",
|
"createdAt": "2024-10-10T15:57:14.304Z",
|
||||||
"updatedAt": "2024-11-27T23:47:29.986Z",
|
"updatedAt": "2024-11-27T23:47:29.986Z",
|
||||||
|
@ -1116,6 +1116,16 @@
|
|||||||
'winner': None,
|
'winner': None,
|
||||||
}),
|
}),
|
||||||
'checklist': list([
|
'checklist': list([
|
||||||
|
dict({
|
||||||
|
'completed': False,
|
||||||
|
'id': 'a2a6702d-58e1-46c2-a3ce-422d525cc0b6',
|
||||||
|
'text': 'Checklist-item1',
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'completed': True,
|
||||||
|
'id': '9f64e1cd-b0ab-4577-8344-c7a5e1827997',
|
||||||
|
'text': 'Checklist-item2',
|
||||||
|
}),
|
||||||
]),
|
]),
|
||||||
'collapseChecklist': False,
|
'collapseChecklist': False,
|
||||||
'completed': False,
|
'completed': False,
|
||||||
@ -3378,6 +3388,16 @@
|
|||||||
'winner': None,
|
'winner': None,
|
||||||
}),
|
}),
|
||||||
'checklist': list([
|
'checklist': list([
|
||||||
|
dict({
|
||||||
|
'completed': False,
|
||||||
|
'id': 'a2a6702d-58e1-46c2-a3ce-422d525cc0b6',
|
||||||
|
'text': 'Checklist-item1',
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'completed': True,
|
||||||
|
'id': '9f64e1cd-b0ab-4577-8344-c7a5e1827997',
|
||||||
|
'text': 'Checklist-item2',
|
||||||
|
}),
|
||||||
]),
|
]),
|
||||||
'collapseChecklist': False,
|
'collapseChecklist': False,
|
||||||
'completed': False,
|
'completed': False,
|
||||||
@ -4511,6 +4531,16 @@
|
|||||||
'winner': None,
|
'winner': None,
|
||||||
}),
|
}),
|
||||||
'checklist': list([
|
'checklist': list([
|
||||||
|
dict({
|
||||||
|
'completed': False,
|
||||||
|
'id': 'a2a6702d-58e1-46c2-a3ce-422d525cc0b6',
|
||||||
|
'text': 'Checklist-item1',
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'completed': True,
|
||||||
|
'id': '9f64e1cd-b0ab-4577-8344-c7a5e1827997',
|
||||||
|
'text': 'Checklist-item2',
|
||||||
|
}),
|
||||||
]),
|
]),
|
||||||
'collapseChecklist': False,
|
'collapseChecklist': False,
|
||||||
'completed': False,
|
'completed': False,
|
||||||
@ -5092,6 +5122,16 @@
|
|||||||
'winner': None,
|
'winner': None,
|
||||||
}),
|
}),
|
||||||
'checklist': list([
|
'checklist': list([
|
||||||
|
dict({
|
||||||
|
'completed': False,
|
||||||
|
'id': 'a2a6702d-58e1-46c2-a3ce-422d525cc0b6',
|
||||||
|
'text': 'Checklist-item1',
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'completed': True,
|
||||||
|
'id': '9f64e1cd-b0ab-4577-8344-c7a5e1827997',
|
||||||
|
'text': 'Checklist-item2',
|
||||||
|
}),
|
||||||
]),
|
]),
|
||||||
'collapseChecklist': False,
|
'collapseChecklist': False,
|
||||||
'completed': False,
|
'completed': False,
|
||||||
|
@ -1,18 +1,20 @@
|
|||||||
"""Test Habitica actions."""
|
"""Test Habitica actions."""
|
||||||
|
|
||||||
from collections.abc import Generator
|
from collections.abc import Generator
|
||||||
from datetime import datetime
|
from datetime import UTC, datetime
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import AsyncMock, patch
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from aiohttp import ClientError
|
from aiohttp import ClientError
|
||||||
|
from freezegun.api import freeze_time
|
||||||
from habiticalib import (
|
from habiticalib import (
|
||||||
Checklist,
|
Checklist,
|
||||||
Direction,
|
Direction,
|
||||||
Frequency,
|
Frequency,
|
||||||
HabiticaTaskResponse,
|
HabiticaTaskResponse,
|
||||||
Reminders,
|
Reminders,
|
||||||
|
Repeat,
|
||||||
Skill,
|
Skill,
|
||||||
Task,
|
Task,
|
||||||
TaskPriority,
|
TaskPriority,
|
||||||
@ -32,6 +34,7 @@ from homeassistant.components.habitica.const import (
|
|||||||
ATTR_COUNTER_UP,
|
ATTR_COUNTER_UP,
|
||||||
ATTR_DIRECTION,
|
ATTR_DIRECTION,
|
||||||
ATTR_FREQUENCY,
|
ATTR_FREQUENCY,
|
||||||
|
ATTR_INTERVAL,
|
||||||
ATTR_ITEM,
|
ATTR_ITEM,
|
||||||
ATTR_KEYWORD,
|
ATTR_KEYWORD,
|
||||||
ATTR_NOTES,
|
ATTR_NOTES,
|
||||||
@ -40,8 +43,12 @@ from homeassistant.components.habitica.const import (
|
|||||||
ATTR_REMOVE_CHECKLIST_ITEM,
|
ATTR_REMOVE_CHECKLIST_ITEM,
|
||||||
ATTR_REMOVE_REMINDER,
|
ATTR_REMOVE_REMINDER,
|
||||||
ATTR_REMOVE_TAG,
|
ATTR_REMOVE_TAG,
|
||||||
|
ATTR_REPEAT,
|
||||||
|
ATTR_REPEAT_MONTHLY,
|
||||||
ATTR_SCORE_CHECKLIST_ITEM,
|
ATTR_SCORE_CHECKLIST_ITEM,
|
||||||
ATTR_SKILL,
|
ATTR_SKILL,
|
||||||
|
ATTR_START_DATE,
|
||||||
|
ATTR_STREAK,
|
||||||
ATTR_TAG,
|
ATTR_TAG,
|
||||||
ATTR_TARGET,
|
ATTR_TARGET,
|
||||||
ATTR_TASK,
|
ATTR_TASK,
|
||||||
@ -63,6 +70,7 @@ from homeassistant.components.habitica.const import (
|
|||||||
SERVICE_SCORE_REWARD,
|
SERVICE_SCORE_REWARD,
|
||||||
SERVICE_START_QUEST,
|
SERVICE_START_QUEST,
|
||||||
SERVICE_TRANSFORMATION,
|
SERVICE_TRANSFORMATION,
|
||||||
|
SERVICE_UPDATE_DAILY,
|
||||||
SERVICE_UPDATE_HABIT,
|
SERVICE_UPDATE_HABIT,
|
||||||
SERVICE_UPDATE_REWARD,
|
SERVICE_UPDATE_REWARD,
|
||||||
SERVICE_UPDATE_TODO,
|
SERVICE_UPDATE_TODO,
|
||||||
@ -952,6 +960,7 @@ async def test_get_tasks(
|
|||||||
(SERVICE_UPDATE_REWARD, "5e2ea1df-f6e6-4ba3-bccb-97c5ec63e99b"),
|
(SERVICE_UPDATE_REWARD, "5e2ea1df-f6e6-4ba3-bccb-97c5ec63e99b"),
|
||||||
(SERVICE_UPDATE_HABIT, "f21fa608-cfc6-4413-9fc7-0eb1b48ca43a"),
|
(SERVICE_UPDATE_HABIT, "f21fa608-cfc6-4413-9fc7-0eb1b48ca43a"),
|
||||||
(SERVICE_UPDATE_TODO, "88de7cd9-af2b-49ce-9afd-bf941d87336b"),
|
(SERVICE_UPDATE_TODO, "88de7cd9-af2b-49ce-9afd-bf941d87336b"),
|
||||||
|
(SERVICE_UPDATE_DAILY, "6e53f1f5-a315-4edd-984d-8d762e4a08ef"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("habitica")
|
@pytest.mark.usefixtures("habitica")
|
||||||
@ -1606,6 +1615,270 @@ async def test_create_todo(
|
|||||||
habitica.create_task.assert_awaited_with(call_args)
|
habitica.create_task.assert_awaited_with(call_args)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("service_data", "call_args"),
|
||||||
|
[
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_RENAME: "RENAME",
|
||||||
|
},
|
||||||
|
Task(text="RENAME"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_NOTES: "NOTES",
|
||||||
|
},
|
||||||
|
Task(notes="NOTES"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_ADD_CHECKLIST_ITEM: "Checklist-item",
|
||||||
|
},
|
||||||
|
Task(
|
||||||
|
{
|
||||||
|
"checklist": [
|
||||||
|
Checklist(
|
||||||
|
id=UUID("a2a6702d-58e1-46c2-a3ce-422d525cc0b6"),
|
||||||
|
text="Checklist-item1",
|
||||||
|
completed=False,
|
||||||
|
),
|
||||||
|
Checklist(
|
||||||
|
id=UUID("9f64e1cd-b0ab-4577-8344-c7a5e1827997"),
|
||||||
|
text="Checklist-item2",
|
||||||
|
completed=True,
|
||||||
|
),
|
||||||
|
Checklist(
|
||||||
|
id=UUID("12345678-1234-5678-1234-567812345678"),
|
||||||
|
text="Checklist-item",
|
||||||
|
completed=False,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_REMOVE_CHECKLIST_ITEM: "Checklist-item1",
|
||||||
|
},
|
||||||
|
Task(
|
||||||
|
{
|
||||||
|
"checklist": [
|
||||||
|
Checklist(
|
||||||
|
id=UUID("9f64e1cd-b0ab-4577-8344-c7a5e1827997"),
|
||||||
|
text="Checklist-item2",
|
||||||
|
completed=True,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_SCORE_CHECKLIST_ITEM: "Checklist-item1",
|
||||||
|
},
|
||||||
|
Task(
|
||||||
|
{
|
||||||
|
"checklist": [
|
||||||
|
Checklist(
|
||||||
|
id=UUID("a2a6702d-58e1-46c2-a3ce-422d525cc0b6"),
|
||||||
|
text="Checklist-item1",
|
||||||
|
completed=True,
|
||||||
|
),
|
||||||
|
Checklist(
|
||||||
|
id=UUID("9f64e1cd-b0ab-4577-8344-c7a5e1827997"),
|
||||||
|
text="Checklist-item2",
|
||||||
|
completed=True,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_UNSCORE_CHECKLIST_ITEM: "Checklist-item2",
|
||||||
|
},
|
||||||
|
Task(
|
||||||
|
{
|
||||||
|
"checklist": [
|
||||||
|
Checklist(
|
||||||
|
id=UUID("a2a6702d-58e1-46c2-a3ce-422d525cc0b6"),
|
||||||
|
text="Checklist-item1",
|
||||||
|
completed=False,
|
||||||
|
),
|
||||||
|
Checklist(
|
||||||
|
id=UUID("9f64e1cd-b0ab-4577-8344-c7a5e1827997"),
|
||||||
|
text="Checklist-item2",
|
||||||
|
completed=False,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_PRIORITY: "trivial",
|
||||||
|
},
|
||||||
|
Task(priority=TaskPriority.TRIVIAL),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_START_DATE: "2025-03-05",
|
||||||
|
},
|
||||||
|
Task(startDate=datetime(2025, 3, 5)),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_FREQUENCY: "weekly",
|
||||||
|
},
|
||||||
|
Task(frequency=Frequency.WEEKLY),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_INTERVAL: 5,
|
||||||
|
},
|
||||||
|
Task(everyX=5),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_FREQUENCY: "weekly",
|
||||||
|
ATTR_REPEAT: ["m", "t", "w", "th"],
|
||||||
|
},
|
||||||
|
Task(
|
||||||
|
frequency=Frequency.WEEKLY,
|
||||||
|
repeat=Repeat(m=True, t=True, w=True, th=True),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_FREQUENCY: "monthly",
|
||||||
|
ATTR_REPEAT_MONTHLY: "day_of_month",
|
||||||
|
},
|
||||||
|
Task(frequency=Frequency.MONTHLY, daysOfMonth=[20], weeksOfMonth=[]),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_FREQUENCY: "monthly",
|
||||||
|
ATTR_REPEAT_MONTHLY: "day_of_week",
|
||||||
|
},
|
||||||
|
Task(
|
||||||
|
frequency=Frequency.MONTHLY,
|
||||||
|
daysOfMonth=[],
|
||||||
|
weeksOfMonth=[2],
|
||||||
|
repeat=Repeat(
|
||||||
|
m=False, t=False, w=False, th=False, f=True, s=False, su=False
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_REMINDER: ["10:00"],
|
||||||
|
},
|
||||||
|
Task(
|
||||||
|
{
|
||||||
|
"reminders": [
|
||||||
|
Reminders(
|
||||||
|
id=UUID("12345678-1234-5678-1234-567812345678"),
|
||||||
|
time=datetime(2025, 2, 25, 10, 0, tzinfo=UTC),
|
||||||
|
startDate=None,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_REMOVE_REMINDER: ["10:00"],
|
||||||
|
},
|
||||||
|
Task({"reminders": []}),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_CLEAR_REMINDER: True,
|
||||||
|
},
|
||||||
|
Task({"reminders": []}),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_STREAK: 10,
|
||||||
|
},
|
||||||
|
Task(streak=10),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{
|
||||||
|
ATTR_ALIAS: "ALIAS",
|
||||||
|
},
|
||||||
|
Task(alias="ALIAS"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
@pytest.mark.usefixtures("mock_uuid4")
|
||||||
|
@freeze_time("2025-02-25T22:00:00.000Z")
|
||||||
|
async def test_update_daily(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
habitica: AsyncMock,
|
||||||
|
service_data: dict[str, Any],
|
||||||
|
call_args: Task,
|
||||||
|
) -> None:
|
||||||
|
"""Test Habitica update daily action."""
|
||||||
|
task_id = "6e53f1f5-a315-4edd-984d-8d762e4a08ef"
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
DOMAIN,
|
||||||
|
SERVICE_UPDATE_DAILY,
|
||||||
|
service_data={
|
||||||
|
ATTR_CONFIG_ENTRY: config_entry.entry_id,
|
||||||
|
ATTR_TASK: task_id,
|
||||||
|
**service_data,
|
||||||
|
},
|
||||||
|
return_response=True,
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
habitica.update_task.assert_awaited_with(UUID(task_id), call_args)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service_data",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
ATTR_FREQUENCY: "daily",
|
||||||
|
ATTR_REPEAT: ["m", "t", "w", "th"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ATTR_FREQUENCY: "weekly",
|
||||||
|
ATTR_REPEAT_MONTHLY: "day_of_month",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ATTR_FREQUENCY: "weekly",
|
||||||
|
ATTR_REPEAT_MONTHLY: "day_of_week",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
||||||
|
@pytest.mark.usefixtures("mock_uuid4")
|
||||||
|
@freeze_time("2025-02-25T22:00:00.000Z")
|
||||||
|
async def test_update_daily_service_validation_errors(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
habitica: AsyncMock,
|
||||||
|
service_data: dict[str, Any],
|
||||||
|
) -> None:
|
||||||
|
"""Test Habitica update daily action."""
|
||||||
|
task_id = "6e53f1f5-a315-4edd-984d-8d762e4a08ef"
|
||||||
|
|
||||||
|
with pytest.raises(ServiceValidationError):
|
||||||
|
await hass.services.async_call(
|
||||||
|
DOMAIN,
|
||||||
|
SERVICE_UPDATE_DAILY,
|
||||||
|
service_data={
|
||||||
|
ATTR_CONFIG_ENTRY: config_entry.entry_id,
|
||||||
|
ATTR_TASK: task_id,
|
||||||
|
**service_data,
|
||||||
|
},
|
||||||
|
return_response=True,
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_tags(
|
async def test_tags(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: MockConfigEntry,
|
config_entry: MockConfigEntry,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user