Files
notifications-admin/tests/app/main/views/test_tour.py
Alex Janousek 6f5750f095 Removed all govuk css (#2814)
* Removed all govuk css

* Updated reference files

* Removing govuk js

* Fixed casing for modules, removed unused page

* Got more reference images

* Updated template page

* Removed govuk padding util

* Updated hint to uswds hint

* More govuk cleanup

* Commiting backstopjs ref files

* Fixed all unit tests that broke due to brittleness around govuk styling

* Added new ref images

* Final removal of govuk

* Officially removed all govuk references

* Updated reference file

* Updated link to button

* UI modernization

* Cleanup

* removed govuk escaping tests since they are no longer needed

* Fix CodeQL security issue in escapeElementName function

- Escape backslashes first before other special characters
- Prevents potential double-escaping vulnerability
- Addresses CodeQL alert about improper string escaping

* Found more govuk removal. Fixed unit tests

* Add missing pipeline check to pre-commit

* updated test

* Updated e2e test

* More update to e2e test

* Fixed another e2e test

* Simple PR comments addressed

* More updates

* Updated backstop ref files

* Refactored folder selection for non-admins

* Updated redundant line

* Updated tests to include correct mocks

* Added more ref files

* Addressing carlos comments

* Addressing Carlo comments, cleanup of window initing

* More cleanup and addressing carlo comments

* Fixing a11 scan

* Fixed a few issues with javascript

* Fixed for pr

* Fixing e2e tests

* Tweaking e2e test

* Added more ref files and cleaned up urls.js

* Fixed bug with creating new template

* Removed brittle test - addressed code ql comment

* e2e race condition fix

* More e2e test fixes

* Updated e2e tests to not wait for text sent

* Updated test to not wait for button click response

* Made tear down more resilent if staging is down

* reverted e2e test to what was working before main merge

* Updated backstopRef images

* Updated gulp to include job-polling differently
2025-10-06 09:38:54 -04:00

661 lines
18 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import pytest
from flask import url_for
from app import current_user
from app.enums import ServicePermission
from tests import validate_route_permission
from tests.conftest import SERVICE_ONE_ID, create_template, normalize_spaces
def test_should_200_for_tour_start(
client_request,
mock_get_service_template_with_multiple_placeholders,
service_one,
fake_uuid,
):
page = client_request.get(
"main.begin_tour",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
)
page_content = normalize_spaces(str(page))
assert ("Try sending yourself this example") in page_content
assert "Every message is sent from a template" in page_content
assert normalize_spaces(page.select(".sms-message-recipient")[0].text) == (
"To: 202-867-5303"
)
assert normalize_spaces(page.select(".sms-message-wrapper")[0].text) == (
"service one: ((one)) ((two)) ((three))"
)
# Find the tour step button specifically, not just any usa-button
tour_buttons = [
btn for btn in page.select("a.usa-button") if "tour" in btn.get("href", "")
]
assert len(tour_buttons) > 0, "No tour button found"
assert tour_buttons[0]["href"] == url_for(
".tour_step", service_id=SERVICE_ONE_ID, template_id=fake_uuid, step_index=1
)
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": "202-867-5303"}
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"])
def test_should_404_if_non_sms_template_for_tour_start(
client_request,
fake_uuid,
mocker,
template_type,
):
mocker.patch(
"app.service_api_client.get_service_template",
return_value={"data": create_template(template_type=template_type)},
)
client_request.get(
"main.begin_tour",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
_expected_status=404,
)
def test_should_404_if_no_mobile_number_for_tour_start(
client_request,
mock_get_service_template_with_multiple_placeholders,
service_one,
fake_uuid,
active_user_with_permissions_no_mobile,
):
client_request.login(active_user_with_permissions_no_mobile)
assert current_user.mobile_number is None
client_request.get(
"main.begin_tour",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
_expected_status=404,
)
def test_should_403_if_user_does_not_have_send_permissions_for_tour_start(
mocker,
notify_admin,
client_request,
api_user_active,
mock_get_service_template_with_multiple_placeholders,
service_one,
fake_uuid,
):
validate_route_permission(
mocker,
notify_admin,
"GET",
403,
url_for(
"main.begin_tour",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
),
[ServicePermission.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)
page_content = normalize_spaces(str(page))
assert ("Try sending yourself this example") in page_content
assert "The template pulls in the data you provide" in page_content
assert normalize_spaces(page.select(".sms-message-recipient")[0].text) == (
"To: 202-867-5303"
)
assert normalize_spaces(page.select(".sms-message-wrapper")[0].text) == (
"service one: ((one)) ((two)) ((three))"
)
def test_should_show_empty_text_box(
client_request,
mock_get_service_template_with_multiple_placeholders,
service_one,
fake_uuid,
):
with client_request.session_transaction() as session:
session["placeholders"] = {"phone number": "202-867-5303"}
page = client_request.get(
"main.tour_step", service_id=SERVICE_ONE_ID, template_id=fake_uuid, step_index=1
)
textbox = page.select_one(".usa-input")
assert "value" not in textbox
assert textbox["name"] == "placeholder_value"
assert textbox["class"] == [
"form-control",
"usa-input",
]
# data-module=autofocus is set on a containing element so it
# shouldnt also be set on the textbox itself
assert "data-module" not in textbox
assert normalize_spaces(page.select_one("label").text) == "one"
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": "202-867-5303",
}
page = client_request.get(
"main.tour_step", service_id=SERVICE_ONE_ID, template_id=fake_uuid, step_index=1
)
assert page.select(".usa-input")[0]["value"] == "hello"
@pytest.mark.parametrize("template_type", ["email"])
@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,
)
def test_should_404_for_get_tour_step_0(
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=0,
_expected_status=404,
)
@pytest.mark.parametrize("method", ["GET", "POST"])
def test_should_403_if_user_does_not_have_send_permissions_for_tour_step(
mocker,
notify_admin,
client_request,
api_user_active,
mock_get_service_template_with_multiple_placeholders,
service_one,
fake_uuid,
method,
):
validate_route_permission(
mocker,
notify_admin,
method,
403,
url_for(
"main.tour_step",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
step_index=1,
),
[ServicePermission.VIEW_ACTIVITY],
api_user_active,
service_one,
)
def test_tour_step_redirects_to_tour_start_if_placeholders_doesnt_exist_in_session(
client_request,
mock_get_service_template_with_multiple_placeholders,
service_one,
fake_uuid,
):
with client_request.session_transaction() as session:
assert "placeholders" not in session
client_request.get(
"main.tour_step",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
step_index=1,
_expected_status=302,
_expected_redirect=url_for(
"main.begin_tour",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
),
)
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("nav.usa-breadcrumb a")[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("nav.usa-breadcrumb a")[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,
),
)
with client_request.session_transaction() as session:
assert session["placeholders"] == {
"one": "hello",
"phone number": "202-867-5303",
}
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": "202-867-5303"}
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,
),
)
with client_request.session_transaction() as session:
assert session["placeholders"] == {
"one": "hello",
"two": "is it me you are looking for",
"phone number": "202-867-5303",
}
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": "202-867-5303"}
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(".usa-error-message")[0].text) == (
"Error: Cannot be empty"
)
assert normalize_spaces(page.select(".sms-message-recipient")[0].text) == (
"To: 202-867-5303"
)
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": "202-867-5303"}
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": "202-867-5303",
}
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_tour_notification",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
),
)
with client_request.session_transaction() as session:
assert session["placeholders"] == {
"one": "hello",
"two": "hi",
"three": "howdy",
"phone number": "202-867-5303",
}
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,
),
)
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": "202-867-5303",
}
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_tour_notification",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
),
)
def test_should_200_for_check_tour_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",
"three": "howdy",
"phone number": "202-867-5303",
}
page = client_request.get(
"main.check_tour_notification",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
)
page_content = normalize_spaces(str(page))
assert "Try sending yourself this example" in page_content
assert "Notify delivers the message" in page_content
assert normalize_spaces(page.select(".sms-message-recipient")[0].text) == (
"To: 202-867-5303"
)
assert normalize_spaces(page.select(".sms-message-wrapper")[0].text) == (
"service one: hello hi howdy"
)
# post to send_notification keeps help argument
assert page.form.attrs["action"] == url_for(
"main.send_notification",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
help=3,
)
def test_back_link_from_check_tour_notification_points_to_last_tour_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",
"two": "hi",
"three": "howdy",
"phone number": "202-867-5303",
}
page = client_request.get(
"main.check_tour_notification",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
)
assert page.select("nav.usa-breadcrumb a")[0]["href"] == url_for(
"main.tour_step", service_id=SERVICE_ONE_ID, template_id=fake_uuid, step_index=3
)
def test_check_tour_notification_redirects_to_tour_start_if_placeholders_doesnt_exist_in_session(
client_request,
mock_get_service_template_with_multiple_placeholders,
service_one,
fake_uuid,
):
with client_request.session_transaction() as session:
assert "placeholders" not in session
client_request.get(
"main.check_tour_notification",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
step_index=1,
_expected_status=302,
_expected_redirect=url_for(
"main.begin_tour",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
),
)
def test_check_tour_notification_redirects_to_first_step_if_not_all_placeholders_in_session(
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": "202-867-5303",
}
client_request.get(
"main.check_tour_notification",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
_expected_status=302,
_expected_redirect=url_for(
"main.tour_step",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
step_index=1,
),
)
def test_shows_link_to_end_tour(
client_request,
mock_get_notification,
fake_uuid,
):
page = client_request.get(
"main.view_notification",
service_id=SERVICE_ONE_ID,
notification_id=fake_uuid,
help=3,
)
assert page.select(".banner-tour a")[0]["href"] == url_for(
"main.go_to_dashboard_after_tour",
service_id=SERVICE_ONE_ID,
example_template_id="5407f4db-51c7-4150-8758-35412d42186a",
)
def test_go_to_dashboard_after_tour_link(
client_request,
mocker,
api_user_active,
mock_login,
mock_get_service,
mock_has_permissions,
mock_delete_service_template,
fake_uuid,
):
client_request.get(
"main.go_to_dashboard_after_tour",
service_id=fake_uuid,
example_template_id=fake_uuid,
_expected_redirect=url_for(
"main.service_dashboard",
service_id=fake_uuid,
),
)
mock_delete_service_template.assert_called_once_with(fake_uuid, fake_uuid)