Files
syn-chat-bot/.venv/lib/python3.9/site-packages/icalendar/tests/test_parsing.py
Hyungi Ahn c2257d3a86 fix: 포트 충돌 회피 — note_bridge 8098, intent_service 8099
Jellyfin(8096), OrbStack(8097) 포트 충돌으로 변경.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:53:55 +09:00

258 lines
8.9 KiB
Python

"""Tests checking that parsing works"""
import base64
from datetime import datetime
import pytest
from icalendar import Calendar, Event, vBinary, vRecur
from icalendar.parser import Contentline, Parameters, unescape_char
@pytest.mark.parametrize(
"calendar_name",
[
# Issue #178 - A component with an unknown/invalid name is represented
# as one of the known components, the information about the original
# component name is lost.
# https://github.com/collective/icalendar/issues/178 https://github.com/collective/icalendar/pull/180
# Parsing of a nonstandard component
"issue_178_component_with_invalid_name_represented",
# Nonstandard component inside other components, also has properties
"issue_178_custom_component_inside_other",
# Nonstandard component is able to contain other components
"issue_178_custom_component_contains_other",
],
)
def test_calendar_to_ical_is_inverse_of_from_ical(calendars, calendar_name):
calendar = getattr(calendars, calendar_name)
assert calendar.to_ical().splitlines() == calendar.raw_ics.splitlines()
assert calendar.to_ical() == calendar.raw_ics
@pytest.mark.parametrize(
("raw_content_line", "expected_output"),
[
# Issue #142 - Multivalued parameters. This is needed for VCard 3.0.
# see https://github.com/collective/icalendar/pull/142
(
"TEL;TYPE=HOME,VOICE:000000000",
("TEL", Parameters({"TYPE": ["HOME", "VOICE"]}), "000000000"),
),
# Issue #143 - Allow dots in property names. Another vCard related issue.
# see https://github.com/collective/icalendar/pull/143
(
"ITEMADRNULLTHISISTHEADRESS08158SOMECITY12345.ADR:;;This is the Adress 08; Some City;;12345;Germany",
(
"ITEMADRNULLTHISISTHEADRESS08158SOMECITY12345.ADR",
Parameters(),
";;This is the Adress 08; Some City;;12345;Germany",
),
),
(
"ITEMADRNULLTHISISTHEADRESS08158SOMECITY12345.X-ABLABEL:",
(
"ITEMADRNULLTHISISTHEADRESS08158SOMECITY12345.X-ABLABEL",
Parameters(),
"",
),
),
],
)
def test_content_lines_parsed_properly(raw_content_line, expected_output):
assert Contentline.from_ical(raw_content_line).parts() == expected_output
@pytest.mark.parametrize(
"timezone_info",
[
# General timezone aware dates in ical string
(b"DTSTART;TZID=America/New_York:20130907T120000"),
(b"DTEND;TZID=America/New_York:20130907T170000"),
# Specific timezone aware exdates in ical string
(b"EXDATE;TZID=America/New_York:20131012T120000"),
(b"EXDATE;TZID=America/New_York:20131011T120000"),
],
)
def test_timezone_info_present_in_ical_issue_112(events, timezone_info):
"""Issue #112 - No timezone info on EXDATE
https://github.com/collective/icalendar/issues/112
"""
assert timezone_info in events.issue_112_missing_tzinfo_on_exdate.to_ical()
def test_timezone_name_parsed_issue_112(events):
"""Issue #112 - No timezone info on EXDATE
https://github.com/collective/icalendar/issues/112
"""
assert (
events.issue_112_missing_tzinfo_on_exdate["exdate"][0].dts[0].dt.tzname()
== "EDT"
)
def test_issue_157_removes_trailing_semicolon(events):
"""Issue #157 - Recurring rules and trailing semicolons
https://github.com/collective/icalendar/pull/157
"""
recur = events.issue_157_removes_trailing_semicolon.decoded("RRULE")
assert isinstance(recur, vRecur)
assert recur.to_ical() == b"FREQ=YEARLY;BYDAY=1SU;BYMONTH=11"
@pytest.mark.parametrize(
"event_name",
[
# https://github.com/collective/icalendar/pull/100
("issue_100_transformed_doctests_into_unittests"),
("issue_184_broken_representation_of_period"),
# PERIOD should be put back into shape
"issue_156_RDATE_with_PERIOD",
"issue_156_RDATE_with_PERIOD_list",
"event_with_unicode_organizer",
],
)
def test_event_to_ical_is_inverse_of_from_ical(events, event_name):
"""Make sure that an event's ICS is equal to the ICS it was made from."""
event = events[event_name]
assert event.to_ical().splitlines() == event.raw_ics.splitlines()
assert event.to_ical() == event.raw_ics
def test_decode_rrule_attribute_error_issue_70(events):
# Issue #70 - e.decode("RRULE") causes Attribute Error
# see https://github.com/collective/icalendar/issues/70
recur = events.issue_70_rrule_causes_attribute_error.decoded("RRULE")
assert isinstance(recur, vRecur)
assert recur.to_ical() == b"FREQ=WEEKLY;UNTIL=20070619T225959;INTERVAL=1"
def test_description_parsed_properly_issue_53(events):
"""Issue #53 - Parsing failure on some descriptions?
https://github.com/collective/icalendar/issues/53
"""
assert (
b"July 12 at 6:30 PM"
in events.issue_53_description_parsed_properly["DESCRIPTION"].to_ical()
)
def test_raises_value_error_for_properties_without_parent_pull_179():
"""Found an issue where from_ical() would raise IndexError for
properties without parent components.
https://github.com/collective/icalendar/pull/179
"""
with pytest.raises(ValueError):
Calendar.from_ical("VERSION:2.0")
def test_tzid_parsed_properly_issue_53(timezones):
"""Issue #53 - Parsing failure on some descriptions?
https://github.com/collective/icalendar/issues/53
"""
assert (
timezones.issue_53_tzid_parsed_properly["tzid"].to_ical() == b"America/New_York"
)
def test_timezones_to_ical_is_inverse_of_from_ical(timezones):
"""Issue #55 - Parse error on utc-offset with seconds value
see https://github.com/collective/icalendar/issues/55"""
timezone = timezones["issue_55_parse_error_on_utc_offset_with_seconds"]
assert timezone.to_ical() == timezone.raw_ics
@pytest.mark.parametrize(
("date", "expected_output"),
[
(datetime(2012, 7, 16, 0, 0, 0), b"DTSTART:20120716T000000Z"),
(datetime(2021, 11, 17, 15, 9, 15), b"DTSTART:20211117T150915Z"),
],
)
def test_no_tzid_when_utc(utc, date, expected_output):
"""Issue #58 - TZID on UTC DATE-TIMEs
Issue #335 - UTC timezone identification is broken
https://github.com/collective/icalendar/issues/58
https://github.com/collective/icalendar/issues/335
"""
# According to RFC 5545: "The TZID property parameter MUST NOT be
# applied to DATE-TIME or TIME properties whose time values are
# specified in UTC.
date = date.replace(tzinfo=utc)
event = Event()
event.add("dtstart", date)
assert expected_output in event.to_ical()
def test_vBinary_base64_encoded_issue_82():
"""Issue #82 - vBinary __repr__ called rather than to_ical from
container types
https://github.com/collective/icalendar/issues/82
"""
b = vBinary("text")
b.params["FMTTYPE"] = "text/plain"
assert b.to_ical() == base64.b64encode(b"text")
def test_creates_event_with_base64_encoded_attachment_issue_82(events):
"""Issue #82 - vBinary __repr__ called rather than to_ical from
container types
https://github.com/collective/icalendar/issues/82
"""
b = vBinary("text")
b.params["FMTTYPE"] = "text/plain"
event = Event()
event.add("ATTACH", b)
assert event.to_ical() == events.issue_82_expected_output.raw_ics
@pytest.mark.parametrize(
"calendar_name",
[
# Issue #466 - [BUG] TZID timezone is ignored when forward-slash is used
# https://github.com/collective/icalendar/issues/466
"issue_466_respect_unique_timezone",
"issue_466_convert_tzid_with_slash",
],
)
def test_handles_unique_tzid(calendars, in_timezone, calendar_name):
calendar = calendars[calendar_name]
event = calendar.walk("VEVENT")[0]
print(vars(event))
start_dt = event["dtstart"].dt
end_dt = event["dtend"].dt
assert start_dt == in_timezone(datetime(2022, 10, 21, 20, 0, 0), "Europe/Stockholm")
assert end_dt == in_timezone(datetime(2022, 10, 21, 21, 0, 0), "Europe/Stockholm")
@pytest.mark.parametrize(
("event_name", "expected_cn", "expected_ics"),
[
(
"event_with_escaped_characters",
r"that, that; %th%%at%\ that:",
"это, то; that\\ %th%%at%:",
),
("event_with_escaped_character1", r"Society, 2014", "that"),
("event_with_escaped_character2", r"Society\ 2014", "that"),
("event_with_escaped_character3", r"Society; 2014", "that"),
("event_with_escaped_character4", r"Society: 2014", "that"),
],
)
def test_escaped_characters_read(event_name, expected_cn, expected_ics, events):
event = events[event_name]
assert event["ORGANIZER"].params["CN"] == expected_cn
assert event["ORGANIZER"].to_ical() == expected_ics.encode("utf-8")
def test_unescape_char():
assert unescape_char(b"123") == b"123"
assert unescape_char(b"\\n") == b"\n"