Post to the API when moving folders and templates

This commit adds logic to:
- take the list of selected folders and templates
- split it into two lists (of folders and templates)
- `POST` that data to the API, to effect the movement of said folders
  and templates

I’ve tried to architect it in such a way that we can easily add more
template ‘operations’ in the future, as we add more forms to the choose
template page.
This commit is contained in:
Chris Hill-Scott
2018-11-08 14:46:18 +00:00
parent 980d66bdaa
commit cdb5b47c4d
10 changed files with 322 additions and 25 deletions

View File

@@ -1,3 +1,4 @@
import uuid
from datetime import datetime
from unittest.mock import ANY, Mock
@@ -16,6 +17,10 @@ from tests import (
template_json,
validate_route_permission,
)
from tests.app.main.views.test_template_folders import (
CHILD_FOLDER_ID,
PARENT_FOLDER_ID,
)
from tests.conftest import (
SERVICE_ONE_ID,
SERVICE_TWO_ID,
@@ -23,6 +28,7 @@ from tests.conftest import (
active_caseworking_user,
active_user_view_permissions,
active_user_with_permissions,
fake_uuid,
mock_get_service_email_template,
mock_get_service_letter_template,
mock_get_service_template,
@@ -108,12 +114,12 @@ def test_should_show_page_for_choosing_a_template(
user,
expected_page_title,
):
mocker.patch('app.user_api_client.get_user', return_value=user(fake_uuid))
service_one['permissions'].append('letter')
client_request.login(user(fake_uuid))
page = client_request.get(
'main.choose_template',
service_id=SERVICE_ONE_ID,
service_id=service_one['id'],
**extra_args
)
@@ -169,8 +175,8 @@ def test_should_show_checkboxes_for_selecting_templates(
user,
extra_service_permissions,
):
mocker.patch('app.user_api_client.get_user', return_value=user(fake_uuid))
service_one['permissions'] = service_one['permissions'] + extra_service_permissions
service_one['permissions'] += extra_service_permissions
client_request.login(user(fake_uuid))
page = client_request.get(
'main.choose_template',
@@ -188,6 +194,179 @@ def test_should_show_checkboxes_for_selecting_templates(
assert TEMPLATE_ONE_ID not in checkboxes[index]['id']
@pytest.mark.parametrize('user', [
pytest.param(
active_user_with_permissions
),
pytest.param(
active_user_view_permissions,
marks=pytest.mark.xfail(raises=AssertionError)
),
pytest.param(
active_caseworking_user,
marks=pytest.mark.xfail(raises=AssertionError)
),
])
@pytest.mark.parametrize('extra_service_permissions', [
pytest.param(
['edit_folders']
),
pytest.param(
[],
marks=pytest.mark.xfail(raises=AssertionError)
),
])
@pytest.mark.parametrize('folder_id, expected_destinations', [
(None, []),
(fake_uuid(), []),
])
def test_should_show_radio_buttons_for_move_destination(
client_request,
mocker,
service_one,
mock_get_service_templates,
mock_get_template_folders,
mock_has_no_jobs,
fake_uuid,
user,
extra_service_permissions,
folder_id,
expected_destinations,
):
service_one['permissions'] += extra_service_permissions
client_request.login(user(fake_uuid))
FOLDER_TWO_ID = str(uuid.uuid4())
FOLDER_ONE_TWO_ID = str(uuid.uuid4())
mock_get_template_folders.return_value = [
{'id': PARENT_FOLDER_ID, 'name': 'folder_one', 'parent_id': None},
{'id': FOLDER_TWO_ID, 'name': 'folder_two', 'parent_id': None},
{'id': CHILD_FOLDER_ID, 'name': 'folder_one_one', 'parent_id': PARENT_FOLDER_ID},
{'id': FOLDER_ONE_TWO_ID, 'name': 'folder_one_two', 'parent_id': PARENT_FOLDER_ID},
]
page = client_request.get(
'main.choose_template',
service_id=SERVICE_ONE_ID,
)
radios = page.select('input[type=radio]')
labels = page.select('label[for^=move_to]')
assert radios == page.select('input[name=move_to]')
assert [x['value'] for x in radios] == [
PARENT_FOLDER_ID, FOLDER_TWO_ID, CHILD_FOLDER_ID, FOLDER_ONE_TWO_ID
]
assert [x.text.strip() for x in labels] == [
'folder_one', 'folder_two', 'folder_one_one', 'folder_one_two'
]
assert page.select_one('button[name=operation]')['value'] == 'move'
@pytest.mark.parametrize('user', [
pytest.param(
active_user_with_permissions
),
pytest.param(
active_user_view_permissions,
marks=pytest.mark.xfail(raises=AssertionError)
),
pytest.param(
active_caseworking_user,
marks=pytest.mark.xfail(raises=AssertionError)
),
])
@pytest.mark.parametrize('extra_service_permissions', [
pytest.param(
['edit_folders']
),
pytest.param(
[],
marks=pytest.mark.xfail(raises=AssertionError)
),
])
@pytest.mark.parametrize('folder_id, expected_destinations', [
(None, []),
(fake_uuid(), []),
])
def test_should_post_move_to_api(
client_request,
service_one,
fake_uuid,
mock_get_service_templates,
mock_get_template_folders,
mock_move_to_template_folder,
user,
extra_service_permissions,
folder_id,
expected_destinations,
):
service_one['permissions'] += extra_service_permissions
client_request.login(user(fake_uuid))
FOLDER_TWO_ID = str(uuid.uuid4())
mock_get_template_folders.return_value = [
{'id': PARENT_FOLDER_ID, 'name': 'folder_one', 'parent_id': None},
{'id': FOLDER_TWO_ID, 'name': 'folder_two', 'parent_id': None},
]
client_request.post(
'main.choose_template',
service_id=SERVICE_ONE_ID,
_data={
'operation': 'move',
'move_to': PARENT_FOLDER_ID,
'templates_and_folders': [
FOLDER_TWO_ID,
TEMPLATE_ONE_ID,
],
},
_expected_status=302,
_expected_redirect=url_for(
'main.choose_template',
service_id=SERVICE_ONE_ID,
_external=True,
),
)
mock_move_to_template_folder.assert_called_once_with(
service_id=SERVICE_ONE_ID,
folder_id=PARENT_FOLDER_ID,
folder_ids={FOLDER_TWO_ID},
template_ids={TEMPLATE_ONE_ID},
)
@pytest.mark.parametrize('thing_to_move', [
PARENT_FOLDER_ID, # Cant move a folder inside itself
CHILD_FOLDER_ID, # Cant move a folder which doesnt belong to the service
])
def test_should_validate_illegal_moves(
client_request,
service_one,
fake_uuid,
mock_get_service_templates,
mock_get_template_folders,
mock_move_to_template_folder,
thing_to_move,
):
service_one['permissions'] += 'edit_folders'
FOLDER_TWO_ID = str(uuid.uuid4())
mock_get_template_folders.return_value = [
{'id': PARENT_FOLDER_ID, 'name': 'folder_one', 'parent_id': None},
{'id': FOLDER_TWO_ID, 'name': 'folder_two', 'parent_id': None},
]
client_request.post(
'main.choose_template',
service_id=SERVICE_ONE_ID,
_data={
'operation': 'move',
'move_to': PARENT_FOLDER_ID,
'templates_and_folders': [
thing_to_move,
],
},
_expected_status=200,
_expected_redirect=None,
)
assert mock_move_to_template_folder.called is False
def test_should_not_show_template_nav_if_only_one_type_of_template(
client_request,
mock_get_template_folders,

View File

@@ -1,6 +1,8 @@
import uuid
from unittest.mock import call
import pytest
from orderedset import OrderedSet
from app.notify_client.template_folder_api_client import TemplateFolderAPIClient
@@ -44,3 +46,60 @@ def test_get_template_folders_calls_correct_api_endpoint(mocker, api_user_active
mock_redis_get.assert_called_once_with(redis_key)
mock_api_get.assert_called_once_with(expected_url)
mock_redis_set.assert_called_once_with(redis_key, '{"a": "b"}', ex=604800)
def test_move_templates_and_folders(mocker, api_user_active):
mock_redis_delete = mocker.patch('app.notify_client.RedisClient.delete')
mock_api_post = mocker.patch('app.notify_client.NotifyAdminAPIClient.post')
some_service_id = uuid.uuid4()
some_folder_id = uuid.uuid4()
TemplateFolderAPIClient().move_to_folder(
some_service_id,
some_folder_id,
template_ids=OrderedSet(('a', 'b', 'c')),
folder_ids=OrderedSet(('1', '2', '3')),
)
mock_api_post.assert_called_once_with(
'/service/{}/template-folder/move-to-folder/{}'.format(
some_service_id, some_folder_id
),
{
'folders': ['1', '2', '3'],
'templates': ['a', 'b', 'c'],
},
)
assert mock_redis_delete.call_args_list == [
call('service-{}-template-folders'.format(some_service_id)),
call('service-{}-templates'.format(some_service_id)),
call(
'template-a-version-None',
'template-b-version-None',
'template-c-version-None',
),
]
def test_move_templates_and_folders_to_root(mocker, api_user_active):
mock_api_post = mocker.patch('app.notify_client.NotifyAdminAPIClient.post')
some_service_id = uuid.uuid4()
TemplateFolderAPIClient().move_to_folder(
some_service_id,
None,
template_ids=OrderedSet(('a', 'b', 'c')),
folder_ids=OrderedSet(('1', '2', '3')),
)
mock_api_post.assert_called_once_with(
'/service/{}/template-folder/move-to-folder'.format(some_service_id),
{
'folders': ['1', '2', '3'],
'templates': ['a', 'b', 'c'],
},
)