mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 17:57:11 +00:00
Streamline todoist test fixtures (#91405)
This commit is contained in:
parent
cb6ffa5b03
commit
b0e0ada512
@ -1,6 +1,6 @@
|
|||||||
"""Unit tests for the Todoist calendar platform."""
|
"""Unit tests for the Todoist calendar platform."""
|
||||||
from datetime import timedelta
|
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import AsyncMock, patch
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
@ -24,6 +24,8 @@ from homeassistant.util import dt
|
|||||||
|
|
||||||
from tests.typing import ClientSessionGenerator
|
from tests.typing import ClientSessionGenerator
|
||||||
|
|
||||||
|
SUMMARY = "A task"
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def set_time_zone(hass: HomeAssistant):
|
def set_time_zone(hass: HomeAssistant):
|
||||||
@ -33,19 +35,25 @@ def set_time_zone(hass: HomeAssistant):
|
|||||||
hass.config.set_time_zone("America/Regina")
|
hass.config.set_time_zone("America/Regina")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="due")
|
||||||
|
def mock_due() -> Due:
|
||||||
|
"""Mock a todoist Task Due date/time."""
|
||||||
|
return Due(is_recurring=False, date=dt.now().strftime("%Y-%m-%d"), string="today")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="task")
|
@pytest.fixture(name="task")
|
||||||
def mock_task() -> Task:
|
def mock_task(due: Due) -> Task:
|
||||||
"""Mock a todoist Task instance."""
|
"""Mock a todoist Task instance."""
|
||||||
return Task(
|
return Task(
|
||||||
assignee_id="1",
|
assignee_id="1",
|
||||||
assigner_id="1",
|
assigner_id="1",
|
||||||
comment_count=0,
|
comment_count=0,
|
||||||
is_completed=False,
|
is_completed=False,
|
||||||
content="A task",
|
content=SUMMARY,
|
||||||
created_at="2021-10-01T00:00:00",
|
created_at="2021-10-01T00:00:00",
|
||||||
creator_id="1",
|
creator_id="1",
|
||||||
description="A task",
|
description="A task",
|
||||||
due=Due(is_recurring=False, date=dt.now().strftime("%Y-%m-%d"), string="today"),
|
due=due,
|
||||||
id="1",
|
id="1",
|
||||||
labels=["Label1"],
|
labels=["Label1"],
|
||||||
order=1,
|
order=1,
|
||||||
@ -93,11 +101,36 @@ def get_events_url(entity: str, start: str, end: str) -> str:
|
|||||||
return f"/api/calendars/{entity}?start={urllib.parse.quote(start)}&end={urllib.parse.quote(end)}"
|
return f"/api/calendars/{entity}?start={urllib.parse.quote(start)}&end={urllib.parse.quote(end)}"
|
||||||
|
|
||||||
|
|
||||||
@patch("homeassistant.components.todoist.calendar.TodoistAPIAsync")
|
def get_events_response(start: dict[str, str], end: dict[str, str]) -> dict[str, Any]:
|
||||||
async def test_calendar_entity_unique_id(
|
"""Return an event response with a single task."""
|
||||||
todoist_api, hass: HomeAssistant, api, entity_registry: er.EntityRegistry
|
return {
|
||||||
|
"start": start,
|
||||||
|
"end": end,
|
||||||
|
"summary": SUMMARY,
|
||||||
|
"description": None,
|
||||||
|
"location": None,
|
||||||
|
"uid": None,
|
||||||
|
"recurrence_id": None,
|
||||||
|
"rrule": None,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="todoist_config")
|
||||||
|
def mock_todoist_config() -> dict[str, Any]:
|
||||||
|
"""Mock todoist configuration."""
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="setup_integration", autouse=True)
|
||||||
|
async def mock_setup_integration(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
api: AsyncMock,
|
||||||
|
todoist_config: dict[str, Any],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test unique id is set to project id."""
|
"""Mock setup of the todoist integration."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.todoist.calendar.TodoistAPIAsync"
|
||||||
|
) as todoist_api:
|
||||||
todoist_api.return_value = api
|
todoist_api.return_value = api
|
||||||
assert await setup.async_setup_component(
|
assert await setup.async_setup_component(
|
||||||
hass,
|
hass,
|
||||||
@ -106,91 +139,53 @@ async def test_calendar_entity_unique_id(
|
|||||||
"calendar": {
|
"calendar": {
|
||||||
"platform": DOMAIN,
|
"platform": DOMAIN,
|
||||||
CONF_TOKEN: "token",
|
CONF_TOKEN: "token",
|
||||||
|
**todoist_config,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
await async_update_entity(hass, "calendar.name")
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
async def test_calendar_entity_unique_id(
|
||||||
|
hass: HomeAssistant, api: AsyncMock, entity_registry: er.EntityRegistry
|
||||||
|
) -> None:
|
||||||
|
"""Test unique id is set to project id."""
|
||||||
entity = entity_registry.async_get("calendar.name")
|
entity = entity_registry.async_get("calendar.name")
|
||||||
assert entity.unique_id == "12345"
|
assert entity.unique_id == "12345"
|
||||||
|
|
||||||
|
|
||||||
@patch("homeassistant.components.todoist.calendar.TodoistAPIAsync")
|
@pytest.mark.parametrize(
|
||||||
|
"todoist_config",
|
||||||
|
[{"custom_projects": [{"name": "All projects", "labels": ["Label1"]}]}],
|
||||||
|
)
|
||||||
async def test_update_entity_for_custom_project_with_labels_on(
|
async def test_update_entity_for_custom_project_with_labels_on(
|
||||||
todoist_api, hass: HomeAssistant, api
|
hass: HomeAssistant,
|
||||||
|
api: AsyncMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that the calendar's state is on for a custom project using labels."""
|
"""Test that the calendar's state is on for a custom project using labels."""
|
||||||
todoist_api.return_value = api
|
|
||||||
assert await setup.async_setup_component(
|
|
||||||
hass,
|
|
||||||
"calendar",
|
|
||||||
{
|
|
||||||
"calendar": {
|
|
||||||
"platform": DOMAIN,
|
|
||||||
CONF_TOKEN: "token",
|
|
||||||
"custom_projects": [{"name": "All projects", "labels": ["Label1"]}],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
await async_update_entity(hass, "calendar.all_projects")
|
await async_update_entity(hass, "calendar.all_projects")
|
||||||
state = hass.states.get("calendar.all_projects")
|
state = hass.states.get("calendar.all_projects")
|
||||||
assert state.attributes["labels"] == ["Label1"]
|
assert state.attributes["labels"] == ["Label1"]
|
||||||
assert state.state == "on"
|
assert state.state == "on"
|
||||||
|
|
||||||
|
|
||||||
@patch("homeassistant.components.todoist.calendar.TodoistAPIAsync")
|
@pytest.mark.parametrize("due", [None])
|
||||||
async def test_update_entity_for_custom_project_no_due_date_on(
|
async def test_update_entity_for_custom_project_no_due_date_on(
|
||||||
todoist_api, hass: HomeAssistant, api
|
hass: HomeAssistant,
|
||||||
|
api: AsyncMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that a task without an explicit due date is considered to be in an on state."""
|
"""Test that a task without an explicit due date is considered to be in an on state."""
|
||||||
task_wo_due_date = Task(
|
await async_update_entity(hass, "calendar.name")
|
||||||
assignee_id=None,
|
state = hass.states.get("calendar.name")
|
||||||
assigner_id=None,
|
|
||||||
comment_count=0,
|
|
||||||
is_completed=False,
|
|
||||||
content="No due date task",
|
|
||||||
created_at="2023-04-11T00:25:25.589971Z",
|
|
||||||
creator_id="1",
|
|
||||||
description="",
|
|
||||||
due=None,
|
|
||||||
id="123",
|
|
||||||
labels=["Label1"],
|
|
||||||
order=10,
|
|
||||||
parent_id=None,
|
|
||||||
priority=1,
|
|
||||||
project_id="12345",
|
|
||||||
section_id=None,
|
|
||||||
url="https://todoist.com/showTask?id=123",
|
|
||||||
sync_id=None,
|
|
||||||
)
|
|
||||||
api.get_tasks.return_value = [task_wo_due_date]
|
|
||||||
todoist_api.return_value = api
|
|
||||||
|
|
||||||
assert await setup.async_setup_component(
|
|
||||||
hass,
|
|
||||||
"calendar",
|
|
||||||
{
|
|
||||||
"calendar": {
|
|
||||||
"platform": DOMAIN,
|
|
||||||
CONF_TOKEN: "token",
|
|
||||||
"custom_projects": [{"name": "All projects", "labels": ["Label1"]}],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
await async_update_entity(hass, "calendar.all_projects")
|
|
||||||
state = hass.states.get("calendar.all_projects")
|
|
||||||
assert state.state == "on"
|
assert state.state == "on"
|
||||||
|
|
||||||
|
|
||||||
@patch("homeassistant.components.todoist.calendar.TodoistAPIAsync")
|
@pytest.mark.parametrize("setup_integration", [None])
|
||||||
async def test_failed_coordinator_update(todoist_api, hass: HomeAssistant, api) -> None:
|
async def test_failed_coordinator_update(hass: HomeAssistant, api: AsyncMock) -> None:
|
||||||
"""Test a failed data coordinator update is handled correctly."""
|
"""Test a failed data coordinator update is handled correctly."""
|
||||||
api.get_tasks.side_effect = Exception("API error")
|
api.get_tasks.side_effect = Exception("API error")
|
||||||
todoist_api.return_value = api
|
|
||||||
|
|
||||||
assert await setup.async_setup_component(
|
assert await setup.async_setup_component(
|
||||||
hass,
|
hass,
|
||||||
@ -210,25 +205,14 @@ async def test_failed_coordinator_update(todoist_api, hass: HomeAssistant, api)
|
|||||||
assert state is None
|
assert state is None
|
||||||
|
|
||||||
|
|
||||||
@patch("homeassistant.components.todoist.calendar.TodoistAPIAsync")
|
@pytest.mark.parametrize(
|
||||||
|
"todoist_config",
|
||||||
|
[{"custom_projects": [{"name": "All projects"}]}],
|
||||||
|
)
|
||||||
async def test_calendar_custom_project_unique_id(
|
async def test_calendar_custom_project_unique_id(
|
||||||
todoist_api, hass: HomeAssistant, api, entity_registry: er.EntityRegistry
|
hass: HomeAssistant, entity_registry: er.EntityRegistry
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test unique id is None for any custom projects."""
|
"""Test unique id is None for any custom projects."""
|
||||||
todoist_api.return_value = api
|
|
||||||
assert await setup.async_setup_component(
|
|
||||||
hass,
|
|
||||||
"calendar",
|
|
||||||
{
|
|
||||||
"calendar": {
|
|
||||||
"platform": DOMAIN,
|
|
||||||
CONF_TOKEN: "token",
|
|
||||||
"custom_projects": [{"name": "All projects"}],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
entity = entity_registry.async_get("calendar.all_projects")
|
entity = entity_registry.async_get("calendar.all_projects")
|
||||||
assert entity is None
|
assert entity is None
|
||||||
|
|
||||||
@ -236,66 +220,35 @@ async def test_calendar_custom_project_unique_id(
|
|||||||
assert state.state == "off"
|
assert state.state == "off"
|
||||||
|
|
||||||
|
|
||||||
@patch("homeassistant.components.todoist.calendar.TodoistAPIAsync")
|
@pytest.mark.parametrize(
|
||||||
|
("due", "start", "end", "expected_response"),
|
||||||
|
[
|
||||||
|
(
|
||||||
|
Due(date="2023-03-30", is_recurring=False, string="Mar 30"),
|
||||||
|
"2023-03-28T00:00:00.000Z",
|
||||||
|
"2023-04-01T00:00:00.000Z",
|
||||||
|
[get_events_response({"date": "2023-03-30"}, {"date": "2023-03-31"})],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
async def test_all_day_event(
|
async def test_all_day_event(
|
||||||
todoist_api, hass: HomeAssistant, hass_client: ClientSessionGenerator, api
|
hass: HomeAssistant,
|
||||||
|
hass_client: ClientSessionGenerator,
|
||||||
|
start: str,
|
||||||
|
end: str,
|
||||||
|
expected_response: dict[str, Any],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test for an all day calendar event."""
|
"""Test for an all day calendar event."""
|
||||||
todoist_api.return_value = api
|
|
||||||
assert await setup.async_setup_component(
|
|
||||||
hass,
|
|
||||||
"calendar",
|
|
||||||
{
|
|
||||||
"calendar": {
|
|
||||||
"platform": DOMAIN,
|
|
||||||
CONF_TOKEN: "token",
|
|
||||||
"custom_projects": [{"name": "All projects", "labels": ["Label1"]}],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
await async_update_entity(hass, "calendar.all_projects")
|
|
||||||
client = await hass_client()
|
client = await hass_client()
|
||||||
start = dt.now() - timedelta(days=1)
|
|
||||||
end = dt.now() + timedelta(days=1)
|
|
||||||
response = await client.get(
|
response = await client.get(
|
||||||
get_events_url("calendar.all_projects", start.isoformat(), end.isoformat())
|
get_events_url("calendar.name", start, end),
|
||||||
)
|
)
|
||||||
assert response.status == HTTPStatus.OK
|
assert response.status == HTTPStatus.OK
|
||||||
events = await response.json()
|
assert await response.json() == expected_response
|
||||||
|
|
||||||
expected = [
|
|
||||||
{
|
|
||||||
"start": {"date": dt.now().strftime("%Y-%m-%d")},
|
|
||||||
"end": {"date": (dt.now() + timedelta(days=1)).strftime("%Y-%m-%d")},
|
|
||||||
"summary": "A task",
|
|
||||||
"description": None,
|
|
||||||
"location": None,
|
|
||||||
"uid": None,
|
|
||||||
"recurrence_id": None,
|
|
||||||
"rrule": None,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
assert events == expected
|
|
||||||
|
|
||||||
|
|
||||||
@patch("homeassistant.components.todoist.calendar.TodoistAPIAsync")
|
async def test_create_task_service_call(hass: HomeAssistant, api: AsyncMock) -> None:
|
||||||
async def test_create_task_service_call(todoist_api, hass: HomeAssistant, api) -> None:
|
|
||||||
"""Test api is called correctly after a new task service call."""
|
"""Test api is called correctly after a new task service call."""
|
||||||
todoist_api.return_value = api
|
|
||||||
assert await setup.async_setup_component(
|
|
||||||
hass,
|
|
||||||
"calendar",
|
|
||||||
{
|
|
||||||
"calendar": {
|
|
||||||
"platform": DOMAIN,
|
|
||||||
CONF_TOKEN: "token",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
SERVICE_NEW_TASK,
|
SERVICE_NEW_TASK,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user