Check type and range of REFRESH-INTERVAL in setter

See https://github.com/collective/icalendar/pull/877#discussion_r2366353723
pull/877/head
Nicco Kunzmann 2025-09-22 19:41:11 +01:00
rodzic 5cab351bdd
commit de6a1f70bf
2 zmienionych plików z 40 dodań i 2 usunięć

Wyświetl plik

@ -2,6 +2,7 @@
from __future__ import annotations from __future__ import annotations
from datetime import timedelta
from typing import TYPE_CHECKING, Sequence from typing import TYPE_CHECKING, Sequence
from icalendar.attr import ( from icalendar.attr import (
@ -21,7 +22,7 @@ from icalendar.version import __version__
if TYPE_CHECKING: if TYPE_CHECKING:
import uuid import uuid
from datetime import date, datetime, timedelta from datetime import date, datetime
from icalendar.cal.availability import Availability from icalendar.cal.availability import Availability
from icalendar.cal.event import Event from icalendar.cal.event import Event
@ -480,6 +481,9 @@ Description:
the calendar data. The value of this property SHOULD be used by the calendar data. The value of this property SHOULD be used by
calendar user agents to limit the polling interval for calendar calendar user agents to limit the polling interval for calendar
data updates to the minimum interval specified. data updates to the minimum interval specified.
Raises:
ValueError: When setting a negative duration.
""" """
refresh_interval = self.get("REFRESH-INTERVAL") refresh_interval = self.get("REFRESH-INTERVAL")
return refresh_interval.dt if refresh_interval else None return refresh_interval.dt if refresh_interval else None
@ -487,6 +491,12 @@ Description:
@refresh_interval.setter @refresh_interval.setter
def refresh_interval(self, value: timedelta | None): def refresh_interval(self, value: timedelta | None):
"""Set the REFRESH-INTERVAL.""" """Set the REFRESH-INTERVAL."""
if not isinstance(value, timedelta) and value is not None:
raise TypeError(
"REFRESH-INTERVAL must be a positive timedelta or None (to delete it)."
)
if value is not None and value.total_seconds() < 0:
raise ValueError("REFRESH-INTERVAL must be a positive timedelta.")
del self.refresh_interval del self.refresh_interval
if value is not None: if value is not None:
self.add("REFRESH-INTERVAL", value) self.add("REFRESH-INTERVAL", value)

Wyświetl plik

@ -6,7 +6,7 @@ They are also considered.
from __future__ import annotations from __future__ import annotations
from datetime import datetime, timedelta, timezone from datetime import date, datetime, time, timedelta, timezone
from typing import Union from typing import Union
import pytest import pytest
@ -219,6 +219,34 @@ def test_refresh_interval_default(calendar: Calendar):
assert calendar.refresh_interval is None assert calendar.refresh_interval is None
@pytest.mark.parametrize(
"invalid_value",
[
datetime(2020, 1, 1),
date(2020, 1, 1),
"invalid",
(date(2020, 1, 1), timedelta(days=1)),
time(12, 0),
],
)
def test_invalid_refresh_interval_type(calendar: Calendar, invalid_value):
"""Invalid REFRESH-INTERVAL"""
with pytest.raises(TypeError):
calendar.refresh_interval = invalid_value
def test_invalid_refresh_interval(calendar: Calendar):
with pytest.raises(ValueError):
calendar.refresh_interval = timedelta(seconds=-1)
def test_0_refresh_interval(calendar: Calendar):
"""REFRESH-INTERVAL zero."""
calendar.refresh_interval = timedelta(0)
assert calendar.refresh_interval == timedelta(0)
assert calendar["REFRESH-INTERVAL"].dt == timedelta(0)
def test_refresh_interval_set_to_value(calendar: Calendar): def test_refresh_interval_set_to_value(calendar: Calendar):
"""REFRESH-INTERVAL setting.""" """REFRESH-INTERVAL setting."""
calendar.refresh_interval = timedelta(hours=1) calendar.refresh_interval = timedelta(hours=1)