Merge lp:~frankban/juju-quickstart/remove-jenv into lp:juju-quickstart

Proposed by Francesco Banconi
Status: Merged
Merged at revision: 113
Proposed branch: lp:~frankban/juju-quickstart/remove-jenv
Merge into: lp:juju-quickstart
Diff against target: 422 lines (+200/-38)
8 files modified
quickstart/cli/params.py (+8/-1)
quickstart/cli/views.py (+30/-2)
quickstart/manage.py (+1/-0)
quickstart/models/jenv.py (+14/-0)
quickstart/tests/cli/test_params.py (+9/-2)
quickstart/tests/cli/test_views.py (+102/-33)
quickstart/tests/models/test_jenv.py (+35/-0)
quickstart/tests/test_manage.py (+1/-0)
To merge this branch: bzr merge lp:~frankban/juju-quickstart/remove-jenv
Reviewer Review Type Date Requested Status
Juju GUI Hackers Pending
Review via email: mp+246162@code.launchpad.net

Description of the change

Jenv files removal functionality.

Add the ability to remove jenv files
from the Juju home.

Test: `make check`.

QA:
- `juju bootstrap` an environment;
- create a new user for the environment:
  `juju user add myuser --generate -o ~/.juju/environments/myenv`;
- run quickstart in interactive mode:
  `.venv/bin/python juju-quickstart -i`;
- the "myenv" environment should be listed under
  "Other active environments": select it;
- ensure the corresponding environment description in
  the jenv detail view makes sense;
- click to remove the environment, cancel the removal in the
  confirm dialog and ensure the environment is still there;
- click the "remove" button again, confirm the deletion and
  ensure that a message is displayed and the environment
  file has been deleted. Also quickstart redirects to the
  environments index view and "myenv" is no longer there;
- destroy the environment: done, thank you!

https://codereview.appspot.com/189540043/

To post a comment you must log in.
Revision history for this message
Francesco Banconi (frankban) wrote :

Reviewers: mp+246162_code.launchpad.net,

Message:
Please take a look.

Description:
Jenv files removal functionality.

Add the ability to remove jenv files
from the Juju home.

Test: `make check`.

QA:
- `juju bootstrap` an environment;
- create a new user for the environment:
   `juju user add myuser --generate -o ~/.juju/environments/myenv`;
- run quickstart in interactive mode:
   `.venv/bin/python juju-quickstart -i`;
- the "myenv" environment should be listed under
   "Other active environments": select it;
- ensure the corresponding environment description in
   the jenv detail view makes sense;
- click to remove the environment, cancel the removal in the
   confirm dialog and ensure the environment is still there;
- click the "remove" button again, confirm the deletion and
   ensure that a message is displayed and the environment
   file has been deleted. Also quickstart redirects to the
   environments index view and "myenv" is no longer there;
- destroy the environment: done, thank you!

https://code.launchpad.net/~frankban/juju-quickstart/remove-jenv/+merge/246162

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/189540043/

Affected files (+200, -38 lines):
   A [revision details]
   M quickstart/cli/params.py
   M quickstart/cli/views.py
   M quickstart/manage.py
   M quickstart/models/jenv.py
   M quickstart/tests/cli/test_params.py
   M quickstart/tests/cli/test_views.py
   M quickstart/tests/models/test_jenv.py
   M quickstart/tests/test_manage.py

Revision history for this message
Martin Hilton (martin-hilton) wrote :

LGTM No QA yet, will do so shortly

https://codereview.appspot.com/189540043/diff/1/quickstart/cli/views.py
File quickstart/cli/views.py (right):

https://codereview.appspot.com/189540043/diff/1/quickstart/cli/views.py#newcode528
quickstart/cli/views.py:528: '\nFor this reason, it is not possible to
edit/change it.\n'
Isn't edit/change a tautology? Wouldn't "edit it." be enough.

https://codereview.appspot.com/189540043/

Revision history for this message
Brad Crittenden (bac) wrote :

The code LGTM but I question the need for the functionality in
quickstart. I don't feel strongly enough to abandon the work but I think
it only marginally improves the user experience at the expense of more
complication. Perhaps I'm missing a use-case that warrants the
function.

https://codereview.appspot.com/189540043/diff/1/quickstart/cli/params.py
File quickstart/cli/params.py (right):

https://codereview.appspot.com/189540043/diff/1/quickstart/cli/params.py#newcode37
quickstart/cli/params.py:37: )
Formatting is odd. I'd prefer one per line if you're doing multi-line.

https://codereview.appspot.com/189540043/

115. By Francesco Banconi

Fix typo and improve params formatting.

Revision history for this message
Francesco Banconi (frankban) wrote :

Please take a look.

https://codereview.appspot.com/189540043/diff/1/quickstart/cli/params.py
File quickstart/cli/params.py (right):

https://codereview.appspot.com/189540043/diff/1/quickstart/cli/params.py#newcode37
quickstart/cli/params.py:37: )
On 2015/01/12 15:29:32, bac wrote:
> Formatting is odd. I'd prefer one per line if you're doing
multi-line.

Done.

https://codereview.appspot.com/189540043/diff/1/quickstart/cli/views.py
File quickstart/cli/views.py (right):

https://codereview.appspot.com/189540043/diff/1/quickstart/cli/views.py#newcode528
quickstart/cli/views.py:528: '\nFor this reason, it is not possible to
edit/change it.\n'
On 2015/01/12 14:50:22, martin.hilton wrote:
> Isn't edit/change a tautology? Wouldn't "edit it." be enough.

Done.

https://codereview.appspot.com/189540043/

Revision history for this message
Martin Hilton (martin-hilton) wrote :

QA OK following instructions.

https://codereview.appspot.com/189540043/

Revision history for this message
Francesco Banconi (frankban) wrote :

*** Submitted:

Jenv files removal functionality.

Add the ability to remove jenv files
from the Juju home.

Test: `make check`.

QA:
- `juju bootstrap` an environment;
- create a new user for the environment:
   `juju user add myuser --generate -o ~/.juju/environments/myenv`;
- run quickstart in interactive mode:
   `.venv/bin/python juju-quickstart -i`;
- the "myenv" environment should be listed under
   "Other active environments": select it;
- ensure the corresponding environment description in
   the jenv detail view makes sense;
- click to remove the environment, cancel the removal in the
   confirm dialog and ensure the environment is still there;
- click the "remove" button again, confirm the deletion and
   ensure that a message is displayed and the environment
   file has been deleted. Also quickstart redirects to the
   environments index view and "myenv" is no longer there;
- destroy the environment: done, thank you!

R=martin.hilton, bac
CC=
https://codereview.appspot.com/189540043

https://codereview.appspot.com/189540043/

Revision history for this message
Francesco Banconi (frankban) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'quickstart/cli/params.py'
--- quickstart/cli/params.py 2015-01-07 15:17:49 +0000
+++ quickstart/cli/params.py 2015-01-12 15:39:31 +0000
@@ -30,7 +30,13 @@
30import copy30import copy
3131
3232
33_PARAMS = ('env_type_db', 'env_db', 'jenv_db', 'save_callable')33_PARAMS = (
34 'env_type_db',
35 'env_db',
36 'jenv_db',
37 'save_callable',
38 'remove_jenv_callable',
39)
3440
3541
36class Params(namedtuple('Params', _PARAMS)):42class Params(namedtuple('Params', _PARAMS)):
@@ -48,4 +54,5 @@
48 env_db=copy.deepcopy(self.env_db),54 env_db=copy.deepcopy(self.env_db),
49 jenv_db=copy.deepcopy(self.jenv_db),55 jenv_db=copy.deepcopy(self.jenv_db),
50 save_callable=self.save_callable,56 save_callable=self.save_callable,
57 remove_jenv_callable=self.remove_jenv_callable,
51 )58 )
5259
=== modified file 'quickstart/cli/views.py'
--- quickstart/cli/views.py 2015-01-08 14:53:06 +0000
+++ quickstart/cli/views.py 2015-01-12 15:39:31 +0000
@@ -525,16 +525,26 @@
525 urwid.Text([525 urwid.Text([
526 ('highlight', 'Imported active environment.\n'),526 ('highlight', 'Imported active environment.\n'),
527 'This environment is not included in your environments.yaml file.'527 'This environment is not included in your environments.yaml file.'
528 '\nFor this reason, it is not possible to edit or remove it.\n'528 '\nFor this reason, it is not possible to edit it.\n'
529 'However, you can use the link below to ',529 'However, you can use the link below to ',
530 ('highlight', 'use Juju Quickstart'),530 ('highlight', 'use Juju Quickstart'),
531 ' with this environment.',531 ' with this environment or ',
532 ('highlight', 'remove the corresponding jenv file'),
533 '.\n'
534 'Note that removing the Juju generated environment file does not '
535 'destroy the corresponding active environment.'
532 ]),536 ]),
533 ])537 ])
534538
539 remove_callback = ui.thunk(
540 _remove_jenv, params.jenv_db, env_data, params.remove_jenv_callable,
541 app.set_message, index_view)
542 confirm_removal_callback = ui.thunk(
543 _confirm_removal, app, env_data, remove_callback)
535 controls = [544 controls = [
536 ui.MenuButton('back', ui.thunk(index_view)),545 ui.MenuButton('back', ui.thunk(index_view)),
537 ui.MenuButton('use', ui.thunk(_use, params.env_db, env_data)),546 ui.MenuButton('use', ui.thunk(_use, params.env_db, env_data)),
547 ui.MenuButton(('control alert', 'remove'), confirm_removal_callback),
538 ]548 ]
539 widgets.append(ui.create_controls(*controls))549 widgets.append(ui.create_controls(*controls))
540 listbox = urwid.ListBox(urwid.SimpleFocusListWalker(widgets))550 listbox = urwid.ListBox(urwid.SimpleFocusListWalker(widgets))
@@ -542,6 +552,24 @@
542 app.set_status([' \N{RIGHTWARDS ARROW OVER LEFTWARDS ARROW} navigate '])552 app.set_status([' \N{RIGHTWARDS ARROW OVER LEFTWARDS ARROW} navigate '])
543553
544554
555def _remove_jenv(
556 jenv_db, env_data, remove_jenv_callable, set_message, redirect_view):
557 """Remove the jenv file corresonding to the env_data environment.
558
559 Update the provided jenv_db and return to the given view.
560 Also output a notification using the given set_message callable.
561 """
562 env_name = env_data['name']
563 # Remove the jenv file.
564 msg = remove_jenv_callable(env_name)
565 if msg is None:
566 msg = '{} successfully removed'.format(env_name)
567 # Also remove the environments from the jenv database.
568 del jenv_db['environments'][env_name]
569 set_message(msg)
570 redirect_view()
571
572
545def env_edit(app, params, env_data):573def env_edit(app, params, env_data):
546 """Create or modify a Juju environment.574 """Create or modify a Juju environment.
547575
548576
=== modified file 'quickstart/manage.py'
--- quickstart/manage.py 2015-01-07 14:07:22 +0000
+++ quickstart/manage.py 2015-01-12 15:39:31 +0000
@@ -218,6 +218,7 @@
218 env_db=env_db,218 env_db=env_db,
219 jenv_db=jenv_db,219 jenv_db=jenv_db,
220 save_callable=_create_save_callable(parser, env_file),220 save_callable=_create_save_callable(parser, env_file),
221 remove_jenv_callable=jenv.remove,
221 )222 )
222 new_env_db, env_data = views.show(views.env_index, parameters)223 new_env_db, env_data = views.show(views.env_index, parameters)
223 if new_env_db != env_db:224 if new_env_db != env_db:
224225
=== modified file 'quickstart/models/jenv.py'
--- quickstart/models/jenv.py 2014-12-17 12:28:36 +0000
+++ quickstart/models/jenv.py 2015-01-12 15:39:31 +0000
@@ -174,6 +174,20 @@
174 return db174 return db
175175
176176
177def remove(env_name):
178 """Remove the jenv file corresponding to the given environment name.
179
180 Return None if the removal was successful, an error message otherwise.
181 """
182 jenv_path = _get_jenv_path(env_name)
183 try:
184 os.remove(jenv_path)
185 except OSError as err:
186 msg = 'cannot remove the {} environment: {}'
187 return msg.format(env_name, bytes(err).decode('utf-8'))
188 return None
189
190
177def validate(data):191def validate(data):
178 """Validate the given YAML decoded jenv data.192 """Validate the given YAML decoded jenv data.
179193
180194
=== modified file 'quickstart/tests/cli/test_params.py'
--- quickstart/tests/cli/test_params.py 2015-01-07 14:07:22 +0000
+++ quickstart/tests/cli/test_params.py 2015-01-12 15:39:31 +0000
@@ -33,21 +33,24 @@
33 self.env_db = helpers.make_env_db()33 self.env_db = helpers.make_env_db()
34 self.jenv_db = helpers.make_jenv_db()34 self.jenv_db = helpers.make_jenv_db()
35 self.save_callable = lambda env_db: None35 self.save_callable = lambda env_db: None
36 self.remove_jenv_callable = lambda env_db: None
36 # Set up a params object used in tests.37 # Set up a params object used in tests.
37 self.params = params.Params(38 self.params = params.Params(
38 env_type_db=self.env_type_db,39 env_type_db=self.env_type_db,
39 env_db=self.env_db,40 env_db=self.env_db,
40 jenv_db=self.jenv_db,41 jenv_db=self.jenv_db,
41 save_callable=self.save_callable,42 save_callable=self.save_callable,
43 remove_jenv_callable=self.remove_jenv_callable,
42 )44 )
4345
44 def test_tuple(self):46 def test_tuple(self):
45 # The params object can be used as a tuple.47 # The params object can be used as a tuple.
46 env_type_db, env_db, jenv_db, save_callable = self.params48 env_type_db, env_db, jenv_db, save, remove = self.params
47 self.assertIs(self.env_type_db, env_type_db)49 self.assertIs(self.env_type_db, env_type_db)
48 self.assertIs(self.env_db, env_db)50 self.assertIs(self.env_db, env_db)
49 self.assertIs(self.jenv_db, jenv_db)51 self.assertIs(self.jenv_db, jenv_db)
50 self.assertIs(self.save_callable, save_callable)52 self.assertIs(self.save_callable, save)
53 self.assertIs(self.remove_jenv_callable, remove)
5154
52 def test_attributes(self):55 def test_attributes(self):
53 # Parameters can be accessed as attributes.56 # Parameters can be accessed as attributes.
@@ -55,6 +58,8 @@
55 self.assertIs(self.env_db, self.params.env_db)58 self.assertIs(self.env_db, self.params.env_db)
56 self.assertIs(self.jenv_db, self.params.jenv_db)59 self.assertIs(self.jenv_db, self.params.jenv_db)
57 self.assertIs(self.save_callable, self.params.save_callable)60 self.assertIs(self.save_callable, self.params.save_callable)
61 self.assertIs(
62 self.remove_jenv_callable, self.params.remove_jenv_callable)
5863
59 def test_immutable(self):64 def test_immutable(self):
60 # It is not possible to replace a stored parameter.65 # It is not possible to replace a stored parameter.
@@ -69,6 +74,8 @@
69 self.assertIs(self.env_db, self.params.env_db)74 self.assertIs(self.env_db, self.params.env_db)
70 self.assertIs(self.jenv_db, self.params.jenv_db)75 self.assertIs(self.jenv_db, self.params.jenv_db)
71 self.assertIs(self.save_callable, self.params.save_callable)76 self.assertIs(self.save_callable, self.params.save_callable)
77 self.assertIs(
78 self.remove_jenv_callable, self.params.remove_jenv_callable)
72 # The new params object stores the same data.79 # The new params object stores the same data.
73 self.assertEqual(self.params, params)80 self.assertEqual(self.params, params)
74 # But they do not refer to the same object.81 # But they do not refer to the same object.
7582
=== modified file 'quickstart/tests/cli/test_views.py'
--- quickstart/tests/cli/test_views.py 2015-01-07 15:36:57 +0000
+++ quickstart/tests/cli/test_views.py 2015-01-12 15:39:31 +0000
@@ -137,6 +137,7 @@
137 # Set up the base Urwid application.137 # Set up the base Urwid application.
138 self.loop, self.app = base.setup_urwid_app()138 self.loop, self.app = base.setup_urwid_app()
139 self.save_callable = mock.Mock()139 self.save_callable = mock.Mock()
140 self.remove_jenv_callable = mock.Mock(return_value=None)
140141
141 def get_widgets_in_contents(self, filter_function=None):142 def get_widgets_in_contents(self, filter_function=None):
142 """Return a list of widgets included in the app contents.143 """Return a list of widgets included in the app contents.
@@ -174,8 +175,45 @@
174 env_db=env_db,175 env_db=env_db,
175 jenv_db=jenv_db,176 jenv_db=jenv_db,
176 save_callable=self.save_callable,177 save_callable=self.save_callable,
178 remove_jenv_callable=self.remove_jenv_callable,
177 )179 )
178180
181 def click_remove_button(self, env_name):
182 """Click the remove button in an environment detail view.
183
184 Assume the view was already called.
185 Return the dialog button widgets and the original view contents.
186 """
187 original_contents = self.app.get_contents()
188 # The "remove" button is the last one.
189 remove_button = self.get_control_buttons()[-1]
190 cli_helpers.emit(remove_button)
191 # The original env detail contents have been replaced.
192 contents = self.app.get_contents()
193 self.assertIsNot(contents, original_contents)
194 # A "remove" confirmation dialog is displayed.
195 title_widget, message_widget, buttons = cli_helpers.inspect_dialog(
196 contents)
197 self.assertEqual(
198 'Remove the {} environment'.format(env_name), title_widget.text)
199 self.assertEqual('This action cannot be undone!', message_widget.text)
200 return buttons, original_contents
201
202 def cancel_removal(self, env_name):
203 """Cancel the environment deletion by clicking the "cancel" button."""
204 buttons, original_contents = self.click_remove_button(env_name)
205 # The "cancel" button is the first one in the dialog.
206 cancel_button = buttons[0]
207 cli_helpers.emit(cancel_button)
208 return original_contents
209
210 def confirm_removal(self, env_name):
211 """Confirm the environment deletion."""
212 buttons, _ = self.click_remove_button(env_name)
213 # The "confirm" button is the second one in the dialog.
214 confirm_button = buttons[1]
215 cli_helpers.emit(confirm_button)
216
179217
180class TestEnvIndex(EnvViewTestsMixin, unittest.TestCase):218class TestEnvIndex(EnvViewTestsMixin, unittest.TestCase):
181219
@@ -622,18 +660,7 @@
622 def test_remove_button(self):660 def test_remove_button(self):
623 # A confirmation dialog is displayed if the "remove" button is clicked.661 # A confirmation dialog is displayed if the "remove" button is clicked.
624 self.call_view(env_name='ec2-west')662 self.call_view(env_name='ec2-west')
625 original_contents = self.app.get_contents()663 buttons, _ = self.click_remove_button('ec2-west')
626 # The "remove" button is the last one.
627 remove_button = self.get_control_buttons()[-1]
628 cli_helpers.emit(remove_button)
629 # The original env detail contents have been replaced.
630 contents = self.app.get_contents()
631 self.assertIsNot(contents, original_contents)
632 # A "remove" confirmation dialog is displayed.
633 title_widget, message_widget, buttons = cli_helpers.inspect_dialog(
634 contents)
635 self.assertEqual('Remove the ec2-west environment', title_widget.text)
636 self.assertEqual('This action cannot be undone!', message_widget.text)
637 # The dialog includes the "cancel" and "confirm" buttons.664 # The dialog includes the "cancel" and "confirm" buttons.
638 self.assertEqual(2, len(buttons))665 self.assertEqual(2, len(buttons))
639 captions = map(cli_helpers.get_button_caption, buttons)666 captions = map(cli_helpers.get_button_caption, buttons)
@@ -642,15 +669,7 @@
642 def test_remove_cancelled(self):669 def test_remove_cancelled(self):
643 # The "remove" confirmation dialog can be safely dismissed.670 # The "remove" confirmation dialog can be safely dismissed.
644 self.call_view(env_name='ec2-west')671 self.call_view(env_name='ec2-west')
645 original_contents = self.app.get_contents()672 original_contents = self.cancel_removal('ec2-west')
646 # The "remove" button is the last one.
647 remove_button = self.get_control_buttons()[-1]
648 cli_helpers.emit(remove_button)
649 contents = self.app.get_contents()
650 buttons = cli_helpers.inspect_dialog(contents)[2]
651 # The "cancel" button is the first one in the dialog.
652 cancel_button = buttons[0]
653 cli_helpers.emit(cancel_button)
654 # The original contents have been restored.673 # The original contents have been restored.
655 self.assertIs(original_contents, self.app.get_contents())674 self.assertIs(original_contents, self.app.get_contents())
656675
@@ -659,20 +678,17 @@
659 # The current environment is removed if the "remove" button is clicked678 # The current environment is removed if the "remove" button is clicked
660 # and then the deletion is confirmed. Subsequently the application679 # and then the deletion is confirmed. Subsequently the application
661 # switches to the index view.680 # switches to the index view.
662 self.call_view(env_name='ec2-west')681 env_name = 'ec2-west'
663 # The "remove" button is the last one.682 self.call_view(env_name=env_name)
664 remove_button = self.get_control_buttons()[-1]683 self.confirm_removal(env_name)
665 cli_helpers.emit(remove_button)684 # A message notifies the environment has been removed.
666 contents = self.app.get_contents()685 self.assertEqual(
667 buttons = cli_helpers.inspect_dialog(contents)[2]686 '{} successfully removed'.format(env_name), self.app.get_message())
668 # The "confirm" button is the second one in the dialog.
669 confirm_button = buttons[1]
670 cli_helpers.emit(confirm_button)
671 # The index view has been called passing the modified env_db in params.687 # The index view has been called passing the modified env_db in params.
672 self.assertTrue(mock_env_index.called)688 self.assertTrue(mock_env_index.called)
673 params = mock_env_index.call_args[0][1]689 params = mock_env_index.call_args[0][1]
674 # The new env_db no longer includes the "ec2-west" environment.690 # The new env_db no longer includes the "ec2-west" environment.
675 self.assertNotIn('ec2-west', params.env_db['environments'])691 self.assertNotIn(env_name, params.env_db['environments'])
676 # The new env_db has been saved.692 # The new env_db has been saved.
677 self.save_callable.assert_called_once_with(params.env_db)693 self.save_callable.assert_called_once_with(params.env_db)
678694
@@ -732,11 +748,11 @@
732 self.assertEqual(expected_text, widget.text)748 self.assertEqual(expected_text, widget.text)
733749
734 def test_view_buttons(self):750 def test_view_buttons(self):
735 # The "back" and "use" buttons are displayed.751 # The "back", "use" and "remove" buttons are displayed.
736 self.call_view(env_name='ec2-west')752 self.call_view(env_name='ec2-west')
737 buttons = self.get_control_buttons()753 buttons = self.get_control_buttons()
738 captions = map(cli_helpers.get_button_caption, buttons)754 captions = map(cli_helpers.get_button_caption, buttons)
739 self.assertEqual(['back', 'use'], captions)755 self.assertEqual(['back', 'use', 'remove'], captions)
740756
741 @mock.patch('quickstart.cli.views.env_index')757 @mock.patch('quickstart.cli.views.env_index')
742 def test_back_button(self, mock_env_index):758 def test_back_button(self, mock_env_index):
@@ -759,6 +775,59 @@
759 self.assertEqual(775 self.assertEqual(
760 expected_return_value, context_manager.exception.return_value)776 expected_return_value, context_manager.exception.return_value)
761777
778 def test_remove_button(self):
779 # A confirmation dialog is displayed if the "remove" button is clicked.
780 self.call_view(env_name='test-jenv')
781 buttons, _ = self.click_remove_button('test-jenv')
782 # The dialog includes the "cancel" and "confirm" buttons.
783 self.assertEqual(2, len(buttons))
784 captions = map(cli_helpers.get_button_caption, buttons)
785 self.assertEqual(['cancel', 'confirm'], captions)
786
787 def test_remove_cancelled(self):
788 # The "remove" confirmation dialog can be safely dismissed.
789 self.call_view(env_name='test-jenv')
790 original_contents = self.cancel_removal('test-jenv')
791 # The original contents have been restored.
792 self.assertIs(original_contents, self.app.get_contents())
793
794 @mock.patch('quickstart.cli.views.env_index')
795 def test_remove_confirmed(self, mock_env_index):
796 # The jenv file is removed if the "remove" button is clicked and then
797 # then the deletion is confirmed. Subsequently the application switches
798 # to the index view.
799 env_name = 'test-jenv'
800 self.call_view(env_name=env_name)
801 self.confirm_removal(env_name)
802 # A message notifies the environment has been removed.
803 self.assertEqual(
804 '{} successfully removed'.format(env_name), self.app.get_message())
805 # The index view has been called passing the modified jenv_db params.
806 self.assertTrue(mock_env_index.called)
807 params = mock_env_index.call_args[0][1]
808 # The new jenv_db no longer includes the "test-jenv" environment.
809 self.assertNotIn(env_name, params.jenv_db['environments'])
810 # The corresponding jenv file has been removed.
811 self.remove_jenv_callable.assert_called_once_with(env_name)
812 self.assertEqual(
813 'test-jenv successfully removed', self.app.get_message())
814
815 @mock.patch('quickstart.cli.views.env_index')
816 def test_remove_confirmed_error(self, mock_env_index):
817 # Errors occurred while trying to remove the jenv files are notified.
818 env_name = 'test-jenv'
819 self.call_view(env_name=env_name)
820 # Simulate an error removing the jenv file.
821 self.remove_jenv_callable.return_value = 'bad wolf'
822 self.confirm_removal(env_name)
823 # The error is notified.
824 self.assertEqual('bad wolf'.format(env_name), self.app.get_message())
825 # The index view has been called passing the original jenv_db params.
826 self.assertTrue(mock_env_index.called)
827 params = mock_env_index.call_args[0][1]
828 # The jenv_db still includes the "test_jenv" environment.
829 self.assertIn(env_name, params.jenv_db['environments'])
830
762831
763class TestEnvEdit(EnvViewTestsMixin, unittest.TestCase):832class TestEnvEdit(EnvViewTestsMixin, unittest.TestCase):
764833
765834
=== modified file 'quickstart/tests/models/test_jenv.py'
--- quickstart/tests/models/test_jenv.py 2014-12-17 11:34:06 +0000
+++ quickstart/tests/models/test_jenv.py 2015-01-12 15:39:31 +0000
@@ -272,6 +272,41 @@
272 self.assertEqual({'environments': {}}, jenv_db)272 self.assertEqual({'environments': {}}, jenv_db)
273273
274274
275class TestRemove(helpers.JenvFileTestsMixin, unittest.TestCase):
276
277 @classmethod
278 def setUpClass(cls):
279 # Prepare the jenv file contents.
280 cls.contents = yaml.safe_dump(cls.jenv_data)
281
282 def test_successful_removal(self):
283 # The jenv file is correctly removed.
284 with self.make_jenv('local', self.contents) as path:
285 error = jenv.remove('local')
286 self.assertIsNone(error)
287 self.assertFalse(os.path.exists(path))
288
289 def test_error_directory(self):
290 # An error message is returned if the jenv path points to a directory.
291 with self.make_jenv('local', self.contents) as path:
292 dirname = os.path.dirname(path)
293 os.mkdir(os.path.join(dirname, 'ec2.jenv'))
294 error = jenv.remove('ec2')
295 expected_error = (
296 'cannot remove the ec2 environment: '
297 '[Errno 21] Is a directory: ')
298 self.assertIn(expected_error, error)
299
300 def test_error_not_found(self):
301 # An error is returned if the environment cannot be found.
302 with self.make_jenv('local', self.contents):
303 error = jenv.remove('hp')
304 expected_error = (
305 'cannot remove the hp environment: '
306 '[Errno 2] No such file or directory: ')
307 self.assertIn(expected_error, error)
308
309
275class TestValidate(310class TestValidate(
276 helpers.JenvFileTestsMixin, helpers.ValueErrorTestsMixin,311 helpers.JenvFileTestsMixin, helpers.ValueErrorTestsMixin,
277 unittest.TestCase):312 unittest.TestCase):
278313
=== modified file 'quickstart/tests/test_manage.py'
--- quickstart/tests/test_manage.py 2015-01-07 14:07:22 +0000
+++ quickstart/tests/test_manage.py 2015-01-12 15:39:31 +0000
@@ -399,6 +399,7 @@
399 env_db=env_db,399 env_db=env_db,
400 jenv_db=jenv_db,400 jenv_db=jenv_db,
401 save_callable=mock_save_callable(),401 save_callable=mock_save_callable(),
402 remove_jenv_callable=jenv.remove,
402 )403 )
403 mock_show.assert_called_once_with(views.env_index, expected_params)404 mock_show.assert_called_once_with(views.env_index, expected_params)
404405

Subscribers

People subscribed via source and target branches