Skip to content

Commit 9d214c5

Browse files
committed
Added missing unit tests for WizardHandler
1 parent 1c5f4fe commit 9d214c5

File tree

2 files changed

+70
-11
lines changed

2 files changed

+70
-11
lines changed

awsshell/app.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@
2626
from awsshell.toolbar import Toolbar
2727
from awsshell.utils import build_config_file_path, temporary_file
2828
from awsshell import compat
29-
from awsshell.interaction import InteractionException
30-
from awsshell.wizard import WizardLoader, WizardException
31-
from botocore.exceptions import ClientError
29+
from awsshell.wizard import WizardLoader
3230

3331

3432
LOG = logging.getLogger(__name__)
@@ -155,10 +153,11 @@ def run(self, command, application):
155153

156154

157155
class WizardHandler(object):
158-
def __init__(self, output=sys.stdout, err=sys.stderr):
156+
def __init__(self, output=sys.stdout, err=sys.stderr,
157+
loader=WizardLoader()):
159158
self._output = output
160159
self._err = err
161-
self._wizard_loader = WizardLoader()
160+
self._wizard_loader = loader
162161

163162
def run(self, command, application):
164163
"""Run the specified wizard.
@@ -173,14 +172,12 @@ def run(self, command, application):
173172
try:
174173
wizard = self._wizard_loader.load_wizard(command[1])
175174
wizard.execute()
176-
177-
except (ClientError) as err:
178-
self._err.write("{0}\n".format(err))
179-
except (WizardException, InteractionException) as err:
180-
self._err.write("An error occurred: {0}\n".format(err))
181-
# EOF or Ctrl-C in a wizard drop back to shell
175+
# EOF or Ctrl-C in a wizard drop back to shell silently
182176
except (KeyboardInterrupt, EOFError):
183177
pass
178+
# For any other exception, print it and return to shell
179+
except Exception as err:
180+
self._err.write("{0}\n".format(err))
184181

185182

186183
class DotCommandHandler(object):

tests/unit/test_app.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
from awsshell import shellcomplete
77
from awsshell import compat
88

9+
from awsshell.utils import FileReadError
10+
from awsshell.wizard import WizardException
11+
from awsshell.interaction import InteractionException
12+
from botocore.exceptions import ClientError, BotoCoreError
13+
914

1015
@pytest.fixture
1116
def errstream():
@@ -14,6 +19,7 @@ def errstream():
1419

1520
def test_can_dispatch_dot_commands():
1621
call_args = []
22+
1723
class CustomHandler(object):
1824
def run(self, command, context):
1925
call_args.append((command, context))
@@ -183,3 +189,59 @@ def test_exit_dot_command_exits_shell():
183189
# see the .quit command, we immediately exit and stop prompting
184190
# for more shell commands.
185191
assert mock_prompter.run.call_count == 1
192+
193+
194+
def test_wizard_can_load_and_execute():
195+
# Proper dot command syntax should load and run a wizard
196+
mock_loader = mock.Mock()
197+
mock_wizard = mock_loader.load_wizard.return_value
198+
handler = app.WizardHandler(err=errstream, loader=mock_loader)
199+
handler.run(['.wizard', 'wizname'], None)
200+
201+
assert mock_wizard.execute.call_count == 1
202+
assert mock_loader.load_wizard.call_count == 1
203+
mock_loader.load_wizard.assert_called_with('wizname')
204+
205+
206+
def test_wizard_syntax_error_prints_err_msg(errstream):
207+
# Invalid wizard syntax should print error and not load a wizard
208+
mock_loader = mock.Mock()
209+
handler = app.WizardHandler(err=errstream, loader=mock_loader)
210+
handler.run(['.wizard'], None)
211+
assert 'Invalid syntax' in errstream.getvalue()
212+
assert not mock_loader.load_wizard.called
213+
214+
215+
@pytest.mark.parametrize('err', [EOFError(), KeyboardInterrupt()])
216+
def test_wizard_handles_eof_interrupt(err, errstream):
217+
# EOF and Keyboard should silently drop back to the shell
218+
mock_loader = mock.Mock()
219+
mock_loader.load_wizard.side_effect = err
220+
handler = app.WizardHandler(err=errstream, loader=mock_loader)
221+
try:
222+
handler.run(['.wizard', 'name'], None)
223+
except:
224+
pytest.fail('No exception should have been thrown')
225+
assert errstream.getvalue() == ''
226+
227+
228+
exceptions = [
229+
BotoCoreError(),
230+
FileReadError('error'),
231+
WizardException('error'),
232+
InteractionException('error'),
233+
ClientError({'Error': {}}, 'Operation')
234+
]
235+
236+
237+
@pytest.mark.parametrize('err', exceptions)
238+
def test_wizard_handles_exceptions(err, errstream):
239+
# Test that exceptions are caught and an error message is displayed
240+
mock_loader = mock.Mock()
241+
mock_loader.load_wizard.side_effect = err
242+
handler = app.WizardHandler(err=errstream, loader=mock_loader)
243+
try:
244+
handler.run(['.wizard', 'name'], None)
245+
except:
246+
pytest.fail('No exception should have been thrown')
247+
assert 'error' in errstream.getvalue()

0 commit comments

Comments
 (0)