File: test_calendar.py

package info (click to toggle)
pyicloud 2.0.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 828 kB
  • sloc: python: 9,741; sh: 17; makefile: 3
file content (246 lines) | stat: -rw-r--r-- 9,757 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
"""Test calendar service"""

from datetime import datetime
from typing import Any
from unittest.mock import MagicMock, patch

from requests import Response

from pyicloud.services.calendar import CalendarObject, CalendarService, EventObject
from pyicloud.session import PyiCloudSession


def test_event_object_initialization() -> None:
    """Test EventObject initialization and default values."""
    event = EventObject(pguid="calendar123")
    assert event.pguid == "calendar123"
    assert event.title == "New Event"
    assert event.duration == 60
    assert event.tz == "US/Pacific"
    assert event.guid != ""


def test_event_object_request_data() -> None:
    """Test EventObject request_data property."""
    event = EventObject(pguid="calendar123")
    data: dict[str, Any] = event.request_data
    assert "Event" in data
    assert "ClientState" in data
    assert data["Event"]["title"] == "New Event"
    assert "pguid" in data["Event"]
    assert data["Event"]["pguid"] == "calendar123"
    assert "guid" in data["Event"]
    assert "Collection" in data["ClientState"]


def test_event_object_dt_to_list() -> None:
    """Test EventObject dt_to_list method."""
    event = EventObject(pguid="calendar123")
    dt = datetime(2023, 1, 1, 12, 30)
    result = event.dt_to_list(dt)
    assert result == ["20230101", 2023, 1, 1, 12, 30, 750]


def test_event_object_add_invitees() -> None:
    """Test EventObject add_invitees method."""
    event = EventObject(pguid="calendar123")
    event.add_invitees(["test@example.com", "user@example.com"])
    assert len(event.invitees) == 2
    assert f"{event.guid}:test@example.com" == event.invitees[0]
    assert f"{event.guid}:user@example.com" == event.invitees[1]


def test_calendar_object_initialization() -> None:
    """Test CalendarObject initialization and default values."""
    calendar = CalendarObject(title="My Calendar")
    assert calendar.title == "My Calendar"
    assert calendar.guid != ""
    assert calendar.color.startswith("#")


def test_calendar_object_request_data() -> None:
    """Test CalendarObject request_data property."""
    calendar = CalendarObject(title="My Calendar")
    data: dict[str, Any] = calendar.request_data
    assert "Collection" in data
    assert data["Collection"]["title"] == "My Calendar"
    assert "ClientState" in data
    assert "guid" in data["Collection"]
    assert "color" in data["Collection"]


def test_calendar_service_get_calendars() -> None:
    """Test CalendarService get_calendars method."""
    mock_session = MagicMock(spec=PyiCloudSession)
    mock_response = MagicMock(spec=Response)
    mock_response.json.return_value = {"Collection": [{"title": "Test Calendar"}]}
    mock_session.get.return_value = mock_response
    with patch("pyicloud.services.calendar.get_localzone_name", return_value="UTC"):
        service = CalendarService(
            "https://example.com", mock_session, {"dsid": "12345"}
        )
        calendars = service.get_calendars()
        assert len(calendars) == 1
        assert calendars[0]["title"] == "Test Calendar"


def test_calendar_service_add_calendar() -> None:
    """Test CalendarService add_calendar method."""
    mock_session = MagicMock(spec=PyiCloudSession)
    mock_response = MagicMock(spec=Response)
    mock_response.json.return_value = {"status": "success"}
    mock_session.post.return_value = mock_response
    with patch("pyicloud.services.calendar.get_localzone_name", return_value="UTC"):
        service = CalendarService(
            "https://example.com", mock_session, {"dsid": "12345"}
        )
        calendar = CalendarObject(title="New Calendar")
        response = service.add_calendar(calendar)
        assert response["status"] == "success"


def test_calendar_service_remove_calendar() -> None:
    """Test CalendarService remove_calendar method."""
    mock_session = MagicMock(spec=PyiCloudSession)
    mock_response = MagicMock(spec=Response)
    mock_response.json.return_value = {"status": "success"}
    mock_session.post.return_value = mock_response

    with patch("pyicloud.services.calendar.get_localzone_name", return_value="UTC"):
        service = CalendarService(
            "https://example.com", mock_session, {"dsid": "12345"}
        )
        response = service.remove_calendar("calendar123")
        assert response["status"] == "success"


def test_calendar_service_get_events() -> None:
    """Test CalendarService get_events method."""
    mock_session = MagicMock(spec=PyiCloudSession)
    mock_response = MagicMock(spec=Response)
    mock_response.json.return_value = {"Event": [{"title": "Test Event"}]}
    mock_session.get.return_value = mock_response
    with patch("pyicloud.services.calendar.get_localzone_name", return_value="UTC"):
        service = CalendarService(
            "https://example.com", mock_session, {"dsid": "12345"}
        )
        events = service.get_events()
        assert len(events) == 1
        assert events[0]["title"] == "Test Event"


def test_calendar_service_add_event() -> None:
    """Test CalendarService add_event method."""
    mock_session = MagicMock(spec=PyiCloudSession)
    mock_response = MagicMock(spec=Response)
    mock_response.json.return_value = {"status": "success"}
    mock_session.post.return_value = mock_response
    with patch("pyicloud.services.calendar.get_localzone_name", return_value="UTC"):
        service = CalendarService(
            "https://example.com", mock_session, {"dsid": "12345"}
        )
        service.get_ctag = MagicMock(return_value="etag123")
        event = EventObject(pguid="calendar123", title="New Event")
        response = service.add_event(event)
        assert response["status"] == "success"


def test_calendar_service_remove_event() -> None:
    """Test CalendarService remove_event method."""
    mock_session = MagicMock(spec=PyiCloudSession)
    mock_response = MagicMock(spec=Response)
    mock_response.json.return_value = {"status": "success"}
    mock_session.post.return_value = mock_response
    with patch("pyicloud.services.calendar.get_localzone_name", return_value="UTC"):
        service = CalendarService(
            "https://example.com", mock_session, {"dsid": "12345"}
        )
        service.get_ctag = MagicMock(return_value="etag123")

        event = EventObject(pguid="calendar123", title="New Event")
        response = service.remove_event(event)
        assert response["status"] == "success"

def _service_with_mocks(mock_session: PyiCloudSession) -> CalendarService:
    with patch("pyicloud.services.calendar.get_localzone_name", return_value="UTC"):
        return CalendarService("https://example.com", mock_session, {"dsid": "12345"})


class _FixedDateTime(datetime):
    """Subclass datetime to control today() for tests."""

    fixed: datetime = datetime(2025, 2, 10)

    @classmethod
    def today(cls) -> "_FixedDateTime":  # type: ignore[override]
        return cls.fromtimestamp(cls.fixed.timestamp())


def test_default_params_feb_non_leap() -> None:
    """default_params should compute Feb (non-leap) as 1..28."""
    mock_session = MagicMock(spec=PyiCloudSession)
    service = _service_with_mocks(mock_session)

    # Freeze 'today' to 2025-02-10 (non-leap year)
    _FixedDateTime.fixed = datetime(2025, 2, 10)
    with (
        patch("pyicloud.services.calendar.datetime", _FixedDateTime),
        patch("pyicloud.services.calendar.get_localzone_name", return_value="UTC"),
    ):
        params = service.default_params
        assert params["startDate"] == "2025-02-01"
        assert params["endDate"] == "2025-02-28"


def test_default_params_feb_leap() -> None:
    """default_params should compute Feb (leap year) as 1..29."""
    mock_session = MagicMock(spec=PyiCloudSession)
    service = _service_with_mocks(mock_session)

    # Freeze 'today' to 2028-02-10 (leap year)
    _FixedDateTime.fixed = datetime(2028, 2, 10)
    with (
        patch("pyicloud.services.calendar.datetime", _FixedDateTime),
        patch("pyicloud.services.calendar.get_localzone_name", return_value="UTC"),
    ):
        params = service.default_params
        assert params["startDate"] == "2028-02-01"
        assert params["endDate"] == "2028-02-29"


def test_refresh_client_anchors_from_dt_month() -> None:
    """When only from_dt is provided, anchor to its month for the end bound."""
    mock_session = MagicMock(spec=PyiCloudSession)
    mock_response = MagicMock(spec=Response)
    mock_response.json.return_value = {"Event": []}
    mock_session.get.return_value = mock_response
    service = _service_with_mocks(mock_session)

    from_dt = datetime(2025, 3, 15)
    with patch("pyicloud.services.calendar.get_localzone_name", return_value="UTC"):
        service.refresh_client(from_dt=from_dt, to_dt=None)

    # Inspect params passed to GET
    _, kwargs = mock_session.get.call_args
    params = kwargs["params"]
    assert params["startDate"] == "2025-03-01"
    assert params["endDate"] == "2025-03-31"


def test_refresh_client_anchors_to_dt_month() -> None:
    """When only to_dt is provided, anchor to its month for the start bound."""
    mock_session = MagicMock(spec=PyiCloudSession)
    mock_response = MagicMock(spec=Response)
    mock_response.json.return_value = {"Event": []}
    mock_session.get.return_value = mock_response
    service = _service_with_mocks(mock_session)

    to_dt = datetime(2025, 4, 20)
    with patch("pyicloud.services.calendar.get_localzone_name", return_value="UTC"):
        service.refresh_client(from_dt=None, to_dt=to_dt)

    # Inspect params passed to GET
    _, kwargs = mock_session.get.call_args
    params = kwargs["params"]
    assert params["startDate"] == "2025-04-01"
    assert params["endDate"] == "2025-04-30"