mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-04-27 14:57:41 +00:00
Add fastmail testserver (#572)
This commit is contained in:
parent
325298bf51
commit
668220dbd7
9 changed files with 91 additions and 140 deletions
100
.travis.yml
100
.travis.yml
|
|
@ -21,18 +21,6 @@
|
||||||
"env": "BUILD=style",
|
"env": "BUILD=style",
|
||||||
"python": "3.6"
|
"python": "3.6"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=skip REQUIREMENTS=devel ",
|
|
||||||
"python": "3.3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=skip REQUIREMENTS=release ",
|
|
||||||
"python": "3.3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=skip REQUIREMENTS=minimal ",
|
|
||||||
"python": "3.3"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=devel ",
|
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=devel ",
|
||||||
"python": "3.3"
|
"python": "3.3"
|
||||||
|
|
@ -45,18 +33,6 @@
|
||||||
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=minimal ",
|
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=minimal ",
|
||||||
"python": "3.3"
|
"python": "3.3"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=skip REQUIREMENTS=devel ",
|
|
||||||
"python": "3.4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=skip REQUIREMENTS=release ",
|
|
||||||
"python": "3.4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=skip REQUIREMENTS=minimal ",
|
|
||||||
"python": "3.4"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=devel ",
|
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=devel ",
|
||||||
"python": "3.4"
|
"python": "3.4"
|
||||||
|
|
@ -69,18 +45,6 @@
|
||||||
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=minimal ",
|
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=minimal ",
|
||||||
"python": "3.4"
|
"python": "3.4"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=skip REQUIREMENTS=devel ",
|
|
||||||
"python": "3.5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=skip REQUIREMENTS=release ",
|
|
||||||
"python": "3.5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=skip REQUIREMENTS=minimal ",
|
|
||||||
"python": "3.5"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=devel ",
|
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=devel ",
|
||||||
"python": "3.5"
|
"python": "3.5"
|
||||||
|
|
@ -94,100 +58,44 @@
|
||||||
"python": "3.5"
|
"python": "3.5"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"env": "BUILD=test DAV_SERVER=skip REQUIREMENTS=devel ",
|
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=devel ",
|
||||||
"python": "3.6"
|
"python": "3.6"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"env": "BUILD=test DAV_SERVER=skip REQUIREMENTS=release ",
|
"env": "BUILD=test DAV_SERVER=skip REQUIREMENTS=release ",
|
||||||
"python": "3.6"
|
"python": "3.6"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=skip REQUIREMENTS=minimal ",
|
|
||||||
"python": "3.6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=devel ",
|
|
||||||
"python": "3.6"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=release ",
|
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=release ",
|
||||||
"python": "3.6"
|
"python": "3.6"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=minimal ",
|
|
||||||
"python": "3.6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=owncloud REQUIREMENTS=devel ",
|
|
||||||
"python": "3.6"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"env": "BUILD=test DAV_SERVER=owncloud REQUIREMENTS=release ",
|
"env": "BUILD=test DAV_SERVER=owncloud REQUIREMENTS=release ",
|
||||||
"python": "3.6"
|
"python": "3.6"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=owncloud REQUIREMENTS=minimal ",
|
|
||||||
"python": "3.6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=nextcloud REQUIREMENTS=devel ",
|
|
||||||
"python": "3.6"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"env": "BUILD=test DAV_SERVER=nextcloud REQUIREMENTS=release ",
|
"env": "BUILD=test DAV_SERVER=nextcloud REQUIREMENTS=release ",
|
||||||
"python": "3.6"
|
"python": "3.6"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=nextcloud REQUIREMENTS=minimal ",
|
|
||||||
"python": "3.6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=baikal REQUIREMENTS=devel ",
|
|
||||||
"python": "3.6"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"env": "BUILD=test DAV_SERVER=baikal REQUIREMENTS=release ",
|
"env": "BUILD=test DAV_SERVER=baikal REQUIREMENTS=release ",
|
||||||
"python": "3.6"
|
"python": "3.6"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=baikal REQUIREMENTS=minimal ",
|
|
||||||
"python": "3.6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=davical REQUIREMENTS=devel ",
|
|
||||||
"python": "3.6"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"env": "BUILD=test DAV_SERVER=davical REQUIREMENTS=release ",
|
"env": "BUILD=test DAV_SERVER=davical REQUIREMENTS=release ",
|
||||||
"python": "3.6"
|
"python": "3.6"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=davical REQUIREMENTS=minimal ",
|
|
||||||
"python": "3.6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=icloud REQUIREMENTS=devel ",
|
|
||||||
"python": "3.6"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"env": "BUILD=test DAV_SERVER=icloud REQUIREMENTS=release ",
|
"env": "BUILD=test DAV_SERVER=icloud REQUIREMENTS=release ",
|
||||||
"python": "3.6"
|
"python": "3.6"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"env": "BUILD=test DAV_SERVER=icloud REQUIREMENTS=minimal ",
|
"env": "BUILD=test DAV_SERVER=fastmail REQUIREMENTS=release ",
|
||||||
"python": "3.6"
|
"python": "3.6"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"env": "BUILD=test DAV_SERVER=skip REQUIREMENTS=devel ",
|
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=minimal ",
|
||||||
"python": "pypy3"
|
"python": "3.6"
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=skip REQUIREMENTS=release ",
|
|
||||||
"python": "pypy3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "BUILD=test DAV_SERVER=skip REQUIREMENTS=minimal ",
|
|
||||||
"python": "pypy3"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=devel ",
|
"env": "BUILD=test DAV_SERVER=radicale REQUIREMENTS=devel ",
|
||||||
|
|
|
||||||
|
|
@ -13,3 +13,6 @@ In alphabetical order:
|
||||||
- Markus Unterwaditzer
|
- Markus Unterwaditzer
|
||||||
- Michael Adler
|
- Michael Adler
|
||||||
- Thomas Weißschuh
|
- Thomas Weißschuh
|
||||||
|
|
||||||
|
Additionally `FastMail sponsored a paid account for testing
|
||||||
|
<https://github.com/pimutils/vdirsyncer/issues/571>`_. Thanks!
|
||||||
|
|
|
||||||
|
|
@ -38,21 +38,19 @@ matrix.append({
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
for python in python_versions:
|
for python, requirements in itertools.product(python_versions,
|
||||||
if python == latest_python:
|
("devel", "release", "minimal")):
|
||||||
|
if python == latest_python and requirements == "release":
|
||||||
dav_servers = ("skip", "radicale", "owncloud", "nextcloud", "baikal",
|
dav_servers = ("skip", "radicale", "owncloud", "nextcloud", "baikal",
|
||||||
"davical", "icloud")
|
"davical", "icloud", "fastmail")
|
||||||
rs_servers = ()
|
rs_servers = ()
|
||||||
else:
|
else:
|
||||||
dav_servers = ("skip", "radicale")
|
dav_servers = ("radicale",)
|
||||||
rs_servers = ()
|
rs_servers = ()
|
||||||
|
|
||||||
for (server_type, server), requirements in itertools.product(
|
for server_type, server in itertools.chain(
|
||||||
itertools.chain(
|
|
||||||
(("REMOTESTORAGE", x) for x in rs_servers),
|
(("REMOTESTORAGE", x) for x in rs_servers),
|
||||||
(("DAV", x) for x in dav_servers)
|
(("DAV", x) for x in dav_servers)
|
||||||
),
|
|
||||||
("devel", "release", "minimal")
|
|
||||||
):
|
):
|
||||||
matrix.append({
|
matrix.append({
|
||||||
'python': python,
|
'python': python,
|
||||||
|
|
|
||||||
|
|
@ -203,8 +203,9 @@ class StorageTests(object):
|
||||||
if getattr(self, 'dav_server', '') == 'radicale':
|
if getattr(self, 'dav_server', '') == 'radicale':
|
||||||
pytest.skip('MKCOL is broken under Radicale 1.x')
|
pytest.skip('MKCOL is broken under Radicale 1.x')
|
||||||
|
|
||||||
if getattr(self, 'dav_server', '') == 'icloud':
|
if getattr(self, 'dav_server', '') in \
|
||||||
pytest.skip('iCloud requires a minimum-length for collection name')
|
('icloud', 'fastmail', 'davical'):
|
||||||
|
pytest.skip('Manual cleanup would be necessary.')
|
||||||
|
|
||||||
args = get_storage_args(collection=None)
|
args = get_storage_args(collection=None)
|
||||||
args['collection'] = 'test'
|
args['collection'] = 'test'
|
||||||
|
|
@ -249,8 +250,8 @@ class StorageTests(object):
|
||||||
get_storage_args, get_item):
|
get_storage_args, get_item):
|
||||||
if getattr(self, 'dav_server', '') == 'radicale':
|
if getattr(self, 'dav_server', '') == 'radicale':
|
||||||
pytest.skip('Radicale is fundamentally broken.')
|
pytest.skip('Radicale is fundamentally broken.')
|
||||||
if getattr(self, 'dav_server', '') == 'icloud':
|
if getattr(self, 'dav_server', '') in ('icloud', 'fastmail'):
|
||||||
pytest.skip('iCloud rejects uploads.')
|
pytest.skip('iCloud and FastMail reject this name.')
|
||||||
|
|
||||||
monkeypatch.setattr('vdirsyncer.utils.generate_href', lambda x: x)
|
monkeypatch.setattr('vdirsyncer.utils.generate_href', lambda x: x)
|
||||||
|
|
||||||
|
|
@ -309,7 +310,7 @@ class StorageTests(object):
|
||||||
if item_type != 'VEVENT':
|
if item_type != 'VEVENT':
|
||||||
pytest.skip('This storage instance doesn\'t support iCalendar.')
|
pytest.skip('This storage instance doesn\'t support iCalendar.')
|
||||||
|
|
||||||
uid = u'abc123'
|
uid = str(uuid.uuid4())
|
||||||
item = Item(textwrap.dedent(u'''
|
item = Item(textwrap.dedent(u'''
|
||||||
BEGIN:VCALENDAR
|
BEGIN:VCALENDAR
|
||||||
VERSION:2.0
|
VERSION:2.0
|
||||||
|
|
|
||||||
36
tests/storage/conftest.py
Normal file
36
tests/storage/conftest.py
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def slow_create_collection(request):
|
||||||
|
# We need to properly clean up because otherwise we might run into
|
||||||
|
# storage limits.
|
||||||
|
to_delete = []
|
||||||
|
|
||||||
|
def delete_collections():
|
||||||
|
for s in to_delete:
|
||||||
|
s.session.request('DELETE', '')
|
||||||
|
|
||||||
|
request.addfinalizer(delete_collections)
|
||||||
|
|
||||||
|
def inner(cls, args, collection):
|
||||||
|
assert collection.startswith('test')
|
||||||
|
collection += '-vdirsyncer-ci-' + str(uuid.uuid4())
|
||||||
|
|
||||||
|
args = cls.create_collection(collection, **args)
|
||||||
|
s = cls(**args)
|
||||||
|
_clear_collection(s)
|
||||||
|
assert not list(s.list())
|
||||||
|
to_delete.append(s)
|
||||||
|
return args
|
||||||
|
|
||||||
|
return inner
|
||||||
|
|
||||||
|
|
||||||
|
def _clear_collection(s):
|
||||||
|
for href, etag in s.list():
|
||||||
|
s.delete(href, etag)
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
@ -44,11 +46,11 @@ class DAVStorageTests(ServerMixin, StorageTests):
|
||||||
|
|
||||||
def test_dav_unicode_href(self, s, get_item, monkeypatch):
|
def test_dav_unicode_href(self, s, get_item, monkeypatch):
|
||||||
if self.dav_server == 'radicale':
|
if self.dav_server == 'radicale':
|
||||||
pytest.xfail('Radicale is unable to deal with unicode hrefs')
|
pytest.skip('Radicale is unable to deal with unicode hrefs')
|
||||||
|
|
||||||
monkeypatch.setattr(s, '_get_href',
|
monkeypatch.setattr(s, '_get_href',
|
||||||
lambda item: item.ident + s.fileext)
|
lambda item: item.ident + s.fileext)
|
||||||
item = get_item(uid=u'lolätvdirsynceröü град сатану')
|
item = get_item(uid=u'град сатану' + str(uuid.uuid4()))
|
||||||
href, etag = s.upload(item)
|
href, etag = s.upload(item)
|
||||||
item2, etag2 = s.get(href)
|
item2, etag2 = s.get(href)
|
||||||
assert_item_equals(item, item2)
|
assert_item_equals(item, item2)
|
||||||
|
|
|
||||||
27
tests/storage/servers/fastmail/__init__.py
Normal file
27
tests/storage/servers/fastmail/__init__.py
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
class ServerMixin(object):
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def get_storage_args(self, slow_create_collection):
|
||||||
|
def inner(collection='test'):
|
||||||
|
args = {
|
||||||
|
'username': os.environ['FASTMAIL_USERNAME'],
|
||||||
|
'password': os.environ['FASTMAIL_PASSWORD']
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.storage_class.fileext == '.ics':
|
||||||
|
args['url'] = 'https://caldav.messagingengine.com/'
|
||||||
|
elif self.storage_class.fileext == '.vcf':
|
||||||
|
args['url'] = 'https://carddav.messagingengine.com/'
|
||||||
|
else:
|
||||||
|
raise RuntimeError()
|
||||||
|
|
||||||
|
if collection is not None:
|
||||||
|
args = slow_create_collection(self.storage_class, args,
|
||||||
|
collection)
|
||||||
|
return args
|
||||||
|
return inner
|
||||||
0
tests/storage/servers/fastmail/install.sh
Normal file
0
tests/storage/servers/fastmail/install.sh
Normal file
|
|
@ -1,28 +1,12 @@
|
||||||
import os
|
import os
|
||||||
import uuid
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
def _clear_collection(s):
|
|
||||||
for href, etag in s.list():
|
|
||||||
s.delete(href, etag)
|
|
||||||
|
|
||||||
|
|
||||||
class ServerMixin(object):
|
class ServerMixin(object):
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def get_storage_args(self, item_type, request):
|
def get_storage_args(self, item_type, slow_create_collection):
|
||||||
# We need to properly clean up because otherwise we will run into
|
|
||||||
# iCloud's storage limit.
|
|
||||||
collections_to_delete = []
|
|
||||||
|
|
||||||
def delete_collections():
|
|
||||||
for s in collections_to_delete:
|
|
||||||
s.session.request('DELETE', '')
|
|
||||||
|
|
||||||
request.addfinalizer(delete_collections)
|
|
||||||
|
|
||||||
if item_type != 'VEVENT':
|
if item_type != 'VEVENT':
|
||||||
# For some reason the collections created by vdirsyncer are not
|
# For some reason the collections created by vdirsyncer are not
|
||||||
# usable as task lists.
|
# usable as task lists.
|
||||||
|
|
@ -42,15 +26,7 @@ class ServerMixin(object):
|
||||||
raise RuntimeError()
|
raise RuntimeError()
|
||||||
|
|
||||||
if collection is not None:
|
if collection is not None:
|
||||||
assert collection.startswith('test')
|
args = slow_create_collection(self.storage_class, args,
|
||||||
# iCloud requires a minimum length for collection names
|
collection)
|
||||||
collection += '-vdirsyncer-ci-' + str(uuid.uuid4())
|
|
||||||
|
|
||||||
args = self.storage_class.create_collection(collection,
|
|
||||||
**args)
|
|
||||||
s = self.storage_class(**args)
|
|
||||||
_clear_collection(s)
|
|
||||||
assert not list(s.list())
|
|
||||||
collections_to_delete.append(s)
|
|
||||||
return args
|
return args
|
||||||
return inner
|
return inner
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue