diff --git a/tests/__init__.py b/tests/__init__.py index 0bfc4c9..0bc5e4b 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -15,6 +15,10 @@ from vdirsyncer.utils.vobject import normalize_item as _normalize_item vdirsyncer.log.set_level(vdirsyncer.log.logging.DEBUG) +def blow_up(*a, **kw): + raise AssertionError('Did not expect to be called.') + + def normalize_item(item): if not isinstance(item, text_type): item = item.raw diff --git a/tests/utils/test_main.py b/tests/utils/test_main.py index ca2672e..aeea986 100644 --- a/tests/utils/test_main.py +++ b/tests/utils/test_main.py @@ -7,11 +7,13 @@ :license: MIT, see LICENSE for more details. ''' +import click +from click.testing import CliRunner import pytest import vdirsyncer.utils as utils from vdirsyncer.utils.vobject import split_collection -from .. import normalize_item, SIMPLE_TEMPLATE, BARE_EVENT_TEMPLATE +from .. import blow_up, normalize_item, SIMPLE_TEMPLATE, BARE_EVENT_TEMPLATE def test_parse_options(): @@ -58,7 +60,7 @@ def test_get_password_from_netrc(monkeypatch): return username, 'bogus', password monkeypatch.setattr('netrc.netrc', Netrc) - monkeypatch.setattr('getpass.getpass', None) + monkeypatch.setattr('getpass.getpass', blow_up) _password = utils.get_password(username, resource) assert _password == password @@ -101,13 +103,46 @@ def test_get_password_from_system_keyring(monkeypatch, resources_to_test): return None monkeypatch.setattr('netrc.netrc', Netrc) - monkeypatch.setattr('getpass.getpass', None) + monkeypatch.setattr('getpass.getpass', blow_up) _password = utils.get_password(username, resource) assert _password == password assert netrc_calls == [hostname] +def test_get_password_from_prompt(monkeypatch): + getpass_calls = [] + + class Netrc(object): + def authenticators(self, hostname): + return None + + class Keyring(object): + def get_password(self, *a, **kw): + return None + + monkeypatch.setattr('netrc.netrc', Netrc) + monkeypatch.setattr(utils, 'keyring', Keyring()) + + user = 'my_user' + resource = 'http://example.com' + + @click.command() + def fake_app(): + x = utils.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 the resource {}: '.format(user, resource), + 'Save this password in the keyring? [y/N]: ', + 'Password is my_password' + ] + + + def test_get_class_init_args(): class Foobar(object): def __init__(self, foo, bar, baz=None): diff --git a/vdirsyncer/cli.py b/vdirsyncer/cli.py index 6e2d0f5..8896767 100644 --- a/vdirsyncer/cli.py +++ b/vdirsyncer/cli.py @@ -7,10 +7,10 @@ :license: MIT, see LICENSE for more details. ''' +import functools import json import os import sys -import functools import click diff --git a/vdirsyncer/log.py b/vdirsyncer/log.py index 2ee0e87..0f9b30f 100644 --- a/vdirsyncer/log.py +++ b/vdirsyncer/log.py @@ -7,6 +7,7 @@ :license: MIT, see LICENSE for more details. ''' import logging + import click diff --git a/vdirsyncer/utils/__init__.py b/vdirsyncer/utils/__init__.py index 8ab360e..fe5b704 100644 --- a/vdirsyncer/utils/__init__.py +++ b/vdirsyncer/utils/__init__.py @@ -9,9 +9,10 @@ import os -import requests import click +import requests + from .. import exceptions, log from .compat import iteritems, urlparse @@ -117,7 +118,9 @@ def _password_from_keyring(username, resource): parsed = urlparse.urlsplit(key) path = parsed.path - if path.endswith('/'): + if not path: + return None + elif path.endswith('/'): path = path.rstrip('/') else: path = path.rsplit('/', 1)[0] + '/' @@ -165,7 +168,7 @@ def get_password(username, resource): prompt = ('Server password for {} at the resource {}' .format(username, resource)) - password = click.prompt(prompt=prompt, hide_input=True) + password = click.prompt(prompt, hide_input=True) if keyring is not None and \ click.confirm('Save this password in the keyring?', default=False):