mirror of
https://github.com/certbot/certbot.git
synced 2026-06-07 07:42:08 -04:00
Full coverage and lint for display.ops
This commit is contained in:
parent
138a9e9f01
commit
b4f99df798
2 changed files with 149 additions and 11 deletions
|
|
@ -15,30 +15,49 @@ util = zope.component.getUtility # pylint: disable=invalid-name
|
|||
def choose_plugin(prepared, question):
|
||||
"""Allow the user to choose ther plugin.
|
||||
|
||||
:param list prepared:
|
||||
:param list prepared: List of `~.PluginEntryPoint`.
|
||||
:param str question: Question to be presented to the user.
|
||||
|
||||
:returns: Plugin entry point chosen by the user.
|
||||
:rtype: `~.PluginEntryPoint`
|
||||
|
||||
"""
|
||||
opts = [plugin_ep.name_with_description
|
||||
+ (" [Misconfigured]" if plugin_ep.misconfigured else "")
|
||||
for plugin_ep in prepared.itervalues()]
|
||||
for plugin_ep in prepared]
|
||||
|
||||
while True:
|
||||
code, index = util(interfaces.IDisplay).menu(
|
||||
question, opts, help_label="More Info")
|
||||
|
||||
if code == display_util.OK:
|
||||
return prepared[index][0]
|
||||
return prepared[index]
|
||||
elif code == display_util.HELP:
|
||||
if prepared[index][1] is not None:
|
||||
if prepared[index].misconfigured:
|
||||
msg = "Reported Error: %s" % prepared[index].prepare()
|
||||
else:
|
||||
msg = prepared[index][0].init().more_info()
|
||||
msg = prepared[index].init().more_info()
|
||||
util(interfaces.IDisplay).notification(
|
||||
msg, height=display_util.HEIGHT)
|
||||
else:
|
||||
return None
|
||||
|
||||
def _pick_plugin(config, default, plugins, question, ifaces):
|
||||
|
||||
def pick_plugin(config, default, plugins, question, ifaces):
|
||||
"""Pick plugin.
|
||||
|
||||
:param letsencrypt.client.interfaces.IConfig: Configuration
|
||||
:param str default: Plugin name supplied by user or ``None``.
|
||||
:param letsencrypt.client.plugins.disco.PluginsRegistry plugins:
|
||||
All plugins registered as entry points.
|
||||
:param str question: Question to be presented to the user in case
|
||||
multiple candidates are found.
|
||||
:param list ifaces: Interfaces that plugins must provide.
|
||||
|
||||
:returns: Initialized plugin.
|
||||
:rtype: IPlugin
|
||||
|
||||
"""
|
||||
if default is not None:
|
||||
# throw more UX-friendly error if default not in plugins
|
||||
filtered = plugins.filter(lambda p_ep: p_ep.name == default)
|
||||
|
|
@ -47,8 +66,8 @@ def _pick_plugin(config, default, plugins, question, ifaces):
|
|||
|
||||
filtered.init(config)
|
||||
verified = filtered.verify(ifaces)
|
||||
filtered.prepare()
|
||||
prepared = filtered.available()
|
||||
verified.prepare()
|
||||
prepared = verified.available()
|
||||
|
||||
if len(prepared) > 1:
|
||||
logging.debug("Multiple candidate plugins: %s", prepared)
|
||||
|
|
@ -66,14 +85,14 @@ def pick_authenticator(
|
|||
config, default, plugins, question="How would you "
|
||||
"like to authenticate with Let's Encrypt CA?"):
|
||||
"""Pick authentication plugin."""
|
||||
return _pick_plugin(
|
||||
return pick_plugin(
|
||||
config, default, plugins, question, (interfaces.IAuthenticator,))
|
||||
|
||||
|
||||
def pick_installer(config, default, plugins,
|
||||
question="How would you like to install certificates?"):
|
||||
"""Pick installer plugin."""
|
||||
return _pick_plugin(
|
||||
return pick_plugin(
|
||||
config, default, plugins, question, (interfaces.IInstaller,))
|
||||
|
||||
|
||||
|
|
@ -82,7 +101,7 @@ def pick_configurator(
|
|||
question="How would you like to authenticate and install "
|
||||
"certificates?"):
|
||||
"""Pick configurator plugin."""
|
||||
return _pick_plugin(
|
||||
return pick_plugin(
|
||||
config, default, plugins, question,
|
||||
(interfaces.IAuthenticator, interfaces.IInstaller))
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,129 @@ import mock
|
|||
import zope.component
|
||||
|
||||
from letsencrypt.client import account
|
||||
from letsencrypt.client import interfaces
|
||||
from letsencrypt.client import le_util
|
||||
|
||||
from letsencrypt.client.display import util as display_util
|
||||
|
||||
|
||||
class ChoosePluginTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.client.display.ops.choose_plugin."""
|
||||
|
||||
def setUp(self):
|
||||
zope.component.provideUtility(display_util.FileDisplay(sys.stdout))
|
||||
self.mock_apache = mock.Mock(
|
||||
name_with_description="a", misconfigured=True)
|
||||
self.mock_stand = mock.Mock(
|
||||
name_with_description="s", misconfigured=False)
|
||||
self.mock_stand.init().more_info.return_value = "standalone"
|
||||
self.plugins = [
|
||||
self.mock_apache,
|
||||
self.mock_stand,
|
||||
]
|
||||
|
||||
def _call(self):
|
||||
from letsencrypt.client.display.ops import choose_plugin
|
||||
return choose_plugin(self.plugins, "Question?")
|
||||
|
||||
@mock.patch("letsencrypt.client.display.ops.util")
|
||||
def test_successful_choice(self, mock_util):
|
||||
mock_util().menu.return_value = (display_util.OK, 0)
|
||||
self.assertEqual(self.mock_apache, self._call())
|
||||
|
||||
@mock.patch("letsencrypt.client.display.ops.util")
|
||||
def test_more_info(self, mock_util):
|
||||
mock_util().menu.side_effect = [
|
||||
(display_util.HELP, 0),
|
||||
(display_util.HELP, 1),
|
||||
(display_util.OK, 1),
|
||||
]
|
||||
|
||||
self.assertEqual(self.mock_stand, self._call())
|
||||
self.assertEqual(mock_util().notification.call_count, 2)
|
||||
|
||||
@mock.patch("letsencrypt.client.display.ops.util")
|
||||
def test_no_choice(self, mock_util):
|
||||
mock_util().menu.return_value = (display_util.CANCEL, 0)
|
||||
self.assertTrue(self._call() is None)
|
||||
|
||||
|
||||
class PickPluginTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.client.display.ops.pick_plugin."""
|
||||
|
||||
def setUp(self):
|
||||
self.config = mock.Mock()
|
||||
self.default = None
|
||||
self.reg = mock.MagicMock()
|
||||
self.question = "Question?"
|
||||
self.ifaces = []
|
||||
|
||||
def _call(self):
|
||||
from letsencrypt.client.display.ops import pick_plugin
|
||||
return pick_plugin(self.config, self.default, self.reg,
|
||||
self.question, self.ifaces)
|
||||
|
||||
def test_default_provided(self):
|
||||
self.default = "foo"
|
||||
self._call()
|
||||
self.reg.filter.assert_called_once()
|
||||
|
||||
def test_no_default(self):
|
||||
self._call()
|
||||
self.reg.filter.assert_called_once()
|
||||
|
||||
def test_no_candidate(self):
|
||||
self.assertTrue(self._call() is None)
|
||||
|
||||
def test_single(self):
|
||||
plugin_ep = mock.MagicMock()
|
||||
plugin_ep.init.return_value = "foo"
|
||||
self.reg.ifaces().verify().available.return_value = {"bar": plugin_ep}
|
||||
self.assertEqual("foo", self._call())
|
||||
|
||||
def test_multiple(self):
|
||||
plugin_ep = mock.MagicMock()
|
||||
plugin_ep.init.return_value = "foo"
|
||||
self.reg.ifaces().verify().available.return_value = {
|
||||
"bar": plugin_ep,
|
||||
"baz": plugin_ep,
|
||||
}
|
||||
with mock.patch("letsencrypt.client.display"
|
||||
".ops.choose_plugin") as mock_choose:
|
||||
mock_choose.return_value = plugin_ep
|
||||
self.assertEqual("foo", self._call())
|
||||
mock_choose.assert_called_once_with(
|
||||
[plugin_ep, plugin_ep], self.question)
|
||||
|
||||
|
||||
class ConveniencePickPluginTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.client.display.ops.pick_*."""
|
||||
|
||||
def _test(self, fun, ifaces):
|
||||
config = mock.Mock()
|
||||
default = mock.Mock()
|
||||
plugins = mock.Mock()
|
||||
|
||||
with mock.patch("letsencrypt.client.display.ops.pick_plugin") as mock_p:
|
||||
mock_p.return_value = "foo"
|
||||
self.assertEqual("foo", fun(config, default, plugins, "Question?"))
|
||||
mock_p.assert_called_once_with(
|
||||
config, default, plugins, "Question?", ifaces)
|
||||
|
||||
def test_authenticator(self):
|
||||
from letsencrypt.client.display.ops import pick_authenticator
|
||||
self._test(pick_authenticator, (interfaces.IAuthenticator,))
|
||||
|
||||
def test_installer(self):
|
||||
from letsencrypt.client.display.ops import pick_installer
|
||||
self._test(pick_installer, (interfaces.IInstaller,))
|
||||
|
||||
def test_configurator(self):
|
||||
from letsencrypt.client.display.ops import pick_configurator
|
||||
self._test(pick_configurator, (
|
||||
interfaces.IAuthenticator, interfaces.IInstaller))
|
||||
|
||||
|
||||
class ChooseAccountTest(unittest.TestCase):
|
||||
"""Test choose_account."""
|
||||
def setUp(self):
|
||||
|
|
|
|||
Loading…
Reference in a new issue