diff --git a/app/main/views/tour.py b/app/main/views/tour.py index 98a8f5871..de4ec63a7 100644 --- a/app/main/views/tour.py +++ b/app/main/views/tour.py @@ -1,7 +1,15 @@ -from flask import abort, render_template +from flask import abort, redirect, render_template, session from app import current_service, current_user, url_for from app.main import main +from app.main.views.send import ( + all_placeholders_in_session, + fields_to_fill_in, + get_normalised_placeholders_from_session, + get_notification_check_endpoint, + get_placeholder_form_instance, + get_recipient_and_placeholders_from_session, +) from app.utils import get_template, user_has_permissions @@ -21,6 +29,8 @@ def begin_tour(service_id, template_id): template.values = {"phone_number": current_user.mobile_number} + session['placeholders'] = {} + return render_template( 'views/templates/start-tour.html', template=template, @@ -35,4 +45,61 @@ def begin_tour(service_id, template_id): ) @user_has_permissions('send_messages', restrict_admin_usage=True) def tour_step(service_id, template_id, step_index): - pass + db_template = current_service.get_template(template_id) + + if db_template['template_type'] != 'sms': + abort(404) + + template = get_template( + db_template, + current_service, + show_recipient=True, + ) + + placeholders = fields_to_fill_in(template, prefill_current_user=True) + try: + # user urls are 1 indexed, so start at step-1 + current_placeholder = placeholders[step_index - 1] + except IndexError: + if all_placeholders_in_session(placeholders): + return get_notification_check_endpoint(service_id, template) + return redirect(url_for( + '.tour_step', service_id=current_service.id, template_id=db_template['id'], step_index=1 + )) + + form = get_placeholder_form_instance( + current_placeholder, + dict_to_populate_from=get_normalised_placeholders_from_session(), + template_type=template.template_type, + allow_international_phone_numbers=current_service.has_permission('international_sms') + ) + + if form.validate_on_submit(): + session['placeholders'][current_placeholder] = form.placeholder_value.data + + if all_placeholders_in_session(placeholders): + return get_notification_check_endpoint(service_id, template) + return redirect(url_for( + '.tour_step', service_id=current_service.id, template_id=db_template['id'], step_index=step_index + 1 + )) + + back_link = _get_tour_step_back_link(service_id, template_id, step_index) + + template.values = get_recipient_and_placeholders_from_session(db_template['template_type']) + template.values[current_placeholder] = None + + return render_template( + 'views/send-test.html', + page_title="Example text message", + template=template, + form=form, + back_link=back_link, + help='2' + ) + + +def _get_tour_step_back_link(service_id, template_id, step_index): + if step_index == 1: + return url_for('.begin_tour', service_id=service_id, template_id=template_id) + + return url_for('.tour_step', service_id=service_id, template_id=template_id, step_index=step_index - 1) diff --git a/tests/app/main/views/test_tour.py b/tests/app/main/views/test_tour.py index 6a9decc81..18cea1813 100644 --- a/tests/app/main/views/test_tour.py +++ b/tests/app/main/views/test_tour.py @@ -44,6 +44,25 @@ def test_should_200_for_tour_start( ) +def test_should_clear_session_on_tour_start( + client_request, + mock_get_service_template_with_multiple_placeholders, + service_one, + fake_uuid, +): + with client_request.session_transaction() as session: + session['placeholders'] = {'one': 'hello', 'phone number': '07700 900762'} + + client_request.get( + 'main.begin_tour', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + ) + + with client_request.session_transaction() as session: + assert session['placeholders'] == {} + + @pytest.mark.parametrize('template_type', ['email', 'letter', 'broadcast']) def test_should_404_if_non_sms_template_for_tour_start( client_request, @@ -103,3 +122,339 @@ def test_should_403_if_user_does_not_have_send_permissions_for_tour_start( ['view_activity'], api_user_active, service_one) + + +def test_should_200_for_get_tour_step( + client_request, + mock_get_service_template_with_multiple_placeholders, + service_one, + fake_uuid, +): + with client_request.session_transaction() as session: + session['placeholders'] = {} + + page = client_request.get( + 'main.tour_step', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + step_index=1 + ) + + assert 'Example text message' in normalize_spaces(page.select_one('title').text) + assert normalize_spaces( + page.select('.banner-tour .heading-medium')[0].text + ) == ( + 'Try sending yourself this example' + ) + selected_hint = page.select('.banner-tour .govuk-grid-row')[1] + selected_hint_text = normalize_spaces(selected_hint.select(".govuk-body")[0].text) + assert "greyed-out-step" not in selected_hint["class"] + assert selected_hint_text == 'The template pulls in the data you provide' + + assert normalize_spaces( + page.select('.sms-message-recipient')[0].text + ) == ( + 'To: 07700 900762' + ) + + assert normalize_spaces( + page.select('.sms-message-wrapper')[0].text + ) == ( + 'service one: ((one)) ((two)) ((three))' + ) + + +def test_should_prefill_answers_for_get_tour_step( + client_request, + mock_get_service_template_with_multiple_placeholders, + service_one, + fake_uuid, +): + with client_request.session_transaction() as session: + session['placeholders'] = session['placeholders'] = {'one': 'hello', 'phone number': '07700 900762'} + + page = client_request.get( + 'main.tour_step', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + step_index=1 + ) + + page.select('.govuk-input')[0]['value'] == 'hello' + + +@pytest.mark.parametrize('template_type', ['email', 'letter', 'broadcast']) +@pytest.mark.parametrize('method', ['get', 'post']) +def test_should_404_if_non_sms_template_for_tour_step( + client_request, + fake_uuid, + mocker, + template_type, + method +): + mocker.patch( + 'app.service_api_client.get_service_template', + return_value={'data': create_template(template_type=template_type)} + ) + + getattr(client_request, method)( + 'main.tour_step', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + step_index=1, + _expected_status=404 + ) + + +@pytest.mark.parametrize('method', ['GET', 'POST']) +def test_should_403_if_user_does_not_have_send_permissions_for_tour_step( + mocker, + app_, + client, + api_user_active, + mock_get_service_template_with_multiple_placeholders, + service_one, + fake_uuid, + method +): + validate_route_permission( + mocker, + app_, + method, + 403, + url_for( + 'main.tour_step', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + step_index=1 + ), + ['view_activity'], + api_user_active, + service_one + ) + + +def test_back_link_from_first_get_tour_step_points_to_tour_start( + client_request, + mock_get_service_template_with_multiple_placeholders, + service_one, + fake_uuid, +): + with client_request.session_transaction() as session: + session['placeholders'] = {} + + page = client_request.get( + 'main.tour_step', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + step_index=1 + ) + + assert page.select('.govuk-back-link')[0]['href'] == url_for( + "main.begin_tour", + service_id=SERVICE_ONE_ID, + template_id=fake_uuid + ) + + +def test_back_link_from_get_tour_step_points_to_previous_step( + client_request, + mock_get_service_template_with_multiple_placeholders, + service_one, + fake_uuid, +): + with client_request.session_transaction() as session: + session['placeholders'] = {} + + page = client_request.get( + 'main.tour_step', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + step_index=2 + ) + + assert page.select('.govuk-back-link')[0]['href'] == url_for( + 'main.tour_step', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + step_index=1 + ) + + +def test_post_tour_step_saves_data_and_redirects_to_next_step( + client_request, + mock_get_service_template_with_multiple_placeholders, + service_one, + fake_uuid, +): + with client_request.session_transaction() as session: + session['placeholders'] = {} + + client_request.post( + 'main.tour_step', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + step_index=1, + _data={'placeholder_value': 'hello'}, + _expected_status=302, + _expected_redirect=url_for( + 'main.tour_step', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + step_index=2, + _external=True, + ), + ) + + with client_request.session_transaction() as session: + assert session['placeholders'] == {'one': 'hello', 'phone number': '07700 900762'} + + +def test_post_tour_step_adds_data_to_saved_data_and_redirects_to_next_step( + client_request, + mock_get_service_template_with_multiple_placeholders, + service_one, + fake_uuid, +): + with client_request.session_transaction() as session: + session['placeholders'] = {'one': 'hello', 'phone number': '07700 900762'} + + client_request.post( + 'main.tour_step', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + step_index=2, + _data={'placeholder_value': 'is it me you are looking for'}, + _expected_status=302, + _expected_redirect=url_for( + 'main.tour_step', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + step_index=3, + _external=True, + ), + ) + + with client_request.session_transaction() as session: + assert session['placeholders'] == { + 'one': 'hello', 'two': 'is it me you are looking for', 'phone number': '07700 900762' + } + + +def test_post_tour_step_raises_validation_error_for_form_error( + client_request, + mock_get_service_template_with_multiple_placeholders, + service_one, + fake_uuid, +): + with client_request.session_transaction() as session: + session['placeholders'] = {'one': 'hi', 'phone number': '07700 900762'} + + page = client_request.post( + 'main.tour_step', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + step_index=2, + _data={'placeholder_value': ''}, + _expected_status=200, # should this be 400 + ) + + assert normalize_spaces( + page.select('.govuk-error-message')[0].text + ) == ( + 'Error: Cannot be empty' + ) + + assert normalize_spaces( + page.select('.sms-message-recipient')[0].text + ) == ( + 'To: 07700 900762' + ) + + assert normalize_spaces( + page.select('.sms-message-wrapper')[0].text + ) == ( + 'service one: hi ((two)) ((three))' + ) + + with client_request.session_transaction() as session: + assert session['placeholders'] == {'one': 'hi', 'phone number': '07700 900762'} + + +def test_post_final_tour_step_saves_data_and_redirects_to_check_notification( + client_request, + mock_get_service_template_with_multiple_placeholders, + service_one, + fake_uuid, +): + with client_request.session_transaction() as session: + session['placeholders'] = {'one': 'hello', 'two': 'hi', 'phone number': '07700 900762'} + + client_request.post( + 'main.tour_step', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + step_index=3, + _data={'placeholder_value': 'howdy'}, + _expected_status=302, + _expected_redirect=url_for( + 'main.check_notification', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + help=None, + _external=True + ), # this location needs to change + ) + + with client_request.session_transaction() as session: + session['placeholders'] == {'one': 'hello', 'two': 'hi', 'three': 'howdy', 'phone number': '07700 900762'} + + +def test_get_test_step_out_of_index_redirects_to_first_step( + client_request, + mock_get_service_template_with_multiple_placeholders, + service_one, + fake_uuid, +): + with client_request.session_transaction() as session: + session['placeholders'] = {} + + client_request.get( + 'main.tour_step', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + step_index=4, + _expected_status=302, + _expected_redirect=url_for( + 'main.tour_step', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + step_index=1, + _external=True + ), + ) + + +def test_get_test_step_out_of_index_redirects_to_check_notification_if_all_placeholders_filled( + client_request, + mock_get_service_template_with_multiple_placeholders, + service_one, + fake_uuid, +): + with client_request.session_transaction() as session: + session['placeholders'] = {'one': 'hello', 'two': 'hi', 'three': 'howdy', 'phone number': '07700 900762'} + + client_request.get( + 'main.tour_step', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + step_index=4, + _expected_status=302, + _expected_redirect=url_for( + 'main.check_notification', + service_id=SERVICE_ONE_ID, + template_id=fake_uuid, + help=None, + _external=True + ), # this location needs to change + )