mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-04-27 14:57:41 +00:00
Merge pull request #536 from pimutils/travis-test
Return back to None as non-ETag
This commit is contained in:
commit
7590ff3aef
7 changed files with 62 additions and 31 deletions
|
|
@ -76,7 +76,10 @@ class StorageTests(object):
|
||||||
items = [get_item() for i in range(1, 10)]
|
items = [get_item() for i in range(1, 10)]
|
||||||
hrefs = []
|
hrefs = []
|
||||||
for item in items:
|
for item in items:
|
||||||
hrefs.append(s.upload(item))
|
href, etag = s.upload(item)
|
||||||
|
if etag is None:
|
||||||
|
_, etag = s.get(href)
|
||||||
|
hrefs.append((href, etag))
|
||||||
hrefs.sort()
|
hrefs.sort()
|
||||||
assert hrefs == sorted(s.list())
|
assert hrefs == sorted(s.list())
|
||||||
for href, etag in hrefs:
|
for href, etag in hrefs:
|
||||||
|
|
@ -91,6 +94,8 @@ class StorageTests(object):
|
||||||
|
|
||||||
def test_get_multi_duplicates(self, s, get_item):
|
def test_get_multi_duplicates(self, s, get_item):
|
||||||
href, etag = s.upload(get_item())
|
href, etag = s.upload(get_item())
|
||||||
|
if etag is None:
|
||||||
|
_, etag = s.get(href)
|
||||||
(href2, item, etag2), = s.get_multi([href] * 2)
|
(href2, item, etag2), = s.get_multi([href] * 2)
|
||||||
assert href2 == href
|
assert href2 == href
|
||||||
assert etag2 == etag
|
assert etag2 == etag
|
||||||
|
|
@ -109,10 +114,14 @@ class StorageTests(object):
|
||||||
def test_update(self, s, get_item):
|
def test_update(self, s, get_item):
|
||||||
item = get_item()
|
item = get_item()
|
||||||
href, etag = s.upload(item)
|
href, etag = s.upload(item)
|
||||||
|
if etag is None:
|
||||||
|
_, etag = s.get(href)
|
||||||
assert_item_equals(s.get(href)[0], item)
|
assert_item_equals(s.get(href)[0], item)
|
||||||
|
|
||||||
new_item = get_item(uid=item.uid)
|
new_item = get_item(uid=item.uid)
|
||||||
new_etag = s.update(href, new_item, etag)
|
new_etag = s.update(href, new_item, etag)
|
||||||
|
if new_etag is None:
|
||||||
|
_, new_etag = s.get(href)
|
||||||
# See https://github.com/pimutils/vdirsyncer/issues/48
|
# See https://github.com/pimutils/vdirsyncer/issues/48
|
||||||
assert isinstance(new_etag, (bytes, str))
|
assert isinstance(new_etag, (bytes, str))
|
||||||
assert_item_equals(s.get(href)[0], new_item)
|
assert_item_equals(s.get(href)[0], new_item)
|
||||||
|
|
@ -142,6 +151,8 @@ class StorageTests(object):
|
||||||
def test_list(self, s, get_item):
|
def test_list(self, s, get_item):
|
||||||
assert not list(s.list())
|
assert not list(s.list())
|
||||||
href, etag = s.upload(get_item())
|
href, etag = s.upload(get_item())
|
||||||
|
if etag is None:
|
||||||
|
_, etag = s.get(href)
|
||||||
assert list(s.list()) == [(href, etag)]
|
assert list(s.list()) == [(href, etag)]
|
||||||
|
|
||||||
def test_has(self, s, get_item):
|
def test_has(self, s, get_item):
|
||||||
|
|
@ -153,12 +164,12 @@ class StorageTests(object):
|
||||||
assert not s.has(href)
|
assert not s.has(href)
|
||||||
|
|
||||||
def test_update_others_stay_the_same(self, s, get_item):
|
def test_update_others_stay_the_same(self, s, get_item):
|
||||||
info = dict([
|
info = {}
|
||||||
s.upload(get_item()),
|
for _ in range(4):
|
||||||
s.upload(get_item()),
|
href, etag = s.upload(get_item())
|
||||||
s.upload(get_item()),
|
if etag is None:
|
||||||
s.upload(get_item())
|
_, etag = s.get(href)
|
||||||
])
|
info[href] = etag
|
||||||
|
|
||||||
assert dict(
|
assert dict(
|
||||||
(href, etag) for href, item, etag
|
(href, etag) for href, item, etag
|
||||||
|
|
@ -197,8 +208,8 @@ class StorageTests(object):
|
||||||
**self.storage_class.create_collection(**args)
|
**self.storage_class.create_collection(**args)
|
||||||
)
|
)
|
||||||
|
|
||||||
item = s.upload(get_item())
|
href = s.upload(get_item())[0]
|
||||||
assert item in set(s.list())
|
assert href in set(href for href, etag in s.list())
|
||||||
|
|
||||||
def test_discover_collection_arg(self, requires_collections,
|
def test_discover_collection_arg(self, requires_collections,
|
||||||
get_storage_args):
|
get_storage_args):
|
||||||
|
|
@ -243,18 +254,12 @@ class StorageTests(object):
|
||||||
|
|
||||||
href, etag = s.upload(item)
|
href, etag = s.upload(item)
|
||||||
item2, etag2 = s.get(href)
|
item2, etag2 = s.get(href)
|
||||||
assert etag2 == etag
|
if etag is not None:
|
||||||
assert_item_equals(item2, item)
|
assert etag2 == etag
|
||||||
|
assert_item_equals(item2, item)
|
||||||
|
|
||||||
(href2, etag2), = s.list()
|
(_, etag3), = s.list()
|
||||||
assert etag2 == etag
|
assert etag2 == etag3
|
||||||
|
|
||||||
# https://github.com/owncloud/contacts/issues/581
|
|
||||||
assert href2.replace('%2B', '%20') == href
|
|
||||||
|
|
||||||
item2, etag2 = s.get(href)
|
|
||||||
assert etag2 == etag
|
|
||||||
assert_item_equals(item2, item)
|
|
||||||
|
|
||||||
assert collection in urlunquote(s.collection)
|
assert collection in urlunquote(s.collection)
|
||||||
if self.storage_class.storage_name.endswith('dav'):
|
if self.storage_class.storage_name.endswith('dav'):
|
||||||
|
|
|
||||||
|
|
@ -108,9 +108,10 @@ class TestCalDAVStorage(DAVStorageTests):
|
||||||
|
|
||||||
s.upload(too_old_item)
|
s.upload(too_old_item)
|
||||||
s.upload(too_new_item)
|
s.upload(too_new_item)
|
||||||
href, etag = s.upload(good_item)
|
expected_href, _ = s.upload(good_item)
|
||||||
|
|
||||||
assert list(s.list()) == [(href, etag)]
|
(actual_href, _), = s.list()
|
||||||
|
assert actual_href == expected_href
|
||||||
|
|
||||||
def test_invalid_resource(self, monkeypatch, get_storage_args):
|
def test_invalid_resource(self, monkeypatch, get_storage_args):
|
||||||
calls = []
|
calls = []
|
||||||
|
|
@ -133,13 +134,17 @@ class TestCalDAVStorage(DAVStorageTests):
|
||||||
assert len(calls) == 1
|
assert len(calls) == 1
|
||||||
|
|
||||||
def test_item_types_general(self, s):
|
def test_item_types_general(self, s):
|
||||||
event = s.upload(format_item(EVENT_TEMPLATE))
|
event = s.upload(format_item(EVENT_TEMPLATE))[0]
|
||||||
task = s.upload(format_item(TASK_TEMPLATE))
|
task = s.upload(format_item(TASK_TEMPLATE))[0]
|
||||||
s.item_types = ('VTODO', 'VEVENT')
|
s.item_types = ('VTODO', 'VEVENT')
|
||||||
assert set(s.list()) == set([event, task])
|
|
||||||
|
def l():
|
||||||
|
return set(href for href, etag in s.list())
|
||||||
|
|
||||||
|
assert l() == {event, task}
|
||||||
s.item_types = ('VTODO',)
|
s.item_types = ('VTODO',)
|
||||||
assert set(s.list()) == set([task])
|
assert l() == {task}
|
||||||
s.item_types = ('VEVENT',)
|
s.item_types = ('VEVENT',)
|
||||||
assert set(s.list()) == set([event])
|
assert l() == {event}
|
||||||
s.item_types = ()
|
s.item_types = ()
|
||||||
assert set(s.list()) == set([event, task])
|
assert l() == {event, task}
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit de5c4c79f42e2e64b1eac95aec193a0c08f8065d
|
Subproject commit 196714b287e6045d614b58a5aa2c32acc50ab69f
|
||||||
|
|
@ -500,6 +500,20 @@ class SyncMachine(RuleBasedStateMachine):
|
||||||
s.update = action_failure
|
s.update = action_failure
|
||||||
s.delete = action_failure
|
s.delete = action_failure
|
||||||
|
|
||||||
|
@rule(s=Storage)
|
||||||
|
def none_as_etag(self, s):
|
||||||
|
_old_upload = s.upload
|
||||||
|
_old_update = s.update
|
||||||
|
|
||||||
|
def upload(item):
|
||||||
|
return _old_upload(item)[0], None
|
||||||
|
|
||||||
|
def update(href, item, etag):
|
||||||
|
_old_update(href, item, etag)
|
||||||
|
|
||||||
|
s.upload = upload
|
||||||
|
s.update = update
|
||||||
|
|
||||||
@rule(target=Status)
|
@rule(target=Status)
|
||||||
def newstatus(self):
|
def newstatus(self):
|
||||||
return {}
|
return {}
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,10 @@ class Storage(metaclass=StorageMeta):
|
||||||
def upload(self, item):
|
def upload(self, item):
|
||||||
'''Upload a new item.
|
'''Upload a new item.
|
||||||
|
|
||||||
|
In cases where the new etag is not known, this method may return `None`
|
||||||
|
as etag. This special case only exists because of DAV. Avoid this
|
||||||
|
situation whenever possible.
|
||||||
|
|
||||||
:raises: :exc:`vdirsyncer.exceptions.PreconditionFailed` if there is
|
:raises: :exc:`vdirsyncer.exceptions.PreconditionFailed` if there is
|
||||||
already an item with that href.
|
already an item with that href.
|
||||||
|
|
||||||
|
|
@ -176,6 +180,10 @@ class Storage(metaclass=StorageMeta):
|
||||||
def update(self, href, item, etag):
|
def update(self, href, item, etag):
|
||||||
'''Update an item.
|
'''Update an item.
|
||||||
|
|
||||||
|
In cases where the new etag is not known, this method may return `None`
|
||||||
|
as etag. This special case only exists because of DAV. Avoid this
|
||||||
|
situation whenever possible.
|
||||||
|
|
||||||
:raises: :exc:`vdirsyncer.exceptions.PreconditionFailed` if the etag on
|
:raises: :exc:`vdirsyncer.exceptions.PreconditionFailed` if the etag on
|
||||||
the server doesn't match the given etag or if the item doesn't
|
the server doesn't match the given etag or if the item doesn't
|
||||||
exist.
|
exist.
|
||||||
|
|
|
||||||
|
|
@ -509,7 +509,7 @@ class DAVStorage(Storage):
|
||||||
#
|
#
|
||||||
# In such cases we return a constant etag. The next synchronization
|
# In such cases we return a constant etag. The next synchronization
|
||||||
# will then detect an etag change and will download the new item.
|
# will then detect an etag change and will download the new item.
|
||||||
etag = response.headers.get('etag', 'NULL')
|
etag = response.headers.get('etag', None)
|
||||||
href = self._normalize_href(response.url)
|
href = self._normalize_href(response.url)
|
||||||
return href, etag
|
return href, etag
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -354,7 +354,6 @@ class Update(Action):
|
||||||
meta = self.dest.new_status[self.ident]
|
meta = self.dest.new_status[self.ident]
|
||||||
meta.etag = \
|
meta.etag = \
|
||||||
self.dest.storage.update(meta.href, self.item, meta.etag)
|
self.dest.storage.update(meta.href, self.item, meta.etag)
|
||||||
assert isinstance(meta.etag, (bytes, str))
|
|
||||||
|
|
||||||
self.dest.new_status[self.ident] = meta
|
self.dest.new_status[self.ident] = meta
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue