pykolab/itip pykolab/xml tests/unit
Thomas Brüderli
bruederli at kolabsys.com
Thu Jul 24 13:16:09 CEST 2014
pykolab/itip/__init__.py | 2
pykolab/xml/__init__.py | 2
pykolab/xml/attendee.py | 50 +++++++
pykolab/xml/contact.py | 4
pykolab/xml/contact_reference.py | 21 +++
pykolab/xml/event.py | 72 +++++++++++
pykolab/xml/recurrence_rule.py | 117 ++++++++++++++++++
tests/unit/test-002-attendee.py | 20 +++
tests/unit/test-003-event.py | 244 ++++++++++++++++++++++++++-------------
9 files changed, 446 insertions(+), 86 deletions(-)
New commits:
commit 524849338fcb0cb40bcdb18f4dbe7e9660074f20
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Jul 23 08:23:49 2014 -0400
Add methods to dump Kolab XML objects as dict()
diff --git a/pykolab/itip/__init__.py b/pykolab/itip/__init__.py
index 17da24e..816ee1d 100644
--- a/pykolab/itip/__init__.py
+++ b/pykolab/itip/__init__.py
@@ -144,6 +144,8 @@ def check_event_conflict(kolab_event, itip_event):
if kolab_event.uid == itip_event['uid']:
return conflict
+ # TODO: don't consider conflict if event has TRANSP:TRANSPARENT
+
_es = to_dt(kolab_event.get_start())
_ee = to_dt(kolab_event.get_ical_dtend()) # use iCal style end date: next day for all-day events
diff --git a/pykolab/xml/__init__.py b/pykolab/xml/__init__.py
index 2bb42d4..3e12716 100644
--- a/pykolab/xml/__init__.py
+++ b/pykolab/xml/__init__.py
@@ -4,6 +4,7 @@ from attendee import participant_status_label
from contact import Contact
from contact_reference import ContactReference
+from recurrence_rule import RecurrenceRule
from event import Event
from event import EventIntegrityError
@@ -19,6 +20,7 @@ __all__ = [
"Contact",
"ContactReference",
"Event",
+ "RecurrenceRule",
"event_from_ical",
"event_from_string",
"to_dt",
diff --git a/pykolab/xml/attendee.py b/pykolab/xml/attendee.py
index 5d469c2..7921280 100644
--- a/pykolab/xml/attendee.py
+++ b/pykolab/xml/attendee.py
@@ -56,6 +56,13 @@ class Attendee(kolabformat.Attendee):
"FALSE": False,
}
+ properties_map = {
+ 'role': 'get_role',
+ 'rsvp': 'rsvp',
+ 'partstat': 'get_participant_status',
+ 'cutype': 'get_cutype',
+ }
+
def __init__(
self,
email,
@@ -97,6 +104,12 @@ class Attendee(kolabformat.Attendee):
if not participant_status == None:
self.set_participant_status(participant_status)
+ def copy_from(self, obj):
+ if isinstance(obj, kolabformat.Attendee):
+ kolabformat.Attendee.__init__(self, obj)
+ self.contactreference = ContactReference(obj.contact())
+ self.email = self.contactreference.get_email()
+
def delegate_from(self, delegators):
crefs = []
@@ -138,8 +151,11 @@ class Attendee(kolabformat.Attendee):
self.setDelegatedTo(list(set(crefs)))
- def get_cutype(self):
- return self.cutype()
+ def get_cutype(self, translated=False):
+ cutype = self.cutype()
+ if translated:
+ return self._translate_value(cutype, self.cutype_map)
+ return cutype
def get_delegated_from(self):
return self.delegatedFrom()
@@ -161,16 +177,22 @@ class Attendee(kolabformat.Attendee):
def get_participant_status(self, translated=False):
partstat = self.partStat()
if translated:
- partstat_name_map = dict([(v, k) for (k, v) in self.participant_status_map.iteritems()])
- return partstat_name_map[partstat] if partstat_name_map.has_key(partstat) else 'UNKNOWN'
+ return self._translate_value(partstat, self.participant_status_map)
return partstat
- def get_role(self):
- return self.role()
+ def get_role(self, translated=False):
+ role = self.role()
+ if translated:
+ return self._translate_value(role, self.role_map)
+ return role
def get_rsvp(self):
return self.rsvp()
+ def _translate_value(self, val, map):
+ name_map = dict([(v, k) for (k, v) in map.iteritems()])
+ return name_map[val] if name_map.has_key(val) else 'UNKNOWN'
+
def set_cutype(self, cutype):
if cutype in self.cutype_map.keys():
self.setCutype(self.cutype_map[cutype])
@@ -202,6 +224,22 @@ class Attendee(kolabformat.Attendee):
def set_rsvp(self, rsvp):
self.setRSVP(rsvp)
+ def to_dict(self):
+ data = self.contactreference.to_dict()
+ data.pop('type', None)
+
+ for p, getter in self.properties_map.iteritems():
+ val = None
+ args = {}
+ if hasattr(self, getter):
+ if getter.startswith('get_'):
+ args = dict(translated=True)
+ val = getattr(self, getter)(**args)
+ if val is not None:
+ data[p] = val
+
+ return data
+
def __str__(self):
return self.email
diff --git a/pykolab/xml/contact.py b/pykolab/xml/contact.py
index 1577b58..9a2c103 100644
--- a/pykolab/xml/contact.py
+++ b/pykolab/xml/contact.py
@@ -39,5 +39,9 @@ class Contact(kolabformat.Contact):
def set_name(self, name):
self.setName(name)
+ def to_ditc(self):
+ # TODO: implement this
+ return dict(name=self.name())
+
def __str__(self):
return kolabformat.writeContact(self)
diff --git a/pykolab/xml/contact_reference.py b/pykolab/xml/contact_reference.py
index 0d6dec5..5a832da 100644
--- a/pykolab/xml/contact_reference.py
+++ b/pykolab/xml/contact_reference.py
@@ -11,9 +11,18 @@ import kolabformat
"""
class ContactReference(kolabformat.ContactReference):
+ properties_map = {
+ 'email': 'email',
+ 'name': 'name',
+ 'type': 'type',
+ 'uid': 'uid',
+ }
+
def __init__(self, email=None):
if email == None:
kolabformat.ContactReference.__init__(self)
+ elif isinstance(email, kolabformat.ContactReference):
+ kolabformat.ContactReference.__init__(self, email.email(), email.name(), email.uid())
else:
kolabformat.ContactReference.__init__(self, email)
@@ -31,3 +40,15 @@ class ContactReference(kolabformat.ContactReference):
def set_name(self, name):
self.setName(name)
+
+ def to_dict(self):
+ data = dict()
+
+ for p, getter in self.properties_map.iteritems():
+ val = None
+ if hasattr(self, getter):
+ val = getattr(self, getter)()
+ if val is not None:
+ data[p] = val
+
+ return data
diff --git a/pykolab/xml/event.py b/pykolab/xml/event.py
index 4ac4997..8e41a92 100644
--- a/pykolab/xml/event.py
+++ b/pykolab/xml/event.py
@@ -18,6 +18,7 @@ from pykolab.translate import _
from os import path
from attendee import Attendee
from contact_reference import ContactReference
+from recurrence_rule import RecurrenceRule
log = pykolab.getLogger('pykolab.xml_event')
@@ -55,6 +56,37 @@ class Event(object):
"CONFIDENTIAL": kolabformat.ClassConfidential,
}
+ properties_map = {
+ # property: getter
+ "uid": "get_uid",
+ "created": "get_created",
+ "lastmodified-date": "get_lastmodified",
+ "sequence": "sequence",
+ "classification": "get_classification",
+ "categories": "categories",
+ "start": "get_start",
+ "end": "get_end",
+ "duration": "get_duration",
+ "transparency": "transparency",
+ "rrule": "recurrenceRule",
+ "rdate": "recurrenceDates",
+ "exdate": "exceptionDates",
+ "recurrence-id": "recurrenceID",
+ "summary": "summary",
+ "description": "description",
+ "priority": "priority",
+ "status": "get_status",
+ "location": "location",
+ "organizer": "organizer",
+ "attendee": "get_attendees",
+ "attach": "attachments",
+ "url": "url",
+ "alarm": "alarms",
+ "x-custom": "customProperties",
+ # TODO: add to_dict() support for these
+ # "exception": "exceptions",
+ }
+
def __init__(self, from_ical="", from_string=""):
self._attendees = []
self._categories = []
@@ -271,7 +303,7 @@ class Event(object):
def get_created(self):
try:
- return xmlutils.from_cdatetime(self.event.created(), False)
+ return xmlutils.from_cdatetime(self.event.created(), True)
except ValueError:
return datetime.datetime.now()
@@ -479,7 +511,7 @@ class Event(object):
except:
self.__str__()
- return xmlutils.from_cdatetime(self.event.lastModified(), False)
+ return xmlutils.from_cdatetime(self.event.lastModified(), True)
def get_organizer(self):
organizer = self.event.organizer()
@@ -780,6 +812,42 @@ class Event(object):
else:
raise EventIntegrityError, kolabformat.errorMessage()
+ def to_dict(self):
+ data = dict()
+
+ for p, getter in self.properties_map.iteritems():
+ val = None
+ if hasattr(self, getter):
+ val = getattr(self, getter)()
+ elif hasattr(self.event, getter):
+ val = getattr(self.event, getter)()
+
+ if isinstance(val, kolabformat.cDateTime):
+ val = xmlutils.from_cdatetime(val, True)
+ elif isinstance(val, kolabformat.vectordatetime):
+ val = [xmlutils.from_cdatetime(x, True) for x in val]
+ elif isinstance(val, kolabformat.vectors):
+ val = [str(x) for x in val]
+ elif isinstance(val, kolabformat.vectorcs):
+ for x in val:
+ data[x.identifier] = x.value
+ val = None
+ elif isinstance(val, kolabformat.ContactReference):
+ val = ContactReference(val).to_dict()
+ elif isinstance(val, kolabformat.RecurrenceRule):
+ val = RecurrenceRule(val).to_dict()
+ elif isinstance(val, kolabformat.vectorattachment):
+ val = [dict(fmttype=x.mimetype(), label=x.label(), uri=x.uri()) for x in val]
+ elif isinstance(val, kolabformat.vectoralarm):
+ val = [dict(type=x.type()) for x in val]
+ elif isinstance(val, list):
+ val = [x.to_dict() for x in val if hasattr(x, 'to_dict')]
+
+ if val is not None:
+ data[p] = val
+
+ return data
+
def to_message(self):
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
diff --git a/pykolab/xml/recurrence_rule.py b/pykolab/xml/recurrence_rule.py
new file mode 100644
index 0000000..eb17fd5
--- /dev/null
+++ b/pykolab/xml/recurrence_rule.py
@@ -0,0 +1,117 @@
+import kolabformat
+from pykolab.xml import utils as xmlutils
+
+"""
+ def setFrequency(self, *args): return _kolabformat.RecurrenceRule_setFrequency(self, *args)
+ def frequency(self): return _kolabformat.RecurrenceRule_frequency(self)
+ def setWeekStart(self, *args): return _kolabformat.RecurrenceRule_setWeekStart(self, *args)
+ def weekStart(self): return _kolabformat.RecurrenceRule_weekStart(self)
+ def setEnd(self, *args): return _kolabformat.RecurrenceRule_setEnd(self, *args)
+ def end(self): return _kolabformat.RecurrenceRule_end(self)
+ def setCount(self, *args): return _kolabformat.RecurrenceRule_setCount(self, *args)
+ def count(self): return _kolabformat.RecurrenceRule_count(self)
+ def setInterval(self, *args): return _kolabformat.RecurrenceRule_setInterval(self, *args)
+ def interval(self): return _kolabformat.RecurrenceRule_interval(self)
+ def setBysecond(self, *args): return _kolabformat.RecurrenceRule_setBysecond(self, *args)
+ def bysecond(self): return _kolabformat.RecurrenceRule_bysecond(self)
+ def setByminute(self, *args): return _kolabformat.RecurrenceRule_setByminute(self, *args)
+ def byminute(self): return _kolabformat.RecurrenceRule_byminute(self)
+ def setByhour(self, *args): return _kolabformat.RecurrenceRule_setByhour(self, *args)
+ def byhour(self): return _kolabformat.RecurrenceRule_byhour(self)
+ def setByday(self, *args): return _kolabformat.RecurrenceRule_setByday(self, *args)
+ def byday(self): return _kolabformat.RecurrenceRule_byday(self)
+ def setBymonthday(self, *args): return _kolabformat.RecurrenceRule_setBymonthday(self, *args)
+ def bymonthday(self): return _kolabformat.RecurrenceRule_bymonthday(self)
+ def setByyearday(self, *args): return _kolabformat.RecurrenceRule_setByyearday(self, *args)
+ def byyearday(self): return _kolabformat.RecurrenceRule_byyearday(self)
+ def setByweekno(self, *args): return _kolabformat.RecurrenceRule_setByweekno(self, *args)
+ def byweekno(self): return _kolabformat.RecurrenceRule_byweekno(self)
+ def setBymonth(self, *args): return _kolabformat.RecurrenceRule_setBymonth(self, *args)
+ def bymonth(self): return _kolabformat.RecurrenceRule_bymonth(self)
+ def isValid(self): return _kolabformat.RecurrenceRule_isValid(self)
+"""
+
+class RecurrenceRule(kolabformat.RecurrenceRule):
+ frequency_map = {
+ None: kolabformat.RecurrenceRule.FreqNone,
+ "YEARLY": kolabformat.RecurrenceRule.Yearly,
+ "MONTHLY": kolabformat.RecurrenceRule.Monthly,
+ "WEEKLY": kolabformat.RecurrenceRule.Weekly,
+ "DAILY": kolabformat.RecurrenceRule.Daily,
+ "HOURLY": kolabformat.RecurrenceRule.Hourly,
+ "MINUTELY": kolabformat.RecurrenceRule.Minutely,
+ "SECONDLY": kolabformat.RecurrenceRule.Secondly
+ }
+
+ weekday_map = {
+ "MO": kolabformat.Monday,
+ "TU": kolabformat.Tuesday,
+ "WE": kolabformat.Wednesday,
+ "TH": kolabformat.Thursday,
+ "FR": kolabformat.Friday,
+ "SA": kolabformat.Saturday,
+ "SU": kolabformat.Sunday
+ }
+
+ properties_map = {
+ 'frequency': 'get_frequency',
+ 'interval': 'interval',
+ 'count': 'count',
+ 'until': 'end',
+ 'bymonth': 'bymonth',
+ 'byday': 'byday',
+ 'byyearday': 'byyearday',
+ 'byweekno': 'byweekno',
+ 'byhour': 'byhour',
+ 'byminute': 'byminute',
+ 'wkst': 'get_weekstart'
+ }
+
+ def __init__(self, rrule=None):
+ if rrule == None:
+ kolabformat.RecurrenceRule.__init__(self)
+ else:
+ kolabformat.RecurrenceRule.__init__(self, rrule)
+
+ def get_frequency(self, translated=False):
+ freq = self.frequency()
+ if translated:
+ return self._translate_value(freq, self.frequency_map)
+ return freq
+
+ def get_weekstart(self, translated=False):
+ wkst = self.weekStart()
+ if translated:
+ return self._translate_value(wkst, self.weekday_map)
+ return wkst
+
+ def _translate_value(self, val, map):
+ name_map = dict([(v, k) for (k, v) in map.iteritems()])
+ return name_map[val] if name_map.has_key(val) else 'UNKNOWN'
+
+ def to_dict(self):
+ if not self.isValid() or self.frequency() == kolabformat.RecurrenceRule.FreqNone:
+ return None
+
+ data = dict()
+
+ for p, getter in self.properties_map.iteritems():
+ val = None
+ args = {}
+ if hasattr(self, getter):
+ if getter.startswith('get_'):
+ args = dict(translated=True)
+ if hasattr(self, getter):
+ val = getattr(self, getter)(**args)
+ if isinstance(val, kolabformat.cDateTime):
+ val = xmlutils.from_cdatetime(val, True)
+ elif isinstance(val, kolabformat.vectori):
+ val = [int(v) for x in val]
+ elif isinstance(val, kolabformat.vectordaypos):
+ val = ["%d%s" % (x.occurence, self._translate_value(x.weekday)) for x in val]
+ if val is not None:
+ data[p] = val
+
+ return data
+
+
diff --git a/tests/unit/test-002-attendee.py b/tests/unit/test-002-attendee.py
index 8bcee3c..d7584e3 100644
--- a/tests/unit/test-002-attendee.py
+++ b/tests/unit/test-002-attendee.py
@@ -108,5 +108,25 @@ class TestEventXML(unittest.TestCase):
self.assertEqual(participant_status_label(kolabformat.PartTentative), "Tentatively Accepted")
self.assertEqual(participant_status_label('UNKNOWN'), "UNKNOWN")
+ def test_020_to_dict(self):
+ name = "Doe, Jane"
+ role = 'OPT-PARTICIPANT'
+ cutype = 'RESOURCE'
+ partstat = 'ACCEPTED'
+ self.attendee.set_name(name)
+ self.attendee.set_rsvp(True)
+ self.attendee.set_role(role)
+ self.attendee.set_cutype(cutype)
+ self.attendee.set_participant_status(partstat)
+
+ data = self.attendee.to_dict()
+ self.assertIsInstance(data, dict)
+ self.assertEqual(data['role'], role)
+ self.assertEqual(data['cutype'], cutype)
+ self.assertEqual(data['partstat'], partstat)
+ self.assertEqual(data['name'], name)
+ self.assertEqual(data['email'], 'jane at doe.org')
+ self.assertTrue(data['rsvp'])
+
if __name__ == '__main__':
unittest.main()
diff --git a/tests/unit/test-003-event.py b/tests/unit/test-003-event.py
index 2c5a478..5017091 100644
--- a/tests/unit/test-003-event.py
+++ b/tests/unit/test-003-event.py
@@ -65,6 +65,136 @@ END:VALARM
END:VEVENT
"""
+xml_event = """
+<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
+ <vcalendar>
+ <properties>
+ <prodid>
+ <text>Libkolabxml-1.1</text>
+ </prodid>
+ <version>
+ <text>2.0</text>
+ </version>
+ <x-kolab-version>
+ <text>3.1.0</text>
+ </x-kolab-version>
+ </properties>
+ <components>
+ <vevent>
+ <properties>
+ <uid>
+ <text>75c740bb-b3c6-442c-8021-ecbaeb0a025e</text>
+ </uid>
+ <created>
+ <date-time>2014-07-07T01:28:23Z</date-time>
+ </created>
+ <dtstamp>
+ <date-time>2014-07-07T01:28:23Z</date-time>
+ </dtstamp>
+ <sequence>
+ <integer>1</integer>
+ </sequence>
+ <class>
+ <text>PUBLIC</text>
+ </class>
+ <dtstart>
+ <parameters>
+ <tzid>
+ <text>/kolab.org/Europe/London</text>
+ </tzid>
+ </parameters>
+ <date-time>2014-08-13T10:00:00</date-time>
+ </dtstart>
+ <dtend>
+ <parameters>
+ <tzid><text>/kolab.org/Europe/London</text></tzid>
+ </parameters>
+ <date-time>2014-08-13T14:00:00</date-time>
+ </dtend>
+ <rrule>
+ <recur>
+ <freq>DAILY</freq>
+ <until>
+ <date>2014-07-25</date>
+ </until>
+ </recur>
+ </rrule>
+ <exdate>
+ <parameters>
+ <tzid>
+ <text>/kolab.org/Europe/Berlin</text>
+ </tzid>
+ </parameters>
+ <date>2014-07-19</date>
+ <date>2014-07-26</date>
+ <date>2014-07-12</date>
+ <date>2014-07-13</date>
+ <date>2014-07-20</date>
+ <date>2014-07-27</date>
+ <date>2014-07-05</date>
+ <date>2014-07-06</date>
+ </exdate>
+ <summary>
+ <text>test</text>
+ </summary>
+ <description>
+ <text>test</text>
+ </description>
+ <priority>
+ <integer>5</integer>
+ </priority>
+ <status>
+ <text>CANCELLED</text>
+ </status>
+ <location>
+ <text>Room 101</text>
+ </location>
+ <organizer>
+ <parameters>
+ <cn><text>Doe, John</text></cn>
+ </parameters>
+ <cal-address>mailto:%3Cjohn%40example.org%3E</cal-address>
+ </organizer>
+ <attendee>
+ <parameters>
+ <partstat><text>ACCEPTED</text></partstat>
+ <role><text>REQ-PARTICIPANT</text></role>
+ <rsvp><boolean>true</boolean></rsvp>
+ </parameters>
+ <cal-address>mailto:%3Cjane%40example.org%3E</cal-address>
+ </attendee>
+ <attendee>
+ <parameters>
+ <partstat><text>TENTATIVE</text></partstat>
+ <role><text>OPT-PARTICIPANT</text></role>
+ </parameters>
+ <cal-address>mailto:%3Csomebody%40else.com%3E</cal-address>
+ </attendee>
+ <attach>
+ <parameters>
+ <fmttype>
+ <text>text/html</text>
+ </fmttype>
+ <x-label>
+ <text>noname.1395223627.5555</text>
+ </x-label>
+ </parameters>
+ <uri>cid:noname.1395223627.5555</uri>
+ </attach>
+ <x-custom>
+ <identifier>X-MOZ-RECEIVED-DTSTAMP</identifier>
+ <value>20140224T155612Z</value>
+ </x-custom>
+ <x-custom>
+ <identifier>X-GWSHOW-AS</identifier>
+ <value>BUSY</value>
+ </x-custom>
+ </properties>
+ </vevent>
+ </components>
+ </vcalendar>
+</icalendar>
+"""
class TestEventXML(unittest.TestCase):
event = Event()
@@ -181,7 +311,7 @@ METHOD:REQUEST
event = event_from_ical(ical.walk('VEVENT')[0].to_ical())
self.assertEqual(event.get_location(), "Location")
- self.assertEqual(str(event.get_lastmodified()), "2014-04-07 12:23:11")
+ self.assertEqual(str(event.get_lastmodified()), "2014-04-07 12:23:11+00:00")
self.assertEqual(event.get_description(), "Description\n2 lines")
self.assertEqual(event.get_url(), "http://somelink.com/foo")
self.assertEqual(event.get_transparency(), False)
@@ -310,83 +440,7 @@ END:VEVENT
self.assertEqual(self.event.get_last_occurrence(), None)
def test_022_load_from_xml(self):
- xml = """
-<icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0">
- <vcalendar>
- <properties>
- <prodid>
- <text>Libkolabxml-1.1</text>
- </prodid>
- <version>
- <text>2.0</text>
- </version>
- <x-kolab-version>
- <text>3.1.0</text>
- </x-kolab-version>
- </properties>
- <components>
- <vevent>
- <properties>
- <uid>
- <text>75c740bb-b3c6-442c-8021-ecbaeb0a025e</text>
- </uid>
- <created>
- <date-time>2014-07-07T01:28:23Z</date-time>
- </created>
- <dtstamp>
- <date-time>2014-07-07T01:28:23Z</date-time>
- </dtstamp>
- <sequence>
- <integer>1</integer>
- </sequence>
- <class>
- <text>PUBLIC</text>
- </class>
- <dtstart>
- <parameters>
- <tzid>
- <text>/kolab.org/Europe/London</text>
- </tzid>
- </parameters>
- <date-time>2014-08-13T10:00:00</date-time>
- </dtstart>
- <dtend>
- <parameters>
- <tzid><text>/kolab.org/Europe/London</text></tzid>
- </parameters>
- <date-time>2014-08-13T14:00:00</date-time>
- </dtend>
- <summary>
- <text>test</text>
- </summary>
- <organizer>
- <parameters>
- <cn><text>Doe, John</text></cn>
- </parameters>
- <cal-address>mailto:%3Cjohn%40example.org%3E</cal-address>
- </organizer>
- <attendee>
- <parameters>
- <partstat><text>ACCEPTED</text></partstat>
- <role><text>REQ-PARTICIPANT</text></role>
- <rsvp><boolean>true</boolean></rsvp>
- </parameters>
- <cal-address>mailto:%3Cjane%40example.org%3E</cal-address>
- </attendee>
- <attendee>
- <parameters>
- <partstat><text>TENTATIVE</text></partstat>
- <role><text>OPT-PARTICIPANT</text></role>
- </parameters>
- <cal-address>mailto:%3Csomebody%40else.com%3E</cal-address>
- </attendee>
- </properties>
- </vevent>
- </components>
- </vcalendar>
-</icalendar>
-"""
- event = event_from_string(xml)
+ event = event_from_string(xml_event)
self.assertEqual(event.uid, '75c740bb-b3c6-442c-8021-ecbaeb0a025e')
self.assertEqual(event.get_attendee_by_email("jane at example.org").get_participant_status(), kolabformat.PartAccepted)
self.assertEqual(event.get_sequence(), 1)
@@ -432,6 +486,40 @@ END:VEVENT
event = event_from_ical(vevent)
self.assertRaises(EventIntegrityError, event.to_message)
+ def test_025_to_dict(self):
+ data = event_from_string(xml_event).to_dict()
+
+ self.assertIsInstance(data, dict)
+ self.assertIsInstance(data['start'], datetime.datetime)
+ self.assertIsInstance(data['end'], datetime.datetime)
+ self.assertIsInstance(data['created'], datetime.datetime)
+ self.assertIsInstance(data['lastmodified-date'], datetime.datetime)
+ self.assertEqual(data['uid'], '75c740bb-b3c6-442c-8021-ecbaeb0a025e')
+ self.assertEqual(data['summary'], 'test')
+ self.assertEqual(data['location'], 'Room 101')
+ self.assertEqual(data['description'], 'test')
+ self.assertEqual(data['priority'], 5)
+ self.assertEqual(data['status'], 'CANCELLED')
+ self.assertEqual(data['sequence'], 1)
+ self.assertEqual(data['transparency'], False)
+ self.assertEqual(data['X-GWSHOW-AS'], 'BUSY')
+
+ self.assertIsInstance(data['organizer'], dict)
+ self.assertEqual(data['organizer']['email'], 'john at example.org')
+
+ self.assertEqual(len(data['attendee']), 2)
+ self.assertIsInstance(data['attendee'][0], dict)
+
+ self.assertEqual(len(data['attach']), 1)
+ self.assertIsInstance(data['attach'][0], dict)
+ self.assertEqual(data['attach'][0]['fmttype'], 'text/html')
+
+ self.assertIsInstance(data['rrule'], dict)
+ self.assertEqual(data['rrule']['frequency'], 'DAILY')
+ self.assertEqual(data['rrule']['interval'], 1)
+ self.assertEqual(data['rrule']['wkst'], 'MO')
+ self.assertIsInstance(data['rrule']['until'], datetime.date)
+
if __name__ == '__main__':
unittest.main()
More information about the commits
mailing list