vdirsyncer/tests/utils/test_main.py
Markus Unterwaditzer e2eb79d656 A lot of module restructuring
- Split utils up again
- Optimize performance when importing a specific storage. This is useful
  for khal which uses our FilesystemStorage (and doesn't want to import
  requests).
2015-04-13 17:33:44 +02:00

228 lines
6.9 KiB
Python

# -*- coding: utf-8 -*-
import os
import platform
import stat
import click
from click.testing import CliRunner
import pytest
import requests
import vdirsyncer.doubleclick as doubleclick
import vdirsyncer.utils.http
import vdirsyncer.utils.password
import vdirsyncer.utils as utils
from .. import blow_up
class EmptyNetrc(object):
def __init__(self, file=None):
self._file = file
def authenticators(self, hostname):
return None
class EmptyKeyring(object):
def get_password(self, *a, **kw):
return None
@pytest.fixture(autouse=True)
def empty_password_storages(monkeypatch):
monkeypatch.setattr('netrc.netrc', EmptyNetrc)
monkeypatch.setattr(utils.password, 'keyring', EmptyKeyring())
def test_get_password_from_netrc(monkeypatch):
username = 'foouser'
password = 'foopass'
resource = 'http://example.com/path/to/whatever/'
hostname = 'example.com'
calls = []
class Netrc(object):
def authenticators(self, hostname):
calls.append(hostname)
return username, 'bogus', password
monkeypatch.setattr('netrc.netrc', Netrc)
monkeypatch.setattr('getpass.getpass', blow_up)
_password = utils.password.get_password(username, resource)
assert _password == password
assert calls == [hostname]
def test_get_password_from_system_keyring(monkeypatch):
username = 'foouser'
password = 'foopass'
resource = 'http://example.com/path/to/whatever/'
hostname = 'example.com'
class KeyringMock(object):
def get_password(self, resource, _username):
assert _username == username
assert resource == utils.password.password_key_prefix + hostname
return password
monkeypatch.setattr(utils.password, 'keyring', KeyringMock())
monkeypatch.setattr('getpass.getpass', blow_up)
_password = utils.password.get_password(username, resource)
assert _password == password
def test_get_password_from_command(tmpdir):
username = 'my_username'
resource = 'http://example.com'
password = 'testpassword'
filename = 'command.sh'
filepath = str(tmpdir) + '/' + filename
f = open(filepath, 'w')
f.write('#!/bin/sh\n'
'[ "$1" != "my_username" ] && exit 1\n'
'[ "$2" != "example.com" ] && exit 1\n'
'echo "{}"'.format(password))
f.close()
st = os.stat(filepath)
os.chmod(filepath, st.st_mode | stat.S_IEXEC)
@doubleclick.click.command()
@doubleclick.click.pass_context
def fake_app(ctx):
ctx.obj = {'config': ({'password_command': filepath}, {}, {})}
_password = utils.password.get_password(username, resource)
assert _password == password
runner = CliRunner()
result = runner.invoke(fake_app)
assert not result.exception
def test_get_password_from_prompt():
user = 'my_user'
resource = 'http://example.com'
@click.command()
def fake_app():
x = utils.password.get_password(user, resource)
click.echo('Password is {}'.format(x))
runner = CliRunner()
result = runner.invoke(fake_app, input='my_password\n\n')
assert not result.exception
assert result.output.splitlines() == [
'Server password for {} at host {}: '.format(user, 'example.com'),
'Password is my_password'
]
def test_set_keyring_password(monkeypatch):
class KeyringMock(object):
def get_password(self, resource, username):
assert resource == \
utils.password.password_key_prefix + 'example.com'
assert username == 'foouser'
return None
def set_password(self, resource, username, password):
assert resource == \
utils.password.password_key_prefix + 'example.com'
assert username == 'foouser'
assert password == 'hunter2'
monkeypatch.setattr(utils.password, 'keyring', KeyringMock())
@doubleclick.click.command()
@doubleclick.click.pass_context
def fake_app(ctx):
ctx.obj = {}
x = utils.password.get_password('foouser', 'http://example.com/a/b')
click.echo('password is ' + x)
runner = CliRunner()
result = runner.invoke(fake_app, input='hunter2\ny\n')
assert not result.exception
assert result.output == (
'Server password for foouser at host example.com: \n'
'Save this password in the keyring? [y/N]: y\n'
'password is hunter2\n'
)
def test_get_password_from_cache(monkeypatch):
user = 'my_user'
resource = 'http://example.com'
@doubleclick.click.command()
@doubleclick.click.pass_context
def fake_app(ctx):
ctx.obj = {}
x = utils.password.get_password(user, resource)
click.echo('Password is {}'.format(x))
monkeypatch.setattr(doubleclick.click, 'prompt', blow_up)
assert (user, 'example.com') in ctx.obj['passwords']
x = utils.password.get_password(user, resource)
click.echo('Password is {}'.format(x))
runner = CliRunner()
result = runner.invoke(fake_app, input='my_password\n')
assert not result.exception
assert result.output.splitlines() == [
'Server password for {} at host {}: '.format(user, 'example.com'),
'Save this password in the keyring? [y/N]: ',
'Password is my_password',
'debug: Got password for my_user from internal cache',
'Password is my_password'
]
def test_get_class_init_args():
class Foobar(object):
def __init__(self, foo, bar, baz=None):
pass
all, required = utils.get_class_init_args(Foobar)
assert all == {'foo', 'bar', 'baz'}
assert required == {'foo', 'bar'}
def test_get_class_init_args_on_storage():
from vdirsyncer.storage.memory import MemoryStorage
all, required = utils.get_class_init_args(MemoryStorage)
assert all == set(['fileext', 'collection', 'read_only', 'instance_name',
'collection_human'])
assert not required
@pytest.mark.skipif((not utils.compat.PY2
or platform.python_implementation() == 'PyPy'),
reason='https://github.com/shazow/urllib3/issues/529')
def test_request_ssl(httpsserver):
sha1 = '94:FD:7A:CB:50:75:A4:69:82:0A:F8:23:DF:07:FC:69:3E:CD:90:CA'
md5 = '19:90:F7:23:94:F2:EF:AB:2B:64:2D:57:3D:25:95:2D'
httpsserver.serve_content('') # we need to serve something
with pytest.raises(requests.exceptions.SSLError) as excinfo:
utils.http.request('GET', httpsserver.url)
assert 'certificate verify failed' in str(excinfo.value)
utils.http.request('GET', httpsserver.url, verify=False)
utils.http.request('GET', httpsserver.url,
verify_fingerprint=sha1)
utils.http.request('GET', httpsserver.url, verify_fingerprint=md5)
with pytest.raises(requests.exceptions.SSLError) as excinfo:
utils.http.request('GET', httpsserver.url,
verify_fingerprint=''.join(reversed(sha1)))
assert 'Fingerprints did not match' in str(excinfo.value)