mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Add tests for todo platform of Habitica integration (#128199)
* Add tests for todo platform * refactor mock_called_with * update tests
This commit is contained in:
parent
7d29bff136
commit
fdded9e7ee
@ -3,9 +3,11 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from yarl import URL
|
||||
|
||||
from homeassistant.components.habitica.const import CONF_API_USER, DEFAULT_URL, DOMAIN
|
||||
from homeassistant.const import CONF_API_KEY, CONF_URL
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry, load_json_object_fixture
|
||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||
@ -21,6 +23,23 @@ def disable_plumbum():
|
||||
yield
|
||||
|
||||
|
||||
def mock_called_with(
|
||||
mock_client: AiohttpClientMocker,
|
||||
method: str,
|
||||
url: str,
|
||||
) -> tuple | None:
|
||||
"""Assert request mock was called with json data."""
|
||||
|
||||
return next(
|
||||
(
|
||||
call
|
||||
for call in mock_client.mock_calls
|
||||
if call[0] == method.upper() and call[1] == URL(url)
|
||||
),
|
||||
None,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_habitica(aioclient_mock: AiohttpClientMocker) -> AiohttpClientMocker:
|
||||
"""Mock aiohttp requests."""
|
||||
@ -54,3 +73,9 @@ def mock_config_entry() -> MockConfigEntry:
|
||||
},
|
||||
unique_id="00000000-0000-0000-0000-000000000000",
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def set_tz(hass: HomeAssistant) -> None:
|
||||
"""Fixture to set timezone."""
|
||||
await hass.config.async_set_time_zone("Europe/Berlin")
|
||||
|
51
tests/components/habitica/fixtures/duedate_fixture_1.json
Normal file
51
tests/components/habitica/fixtures/duedate_fixture_1.json
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"_id": "564b9ac9-c53d-4638-9e7f-1cd96fe19baa",
|
||||
"frequency": "daily",
|
||||
"everyX": 1,
|
||||
"repeat": {
|
||||
"m": true,
|
||||
"t": true,
|
||||
"w": true,
|
||||
"th": true,
|
||||
"f": true,
|
||||
"s": true,
|
||||
"su": true
|
||||
},
|
||||
"streak": 1,
|
||||
"nextDue": ["2024-09-22T22:00:00.000Z", "2024-09-23T22:00:00.000Z"],
|
||||
"yesterDaily": true,
|
||||
"history": [],
|
||||
"completed": false,
|
||||
"collapseChecklist": false,
|
||||
"type": "daily",
|
||||
"text": "Zahnseide benutzen",
|
||||
"notes": "Klicke um Änderungen zu machen!",
|
||||
"tags": [],
|
||||
"value": -2.9663035443712333,
|
||||
"priority": 1,
|
||||
"attribute": "str",
|
||||
"challenge": {},
|
||||
"group": {
|
||||
"completedBy": {},
|
||||
"assignedUsers": []
|
||||
},
|
||||
"byHabitica": false,
|
||||
"startDate": "2024-07-06T22:00:00.000Z",
|
||||
"daysOfMonth": [],
|
||||
"weeksOfMonth": [],
|
||||
"checklist": [],
|
||||
"reminders": [],
|
||||
"createdAt": "2024-07-07T17:51:53.268Z",
|
||||
"updatedAt": "2024-09-21T22:24:20.154Z",
|
||||
"userId": "5f359083-ef78-4af0-985a-0b2c6d05797c",
|
||||
"isDue": true,
|
||||
"id": "564b9ac9-c53d-4638-9e7f-1cd96fe19baa"
|
||||
}
|
||||
],
|
||||
"notifications": [],
|
||||
"userV": 589,
|
||||
"appVersion": "5.28.6"
|
||||
}
|
51
tests/components/habitica/fixtures/duedate_fixture_2.json
Normal file
51
tests/components/habitica/fixtures/duedate_fixture_2.json
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"_id": "564b9ac9-c53d-4638-9e7f-1cd96fe19baa",
|
||||
"frequency": "daily",
|
||||
"everyX": 1,
|
||||
"repeat": {
|
||||
"m": true,
|
||||
"t": true,
|
||||
"w": true,
|
||||
"th": true,
|
||||
"f": true,
|
||||
"s": true,
|
||||
"su": true
|
||||
},
|
||||
"streak": 1,
|
||||
"nextDue": ["2024-09-22T22:00:00.000Z", "2024-09-23T22:00:00.000Z"],
|
||||
"yesterDaily": true,
|
||||
"history": [],
|
||||
"completed": false,
|
||||
"collapseChecklist": false,
|
||||
"type": "daily",
|
||||
"text": "Zahnseide benutzen",
|
||||
"notes": "Klicke um Änderungen zu machen!",
|
||||
"tags": [],
|
||||
"value": -2.9663035443712333,
|
||||
"priority": 1,
|
||||
"attribute": "str",
|
||||
"challenge": {},
|
||||
"group": {
|
||||
"completedBy": {},
|
||||
"assignedUsers": []
|
||||
},
|
||||
"byHabitica": false,
|
||||
"startDate": "2024-09-23T22:00:00.000Z",
|
||||
"daysOfMonth": [],
|
||||
"weeksOfMonth": [],
|
||||
"checklist": [],
|
||||
"reminders": [],
|
||||
"createdAt": "2024-07-07T17:51:53.268Z",
|
||||
"updatedAt": "2024-09-21T22:24:20.154Z",
|
||||
"userId": "5f359083-ef78-4af0-985a-0b2c6d05797c",
|
||||
"isDue": false,
|
||||
"id": "564b9ac9-c53d-4638-9e7f-1cd96fe19baa"
|
||||
}
|
||||
],
|
||||
"notifications": [],
|
||||
"userV": 589,
|
||||
"appVersion": "5.28.6"
|
||||
}
|
51
tests/components/habitica/fixtures/duedate_fixture_3.json
Normal file
51
tests/components/habitica/fixtures/duedate_fixture_3.json
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"_id": "564b9ac9-c53d-4638-9e7f-1cd96fe19baa",
|
||||
"frequency": "monthly",
|
||||
"everyX": 1,
|
||||
"repeat": {
|
||||
"m": true,
|
||||
"t": true,
|
||||
"w": true,
|
||||
"th": true,
|
||||
"f": true,
|
||||
"s": true,
|
||||
"su": true
|
||||
},
|
||||
"streak": 1,
|
||||
"nextDue": ["2024-10-22T22:00:00.000Z", "2024-11-22T22:00:00.000Z"],
|
||||
"yesterDaily": true,
|
||||
"history": [],
|
||||
"completed": false,
|
||||
"collapseChecklist": false,
|
||||
"type": "daily",
|
||||
"text": "Zahnseide benutzen",
|
||||
"notes": "Klicke um Änderungen zu machen!",
|
||||
"tags": [],
|
||||
"value": -2.9663035443712333,
|
||||
"priority": 1,
|
||||
"attribute": "str",
|
||||
"challenge": {},
|
||||
"group": {
|
||||
"completedBy": {},
|
||||
"assignedUsers": []
|
||||
},
|
||||
"byHabitica": false,
|
||||
"startDate": "2024-10-22T22:00:00.000Z",
|
||||
"daysOfMonth": [23],
|
||||
"weeksOfMonth": [],
|
||||
"checklist": [],
|
||||
"reminders": [],
|
||||
"createdAt": "2024-07-07T17:51:53.268Z",
|
||||
"updatedAt": "2024-09-21T22:24:20.154Z",
|
||||
"userId": "5f359083-ef78-4af0-985a-0b2c6d05797c",
|
||||
"isDue": false,
|
||||
"id": "564b9ac9-c53d-4638-9e7f-1cd96fe19baa"
|
||||
}
|
||||
],
|
||||
"notifications": [],
|
||||
"userV": 589,
|
||||
"appVersion": "5.28.6"
|
||||
}
|
51
tests/components/habitica/fixtures/duedate_fixture_4.json
Normal file
51
tests/components/habitica/fixtures/duedate_fixture_4.json
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"_id": "564b9ac9-c53d-4638-9e7f-1cd96fe19baa",
|
||||
"frequency": "yearly",
|
||||
"everyX": 1,
|
||||
"repeat": {
|
||||
"m": true,
|
||||
"t": true,
|
||||
"w": true,
|
||||
"th": true,
|
||||
"f": true,
|
||||
"s": true,
|
||||
"su": true
|
||||
},
|
||||
"streak": 1,
|
||||
"nextDue": ["2024-10-22T22:00:00.000Z", "2025-10-22T22:00:00.000Z"],
|
||||
"yesterDaily": true,
|
||||
"history": [],
|
||||
"completed": false,
|
||||
"collapseChecklist": false,
|
||||
"type": "daily",
|
||||
"text": "Zahnseide benutzen",
|
||||
"notes": "Klicke um Änderungen zu machen!",
|
||||
"tags": [],
|
||||
"value": -2.9663035443712333,
|
||||
"priority": 1,
|
||||
"attribute": "str",
|
||||
"challenge": {},
|
||||
"group": {
|
||||
"completedBy": {},
|
||||
"assignedUsers": []
|
||||
},
|
||||
"byHabitica": false,
|
||||
"startDate": "2024-10-22T22:00:00.000Z",
|
||||
"daysOfMonth": [22],
|
||||
"weeksOfMonth": [],
|
||||
"checklist": [],
|
||||
"reminders": [],
|
||||
"createdAt": "2024-07-07T17:51:53.268Z",
|
||||
"updatedAt": "2024-09-21T22:24:20.154Z",
|
||||
"userId": "5f359083-ef78-4af0-985a-0b2c6d05797c",
|
||||
"isDue": false,
|
||||
"id": "564b9ac9-c53d-4638-9e7f-1cd96fe19baa"
|
||||
}
|
||||
],
|
||||
"notifications": [],
|
||||
"userV": 589,
|
||||
"appVersion": "5.28.6"
|
||||
}
|
51
tests/components/habitica/fixtures/duedate_fixture_5.json
Normal file
51
tests/components/habitica/fixtures/duedate_fixture_5.json
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"_id": "564b9ac9-c53d-4638-9e7f-1cd96fe19baa",
|
||||
"frequency": "weekly",
|
||||
"everyX": 1,
|
||||
"repeat": {
|
||||
"m": true,
|
||||
"t": true,
|
||||
"w": true,
|
||||
"th": true,
|
||||
"f": true,
|
||||
"s": true,
|
||||
"su": true
|
||||
},
|
||||
"streak": 1,
|
||||
"nextDue": ["2024-09-20T22:00:00.000Z", "2024-09-27T22:00:00.000Z"],
|
||||
"yesterDaily": true,
|
||||
"history": [],
|
||||
"completed": false,
|
||||
"collapseChecklist": false,
|
||||
"type": "daily",
|
||||
"text": "Zahnseide benutzen",
|
||||
"notes": "Klicke um Änderungen zu machen!",
|
||||
"tags": [],
|
||||
"value": -2.9663035443712333,
|
||||
"priority": 1,
|
||||
"attribute": "str",
|
||||
"challenge": {},
|
||||
"group": {
|
||||
"completedBy": {},
|
||||
"assignedUsers": []
|
||||
},
|
||||
"byHabitica": false,
|
||||
"startDate": "2024-09-25T22:00:00.000Z",
|
||||
"daysOfMonth": [],
|
||||
"weeksOfMonth": [],
|
||||
"checklist": [],
|
||||
"reminders": [],
|
||||
"createdAt": "2024-07-07T17:51:53.268Z",
|
||||
"updatedAt": "2024-09-21T22:24:20.154Z",
|
||||
"userId": "5f359083-ef78-4af0-985a-0b2c6d05797c",
|
||||
"isDue": false,
|
||||
"id": "564b9ac9-c53d-4638-9e7f-1cd96fe19baa"
|
||||
}
|
||||
],
|
||||
"notifications": [],
|
||||
"userV": 589,
|
||||
"appVersion": "5.28.6"
|
||||
}
|
51
tests/components/habitica/fixtures/duedate_fixture_6.json
Normal file
51
tests/components/habitica/fixtures/duedate_fixture_6.json
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"_id": "564b9ac9-c53d-4638-9e7f-1cd96fe19baa",
|
||||
"frequency": "monthly",
|
||||
"everyX": 1,
|
||||
"repeat": {
|
||||
"m": true,
|
||||
"t": true,
|
||||
"w": true,
|
||||
"th": true,
|
||||
"f": true,
|
||||
"s": true,
|
||||
"su": true
|
||||
},
|
||||
"streak": 1,
|
||||
"nextDue": ["2024-09-20T22:00:00.000Z", "2024-10-20T22:00:00.000Z"],
|
||||
"yesterDaily": true,
|
||||
"history": [],
|
||||
"completed": false,
|
||||
"collapseChecklist": false,
|
||||
"type": "daily",
|
||||
"text": "Zahnseide benutzen",
|
||||
"notes": "Klicke um Änderungen zu machen!",
|
||||
"tags": [],
|
||||
"value": -2.9663035443712333,
|
||||
"priority": 1,
|
||||
"attribute": "str",
|
||||
"challenge": {},
|
||||
"group": {
|
||||
"completedBy": {},
|
||||
"assignedUsers": []
|
||||
},
|
||||
"byHabitica": false,
|
||||
"startDate": "2024-09-25T22:00:00.000Z",
|
||||
"daysOfMonth": [],
|
||||
"weeksOfMonth": [],
|
||||
"checklist": [],
|
||||
"reminders": [],
|
||||
"createdAt": "2024-07-07T17:51:53.268Z",
|
||||
"updatedAt": "2024-09-21T22:24:20.154Z",
|
||||
"userId": "5f359083-ef78-4af0-985a-0b2c6d05797c",
|
||||
"isDue": false,
|
||||
"id": "564b9ac9-c53d-4638-9e7f-1cd96fe19baa"
|
||||
}
|
||||
],
|
||||
"notifications": [],
|
||||
"userV": 589,
|
||||
"appVersion": "5.28.6"
|
||||
}
|
51
tests/components/habitica/fixtures/duedate_fixture_7.json
Normal file
51
tests/components/habitica/fixtures/duedate_fixture_7.json
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"_id": "564b9ac9-c53d-4638-9e7f-1cd96fe19baa",
|
||||
"frequency": "monthly",
|
||||
"everyX": 0,
|
||||
"repeat": {
|
||||
"m": true,
|
||||
"t": true,
|
||||
"w": true,
|
||||
"th": true,
|
||||
"f": true,
|
||||
"s": true,
|
||||
"su": true
|
||||
},
|
||||
"streak": 1,
|
||||
"nextDue": ["2024-09-22T22:00:00.000Z", "2024-09-23T22:00:00.000Z"],
|
||||
"yesterDaily": true,
|
||||
"history": [],
|
||||
"completed": false,
|
||||
"collapseChecklist": false,
|
||||
"type": "daily",
|
||||
"text": "Zahnseide benutzen",
|
||||
"notes": "Klicke um Änderungen zu machen!",
|
||||
"tags": [],
|
||||
"value": -2.9663035443712333,
|
||||
"priority": 1,
|
||||
"attribute": "str",
|
||||
"challenge": {},
|
||||
"group": {
|
||||
"completedBy": {},
|
||||
"assignedUsers": []
|
||||
},
|
||||
"byHabitica": false,
|
||||
"startDate": "2024-09-23T22:00:00.000Z",
|
||||
"daysOfMonth": [],
|
||||
"weeksOfMonth": [],
|
||||
"checklist": [],
|
||||
"reminders": [],
|
||||
"createdAt": "2024-07-07T17:51:53.268Z",
|
||||
"updatedAt": "2024-09-21T22:24:20.154Z",
|
||||
"userId": "5f359083-ef78-4af0-985a-0b2c6d05797c",
|
||||
"isDue": false,
|
||||
"id": "564b9ac9-c53d-4638-9e7f-1cd96fe19baa"
|
||||
}
|
||||
],
|
||||
"notifications": [],
|
||||
"userV": 589,
|
||||
"appVersion": "5.28.6"
|
||||
}
|
51
tests/components/habitica/fixtures/duedate_fixture_8.json
Normal file
51
tests/components/habitica/fixtures/duedate_fixture_8.json
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"_id": "564b9ac9-c53d-4638-9e7f-1cd96fe19baa",
|
||||
"frequency": "daily",
|
||||
"everyX": 1,
|
||||
"repeat": {
|
||||
"m": true,
|
||||
"t": true,
|
||||
"w": true,
|
||||
"th": true,
|
||||
"f": true,
|
||||
"s": true,
|
||||
"su": true
|
||||
},
|
||||
"streak": 1,
|
||||
"nextDue": [],
|
||||
"yesterDaily": true,
|
||||
"history": [],
|
||||
"completed": false,
|
||||
"collapseChecklist": false,
|
||||
"type": "daily",
|
||||
"text": "Zahnseide benutzen",
|
||||
"notes": "Klicke um Änderungen zu machen!",
|
||||
"tags": [],
|
||||
"value": -2.9663035443712333,
|
||||
"priority": 1,
|
||||
"attribute": "str",
|
||||
"challenge": {},
|
||||
"group": {
|
||||
"completedBy": {},
|
||||
"assignedUsers": []
|
||||
},
|
||||
"byHabitica": false,
|
||||
"startDate": "2024-09-23T22:00:00.000Z",
|
||||
"daysOfMonth": [],
|
||||
"weeksOfMonth": [],
|
||||
"checklist": [],
|
||||
"reminders": [],
|
||||
"createdAt": "2024-07-07T17:51:53.268Z",
|
||||
"updatedAt": "2024-09-21T22:24:20.154Z",
|
||||
"userId": "5f359083-ef78-4af0-985a-0b2c6d05797c",
|
||||
"isDue": false,
|
||||
"id": "564b9ac9-c53d-4638-9e7f-1cd96fe19baa"
|
||||
}
|
||||
],
|
||||
"notifications": [],
|
||||
"userV": 589,
|
||||
"appVersion": "5.28.6"
|
||||
}
|
69
tests/components/habitica/fixtures/score_with_drop.json
Normal file
69
tests/components/habitica/fixtures/score_with_drop.json
Normal file
@ -0,0 +1,69 @@
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"delta": 0.9999999781878414,
|
||||
"_tmp": {
|
||||
"quest": {
|
||||
"progressDelta": 1.049999977097233
|
||||
},
|
||||
"drop": {
|
||||
"value": 3,
|
||||
"key": "Dragon",
|
||||
"type": "Egg",
|
||||
"dialog": "You've found a Dragon Egg!"
|
||||
}
|
||||
},
|
||||
"buffs": {
|
||||
"str": 0,
|
||||
"int": 0,
|
||||
"per": 0,
|
||||
"con": 0,
|
||||
"stealth": 0,
|
||||
"streaks": false,
|
||||
"seafoam": false,
|
||||
"shinySeed": false,
|
||||
"snowball": false,
|
||||
"spookySparkles": false
|
||||
},
|
||||
"training": {
|
||||
"int": 0,
|
||||
"per": 0,
|
||||
"str": 0,
|
||||
"con": 0
|
||||
},
|
||||
"hp": 25.100000000000016,
|
||||
"mp": 24,
|
||||
"exp": 196,
|
||||
"gp": 30.453660284128997,
|
||||
"lvl": 20,
|
||||
"class": "warrior",
|
||||
"points": 2,
|
||||
"str": 0,
|
||||
"con": 0,
|
||||
"int": 0,
|
||||
"per": 0
|
||||
},
|
||||
"notifications": [
|
||||
{
|
||||
"type": "ITEM_RECEIVED",
|
||||
"data": {
|
||||
"icon": "notif_orca_mount",
|
||||
"title": "Orcas for Summer Splash!",
|
||||
"text": "To celebrate Summer Splash, we've given you an Orca Mount!",
|
||||
"destination": "stable"
|
||||
},
|
||||
"seen": true,
|
||||
"id": "b7a85df1-06ed-4ab1-b56d-43418fc6a5e5"
|
||||
},
|
||||
{
|
||||
"type": "UNALLOCATED_STATS_POINTS",
|
||||
"data": {
|
||||
"points": 2
|
||||
},
|
||||
"seen": true,
|
||||
"id": "bc3f8a69-231f-4eb1-ba48-a00b6c0e0f37"
|
||||
}
|
||||
],
|
||||
"userV": 623,
|
||||
"appVersion": "5.28.6"
|
||||
}
|
189
tests/components/habitica/snapshots/test_todo.ambr
Normal file
189
tests/components/habitica/snapshots/test_todo.ambr
Normal file
@ -0,0 +1,189 @@
|
||||
# serializer version: 1
|
||||
# name: test_complete_todo_item[daily]
|
||||
tuple(
|
||||
'Habitica',
|
||||
'''
|
||||

|
||||
You've found a Dragon Egg!
|
||||
''',
|
||||
)
|
||||
# ---
|
||||
# name: test_complete_todo_item[todo]
|
||||
tuple(
|
||||
'Habitica',
|
||||
'''
|
||||

|
||||
You've found a Dragon Egg!
|
||||
''',
|
||||
)
|
||||
# ---
|
||||
# name: test_todo_items[todo.test_user_dailies]
|
||||
dict({
|
||||
'todo.test_user_dailies': dict({
|
||||
'items': list([
|
||||
dict({
|
||||
'description': 'Klicke um Änderungen zu machen!',
|
||||
'due': '2024-09-22',
|
||||
'status': 'completed',
|
||||
'summary': 'Zahnseide benutzen',
|
||||
'uid': '564b9ac9-c53d-4638-9e7f-1cd96fe19baa',
|
||||
}),
|
||||
dict({
|
||||
'description': 'Klicke um Deinen Terminplan festzulegen!',
|
||||
'due': '2024-09-21',
|
||||
'status': 'needs_action',
|
||||
'summary': '5 Minuten ruhig durchatmen',
|
||||
'uid': 'f2c85972-1a19-4426-bc6d-ce3337b9d99f',
|
||||
}),
|
||||
dict({
|
||||
'description': 'Ein einstündiges Workout im Fitnessstudio absolvieren.',
|
||||
'due': '2024-09-21',
|
||||
'status': 'needs_action',
|
||||
'summary': 'Fitnessstudio besuchen',
|
||||
'uid': '2c6d136c-a1c3-4bef-b7c4-fa980784b1e1',
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
# name: test_todo_items[todo.test_user_to_do_s]
|
||||
dict({
|
||||
'todo.test_user_to_do_s': dict({
|
||||
'items': list([
|
||||
dict({
|
||||
'description': 'Das Buch, das du angefangen hast, bis zum Wochenende fertig lesen.',
|
||||
'due': '2024-09-27',
|
||||
'status': 'needs_action',
|
||||
'summary': 'Buch zu Ende lesen',
|
||||
'uid': '88de7cd9-af2b-49ce-9afd-bf941d87336b',
|
||||
}),
|
||||
dict({
|
||||
'description': 'Strom- und Internetrechnungen rechtzeitig überweisen.',
|
||||
'due': '2024-08-31',
|
||||
'status': 'needs_action',
|
||||
'summary': 'Rechnungen bezahlen',
|
||||
'uid': '2f6fcabc-f670-4ec3-ba65-817e8deea490',
|
||||
}),
|
||||
dict({
|
||||
'description': 'Rasen mähen und die Pflanzen gießen.',
|
||||
'status': 'needs_action',
|
||||
'summary': 'Garten pflegen',
|
||||
'uid': '1aa3137e-ef72-4d1f-91ee-41933602f438',
|
||||
}),
|
||||
dict({
|
||||
'description': 'Den Ausflug für das kommende Wochenende organisieren.',
|
||||
'due': '2024-09-26',
|
||||
'status': 'needs_action',
|
||||
'summary': 'Wochenendausflug planen',
|
||||
'uid': '86ea2475-d1b5-4020-bdcc-c188c7996afa',
|
||||
}),
|
||||
dict({
|
||||
'description': 'Lebensmittel und Haushaltsbedarf für die Woche einkaufen.',
|
||||
'status': 'completed',
|
||||
'summary': 'Wocheneinkauf erledigen',
|
||||
'uid': '162f0bbe-a097-4a06-b4f4-8fbeed85d2ba',
|
||||
}),
|
||||
dict({
|
||||
'description': 'Wohnzimmer und Küche gründlich aufräumen.',
|
||||
'status': 'completed',
|
||||
'summary': 'Wohnung aufräumen',
|
||||
'uid': '3fa06743-aa0f-472b-af1a-f27c755e329c',
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
# name: test_todos[todo.test_user_dailies-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'todo',
|
||||
'entity_category': None,
|
||||
'entity_id': 'todo.test_user_dailies',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Dailies',
|
||||
'platform': 'habitica',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <TodoListEntityFeature: 92>,
|
||||
'translation_key': <HabiticaTodoList.DAILIES: 'dailys'>,
|
||||
'unique_id': '00000000-0000-0000-0000-000000000000_dailys',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_todos[todo.test_user_dailies-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'test-user Dailies',
|
||||
'supported_features': <TodoListEntityFeature: 92>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'todo.test_user_dailies',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '2',
|
||||
})
|
||||
# ---
|
||||
# name: test_todos[todo.test_user_to_do_s-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'todo',
|
||||
'entity_category': None,
|
||||
'entity_id': 'todo.test_user_to_do_s',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': "To-Do's",
|
||||
'platform': 'habitica',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <TodoListEntityFeature: 95>,
|
||||
'translation_key': <HabiticaTodoList.TODOS: 'todos'>,
|
||||
'unique_id': '00000000-0000-0000-0000-000000000000_todos',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_todos[todo.test_user_to_do_s-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': "test-user To-Do's",
|
||||
'supported_features': <TodoListEntityFeature: 95>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'todo.test_user_to_do_s',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '4',
|
||||
})
|
||||
# ---
|
695
tests/components/habitica/test_todo.py
Normal file
695
tests/components/habitica/test_todo.py
Normal file
@ -0,0 +1,695 @@
|
||||
"""Tests for Habitica todo platform."""
|
||||
|
||||
from collections.abc import Generator
|
||||
from datetime import datetime
|
||||
from http import HTTPStatus
|
||||
import json
|
||||
import re
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.habitica.const import DEFAULT_URL, DOMAIN
|
||||
from homeassistant.components.todo import (
|
||||
ATTR_DESCRIPTION,
|
||||
ATTR_DUE_DATE,
|
||||
ATTR_ITEM,
|
||||
ATTR_RENAME,
|
||||
ATTR_STATUS,
|
||||
DOMAIN as TODO_DOMAIN,
|
||||
TodoServices,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import ATTR_ENTITY_ID, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ServiceValidationError
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from .conftest import mock_called_with
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_get_persistent_notifications,
|
||||
load_json_object_fixture,
|
||||
snapshot_platform,
|
||||
)
|
||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||
from tests.typing import WebSocketGenerator
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def switch_only() -> Generator[None]:
|
||||
"""Enable only the todo platform."""
|
||||
with patch(
|
||||
"homeassistant.components.habitica.PLATFORMS",
|
||||
[Platform.TODO],
|
||||
):
|
||||
yield
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_habitica")
|
||||
async def test_todos(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
snapshot: SnapshotAssertion,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test todo platform."""
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
await snapshot_platform(hass, entity_registry, snapshot, config_entry.entry_id)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("entity_id"),
|
||||
[
|
||||
"todo.test_user_to_do_s",
|
||||
"todo.test_user_dailies",
|
||||
],
|
||||
)
|
||||
@pytest.mark.usefixtures("mock_habitica")
|
||||
async def test_todo_items(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
snapshot: SnapshotAssertion,
|
||||
entity_id: str,
|
||||
) -> None:
|
||||
"""Test items on todo lists."""
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
result = await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.GET_ITEMS,
|
||||
{},
|
||||
target={ATTR_ENTITY_ID: entity_id},
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
|
||||
assert result == snapshot
|
||||
|
||||
|
||||
@pytest.mark.freeze_time("2024-09-21 00:00:00")
|
||||
@pytest.mark.parametrize(
|
||||
("entity_id", "uid"),
|
||||
[
|
||||
("todo.test_user_to_do_s", "88de7cd9-af2b-49ce-9afd-bf941d87336b"),
|
||||
("todo.test_user_dailies", "f2c85972-1a19-4426-bc6d-ce3337b9d99f"),
|
||||
],
|
||||
ids=["todo", "daily"],
|
||||
)
|
||||
async def test_complete_todo_item(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
mock_habitica: AiohttpClientMocker,
|
||||
snapshot: SnapshotAssertion,
|
||||
entity_id: str,
|
||||
uid: str,
|
||||
) -> None:
|
||||
"""Test completing an item on the todo list."""
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
mock_habitica.post(
|
||||
f"{DEFAULT_URL}/api/v3/tasks/{uid}/score/up",
|
||||
json=load_json_object_fixture("score_with_drop.json", DOMAIN),
|
||||
)
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.UPDATE_ITEM,
|
||||
{ATTR_ITEM: uid, ATTR_STATUS: "completed"},
|
||||
target={ATTR_ENTITY_ID: entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
assert mock_called_with(
|
||||
mock_habitica, "post", f"{DEFAULT_URL}/api/v3/tasks/{uid}/score/up"
|
||||
)
|
||||
|
||||
# Test notification for item drop
|
||||
notifications = async_get_persistent_notifications(hass)
|
||||
assert len(notifications) == 1
|
||||
_id, *_ = notifications
|
||||
assert snapshot == (notifications[_id]["title"], notifications[_id]["message"])
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("entity_id", "uid"),
|
||||
[
|
||||
("todo.test_user_to_do_s", "162f0bbe-a097-4a06-b4f4-8fbeed85d2ba"),
|
||||
("todo.test_user_dailies", "564b9ac9-c53d-4638-9e7f-1cd96fe19baa"),
|
||||
],
|
||||
ids=["todo", "daily"],
|
||||
)
|
||||
async def test_uncomplete_todo_item(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
mock_habitica: AiohttpClientMocker,
|
||||
entity_id: str,
|
||||
uid: str,
|
||||
) -> None:
|
||||
"""Test uncompleting an item on the todo list."""
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
mock_habitica.post(
|
||||
f"{DEFAULT_URL}/api/v3/tasks/{uid}/score/down",
|
||||
json={"data": {}, "success": True},
|
||||
)
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.UPDATE_ITEM,
|
||||
{ATTR_ITEM: uid, ATTR_STATUS: "needs_action"},
|
||||
target={ATTR_ENTITY_ID: entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
assert mock_called_with(
|
||||
mock_habitica, "post", f"{DEFAULT_URL}/api/v3/tasks/{uid}/score/down"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("uid", "status"),
|
||||
[
|
||||
("88de7cd9-af2b-49ce-9afd-bf941d87336b", "completed"),
|
||||
("162f0bbe-a097-4a06-b4f4-8fbeed85d2ba", "needs_action"),
|
||||
],
|
||||
ids=["completed", "needs_action"],
|
||||
)
|
||||
async def test_complete_todo_item_exception(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
mock_habitica: AiohttpClientMocker,
|
||||
uid: str,
|
||||
status: str,
|
||||
) -> None:
|
||||
"""Test exception when completing/uncompleting an item on the todo list."""
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
mock_habitica.post(
|
||||
re.compile(f"{DEFAULT_URL}/api/v3/tasks/{uid}/score/.+"),
|
||||
status=HTTPStatus.NOT_FOUND,
|
||||
)
|
||||
with pytest.raises(
|
||||
expected_exception=ServiceValidationError,
|
||||
match=r"Unable to update the score for your Habitica to-do `.+`, please try again",
|
||||
):
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.UPDATE_ITEM,
|
||||
{ATTR_ITEM: uid, ATTR_STATUS: status},
|
||||
target={ATTR_ENTITY_ID: "todo.test_user_to_do_s"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("entity_id", "uid", "date"),
|
||||
[
|
||||
(
|
||||
"todo.test_user_to_do_s",
|
||||
"88de7cd9-af2b-49ce-9afd-bf941d87336b",
|
||||
"2024-07-30",
|
||||
),
|
||||
(
|
||||
"todo.test_user_dailies",
|
||||
"f2c85972-1a19-4426-bc6d-ce3337b9d99f",
|
||||
None,
|
||||
),
|
||||
],
|
||||
ids=["todo", "daily"],
|
||||
)
|
||||
async def test_update_todo_item(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
mock_habitica: AiohttpClientMocker,
|
||||
entity_id: str,
|
||||
uid: str,
|
||||
date: str,
|
||||
) -> None:
|
||||
"""Test update details of a item on the todo list."""
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
mock_habitica.put(
|
||||
f"{DEFAULT_URL}/api/v3/tasks/{uid}",
|
||||
json={"data": {}, "success": True},
|
||||
)
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.UPDATE_ITEM,
|
||||
{
|
||||
ATTR_ITEM: uid,
|
||||
ATTR_RENAME: "test-summary",
|
||||
ATTR_DESCRIPTION: "test-description",
|
||||
ATTR_DUE_DATE: date,
|
||||
},
|
||||
target={ATTR_ENTITY_ID: entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
mock_call = mock_called_with(
|
||||
mock_habitica, "PUT", f"{DEFAULT_URL}/api/v3/tasks/{uid}"
|
||||
)
|
||||
assert mock_call
|
||||
assert json.loads(mock_call[2]) == {
|
||||
"date": date,
|
||||
"notes": "test-description",
|
||||
"text": "test-summary",
|
||||
}
|
||||
|
||||
|
||||
async def test_update_todo_item_exception(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
mock_habitica: AiohttpClientMocker,
|
||||
) -> None:
|
||||
"""Test exception when update item on the todo list."""
|
||||
uid = "88de7cd9-af2b-49ce-9afd-bf941d87336b"
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
mock_habitica.put(
|
||||
f"{DEFAULT_URL}/api/v3/tasks/{uid}",
|
||||
status=HTTPStatus.NOT_FOUND,
|
||||
)
|
||||
with pytest.raises(
|
||||
expected_exception=ServiceValidationError,
|
||||
match="Unable to update the Habitica to-do `test-summary`, please try again",
|
||||
):
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.UPDATE_ITEM,
|
||||
{
|
||||
ATTR_ITEM: uid,
|
||||
ATTR_RENAME: "test-summary",
|
||||
ATTR_DESCRIPTION: "test-description",
|
||||
ATTR_DUE_DATE: "2024-07-30",
|
||||
},
|
||||
target={ATTR_ENTITY_ID: "todo.test_user_to_do_s"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
|
||||
async def test_add_todo_item(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
mock_habitica: AiohttpClientMocker,
|
||||
) -> None:
|
||||
"""Test add a todo item to the todo list."""
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
mock_habitica.post(
|
||||
f"{DEFAULT_URL}/api/v3/tasks/user",
|
||||
json={"data": {}, "success": True},
|
||||
status=HTTPStatus.CREATED,
|
||||
)
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.ADD_ITEM,
|
||||
{
|
||||
ATTR_ITEM: "test-summary",
|
||||
ATTR_DESCRIPTION: "test-description",
|
||||
ATTR_DUE_DATE: "2024-07-30",
|
||||
},
|
||||
target={ATTR_ENTITY_ID: "todo.test_user_to_do_s"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
mock_call = mock_called_with(
|
||||
mock_habitica,
|
||||
"post",
|
||||
f"{DEFAULT_URL}/api/v3/tasks/user",
|
||||
)
|
||||
assert mock_call
|
||||
assert json.loads(mock_call[2]) == {
|
||||
"date": "2024-07-30",
|
||||
"notes": "test-description",
|
||||
"text": "test-summary",
|
||||
"type": "todo",
|
||||
}
|
||||
|
||||
|
||||
async def test_add_todo_item_exception(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
mock_habitica: AiohttpClientMocker,
|
||||
) -> None:
|
||||
"""Test exception when adding a todo item to the todo list."""
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
mock_habitica.post(
|
||||
f"{DEFAULT_URL}/api/v3/tasks/user",
|
||||
status=HTTPStatus.NOT_FOUND,
|
||||
)
|
||||
with pytest.raises(
|
||||
expected_exception=ServiceValidationError,
|
||||
match="Unable to create new to-do `test-summary` for Habitica, please try again",
|
||||
):
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.ADD_ITEM,
|
||||
{
|
||||
ATTR_ITEM: "test-summary",
|
||||
ATTR_DESCRIPTION: "test-description",
|
||||
ATTR_DUE_DATE: "2024-07-30",
|
||||
},
|
||||
target={ATTR_ENTITY_ID: "todo.test_user_to_do_s"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
|
||||
async def test_delete_todo_item(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
mock_habitica: AiohttpClientMocker,
|
||||
) -> None:
|
||||
"""Test deleting a todo item from the todo list."""
|
||||
|
||||
uid = "2f6fcabc-f670-4ec3-ba65-817e8deea490"
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
mock_habitica.delete(
|
||||
f"{DEFAULT_URL}/api/v3/tasks/{uid}",
|
||||
json={"data": {}, "success": True},
|
||||
)
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.REMOVE_ITEM,
|
||||
{ATTR_ITEM: uid},
|
||||
target={ATTR_ENTITY_ID: "todo.test_user_to_do_s"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
assert mock_called_with(
|
||||
mock_habitica, "delete", f"{DEFAULT_URL}/api/v3/tasks/{uid}"
|
||||
)
|
||||
|
||||
|
||||
async def test_delete_todo_item_exception(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
mock_habitica: AiohttpClientMocker,
|
||||
) -> None:
|
||||
"""Test exception when deleting a todo item from the todo list."""
|
||||
|
||||
uid = "2f6fcabc-f670-4ec3-ba65-817e8deea490"
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
mock_habitica.delete(
|
||||
f"{DEFAULT_URL}/api/v3/tasks/{uid}",
|
||||
status=HTTPStatus.NOT_FOUND,
|
||||
)
|
||||
with pytest.raises(
|
||||
expected_exception=ServiceValidationError,
|
||||
match="Unable to delete item from Habitica to-do list, please try again",
|
||||
):
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.REMOVE_ITEM,
|
||||
{ATTR_ITEM: uid},
|
||||
target={ATTR_ENTITY_ID: "todo.test_user_to_do_s"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
|
||||
async def test_delete_completed_todo_items(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
mock_habitica: AiohttpClientMocker,
|
||||
) -> None:
|
||||
"""Test deleting completed todo items from the todo list."""
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
mock_habitica.post(
|
||||
f"{DEFAULT_URL}/api/v3/tasks/clearCompletedTodos",
|
||||
json={"data": {}, "success": True},
|
||||
)
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.REMOVE_COMPLETED_ITEMS,
|
||||
{},
|
||||
target={ATTR_ENTITY_ID: "todo.test_user_to_do_s"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
assert mock_called_with(
|
||||
mock_habitica, "post", f"{DEFAULT_URL}/api/v3/tasks/clearCompletedTodos"
|
||||
)
|
||||
|
||||
|
||||
async def test_delete_completed_todo_items_exception(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
mock_habitica: AiohttpClientMocker,
|
||||
) -> None:
|
||||
"""Test exception when deleting completed todo items from the todo list."""
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
mock_habitica.post(
|
||||
f"{DEFAULT_URL}/api/v3/tasks/clearCompletedTodos",
|
||||
status=HTTPStatus.NOT_FOUND,
|
||||
)
|
||||
with pytest.raises(
|
||||
expected_exception=ServiceValidationError,
|
||||
match="Unable to delete completed to-do items from Habitica to-do list, please try again",
|
||||
):
|
||||
await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.REMOVE_COMPLETED_ITEMS,
|
||||
{},
|
||||
target={ATTR_ENTITY_ID: "todo.test_user_to_do_s"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("entity_id", "uid", "previous_uid"),
|
||||
[
|
||||
(
|
||||
"todo.test_user_to_do_s",
|
||||
"1aa3137e-ef72-4d1f-91ee-41933602f438",
|
||||
"88de7cd9-af2b-49ce-9afd-bf941d87336b",
|
||||
),
|
||||
(
|
||||
"todo.test_user_dailies",
|
||||
"2c6d136c-a1c3-4bef-b7c4-fa980784b1e1",
|
||||
"564b9ac9-c53d-4638-9e7f-1cd96fe19baa",
|
||||
),
|
||||
],
|
||||
ids=["todo", "daily"],
|
||||
)
|
||||
async def test_move_todo_item(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
mock_habitica: AiohttpClientMocker,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
entity_id: str,
|
||||
uid: str,
|
||||
previous_uid: str,
|
||||
) -> None:
|
||||
"""Test move todo items."""
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
for pos in (0, 1):
|
||||
mock_habitica.post(
|
||||
f"{DEFAULT_URL}/api/v3/tasks/{uid}/move/to/{pos}",
|
||||
json={"data": {}, "success": True},
|
||||
)
|
||||
|
||||
client = await hass_ws_client()
|
||||
# move to second position
|
||||
data = {
|
||||
"id": id,
|
||||
"type": "todo/item/move",
|
||||
"entity_id": entity_id,
|
||||
"uid": uid,
|
||||
"previous_uid": previous_uid,
|
||||
}
|
||||
await client.send_json_auto_id(data)
|
||||
resp = await client.receive_json()
|
||||
assert resp.get("success")
|
||||
|
||||
# move to top position
|
||||
data = {
|
||||
"id": id,
|
||||
"type": "todo/item/move",
|
||||
"entity_id": entity_id,
|
||||
"uid": uid,
|
||||
}
|
||||
await client.send_json_auto_id(data)
|
||||
resp = await client.receive_json()
|
||||
assert resp.get("success")
|
||||
|
||||
for pos in (0, 1):
|
||||
assert mock_called_with(
|
||||
mock_habitica,
|
||||
"post",
|
||||
f"{DEFAULT_URL}/api/v3/tasks/{uid}/move/to/{pos}",
|
||||
)
|
||||
|
||||
|
||||
async def test_move_todo_item_exception(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
mock_habitica: AiohttpClientMocker,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test exception when moving todo item."""
|
||||
|
||||
uid = "1aa3137e-ef72-4d1f-91ee-41933602f438"
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
mock_habitica.post(
|
||||
f"{DEFAULT_URL}/api/v3/tasks/{uid}/move/to/0",
|
||||
status=HTTPStatus.NOT_FOUND,
|
||||
)
|
||||
|
||||
client = await hass_ws_client()
|
||||
|
||||
data = {
|
||||
"id": id,
|
||||
"type": "todo/item/move",
|
||||
"entity_id": "todo.test_user_to_do_s",
|
||||
"uid": uid,
|
||||
}
|
||||
await client.send_json_auto_id(data)
|
||||
resp = await client.receive_json()
|
||||
assert resp.get("success") is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("fixture", "calculated_due_date"),
|
||||
[
|
||||
("duedate_fixture_1.json", (2024, 9, 23)),
|
||||
("duedate_fixture_2.json", (2024, 9, 24)),
|
||||
("duedate_fixture_3.json", (2024, 10, 23)),
|
||||
("duedate_fixture_4.json", (2024, 10, 23)),
|
||||
("duedate_fixture_5.json", (2024, 9, 28)),
|
||||
("duedate_fixture_6.json", (2024, 10, 21)),
|
||||
("duedate_fixture_7.json", None),
|
||||
("duedate_fixture_8.json", None),
|
||||
],
|
||||
ids=[
|
||||
"default",
|
||||
"daily starts on startdate",
|
||||
"monthly starts on startdate",
|
||||
"yearly starts on startdate",
|
||||
"weekly",
|
||||
"monthly starts on fixed day",
|
||||
"grey daily",
|
||||
"empty nextDue",
|
||||
],
|
||||
)
|
||||
@pytest.mark.usefixtures("set_tz")
|
||||
async def test_next_due_date(
|
||||
hass: HomeAssistant,
|
||||
fixture: str,
|
||||
calculated_due_date: tuple | None,
|
||||
config_entry: MockConfigEntry,
|
||||
aioclient_mock: AiohttpClientMocker,
|
||||
) -> None:
|
||||
"""Test next_due_date calculation."""
|
||||
|
||||
dailies_entity = "todo.test_user_dailies"
|
||||
|
||||
aioclient_mock.get(
|
||||
f"{DEFAULT_URL}/api/v3/user", json=load_json_object_fixture("user.json", DOMAIN)
|
||||
)
|
||||
aioclient_mock.get(
|
||||
f"{DEFAULT_URL}/api/v3/tasks/user",
|
||||
params={"type": "completedTodos"},
|
||||
json={"data": []},
|
||||
)
|
||||
aioclient_mock.get(
|
||||
f"{DEFAULT_URL}/api/v3/tasks/user",
|
||||
json=load_json_object_fixture(fixture, DOMAIN),
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
result = await hass.services.async_call(
|
||||
TODO_DOMAIN,
|
||||
TodoServices.GET_ITEMS,
|
||||
{},
|
||||
target={ATTR_ENTITY_ID: dailies_entity},
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
|
||||
assert (
|
||||
result[dailies_entity]["items"][0].get("due") is None
|
||||
if not calculated_due_date
|
||||
else datetime(*calculated_due_date).date()
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user