summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Brox <tobias@redpill-linpro.com>2022-01-07 21:33:22 +0100
committerTobias Brox <tobias@redpill-linpro.com>2022-01-07 21:33:22 +0100
commit67e47bce745813f1694ba755bf3b79fc8849a37e (patch)
treef2e96ae98d0f050efefb3add340ad65df679d820
parent509b4f01edab892c8581c5afac4378da46d822c4 (diff)
downloadpython-caldav-67e47bce745813f1694ba755bf3b79fc8849a37e.zip
bugfix: no_overwrite, no_create flags in save_todo would only work for events
-rw-r--r--caldav/objects.py15
-rw-r--r--tests/test_caldav.py21
2 files changed, 27 insertions, 9 deletions
diff --git a/caldav/objects.py b/caldav/objects.py
index 91f4af9..4032273 100644
--- a/caldav/objects.py
+++ b/caldav/objects.py
@@ -974,7 +974,7 @@ class Calendar(DAVObject):
except error.NotFoundError:
raise
except Exception as err:
- raise NotImplementedError("The object_by_uid is not compatible with some server implementations. work in progress.")
+ raise NotImplementedError(f"Server said {str(err)}. The object_by_uid is not compatible with some server implementations. work in progress.")
# Ref Lucas Verney, we've actually done a substring search, if the
# uid given in the query is short (i.e. just "0") we're likely to
@@ -1473,17 +1473,20 @@ class CalendarObjectResource(DAVObject):
## a unique new calendar item is created to the server without
## overwriting old stuff or vice versa - it seems silly to me
## to do a PUT instead of POST when creating new data).
+ ## TODO: the "find id"-logic is duplicated in _create,
+ ## should be refactored
if not self.id:
- try:
- self.id = self.vobject_instance.vevent.uid.value
- except AttributeError:
- pass
+ for component in self.vobject_instance.getChildren():
+ if hasattr(component, 'uid'):
+ self.id = component.uid.value
if not self.id and no_create:
raise error.ConsistencyError("no_create flag was set, but no ID given")
existing = None
## some servers require one to explicitly search for the right kind of object.
## todo: would arguably be nicer to verify the type of the object and take it from there
- if obj_type:
+ if not self.id:
+ methods = []
+ elif obj_type:
methods = (getattr(self.parent, "%s_by_uid" % obj_type),)
else:
methods = (self.parent.object_by_uid, self.parent.event_by_uid, self.parent.todo_by_uid, self.parent.journal_by_uid)
diff --git a/tests/test_caldav.py b/tests/test_caldav.py
index a4fa1b4..a516843 100644
--- a/tests/test_caldav.py
+++ b/tests/test_caldav.py
@@ -1041,6 +1041,7 @@ class RepeatedFunctionalTestsBaseClass(object):
# add todo-item
logging.info("Adding todo item to calendar Yep")
t1 = c.save_todo(todo)
+ assert_equal(t1.id, '20070313T123432Z-456553@example.com')
# c.todos() should give a full list of todo items
logging.info("Fetching the full list of todo items (should be one)")
@@ -1398,7 +1399,10 @@ class RepeatedFunctionalTestsBaseClass(object):
# add event
e1 = c.save_event(ev1)
+ if not self.check_compatibility_flag('no_todo'):
+ t1 = c.save_todo(todo)
assert_not_equal(e1.url, None)
+ assert_not_equal(t1.url, None)
if not self.check_compatibility_flag('event_by_url_is_broken'):
assert_equal(c.event_by_url(e1.url).url, e1.url)
assert_equal(c.event_by_uid(e1.id).url, e1.url)
@@ -1407,25 +1411,36 @@ class RepeatedFunctionalTestsBaseClass(object):
## (but some calendars may throw a "409 Conflict")
if not self.check_compatibility_flag('no_overwrite'):
e2 = c.save_event(ev1)
+ if not self.check_compatibility_flag('no_todo'):
+ t2 = c.save_todo(todo)
## add same event with "no_create". Should work like a charm.
e2 = c.save_event(ev1, no_create=True)
-
- e2.instance.vevent.summary.value = e2.instance.vevent.summary.value + '!'
+ if not self.check_compatibility_flag('no_todo'):
+ t2 = c.save_todo(todo, no_create=True)
## this should also work.
+ e2.instance.vevent.summary.value = e2.instance.vevent.summary.value + '!'
e2.save(no_create=True)
+ if not self.check_compatibility_flag('no_todo'):
+ t2.instance.vtodo.summary.value = t2.instance.vtodo.summary.value + '!'
+ t2.save(no_create=True)
+
+
if not self.check_compatibility_flag('event_by_url_is_broken'):
e3 = c.event_by_url(e1.url)
assert_equal(e3.instance.vevent.summary.value, 'Bastille Day Party!')
## "no_overwrite" should throw a ConsistencyError
assert_raises(error.ConsistencyError, c.save_event, ev1, no_overwrite=True)
+ if not self.check_compatibility_flag('no_todo'):
+ assert_raises(error.ConsistencyError, c.save_todo, todo, no_overwrite=True)
# delete event
e1.delete()
-
+ if not self.check_compatibility_flag('no_todo'):
+ t1.delete
# Verify that we can't look it up, both by URL and by ID
assert_raises(error.NotFoundError, c.event_by_url, e1.url)