Merge branch 'master' into test_restructure_issue_168

pull/413/head
Jaca 2022-10-03 18:52:18 +02:00 zatwierdzone przez GitHub
commit 76b51ae8b6
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
19 zmienionych plików z 334 dodań i 380 usunięć

Wyświetl plik

@ -0,0 +1,14 @@
BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
BEGIN:VEVENT
DTSTART:20140401T000000Z
DTEND:20140401T010000Z
DTSTAMP:20140401T000000Z
SUMMARY:Broken Eevnt
CLASS:PUBLIC
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT
X
END:VCALENDAR

Wyświetl plik

@ -1,10 +1,15 @@
import os
import logging
import pytest
import icalendar
import pytz
from datetime import datetime
from dateutil import tz
try:
import zoneinfo
except ModuleNotFoundError:
from backports import zoneinfo
LOGGER = logging.getLogger(__name__)
class DataSource:
'''A collection of parsed ICS elements (e.g calendars, timezones, events)'''
@ -13,18 +18,18 @@ class DataSource:
self._data_source_folder = data_source_folder
def __getattr__(self, attribute):
if not attribute in self.__dict__:
source_file = attribute.replace('-', '_') + '.ics'
source_path = os.path.join(self.__dict__['_data_source_folder'], source_file)
with open(source_path, 'rb') as f:
try:
raw_ics = f.read()
source = self.__dict__['_parser'](raw_ics)
source.raw_ics = raw_ics
self.__dict__[attribute] = source
except ValueError as error:
LOGGER.error(f'Could not load {source_file} due to {error}')
return self.__dict__[attribute]
"""Parse a file and return the result stored in the attribute."""
source_file = attribute.replace('-', '_') + '.ics'
source_path = os.path.join(self._data_source_folder, source_file)
with open(source_path, 'rb') as f:
raw_ics = f.read()
source = self._parser(raw_ics)
source.raw_ics = raw_ics
self.__dict__[attribute] = source
return source
def __getitem__(self, key):
return getattr(self, key)
def __repr__(self):
return repr(self.__dict__)
@ -42,7 +47,15 @@ def timezones():
def events():
return DataSource(EVENTS_FOLDER, icalendar.Event.from_ical)
@pytest.fixture(params=[
pytz.utc,
zoneinfo.ZoneInfo('UTC'),
pytz.timezone('UTC'),
tz.UTC,
tz.gettz('UTC')])
def utc(request):
return request.param
@pytest.fixture
def calendars():
return DataSource(CALENDARS_FOLDER, icalendar.Calendar.from_ical)

Wyświetl plik

@ -0,0 +1,3 @@
BEGIN:VEVENT
SUMMARY;LANGUAGE=ru:te
END:VEVENT

Wyświetl plik

@ -0,0 +1,14 @@
BEGIN:VEVENT
SUMMARY:wichtiger termin 1
DTSTART:20130416T100000Z
DTEND:20130416T110000Z
DTSTAMP:20130416T092616Z
UID:20130416112341.10064jz0k4j7uem8@acmenet.de
CLASS:PUBLIC
CREATED:20130416T092341Z
LAST-MODIFIED:20130416T092341Z
LOCATION:im büro
ORGANIZER;CN="acme, ädmin":mailto:adm-acme@mydomain.de
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT

Wyświetl plik

@ -0,0 +1,10 @@
BEGIN:VEVENT
DTSTART:20140401T000000Z
DTEND:20140401T010000Z
DTSTAMP:20140401T000000Z
SUMMARY:Broken Eevnt
CLASS:PUBLIC
STATUS:CONFIRMED
TRANSP:OPAQUE
X
END:VEVENT

Wyświetl plik

@ -1,30 +1,3 @@
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:Market East
X-WR-TIMEZONE:America/New_York
X-WR-CALDESC:
BEGIN:VTIMEZONE
TZID:America/New_York
X-LIC-LOCATION:America/New_York
BEGIN:DAYLIGHT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=America/New_York:20130907T120000
DTEND;TZID=America/New_York:20130907T170000
@ -45,4 +18,3 @@ SUMMARY:Market East Live!
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

Wyświetl plik

@ -0,0 +1,4 @@
BEGIN:VEVENT
DTSTART:20150325T101010
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU;
END:VEVENT

Wyświetl plik

@ -0,0 +1,6 @@
BEGIN:VEVENT
DTSTART:20150219T133000
DTSTAMP:20150219T133000
UID:1234567
RDATE;VALUE=PERIOD:20150219T133000/PT10H
END:VEVENT

Wyświetl plik

@ -0,0 +1,19 @@
BEGIN:VEVENT
DTSTAMP:20120605T003759Z
DTSTART;TZID=America/New_York:20120712T183000
DTEND;TZID=America/New_York:20120712T213000
STATUS:CONFIRMED
SUMMARY:DevOps DC Meetup
DESCRIPTION:DevOpsDC\nThursday\, July 12 at 6:30 PM\n\nThis will be a joi
nt meetup / hack night with the DC jQuery Users Group. The idea behind
the hack night: Small teams consisting of at least 1 member...\n\nDeta
ils: http://www.meetup.com/DevOpsDC/events/47635522/
CLASS:PUBLIC
CREATED:20120111T120339Z
GEO:38.90;-77.01
LOCATION:Fathom Creative\, Inc. (1333 14th Street Northwest\, Washington
D.C.\, DC 20005)
URL:http://www.meetup.com/DevOpsDC/events/47635522/
LAST-MODIFIED:20120522T174406Z
UID:event_qtkfrcyqkbnb@meetup.com
END:VEVENT

Wyświetl plik

@ -0,0 +1,3 @@
BEGIN:VEVENT
SUMMARY:abcdef
END:VEVENT

Wyświetl plik

@ -0,0 +1,3 @@
BEGIN:VEVENT
SUMMARY:åäö
END:VEVENT

Wyświetl plik

@ -0,0 +1,12 @@
BEGIN:VEVENT
CREATED:20081114T072804Z
UID:D449CA84-00A3-4E55-83E1-34B58268853B
DTEND:20070220T180000
RRULE:FREQ=WEEKLY;INTERVAL=1;UNTIL=20070619T225959
TRANSP:OPAQUE
SUMMARY:Esb mellon phone conf
DTSTART:20070220T170000
DTSTAMP:20070221T095412Z
SEQUENCE:0
END:VEVENT

Wyświetl plik

@ -1,5 +1,7 @@
import unittest
import pytest
import datetime
import icalendar
import os
@ -88,3 +90,22 @@ class TestEncoding(unittest.TestCase):
+ b'\xc3\xa4\xc3\xb6\xc3\xbc\xc3\x9f\xc3\x84\xc3\x96\xc3\x9c\r\n'
+ b'END:VEVENT\r\nEND:VCALENDAR\r\n'
)
@pytest.mark.parametrize('event_name', [
# Non-unicode characters in summary
'issue_64_event_with_non_unicode_summary',
# Unicode characters in summary
'issue_64_event_with_unicode_summary',
# chokes on umlauts in ORGANIZER
'issue_101_icalendar_chokes_on_umlauts_in_organizer'
])
def test_events_unicoded(events, event_name):
'''Issue #64 - Event.to_ical() fails for unicode strings
Issue #101 - icalendar is choking on umlauts in ORGANIZER
https://github.com/collective/icalendar/issues/64
https://github.com/collective/icalendar/issues/101
'''
event = getattr(events, event_name)
assert event.to_ical() == event.raw_ics

Wyświetl plik

@ -1,4 +1,3 @@
from icalendar.parser_tools import to_unicode
import unittest
import datetime
@ -15,120 +14,6 @@ except ModuleNotFoundError:
class TestIssues(unittest.TestCase):
def test_issue_53(self):
"""Issue #53 - Parsing failure on some descriptions?
https://github.com/collective/icalendar/issues/53
"""
directory = os.path.dirname(__file__)
ics = open(os.path.join(directory, 'issue_53_parsing_failure.ics'),
'rb')
cal = icalendar.Calendar.from_ical(ics.read())
ics.close()
event = cal.walk('VEVENT')[0]
desc = event.get('DESCRIPTION')
self.assertTrue(b'July 12 at 6:30 PM' in desc.to_ical())
timezones = cal.walk('VTIMEZONE')
self.assertEqual(len(timezones), 1)
tz = timezones[0]
self.assertEqual(tz['tzid'].to_ical(), b"America/New_York")
def test_issue_55(self):
"""Issue #55 - Parse error on utc-offset with seconds value
https://github.com/collective/icalendar/issues/55
"""
ical_str = """BEGIN:VTIMEZONE
TZID:America/Los Angeles
BEGIN:STANDARD
DTSTART:18831118T120702
RDATE:18831118T120702
TZNAME:PST
TZOFFSETFROM:-075258
TZOFFSETTO:-0800
END:STANDARD
END:VTIMEZONE"""
tz = icalendar.Timezone.from_ical(ical_str)
self.assertEqual(
tz.to_ical(),
b'BEGIN:VTIMEZONE\r\nTZID:America/Los Angeles\r\n'
b'BEGIN:STANDARD\r\n'
b'DTSTART:18831118T120702\r\nRDATE:18831118T120702\r\nTZNAME:PST'
b'\r\nTZOFFSETFROM:-075258\r\nTZOFFSETTO:-0800\r\n'
b'END:STANDARD\r\n'
b'END:VTIMEZONE\r\n')
def test_issue_58(self):
"""Issue #58 - TZID on UTC DATE-TIMEs
https://github.com/collective/icalendar/issues/58
"""
# According to RFC 2445: "The TZID property parameter MUST NOT be
# applied to DATE-TIME or TIME properties whose time values are
# specified in UTC."
event = icalendar.Event()
dt = pytz.utc.localize(datetime.datetime(2012, 7, 16, 0, 0, 0))
event.add('dtstart', dt)
self.assertEqual(
event.to_ical(),
b"BEGIN:VEVENT\r\n"
b"DTSTART;VALUE=DATE-TIME:20120716T000000Z\r\n"
b"END:VEVENT\r\n"
)
def test_issue_64(self):
"""Issue #64 - Event.to_ical() fails for unicode strings
https://github.com/collective/icalendar/issues/64
"""
# Non-unicode characters
event = icalendar.Event()
event.add("dtstart", datetime.datetime(2012, 9, 3, 0, 0, 0))
event.add("summary", "abcdef")
self.assertEqual(
event.to_ical(),
b"BEGIN:VEVENT\r\nSUMMARY:abcdef\r\nDTSTART;VALUE=DATE-TIME:"
b"20120903T000000\r\nEND:VEVENT\r\n"
)
# Unicode characters
event = icalendar.Event()
event.add("dtstart", datetime.datetime(2012, 9, 3, 0, 0, 0))
event.add("summary", "åäö")
self.assertEqual(
event.to_ical(),
b"BEGIN:VEVENT\r\nSUMMARY:\xc3\xa5\xc3\xa4\xc3\xb6\r\n"
b"DTSTART;VALUE=DATE-TIME:20120903T000000\r\nEND:VEVENT\r\n"
)
def test_issue_70(self):
"""Issue #70 - e.decode("RRULE") causes Attribute Error
https://github.com/collective/icalendar/issues/70
"""
ical_str = """BEGIN:VEVENT
CREATED:20081114T072804Z
UID:D449CA84-00A3-4E55-83E1-34B58268853B
DTEND:20070220T180000
RRULE:FREQ=WEEKLY;INTERVAL=1;UNTIL=20070619T225959
TRANSP:OPAQUE
SUMMARY:Esb mellon phone conf
DTSTART:20070220T170000
DTSTAMP:20070221T095412Z
SEQUENCE:0
END:VEVENT"""
cal = icalendar.Calendar.from_ical(ical_str)
recur = cal.decoded("RRULE")
self.assertIsInstance(recur, icalendar.vRecur)
self.assertEqual(
recur.to_ical(),
b'FREQ=WEEKLY;UNTIL=20070619T225959;INTERVAL=1'
)
def test_issue_82(self):
"""Issue #82 - vBinary __repr__ called rather than to_ical from
container types
@ -146,119 +31,6 @@ END:VEVENT"""
b"VALUE=BINARY:dGV4dA==\r\nEND:VEVENT\r\n"
)
def test_issue_100(self):
"""Issue #100 - Transformed doctests into unittests, Test fixes and
cleanup.
https://github.com/collective/icalendar/pull/100
"""
ical_content = "BEGIN:VEVENT\r\nSUMMARY;LANGUAGE=ru:te\r\nEND:VEVENT"
icalendar.Event.from_ical(ical_content).to_ical()
def test_issue_101(self):
"""Issue #101 - icalendar is choking on umlauts in ORGANIZER
https://github.com/collective/icalendar/issues/101
"""
ical_str = r"""BEGIN:VCALENDAR
VERSION:2.0
X-WR-CALNAME:Kalender von acme\, admin
PRODID:-//The Horde Project//Horde_iCalendar Library\, Horde 3.3.5//EN
METHOD:PUBLISH
BEGIN:VEVENT
DTSTART:20130416T100000Z
DTEND:20130416T110000Z
DTSTAMP:20130416T092616Z
UID:20130416112341.10064jz0k4j7uem8@acmenet.de
CREATED:20130416T092341Z
LAST-MODIFIED:20130416T092341Z
SUMMARY:wichtiger termin 1
ORGANIZER;CN="acme, ädmin":mailto:adm-acme@mydomain.de
LOCATION:im büro
CLASS:PUBLIC
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR"""
cal = icalendar.Calendar.from_ical(ical_str)
org_cn = cal.walk('VEVENT')[0]['ORGANIZER'].params['CN']
self.assertEqual(org_cn, 'acme, ädmin')
def test_issue_104__ignore_exceptions(self):
"""
Issue #104 - line parsing error in a VEVENT
(which has ignore_exceptions). Should mark the event broken
but not raise an exception.
https://github.com/collective/icalendar/issues/104
"""
ical_str = """
BEGIN:VEVENT
DTSTART:20140401T000000Z
DTEND:20140401T010000Z
DTSTAMP:20140401T000000Z
SUMMARY:Broken Eevnt
CLASS:PUBLIC
STATUS:CONFIRMED
TRANSP:OPAQUE
X
END:VEVENT"""
event = icalendar.Calendar.from_ical(ical_str)
self.assertTrue(isinstance(event, icalendar.Event))
self.assertTrue(event.is_broken) # REMOVE FOR NEXT MAJOR RELEASE
self.assertEqual(
event.errors,
[(None, "Content line could not be parsed into parts: 'X': Invalid content line")] # noqa
)
def test_issue_104__no_ignore_exceptions(self):
"""
Issue #104 - line parsing error in a VCALENDAR
(which doesn't have ignore_exceptions). Should raise an exception.
"""
ical_str = """BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
BEGIN:VEVENT
DTSTART:20140401T000000Z
DTEND:20140401T010000Z
DTSTAMP:20140401T000000Z
SUMMARY:Broken Eevnt
CLASS:PUBLIC
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT
X
END:VCALENDAR"""
with self.assertRaises(ValueError):
icalendar.Calendar.from_ical(ical_str)
def test_issue_112(self):
"""Issue #112 - No timezone info on EXDATE
https://github.com/collective/icalendar/issues/112
"""
directory = os.path.dirname(__file__)
path = os.path.join(directory,
'issue_112_missing_tzinfo_on_exdate.ics')
with open(path, 'rb') as ics:
cal = icalendar.Calendar.from_ical(ics.read())
event = cal.walk('VEVENT')[0]
event_ical = to_unicode(event.to_ical()) # Py3 str type doesn't
# support buffer API
# General timezone aware dates in ical string
self.assertTrue('DTSTART;TZID=America/New_York:20130907T120000'
in event_ical)
self.assertTrue('DTEND;TZID=America/New_York:20130907T170000'
in event_ical)
# Specific timezone aware exdates in ical string
self.assertTrue('EXDATE;TZID=America/New_York:20131012T120000'
in event_ical)
self.assertTrue('EXDATE;TZID=America/New_York:20131011T120000'
in event_ical)
self.assertEqual(event['exdate'][0].dts[0].dt.tzname(), 'EDT')
def test_issue_116(self):
"""Issue #116/#117 - How to add 'X-APPLE-STRUCTURED-LOCATION'
https://github.com/collective/icalendar/issues/116
@ -289,70 +61,6 @@ END:VCALENDAR"""
icalendar.Event.from_ical(event.to_ical()).to_ical()
)
def test_issue_142(self):
"""Issue #142 - Multivalued parameters
This is needed for VCard 3.0.
https://github.com/collective/icalendar/pull/142
"""
from icalendar.parser import Contentline, Parameters
ctl = Contentline.from_ical("TEL;TYPE=HOME,VOICE:000000000")
self.assertEqual(
ctl.parts(),
('TEL', Parameters({'TYPE': ['HOME', 'VOICE']}), '000000000'),
)
def test_issue_143(self):
"""Issue #143 - Allow dots in property names.
Another vCard related issue.
https://github.com/collective/icalendar/pull/143
"""
from icalendar.parser import Contentline, Parameters
ctl = Contentline.from_ical("ITEMADRNULLTHISISTHEADRESS08158SOMECITY12345.ADR:;;This is the Adress 08; Some City;;12345;Germany") # nopep8
self.assertEqual(
ctl.parts(),
('ITEMADRNULLTHISISTHEADRESS08158SOMECITY12345.ADR',
Parameters(),
';;This is the Adress 08; Some City;;12345;Germany'),
)
ctl2 = Contentline.from_ical("ITEMADRNULLTHISISTHEADRESS08158SOMECITY12345.X-ABLABEL:") # nopep8
self.assertEqual(
ctl2.parts(),
('ITEMADRNULLTHISISTHEADRESS08158SOMECITY12345.X-ABLABEL',
Parameters(),
''),
)
def test_issue_157(self):
"""Issue #157 - Recurring rules and trailing semicolons
https://github.com/collective/icalendar/pull/157
"""
# The trailing semicolon caused a problem
ical_str = """BEGIN:VEVENT
DTSTART:20150325T101010
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU;
END:VEVENT"""
cal = icalendar.Calendar.from_ical(ical_str)
recur = cal.decoded("RRULE")
self.assertIsInstance(recur, icalendar.vRecur)
self.assertEqual(
recur.to_ical(),
b'FREQ=YEARLY;BYDAY=1SU;BYMONTH=11'
)
def test_index_error_issue(self):
"""Found an issue where from_ical() would raise IndexError for
properties without parent components.
https://github.com/collective/icalendar/pull/179
"""
with self.assertRaises(ValueError):
icalendar.Calendar.from_ical('VERSION:2.0')
def test_issue_178(self):
"""Issue #178 - A component with an unknown/invalid name is represented
as one of the known components, the information about the original
@ -395,26 +103,6 @@ END:VEVENT"""
b'BEGIN:VEVENT\r\nDTSTART:20150122\r\nUID:12345\r\n'
b'END:VEVENT\r\nEND:MYCOMPTOO\r\n')
def test_issue_184(self):
"""Issue #184 - Previous changes in code broke already broken
representation of PERIOD values - in a new way"""
ical_str = ['BEGIN:VEVENT',
'DTSTAMP:20150219T133000',
'DTSTART:20150219T133000',
'UID:1234567',
'RDATE;VALUE=PERIOD:20150219T133000/PT10H',
'END:VEVENT']
event = icalendar.Event.from_ical('\r\n'.join(ical_str))
self.assertEqual(event.errors, [])
self.assertEqual(event.to_ical(),
b'BEGIN:VEVENT\r\nDTSTART:20150219T133000\r\n'
b'DTSTAMP:20150219T133000\r\nUID:1234567\r\n'
b'RDATE;VALUE=PERIOD:20150219T133000/PT10H\r\n'
b'END:VEVENT\r\n'
)
def test_issue_237(self):
"""Issue #237 - Fail to parse timezone with non-ascii TZID"""
@ -458,27 +146,3 @@ END:VEVENT"""
expected_tzname = 'Brasília standard'.encode('ascii', 'replace')
self.assertEqual(dtstart.tzinfo.zone, expected_zone)
self.assertEqual(dtstart.tzname(), expected_tzname)
def test_issue_345(self):
"""Issue #345 - Why is tools.UIDGenerator a class (that must be instantiated) instead of a module? """
uid1 = icalendar.tools.UIDGenerator.uid()
uid2 = icalendar.tools.UIDGenerator.uid('test.test')
uid3 = icalendar.tools.UIDGenerator.uid(unique='123')
uid4 = icalendar.tools.UIDGenerator.uid('test.test', '123')
self.assertEqual(uid1.split('@')[1], 'example.com')
self.assertEqual(uid2.split('@')[1], 'test.test')
self.assertEqual(uid3.split('-')[1], '123@example.com')
self.assertEqual(uid4.split('-')[1], '123@test.test')
@pytest.mark.parametrize("zone", [
pytz.utc,
zoneinfo.ZoneInfo('UTC'),
pytz.timezone('UTC'),
tz.UTC,
tz.gettz('UTC')])
def test_issue_335_identify_UTC(zone):
myevent = icalendar.Event()
dt = datetime.datetime(2021, 11, 17, 15, 9, 15)
myevent.add('dtstart', dt.astimezone(zone))
assert 'DTSTART;VALUE=DATE-TIME:20211117T150915Z' in myevent.to_ical().decode('ASCII')

Wyświetl plik

@ -0,0 +1,20 @@
import pytest
from icalendar import Event, Calendar
def test_ignore_exceptions_on_broken_events_issue_104(events):
''' Issue #104 - line parsing error in a VEVENT
(which has ignore_exceptions). Should mark the event broken
but not raise an exception.
https://github.com/collective/icalendar/issues/104
'''
assert events.issue_104_mark_events_broken.is_broken # TODO: REMOVE FOR NEXT MAJOR RELEASE
assert events.issue_104_mark_events_broken.errors == [(None, "Content line could not be parsed into parts: 'X': Invalid content line")]
def test_dont_ignore_exceptions_on_broken_calendars_issue_104(calendars):
'''Issue #104 - line parsing error in a VCALENDAR
(which doesn't have ignore_exceptions). Should raise an exception.
'''
with pytest.raises(ValueError):
calendars.issue_104_broken_calendar

Wyświetl plik

@ -0,0 +1,121 @@
'''Tests checking that parsing works'''
import pytest
from icalendar import Calendar, vRecur, vBinary, Event
from datetime import datetime
from icalendar.parser import Contentline, Parameters
@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
'''
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'),
])
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() == 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;VALUE=DATE-TIME:20120716T000000Z'),
(datetime(2021, 11, 17, 15, 9, 15), b'DTSTART;VALUE=DATE-TIME: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 2445: "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()

Wyświetl plik

@ -1,6 +1,7 @@
import pytest
import unittest
from icalendar.tools import UIDGenerator
from icalendar.tools import UIDGenerator
class TestTools(unittest.TestCase):
@ -26,3 +27,28 @@ class TestTools(unittest.TestCase):
txt = uid.to_ical()
self.assertTrue(len(txt) == length)
self.assertTrue(b'-/path/to/content@Example.ORG' in txt)
@pytest.mark.parametrize('split,expected,args,kw', [
# default argument host_name
("@", "example.com", (), {},),
("@", "example.com", ("example.com",), {}),
("@", "example.com", (), {"host_name":"example.com"}),
# replaced host_name
("@", "test.test", ("test.test",), {}),
("@", "test.test", (), {"host_name":"test.test"}),
# replace unique
("-", "123@example.com", (), {"unique": "123"},),
("-", "abc@example.com", (), {"unique": "abc"},),
# replace host_name and unique
("-", "1234@test.icalendar", (), {"unique": "1234", "host_name":"test.icalendar"},),
("-", "abc@test.example.com", ("test.example.com", "abc"), {},),
])
def test_uid_generator_issue_345(args, kw, split, expected):
'''Issue #345 - Why is tools.UIDGenerator a class (that must be instantiated) instead of a module?
see https://github.com/collective/icalendar/issues/345
'''
uid = UIDGenerator.uid(*args, **kw)
assert uid.split(split)[1] == expected

Wyświetl plik

@ -0,0 +1,19 @@
BEGIN:VTIMEZONE
TZID:America/New_York
TZURL:http://tzurl.org/zoneinfo-outlook/America/New_York
X-LIC-LOCATION:America/New_York
BEGIN:DAYLIGHT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE

Wyświetl plik

@ -0,0 +1,10 @@
BEGIN:VTIMEZONE
TZID:America/Los Angeles
BEGIN:STANDARD
DTSTART:18831118T120702
RDATE:18831118T120702
TZNAME:PST
TZOFFSETFROM:-075258
TZOFFSETTO:-0800
END:STANDARD
END:VTIMEZONE