feat: enhance calendar ICS generation with event type filtering
All checks were successful
CI / lint-and-test (push) Successful in 22s
All checks were successful
CI / lint-and-test (push) Successful in 22s
- Added support for filtering calendar events by type in the ICS generation API endpoint, allowing users to specify whether to include only duty shifts or all event types (duty, unavailable, vacation). - Updated the `get_duties_for_user` function to accept an optional `event_types` parameter, enabling more flexible data retrieval based on user preferences. - Enhanced unit tests to cover the new event type filtering functionality, ensuring correct behavior and reliability of the ICS generation process.
This commit is contained in:
@@ -304,7 +304,9 @@ def test_calendar_ical_200_returns_only_that_users_duties(
|
||||
assert r.headers.get("content-type", "").startswith("text/calendar")
|
||||
assert b"BEGIN:VCALENDAR" in r.content
|
||||
mock_get_user.assert_called_once()
|
||||
mock_get_duties.assert_called_once_with(ANY, 1, from_date=ANY, to_date=ANY)
|
||||
mock_get_duties.assert_called_once_with(
|
||||
ANY, 1, from_date=ANY, to_date=ANY, event_types=["duty"]
|
||||
)
|
||||
mock_build_ics.assert_called_once()
|
||||
# Only User A's duty was passed to build_personal_ics
|
||||
duties_arg = mock_build_ics.call_args[0][0]
|
||||
@@ -313,6 +315,59 @@ def test_calendar_ical_200_returns_only_that_users_duties(
|
||||
assert duties_arg[0][1] == "User A"
|
||||
|
||||
|
||||
@patch("duty_teller.api.app.build_personal_ics")
|
||||
@patch("duty_teller.api.app.get_duties_for_user")
|
||||
@patch("duty_teller.api.app.get_user_by_calendar_token")
|
||||
def test_calendar_ical_events_all_returns_all_event_types(
|
||||
mock_get_user, mock_get_duties, mock_build_ics, client
|
||||
):
|
||||
"""GET /api/calendar/ical/{token}.ics?events=all returns ICS with duty, unavailable, vacation."""
|
||||
from types import SimpleNamespace
|
||||
|
||||
mock_user = SimpleNamespace(id=1, full_name="User A")
|
||||
mock_get_user.return_value = mock_user
|
||||
duty = SimpleNamespace(
|
||||
id=10,
|
||||
user_id=1,
|
||||
start_at="2026-06-15T09:00:00Z",
|
||||
end_at="2026-06-15T18:00:00Z",
|
||||
event_type="duty",
|
||||
)
|
||||
unavailable = SimpleNamespace(
|
||||
id=11,
|
||||
user_id=1,
|
||||
start_at="2026-06-16T09:00:00Z",
|
||||
end_at="2026-06-16T18:00:00Z",
|
||||
event_type="unavailable",
|
||||
)
|
||||
vacation = SimpleNamespace(
|
||||
id=12,
|
||||
user_id=1,
|
||||
start_at="2026-06-17T09:00:00Z",
|
||||
end_at="2026-06-17T18:00:00Z",
|
||||
event_type="vacation",
|
||||
)
|
||||
mock_get_duties.return_value = [
|
||||
(duty, "User A"),
|
||||
(unavailable, "User A"),
|
||||
(vacation, "User A"),
|
||||
]
|
||||
mock_build_ics.return_value = b"BEGIN:VCALENDAR\r\nVEVENT\r\nEND:VCALENDAR"
|
||||
token = "y" * 43
|
||||
|
||||
r = client.get(f"/api/calendar/ical/{token}.ics", params={"events": "all"})
|
||||
assert r.status_code == 200
|
||||
assert r.headers.get("content-type", "").startswith("text/calendar")
|
||||
mock_get_duties.assert_called_once_with(
|
||||
ANY, 1, from_date=ANY, to_date=ANY, event_types=None
|
||||
)
|
||||
duties_arg = mock_build_ics.call_args[0][0]
|
||||
assert len(duties_arg) == 3
|
||||
assert duties_arg[0][0].event_type == "duty"
|
||||
assert duties_arg[1][0].event_type == "unavailable"
|
||||
assert duties_arg[2][0].event_type == "vacation"
|
||||
|
||||
|
||||
# --- /api/calendar-events ---
|
||||
|
||||
|
||||
@@ -330,7 +385,10 @@ def test_calendar_events_empty_url_returns_empty_list(client):
|
||||
mock_get.assert_not_called()
|
||||
|
||||
|
||||
@patch("duty_teller.api.app.config.EXTERNAL_CALENDAR_ICS_URL", "https://example.com/cal.ics")
|
||||
@patch(
|
||||
"duty_teller.api.app.config.EXTERNAL_CALENDAR_ICS_URL",
|
||||
"https://example.com/cal.ics",
|
||||
)
|
||||
@patch("duty_teller.api.app.config.MINI_APP_SKIP_AUTH", True)
|
||||
def test_calendar_events_200_returns_list_with_date_summary(client):
|
||||
"""GET /api/calendar-events with auth and URL set returns list of {date, summary}."""
|
||||
|
||||
Reference in New Issue
Block a user