Merge, and adjusting a test

This commit is contained in:
Jonathan Bobel
2024-01-02 14:06:11 -05:00
127 changed files with 796 additions and 8247 deletions
@@ -928,10 +928,8 @@ def test_organization_settings_for_platform_admin(
"Label Value Action",
"Name Test organization Change organization name",
"Sector Federal government Change sector for the organization",
"Request to go live notes None Change go live notes for the organization",
"Billing details None Change billing details for the organization",
"Notes None Change the notes for the organization",
"Default email branding GOV.UK Change default email branding for the organization",
"Known email domains None Change known email domains for the organization",
]
@@ -1347,48 +1345,6 @@ def test_update_organization_with_non_unique_name(
)
def test_get_edit_organization_go_live_notes_page(
client_request,
platform_admin_user,
mock_get_organization,
organization_one,
):
client_request.login(platform_admin_user)
page = client_request.get(
".edit_organization_go_live_notes",
org_id=organization_one["id"],
)
assert page.find("textarea", id="request_to_go_live_notes")
@pytest.mark.parametrize(
("input_note", "saved_note"),
[("Needs permission", "Needs permission"), (" ", None)],
)
def test_post_edit_organization_go_live_notes_updates_go_live_notes(
client_request,
platform_admin_user,
mock_get_organization,
mock_update_organization,
organization_one,
input_note,
saved_note,
):
client_request.login(platform_admin_user)
client_request.post(
".edit_organization_go_live_notes",
org_id=organization_one["id"],
_data={"request_to_go_live_notes": input_note},
_expected_redirect=url_for(
".organization_settings",
org_id=organization_one["id"],
),
)
mock_update_organization.assert_called_once_with(
organization_one["id"], request_to_go_live_notes=saved_note
)
def test_organization_settings_links_to_edit_organization_notes_page(
mocker,
mock_get_organization,
@@ -1,519 +0,0 @@
from unittest.mock import ANY, PropertyMock
import pytest
from flask import url_for
from notifications_utils.clients.zendesk.zendesk_client import NotifySupportTicket
from tests import sample_uuid
from tests.conftest import ORGANISATION_ID, SERVICE_ONE_ID, normalize_spaces
@pytest.mark.parametrize(
("organization_type", "expected_options"),
[
(
"other",
[
("something_else", "Something else"),
],
),
],
)
def test_email_branding_request_page_when_no_branding_is_set(
service_one,
client_request,
mocker,
mock_get_email_branding,
organization_type,
expected_options,
):
service_one["email_branding"] = None
service_one["organization_type"] = organization_type
mocker.patch(
"app.models.service.Service.email_branding_id",
new_callable=PropertyMock,
return_value=None,
)
page = client_request.get(".email_branding_request", service_id=SERVICE_ONE_ID)
assert mock_get_email_branding.called is False
assert page.find_all("iframe")[1]["src"] == url_for(
"main.email_template", branding_style="__NONE__"
)
button_text = normalize_spaces(page.select_one(".page-footer button").text)
assert [
(
radio["value"],
page.select_one("label[for={}]".format(radio["id"])).text.strip(),
)
for radio in page.select("input[type=radio]")
] == expected_options
assert button_text == "Continue"
def test_email_branding_request_page_shows_branding_if_set(
mocker,
service_one,
client_request,
mock_get_email_branding,
mock_get_service_organization,
):
mocker.patch(
"app.models.service.Service.email_branding_id",
new_callable=PropertyMock,
return_value="some-random-branding",
)
page = client_request.get(".email_branding_request", service_id=SERVICE_ONE_ID)
assert page.find_all("iframe")[1]["src"] == url_for(
"main.email_template", branding_style="some-random-branding"
)
def test_email_branding_request_page_back_link(
client_request,
):
page = client_request.get(".email_branding_request", service_id=SERVICE_ONE_ID)
back_link = page.select_one("a.usa-back-link")
assert len(back_link) > 0, "No back link found on the page"
assert back_link["href"] == url_for(".service_settings", service_id=SERVICE_ONE_ID)
@pytest.mark.parametrize(
("data", "org_type", "endpoint"),
[
(
{
"options": "govuk",
},
"federal",
"main.email_branding_govuk",
),
(
{
"options": "govuk_and_org",
},
"federal",
"main.email_branding_govuk_and_org",
),
(
{
"options": "something_else",
},
"federal",
"main.email_branding_something_else",
),
],
)
def test_email_branding_request_submit(
client_request,
service_one,
mocker,
mock_get_email_branding,
organization_one,
data,
org_type,
endpoint,
):
organization_one["organization_type"] = org_type
service_one["email_branding"] = sample_uuid()
service_one["organization"] = organization_one
mocker.patch(
"app.organizations_client.get_organization",
return_value=organization_one,
)
client_request.post(
".email_branding_request",
service_id=SERVICE_ONE_ID,
_data=data,
_expected_status=302,
_expected_redirect=url_for(
endpoint,
service_id=SERVICE_ONE_ID,
),
)
def test_email_branding_request_submit_when_no_radio_button_is_selected(
client_request,
service_one,
mock_get_email_branding,
):
service_one["email_branding"] = sample_uuid()
page = client_request.post(
".email_branding_request",
service_id=SERVICE_ONE_ID,
_data={"options": ""},
_follow_redirects=True,
)
assert page.h1.text == "Change email branding"
assert (
normalize_spaces(page.select_one(".error-message").text) == "Select an option"
)
@pytest.mark.parametrize(
("endpoint", "expected_heading"),
[
("main.email_branding_govuk_and_org", "Before you request new branding"),
],
)
def test_email_branding_description_pages_for_org_branding(
client_request,
mocker,
service_one,
organization_one,
mock_get_email_branding,
endpoint,
expected_heading,
):
service_one["email_branding"] = sample_uuid()
service_one["organization"] = organization_one
mocker.patch(
"app.organizations_client.get_organization",
return_value=organization_one,
)
page = client_request.get(
endpoint,
service_id=SERVICE_ONE_ID,
)
assert page.h1.text == expected_heading
assert (
normalize_spaces(page.select_one(".page-footer button").text)
== "Request new branding"
)
@pytest.mark.parametrize(
("endpoint", "service_org_type", "branding_preview_id"),
[("main.email_branding_govuk", "central", "__NONE__")],
)
@pytest.mark.skip(reason="Update for TTS")
def test_email_branding_govuk_and_nhs_pages(
client_request,
mocker,
service_one,
organization_one,
mock_get_email_branding,
endpoint,
service_org_type,
branding_preview_id,
):
organization_one["organization_type"] = service_org_type
service_one["email_branding"] = sample_uuid()
service_one["organization"] = organization_one
mocker.patch(
"app.organizations_client.get_organization",
return_value=organization_one,
)
page = client_request.get(
endpoint,
service_id=SERVICE_ONE_ID,
)
assert page.h1.text == "Check your new branding"
assert "Emails from service one will look like this" in normalize_spaces(page.text)
assert page.find("iframe")["src"] == url_for(
"main.email_template", branding_style=branding_preview_id
)
assert (
normalize_spaces(page.select_one(".page-footer button").text)
== "Use this branding"
)
@pytest.mark.skip(reason="Update for TTS")
def test_email_branding_something_else_page(client_request, service_one):
# expect to have a "NHS" option as well as the
# fallback, so back button goes to choices page
service_one["organization_type"] = "nhs_central"
page = client_request.get(
"main.email_branding_something_else",
service_id=SERVICE_ONE_ID,
)
assert normalize_spaces(page.h1.text) == "Describe the branding you want"
assert page.select_one("textarea")["name"] == ("something_else")
assert (
normalize_spaces(page.select_one(".page-footer button").text)
== "Request new branding"
)
assert page.select_one(".usa-back-link")["href"] == url_for(
"main.email_branding_request",
service_id=SERVICE_ONE_ID,
)
def test_get_email_branding_something_else_page_is_only_option(
client_request, service_one
):
# should only have a "something else" option
# so back button goes back to settings page
service_one["organization_type"] = "other"
page = client_request.get(
"main.email_branding_something_else",
service_id=SERVICE_ONE_ID,
)
assert page.select_one(".usa-back-link")["href"] == url_for(
"main.service_settings",
service_id=SERVICE_ONE_ID,
)
@pytest.mark.parametrize(
"endpoint",
[
("main.email_branding_govuk"),
("main.email_branding_govuk_and_org"),
("main.email_branding_organization"),
],
)
def test_email_branding_pages_give_404_if_selected_branding_not_allowed(
client_request,
endpoint,
):
# The only email branding allowed is 'something_else', so trying to visit any of the other
# endpoints gives a 404 status code.
client_request.get(endpoint, service_id=SERVICE_ONE_ID, _expected_status=404)
def test_email_branding_govuk_submit(
mocker,
client_request,
service_one,
organization_one,
no_reply_to_email_addresses,
mock_get_email_branding,
single_sms_sender,
mock_update_service,
):
mocker.patch(
"app.organizations_client.get_organization",
return_value=organization_one,
)
mocker.patch(
"app.models.service.Service.organization_id",
new_callable=PropertyMock,
return_value=ORGANISATION_ID,
)
service_one["email_branding"] = sample_uuid()
page = client_request.post(
".email_branding_govuk",
service_id=SERVICE_ONE_ID,
_follow_redirects=True,
)
mock_update_service.assert_called_once_with(
SERVICE_ONE_ID,
email_branding=None,
)
assert page.h1.text == "Settings"
assert (
normalize_spaces(page.select_one(".banner-default").text)
== "Youve updated your email branding"
)
@pytest.mark.skip(reason="Update for TTS")
def test_email_branding_govuk_and_org_submit(
mocker,
client_request,
service_one,
organization_one,
no_reply_to_email_addresses,
mock_get_email_branding,
single_sms_sender,
):
mocker.patch(
"app.organizations_client.get_organization",
return_value=organization_one,
)
mocker.patch(
"app.models.service.Service.organization_id",
new_callable=PropertyMock,
return_value=ORGANISATION_ID,
)
service_one["email_branding"] = sample_uuid()
mock_create_ticket = mocker.spy(NotifySupportTicket, "__init__")
mock_send_ticket_to_zendesk = mocker.patch(
"app.main.views.service_settings.zendesk_client.send_ticket_to_zendesk",
autospec=True,
)
page = client_request.post(
".email_branding_govuk_and_org",
service_id=SERVICE_ONE_ID,
_follow_redirects=True,
)
mock_create_ticket.assert_called_once_with(
ANY,
message="\n".join(
[
"Organization: organization one",
"Service: service one",
"http://localhost/services/596364a0-858e-42c8-9062-a8fe822260eb",
"",
"---",
"Current branding: Organization name",
"Branding requested: GOV.UK and organization one\n",
]
),
subject="Email branding request - service one",
ticket_type="question",
user_name="Test User",
user_email="test@user.gsa.gov",
org_id=ORGANISATION_ID,
org_type="central",
service_id=SERVICE_ONE_ID,
)
mock_send_ticket_to_zendesk.assert_called_once()
assert normalize_spaces(page.select_one(".banner-default").text) == (
"Thanks for your branding request. Well get back to you "
"within one working day."
)
@pytest.mark.skip(reason="Update for TTS")
def test_email_branding_organization_submit(
mocker,
client_request,
service_one,
organization_one,
no_reply_to_email_addresses,
mock_get_email_branding,
single_sms_sender,
):
mocker.patch(
"app.organizations_client.get_organization",
return_value=organization_one,
)
mocker.patch(
"app.models.service.Service.organization_id",
new_callable=PropertyMock,
return_value=ORGANISATION_ID,
)
service_one["email_branding"] = sample_uuid()
mock_create_ticket = mocker.spy(NotifySupportTicket, "__init__")
mock_send_ticket_to_zendesk = mocker.patch(
"app.main.views.service_settings.zendesk_client.send_ticket_to_zendesk",
autospec=True,
)
page = client_request.post(
".email_branding_organization",
service_id=SERVICE_ONE_ID,
_follow_redirects=True,
)
mock_create_ticket.assert_called_once_with(
ANY,
message="\n".join(
[
"Organization: organization one",
"Service: service one",
"http://localhost/services/596364a0-858e-42c8-9062-a8fe822260eb",
"",
"---",
"Current branding: Organization name",
"Branding requested: organization one\n",
]
),
subject="Email branding request - service one",
ticket_type="question",
user_name="Test User",
user_email="test@user.gsa.gov",
org_id=ORGANISATION_ID,
org_type="central",
service_id=SERVICE_ONE_ID,
)
mock_send_ticket_to_zendesk.assert_called_once()
assert normalize_spaces(page.select_one(".banner-default").text) == (
"Thanks for your branding request. Well get back to you "
"within one working day."
)
def test_email_branding_something_else_submit(
client_request,
mocker,
service_one,
no_reply_to_email_addresses,
mock_get_email_branding,
single_sms_sender,
):
service_one["email_branding"] = sample_uuid()
service_one["organization_type"] = "nhs_local"
mock_create_ticket = mocker.spy(NotifySupportTicket, "__init__")
mock_send_ticket_to_zendesk = mocker.patch(
"app.main.views.service_settings.zendesk_client.send_ticket_to_zendesk",
autospec=True,
)
page = client_request.post(
".email_branding_something_else",
service_id=SERVICE_ONE_ID,
_data={"something_else": "Homer Simpson"},
_follow_redirects=True,
)
mock_create_ticket.assert_called_once_with(
ANY,
message="\n".join(
[
"Organization: Cant tell (domain is user.gsa.gov)",
"Service: service one",
"http://localhost/services/596364a0-858e-42c8-9062-a8fe822260eb",
"",
"---",
"Current branding: Organization name",
"Branding requested: Something else\n",
"Homer Simpson\n",
]
),
subject="Email branding request - service one",
ticket_type="question",
user_name="Test User",
user_email="test@user.gsa.gov",
org_id=None,
org_type="nhs_local",
service_id=SERVICE_ONE_ID,
)
mock_send_ticket_to_zendesk.assert_called_once()
assert normalize_spaces(page.select_one(".banner-default").text) == (
"Thanks for your branding request. Well get back to you "
"within one working day."
)
def test_email_branding_something_else_submit_shows_error_if_textbox_is_empty(
client_request,
):
page = client_request.post(
".email_branding_something_else",
service_id=SERVICE_ONE_ID,
_data={"something_else": ""},
_follow_redirects=True,
)
assert normalize_spaces(page.h1.text) == "Describe the branding you want"
assert (
normalize_spaces(page.select_one(".usa-error-message").text)
== "Error: Cannot be empty"
)
File diff suppressed because it is too large Load Diff
-3
View File
@@ -97,7 +97,6 @@ def test_should_add_service_and_redirect_to_tour_when_no_services(
mock_create_service_template,
mock_get_services_with_no_services,
api_user_active,
mock_get_all_email_branding,
inherited,
email_address,
posted,
@@ -153,7 +152,6 @@ def test_add_service_has_to_choose_org_type(
mock_create_service_template,
mock_get_services_with_no_services,
api_user_active,
mock_get_all_email_branding,
platform_admin_user,
):
client_request.login(platform_admin_user)
@@ -227,7 +225,6 @@ def test_should_add_service_and_redirect_to_dashboard_when_existing_service(
api_user_active,
organization_type,
free_allowance,
mock_get_all_email_branding,
platform_admin_user,
):
client_request.login(platform_admin_user)
-451
View File
@@ -1,451 +0,0 @@
from io import BytesIO
from unittest.mock import call
import pytest
from flask import url_for
from notifications_python_client.errors import HTTPError
from app.s3_client.s3_logo_client import EMAIL_LOGO_LOCATION_STRUCTURE, TEMP_TAG
from tests.conftest import create_email_branding, normalize_spaces
def test_email_branding_page_shows_full_branding_list(
client_request, platform_admin_user, mock_get_all_email_branding
):
client_request.login(platform_admin_user)
page = client_request.get(".email_branding")
links = page.select(".message-name a")
brand_names = [normalize_spaces(link.text) for link in links]
hrefs = [link["href"] for link in links]
assert normalize_spaces(page.select_one("h1").text) == "Email branding"
assert page.select(".grid-col-9 a")[-1]["href"] == url_for(
"main.create_email_branding"
)
assert brand_names == [
"org 1",
"org 2",
"org 3",
"org 4",
"org 5",
]
assert hrefs == [
url_for(".update_email_branding", branding_id=1),
url_for(".update_email_branding", branding_id=2),
url_for(".update_email_branding", branding_id=3),
url_for(".update_email_branding", branding_id=4),
url_for(".update_email_branding", branding_id=5),
]
def test_edit_email_branding_shows_the_correct_branding_info(
client_request, platform_admin_user, mock_get_email_branding, fake_uuid
):
client_request.login(platform_admin_user)
page = client_request.get(
".update_email_branding",
branding_id=fake_uuid,
_test_page_title=False, # TODO: Fix page titles
)
assert page.select_one("#logo-img > img")["src"].endswith("/example.png")
assert page.select_one("#name").attrs.get("value") == "Organization name"
assert page.select_one("#file").attrs.get("accept") == ".png"
assert page.select_one("#text").attrs.get("value") == "Organization text"
assert page.select_one("#colour").attrs.get("value") == "#f00"
def test_create_email_branding_does_not_show_any_branding_info(
client_request, platform_admin_user, mock_no_email_branding
):
client_request.login(platform_admin_user)
page = client_request.get(
".create_email_branding",
_test_page_title=False, # TODO: Fix page titles
)
assert page.select_one("#logo-img > img") is None
assert page.select_one("#name").attrs.get("value") is None
assert page.select_one("#file").attrs.get("accept") == ".png"
assert page.select_one("#text").attrs.get("value") is None
assert page.select_one("#colour").attrs.get("value") is None
def test_create_new_email_branding_without_logo(
client_request,
platform_admin_user,
mocker,
fake_uuid,
mock_create_email_branding,
):
data = {
"logo": None,
"colour": "#ff0000",
"text": "new text",
"name": "new name",
"brand_type": "org",
}
mock_persist = mocker.patch("app.main.views.email_branding.persist_logo")
mocker.patch("app.main.views.email_branding.delete_email_temp_files_created_by")
client_request.login(platform_admin_user)
client_request.post(
".create_email_branding",
_content_type="multipart/form-data",
_data=data,
)
assert mock_create_email_branding.called
assert mock_create_email_branding.call_args == call(
logo=data["logo"],
name=data["name"],
text=data["text"],
colour=data["colour"],
brand_type=data["brand_type"],
)
assert mock_persist.call_args_list == []
def test_create_email_branding_requires_a_name_when_submitting_logo_details(
client_request,
mocker,
mock_create_email_branding,
platform_admin_user,
):
mocker.patch("app.main.views.email_branding.persist_logo")
mocker.patch("app.main.views.email_branding.delete_email_temp_files_created_by")
data = {
"operation": "email-branding-details",
"logo": "",
"colour": "#ff0000",
"text": "new text",
"name": "",
"brand_type": "org",
}
client_request.login(platform_admin_user)
page = client_request.post(
".create_email_branding",
_content_type="multipart/form-data",
_data=data,
_expected_status=200,
)
assert (
page.select_one(".usa-error-message").text.strip()
== "Error: This field is required"
)
assert mock_create_email_branding.called is False
def test_create_email_branding_does_not_require_a_name_when_uploading_a_file(
client_request,
mocker,
platform_admin_user,
):
mocker.patch(
"app.main.views.email_branding.upload_email_logo", return_value="temp_filename"
)
data = {
"file": (BytesIO("".encode("utf-8")), "test.png"),
"colour": "",
"text": "",
"name": "",
"brand_type": "org",
}
client_request.login(platform_admin_user)
page = client_request.post(
".create_email_branding",
_content_type="multipart/form-data",
_data=data,
_follow_redirects=True,
)
assert not page.find(".error-message")
def test_create_new_email_branding_when_branding_saved(
client_request, platform_admin_user, mocker, mock_create_email_branding, fake_uuid
):
with client_request.session_transaction() as session:
user_id = session["user_id"]
data = {
"logo": "test.png",
"colour": "#ff0000",
"text": "new text",
"name": "new name",
"brand_type": "org_banner",
}
temp_filename = EMAIL_LOGO_LOCATION_STRUCTURE.format(
temp=TEMP_TAG.format(user_id=user_id),
unique_id=fake_uuid,
filename=data["logo"],
)
mocker.patch("app.main.views.email_branding.persist_logo")
mocker.patch("app.main.views.email_branding.delete_email_temp_files_created_by")
client_request.login(platform_admin_user)
client_request.post(
".create_email_branding",
logo=temp_filename,
_content_type="multipart/form-data",
_data={
"colour": data["colour"],
"name": data["name"],
"text": data["text"],
"cdn_url": "https://static-logos.cdn.com",
"brand_type": data["brand_type"],
},
)
updated_logo_name = "{}-{}".format(fake_uuid, data["logo"])
assert mock_create_email_branding.called
assert mock_create_email_branding.call_args == call(
logo=updated_logo_name,
name=data["name"],
text=data["text"],
colour=data["colour"],
brand_type=data["brand_type"],
)
@pytest.mark.parametrize(
("endpoint", "has_data"),
[
("main.create_email_branding", False),
("main.update_email_branding", True),
],
)
def test_deletes_previous_temp_logo_after_uploading_logo(
client_request, platform_admin_user, mocker, endpoint, has_data, fake_uuid
):
if has_data:
mocker.patch(
"app.email_branding_client.get_email_branding",
return_value=create_email_branding(fake_uuid),
)
with client_request.session_transaction() as session:
user_id = session["user_id"]
temp_old_filename = EMAIL_LOGO_LOCATION_STRUCTURE.format(
temp=TEMP_TAG.format(user_id=user_id),
unique_id=fake_uuid,
filename="old_test.png",
)
temp_filename = EMAIL_LOGO_LOCATION_STRUCTURE.format(
temp=TEMP_TAG.format(user_id=user_id), unique_id=fake_uuid, filename="test.png"
)
mocked_upload_email_logo = mocker.patch(
"app.main.views.email_branding.upload_email_logo", return_value=temp_filename
)
mocked_delete_email_temp_file = mocker.patch(
"app.main.views.email_branding.delete_email_temp_file"
)
client_request.login(platform_admin_user)
client_request.post(
"main.create_email_branding",
logo=temp_old_filename,
branding_id=fake_uuid,
_data={"file": (BytesIO("".encode("utf-8")), "test.png")},
_content_type="multipart/form-data",
)
assert mocked_upload_email_logo.called
assert mocked_delete_email_temp_file.called
assert mocked_delete_email_temp_file.call_args == call(temp_old_filename)
def test_update_existing_branding(
client_request,
platform_admin_user,
mocker,
fake_uuid,
mock_get_email_branding,
mock_update_email_branding,
):
with client_request.session_transaction() as session:
user_id = session["user_id"]
data = {
"logo": "test.png",
"colour": "#0000ff",
"text": "new text",
"name": "new name",
"brand_type": "both",
}
temp_filename = EMAIL_LOGO_LOCATION_STRUCTURE.format(
temp=TEMP_TAG.format(user_id=user_id),
unique_id=fake_uuid,
filename=data["logo"],
)
mocker.patch("app.main.views.email_branding.persist_logo")
mocker.patch("app.main.views.email_branding.delete_email_temp_files_created_by")
client_request.login(platform_admin_user)
client_request.post(
".update_email_branding",
logo=temp_filename,
branding_id=fake_uuid,
_content_type="multipart/form-data",
_data={
"colour": data["colour"],
"name": data["name"],
"text": data["text"],
"cdn_url": "https://static-logos.cdn.com",
"brand_type": data["brand_type"],
},
)
updated_logo_name = "{}-{}".format(fake_uuid, data["logo"])
assert mock_update_email_branding.called
assert mock_update_email_branding.call_args == call(
branding_id=fake_uuid,
logo=updated_logo_name,
name=data["name"],
text=data["text"],
colour=data["colour"],
brand_type=data["brand_type"],
)
def test_temp_logo_is_shown_after_uploading_logo(
client_request,
platform_admin_user,
mocker,
fake_uuid,
):
with client_request.session_transaction() as session:
user_id = session["user_id"]
temp_filename = EMAIL_LOGO_LOCATION_STRUCTURE.format(
temp=TEMP_TAG.format(user_id=user_id), unique_id=fake_uuid, filename="test.png"
)
mocker.patch(
"app.main.views.email_branding.upload_email_logo", return_value=temp_filename
)
mocker.patch("app.main.views.email_branding.delete_email_temp_file")
client_request.login(platform_admin_user)
page = client_request.post(
"main.create_email_branding",
_data={"file": (BytesIO("".encode("utf-8")), "test.png")},
_content_type="multipart/form-data",
_follow_redirects=True,
)
assert page.select_one("#logo-img > img").attrs["src"].endswith(temp_filename)
def test_logo_persisted_when_organization_saved(
client_request, platform_admin_user, mock_create_email_branding, mocker, fake_uuid
):
with client_request.session_transaction() as session:
user_id = session["user_id"]
temp_filename = EMAIL_LOGO_LOCATION_STRUCTURE.format(
temp=TEMP_TAG.format(user_id=user_id), unique_id=fake_uuid, filename="test.png"
)
mocked_upload_email_logo = mocker.patch(
"app.main.views.email_branding.upload_email_logo"
)
mocked_persist_logo = mocker.patch("app.main.views.email_branding.persist_logo")
mocked_delete_email_temp_files_by = mocker.patch(
"app.main.views.email_branding.delete_email_temp_files_created_by"
)
client_request.login(platform_admin_user)
client_request.post(
".create_email_branding",
logo=temp_filename,
_content_type="multipart/form-data",
)
assert not mocked_upload_email_logo.called
assert mocked_persist_logo.called
assert mocked_delete_email_temp_files_by.called
assert mocked_delete_email_temp_files_by.call_args == call(user_id)
assert mock_create_email_branding.called
def test_logo_does_not_get_persisted_if_updating_email_branding_client_throws_an_error(
client_request, platform_admin_user, mock_create_email_branding, mocker, fake_uuid
):
with client_request.session_transaction() as session:
user_id = session["user_id"]
temp_filename = EMAIL_LOGO_LOCATION_STRUCTURE.format(
temp=TEMP_TAG.format(user_id=user_id), unique_id=fake_uuid, filename="test.png"
)
mocked_persist_logo = mocker.patch("app.main.views.email_branding.persist_logo")
mocked_delete_email_temp_files_by = mocker.patch(
"app.main.views.email_branding.delete_email_temp_files_created_by"
)
mocker.patch(
"app.main.views.email_branding.email_branding_client.create_email_branding",
side_effect=HTTPError(),
)
client_request.login(platform_admin_user)
client_request.post(
".create_email_branding",
logo=temp_filename,
_content_type="multipart/form-data",
_expected_status=500,
)
assert not mocked_persist_logo.called
assert not mocked_delete_email_temp_files_by.called
@pytest.mark.parametrize(
("colour_hex", "expected_status_code"),
[
("#FF00FF", 302),
("hello", 200),
("", 302),
],
)
def test_colour_regex_validation(
client_request,
platform_admin_user,
mocker,
fake_uuid,
colour_hex,
expected_status_code,
mock_create_email_branding,
):
data = {
"logo": None,
"colour": colour_hex,
"text": "new text",
"name": "new name",
"brand_type": "org",
}
mocker.patch("app.main.views.email_branding.delete_email_temp_files_created_by")
client_request.login(platform_admin_user)
client_request.post(
".create_email_branding",
_content_type="multipart/form-data",
_data=data,
_expected_status=expected_status_code,
)
@@ -1,95 +0,0 @@
import re
import pytest
@pytest.mark.parametrize(
("query_args", "result"), [({}, True), ({"govuk_banner": "false"}, "false")]
)
def test_renders(client_request, mocker, query_args, result):
mocker.patch(
"app.main.views.index.HTMLEmailTemplate.__str__", return_value="rendered"
)
response = client_request.get_response("main.email_template", **query_args)
assert response.get_data(as_text=True) == "rendered"
def test_displays_both_branding(
client_request, mock_get_email_branding_with_both_brand_type
):
page = client_request.get(
"main.email_template", branding_style="1", _test_page_title=False
)
mock_get_email_branding_with_both_brand_type.assert_called_once_with("1")
assert page.find("img", attrs={"src": re.compile("example.png$")})
assert (
page.select(
"body > table:nth-of-type(3) table > tr:nth-of-type(1) > td:nth-of-type(2)"
)[0]
.get_text()
.strip()
== "Organization text"
) # brand text is set
def test_displays_org_branding(client_request, mock_get_email_branding):
# mock_get_email_branding has 'brand_type' of 'org'
page = client_request.get(
"main.email_template", branding_style="1", _test_page_title=False
)
mock_get_email_branding.assert_called_once_with("1")
assert not page.find("a", attrs={"href": "https://www.gsa.gov"})
assert page.find("img", attrs={"src": re.compile("example.png")})
assert not page.select(
"body > table > tr > td[bgcolor='#f00']"
) # banner colour is not set
assert (
page.select(
"body > table:nth-of-type(1) > tr:nth-of-type(1) > td:nth-of-type(2)"
)[0]
.get_text()
.strip()
== "Organization text"
) # brand text is set
def test_displays_org_branding_with_banner(
client_request, mock_get_email_branding_with_org_banner_brand_type
):
page = client_request.get(
"main.email_template", branding_style="1", _test_page_title=False
)
mock_get_email_branding_with_org_banner_brand_type.assert_called_once_with("1")
assert not page.find("a", attrs={"href": "https://www.gsa.gov"})
assert page.find("img", attrs={"src": re.compile("example.png")})
assert page.select("body > table > tr > td[bgcolor='#f00']") # banner colour is set
assert (
page.select("body > table table > tr > td > span")[0].get_text().strip()
== "Organization text"
) # brand text is set
def test_displays_org_branding_with_banner_without_brand_text(
client_request, mock_get_email_branding_without_brand_text
):
# mock_get_email_branding_without_brand_text has 'brand_type' of 'org_banner'
page = client_request.get(
"main.email_template", branding_style="1", _test_page_title=False
)
mock_get_email_branding_without_brand_text.assert_called_once_with("1")
assert not page.find("a", attrs={"href": "https://www.gsa.gov"})
assert page.find("img", attrs={"src": re.compile("example.png")})
assert page.select("body > table > tr > td[bgcolor='#f00']") # banner colour is set
assert (
not page.select("body > table table > tr > td > span") == 0
) # brand text is not set
+5 -802
View File
@@ -1,812 +1,15 @@
from functools import partial
from unittest.mock import ANY, PropertyMock
import pytest
from flask import url_for
from freezegun import freeze_time
from notifications_utils.clients.zendesk.zendesk_client import NotifySupportTicket
from app.main.views.feedback import in_business_hours
from app.models.feedback import (
GENERAL_TICKET_TYPE,
PROBLEM_TICKET_TYPE,
QUESTION_TICKET_TYPE,
)
from tests.conftest import SERVICE_ONE_ID, normalize_spaces
def no_redirect():
return lambda: None
@pytest.mark.skip(reason="Not currently using Zendesk")
def test_get_support_index_page(
client_request,
):
page = client_request.get(".support")
assert page.select_one("form")["method"] == "post"
assert "action" not in page.select_one("form")
assert normalize_spaces(page.select_one("h1").text) == "Support"
assert (
normalize_spaces(page.select_one("form label[for=support_type-0]").text)
== "Report a problem"
)
assert page.select_one("form input#support_type-0")["value"] == "report-problem"
assert (
normalize_spaces(page.select_one("form label[for=support_type-1]").text)
== "Ask a question or give feedback"
)
assert (
page.select_one("form input#support_type-1")["value"]
== "ask-question-give-feedback"
)
assert (
normalize_spaces(page.select_one("form button[type=submit]").text) == "Continue"
)
@pytest.mark.skip(reason="Not currently using Zendesk")
def test_get_support_index_page_when_signed_out(
client_request,
):
client_request.logout()
page = client_request.get(".support")
assert page.select_one("form")["method"] == "post"
assert "action" not in page.select_one("form")
assert normalize_spaces(page.select_one("form label[for=who-0]").text) == (
"I work in the public sector and need to send emails or text messages"
)
assert page.select_one("form input#who-0")["value"] == "public-sector"
assert normalize_spaces(page.select_one("form label[for=who-1]").text) == (
"Im a member of the public with a question for the government"
)
assert page.select_one("form input#who-1")["value"] == "public"
assert (
normalize_spaces(page.select_one("form button[type=submit]").text) == "Continue"
)
@freeze_time("2016-12-12 12:00:00.000000")
@pytest.mark.parametrize(
("support_type", "expected_h1"),
[
(PROBLEM_TICKET_TYPE, "Report a problem"),
(QUESTION_TICKET_TYPE, "Ask a question or give feedback"),
],
)
def test_choose_support_type(
client_request,
mock_get_non_empty_organizations_and_services_for_user,
support_type,
expected_h1,
):
page = client_request.post(
"main.support",
_data={"support_type": support_type},
_follow_redirects=True,
)
assert page.h1.string.strip() == expected_h1
assert not page.select_one("input[name=name]")
assert not page.select_one("input[name=email_address]")
assert page.find("form").find("p").text.strip() == (
"Well reply to test@user.gsa.gov"
)
from tests.conftest import normalize_spaces
@freeze_time("2016-12-12 12:00:00.000000")
def test_get_support_as_someone_in_the_public_sector(
mocker,
active_user_with_permissions,
client_request,
):
client_request.logout()
page = client_request.post(
page = client_request.get(
"main.support",
_data={"who": "public-sector"},
_follow_redirects=True,
)
assert normalize_spaces(page.select("h1")) == ("Contact Notify.gov support")
assert page.select_one("form textarea[name=feedback]")
assert page.select_one("form input[name=name]")
assert page.select_one("form input[name=email_address]")
assert page.select_one("form button[type=submit]")
def test_get_support_as_member_of_public(
client_request,
):
client_request.logout()
page = client_request.post(
"main.support",
_data={"who": "public"},
_follow_redirects=True,
)
assert normalize_spaces(page.select("h1")) == (
"The Notify.gov service is for people who work in the government"
)
assert len(page.select("h2 a")) == 3
assert not page.select("form")
assert not page.select("input")
assert not page.select("form [type=submit]")
@freeze_time("2016-12-12 12:00:00.000000")
@pytest.mark.parametrize(
("ticket_type", "expected_status_code"),
[(PROBLEM_TICKET_TYPE, 200), (QUESTION_TICKET_TYPE, 200), ("gripe", 404)],
)
def test_get_feedback_page(client_request, ticket_type, expected_status_code):
client_request.logout()
client_request.get(
"main.feedback",
ticket_type=ticket_type,
_expected_status=expected_status_code,
)
@freeze_time("2016-12-12 12:00:00.000000")
@pytest.mark.parametrize(
("ticket_type", "zendesk_ticket_type"),
[
(PROBLEM_TICKET_TYPE, "incident"),
(QUESTION_TICKET_TYPE, "question"),
(GENERAL_TICKET_TYPE, "question"),
],
)
def test_passed_non_logged_in_user_details_through_flow(
client_request, mocker, ticket_type, zendesk_ticket_type
):
client_request.logout()
mock_create_ticket = mocker.spy(NotifySupportTicket, "__init__")
mock_send_ticket_to_zendesk = mocker.patch(
"app.main.views.feedback.zendesk_client.send_ticket_to_zendesk",
autospec=True,
)
data = {
"feedback": "blah",
"name": "Anne Example",
"email_address": "anne@example.com",
}
client_request.post(
"main.feedback",
ticket_type=ticket_type,
_data=data,
_expected_redirect=url_for(
"main.thanks",
out_of_hours_emergency=False,
email_address_provided=True,
),
)
mock_create_ticket.assert_called_once_with(
ANY,
subject="Notify feedback",
message="blah\n",
ticket_type=zendesk_ticket_type,
p1=False,
user_name="Anne Example",
user_email="anne@example.com",
org_id=None,
org_type=None,
service_id=None,
)
mock_send_ticket_to_zendesk.assert_called_once()
@freeze_time("2016-12-12 12:00:00.000000")
@pytest.mark.parametrize(
"data",
[
{"feedback": "blah"},
{"feedback": "blah", "name": "Ignored", "email_address": "ignored@email.com"},
],
)
@pytest.mark.parametrize(
("ticket_type", "zendesk_ticket_type"),
[
(PROBLEM_TICKET_TYPE, "incident"),
(QUESTION_TICKET_TYPE, "question"),
(GENERAL_TICKET_TYPE, "question"),
],
)
def test_passes_user_details_through_flow(
client_request,
mock_get_non_empty_organizations_and_services_for_user,
mocker,
ticket_type,
zendesk_ticket_type,
data,
):
mock_create_ticket = mocker.spy(NotifySupportTicket, "__init__")
mock_send_ticket_to_zendesk = mocker.patch(
"app.main.views.feedback.zendesk_client.send_ticket_to_zendesk",
autospec=True,
)
client_request.post(
"main.feedback",
ticket_type=ticket_type,
_data=data,
_expected_status=302,
_expected_redirect=url_for(
"main.thanks",
email_address_provided=True,
out_of_hours_emergency=False,
),
)
mock_create_ticket.assert_called_once_with(
ANY,
subject="Notify feedback",
message=ANY,
ticket_type=zendesk_ticket_type,
p1=False,
user_name="Test User",
user_email="test@user.gsa.gov",
org_id=None,
org_type="federal",
service_id=SERVICE_ONE_ID,
)
assert mock_create_ticket.call_args[1]["message"] == "\n".join(
[
"blah",
'Service: "service one"',
url_for(
"main.service_dashboard",
service_id=SERVICE_ONE_ID,
_external=True,
),
"",
]
)
mock_send_ticket_to_zendesk.assert_called_once()
@freeze_time("2016-12-12 12:00:00.000000")
@pytest.mark.parametrize(
"data",
[
{"feedback": "blah", "name": "Fred"},
{"feedback": "blah"},
],
)
@pytest.mark.parametrize(
"ticket_type",
[
PROBLEM_TICKET_TYPE,
QUESTION_TICKET_TYPE,
],
)
def test_email_address_required_for_problems_and_questions(
client_request,
mocker,
data,
ticket_type,
):
mocker.patch("app.main.views.feedback.zendesk_client")
client_request.logout()
page = client_request.post(
"main.feedback", ticket_type=ticket_type, _data=data, _expected_status=200
)
assert normalize_spaces(page.select_one(".usa-error-message").text) == (
"Error: Cannot be empty"
)
@freeze_time("2016-12-12 12:00:00.000000")
@pytest.mark.parametrize("ticket_type", [PROBLEM_TICKET_TYPE, QUESTION_TICKET_TYPE])
def test_email_address_must_be_valid_if_provided_to_support_form(
client_request,
mocker,
ticket_type,
):
client_request.logout()
page = client_request.post(
"main.feedback",
ticket_type=ticket_type,
_data={
"feedback": "blah",
"email_address": "not valid",
},
_expected_status=200,
)
assert normalize_spaces(page.select_one("span.usa-error-message").text) == (
"Error: Enter a valid email address"
)
@pytest.mark.parametrize(
("ticket_type", "severe", "is_in_business_hours", "is_out_of_hours_emergency"),
[
# business hours, never an emergency
(PROBLEM_TICKET_TYPE, "yes", True, False),
(QUESTION_TICKET_TYPE, "yes", True, False),
(PROBLEM_TICKET_TYPE, "no", True, False),
(QUESTION_TICKET_TYPE, "no", True, False),
# out of hours, if the user says its not an emergency
(PROBLEM_TICKET_TYPE, "no", False, False),
(QUESTION_TICKET_TYPE, "no", False, False),
# out of hours, only problems can be emergencies
(PROBLEM_TICKET_TYPE, "yes", False, True),
(QUESTION_TICKET_TYPE, "yes", False, False),
],
)
def test_urgency(
client_request,
mock_get_non_empty_organizations_and_services_for_user,
mocker,
ticket_type,
severe,
is_in_business_hours,
is_out_of_hours_emergency,
):
mocker.patch(
"app.main.views.feedback.in_business_hours", return_value=is_in_business_hours
)
mock_ticket = mocker.patch("app.main.views.feedback.NotifySupportTicket")
mocker.patch(
"app.main.views.feedback.zendesk_client.send_ticket_to_zendesk",
autospec=True,
)
client_request.post(
"main.feedback",
ticket_type=ticket_type,
severe=severe,
_data={"feedback": "blah", "email_address": "test@example.com"},
_expected_status=302,
_expected_redirect=url_for(
"main.thanks",
out_of_hours_emergency=is_out_of_hours_emergency,
email_address_provided=True,
),
)
assert mock_ticket.call_args[1]["p1"] == is_out_of_hours_emergency
ids, params = zip(
*[
(
"non-logged in users always have to triage",
(
GENERAL_TICKET_TYPE,
False,
False,
True,
302,
partial(url_for, "main.triage", ticket_type=GENERAL_TICKET_TYPE),
),
),
(
"trial services are never high priority",
(PROBLEM_TICKET_TYPE, False, True, False, 200, no_redirect()),
),
(
"we can triage in hours",
(PROBLEM_TICKET_TYPE, True, True, True, 200, no_redirect()),
),
(
"only problems are high priority",
(QUESTION_TICKET_TYPE, False, True, True, 200, no_redirect()),
),
(
"should triage out of hours",
(
PROBLEM_TICKET_TYPE,
False,
True,
True,
302,
partial(url_for, "main.triage", ticket_type=PROBLEM_TICKET_TYPE),
),
),
]
)
@pytest.mark.parametrize(
(
"ticket_type",
"is_in_business_hours",
"logged_in",
"has_live_services",
"expected_status",
"expected_redirect",
),
params,
ids=ids,
)
def test_redirects_to_triage(
client_request,
api_user_active,
mocker,
mock_get_user,
ticket_type,
is_in_business_hours,
logged_in,
has_live_services,
expected_status,
expected_redirect,
):
mocker.patch(
"app.models.user.User.live_services",
new_callable=PropertyMock,
return_value=[{}, {}] if has_live_services else [],
)
mocker.patch(
"app.main.views.feedback.in_business_hours", return_value=is_in_business_hours
)
if not logged_in:
client_request.logout()
client_request.get(
"main.feedback",
ticket_type=ticket_type,
_expected_status=expected_status,
_expected_redirect=expected_redirect(),
)
@pytest.mark.parametrize(
("ticket_type", "expected_h1"),
[
(PROBLEM_TICKET_TYPE, "Report a problem"),
(GENERAL_TICKET_TYPE, "Contact Notify.gov support"),
],
)
def test_options_on_triage_page(
client_request,
ticket_type,
expected_h1,
):
page = client_request.get("main.triage", ticket_type=ticket_type)
assert normalize_spaces(page.select_one("h1").text) == expected_h1
assert page.select("form input[type=radio]")[0]["value"] == "yes"
assert page.select("form input[type=radio]")[1]["value"] == "no"
def test_doesnt_lose_message_if_post_across_closing(
client_request,
mocker,
):
mocker.patch("app.models.user.User.live_services", return_value=True)
mocker.patch("app.main.views.feedback.in_business_hours", return_value=False)
page = client_request.post(
"main.feedback",
ticket_type=PROBLEM_TICKET_TYPE,
_data={"feedback": "foo"},
_expected_status=302,
_expected_redirect=url_for(".triage", ticket_type=PROBLEM_TICKET_TYPE),
)
with client_request.session_transaction() as session:
assert session["feedback_message"] == "foo"
page = client_request.get(
"main.feedback",
ticket_type=PROBLEM_TICKET_TYPE,
severe="yes",
)
with client_request.session_transaction() as session:
assert page.find("textarea", {"name": "feedback"}).text == "\r\nfoo"
assert "feedback_message" not in session
@pytest.mark.parametrize(
("when", "is_in_business_hours"),
[
("2016-06-06 09:29:59+0100", False), # opening time, summer and winter
("2016-12-12 09:29:59+0000", False),
("2016-06-06 09:30:00+0100", True),
("2016-12-12 09:30:00+0000", True),
("2016-12-12 12:00:00+0000", True), # middle of the day
("2016-12-12 17:29:59+0000", True), # closing time
("2016-12-12 17:30:00+0000", False),
("2016-12-10 12:00:00+0000", False), # Saturday
("2016-12-11 12:00:00+0000", False), # Sunday
("2016-01-01 12:00:00+0000", False), # Bank holiday
],
)
def test_in_business_hours(when, is_in_business_hours):
with freeze_time(when):
assert in_business_hours() == is_in_business_hours
@pytest.mark.parametrize(
"ticket_type",
[
GENERAL_TICKET_TYPE,
PROBLEM_TICKET_TYPE,
],
)
@pytest.mark.parametrize(
("choice", "expected_redirect_param"),
[
("yes", "yes"),
("no", "no"),
],
)
def test_triage_redirects_to_correct_url(
client_request,
ticket_type,
choice,
expected_redirect_param,
):
client_request.post(
"main.triage",
ticket_type=ticket_type,
_data={"severe": choice},
_expected_status=302,
_expected_redirect=url_for(
"main.feedback",
ticket_type=ticket_type,
severe=expected_redirect_param,
),
)
@pytest.mark.parametrize(
("extra_args", "expected_back_link"),
[
(
{"severe": "yes"},
partial(url_for, "main.triage", ticket_type=PROBLEM_TICKET_TYPE),
),
(
{"severe": "no"},
partial(url_for, "main.triage", ticket_type=PROBLEM_TICKET_TYPE),
),
({"severe": "foo"}, partial(url_for, "main.support")), # hacking the URL
({}, partial(url_for, "main.support")),
],
)
@freeze_time("2012-12-12 12:12")
def test_back_link_from_form(
client_request,
mock_get_non_empty_organizations_and_services_for_user,
extra_args,
expected_back_link,
):
page = client_request.get(
"main.feedback", ticket_type=PROBLEM_TICKET_TYPE, **extra_args
)
assert page.select_one(".usa-back-link")["href"] == expected_back_link()
assert normalize_spaces(page.select_one("h1").text) == "Report a problem"
@pytest.mark.parametrize(
(
"is_in_business_hours",
"severe",
"expected_status_code",
"expected_redirect",
"expected_status_code_when_logged_in",
"expected_redirect_when_logged_in",
),
[
(True, "yes", 200, no_redirect(), 200, no_redirect()),
(True, "no", 200, no_redirect(), 200, no_redirect()),
(
False,
"no",
200,
no_redirect(),
200,
no_redirect(),
),
# Treat empty query param as mangled URL ask question again
(
False,
"",
302,
partial(url_for, "main.triage", ticket_type=PROBLEM_TICKET_TYPE),
302,
partial(url_for, "main.triage", ticket_type=PROBLEM_TICKET_TYPE),
),
# User hasnt answered the triage question
(
False,
None,
302,
partial(url_for, "main.triage", ticket_type=PROBLEM_TICKET_TYPE),
302,
partial(url_for, "main.triage", ticket_type=PROBLEM_TICKET_TYPE),
),
# Escalation is needed for non-logged-in users
(
False,
"yes",
302,
partial(url_for, "main.bat_phone"),
200,
no_redirect(),
),
],
)
def test_should_be_shown_the_bat_email(
client_request,
active_user_with_permissions,
mocker,
service_one,
mock_get_non_empty_organizations_and_services_for_user,
is_in_business_hours,
severe,
expected_status_code,
expected_redirect,
expected_status_code_when_logged_in,
expected_redirect_when_logged_in,
):
mocker.patch(
"app.main.views.feedback.in_business_hours", return_value=is_in_business_hours
)
feedback_page = url_for(
"main.feedback", ticket_type=PROBLEM_TICKET_TYPE, severe=severe
)
client_request.logout()
client_request.get_url(
feedback_page,
_expected_status=expected_status_code,
_expected_redirect=expected_redirect(),
)
# logged in users should never be redirected to the bat email page
client_request.login(active_user_with_permissions)
client_request.get_url(
feedback_page,
_expected_status=expected_status_code_when_logged_in,
_expected_redirect=expected_redirect_when_logged_in(),
)
@pytest.mark.parametrize(
(
"severe",
"expected_status_code",
"expected_redirect",
"expected_status_code_when_logged_in",
"expected_redirect_when_logged_in",
),
[
# User hasnt answered the triage question
(
None,
302,
partial(url_for, "main.triage", ticket_type=GENERAL_TICKET_TYPE),
302,
partial(url_for, "main.triage", ticket_type=GENERAL_TICKET_TYPE),
),
# Escalation is needed for non-logged-in users
(
"yes",
302,
partial(url_for, "main.bat_phone"),
200,
no_redirect(),
),
],
)
def test_should_be_shown_the_bat_email_for_general_questions(
client_request,
active_user_with_permissions,
mocker,
service_one,
mock_get_non_empty_organizations_and_services_for_user,
severe,
expected_status_code,
expected_redirect,
expected_status_code_when_logged_in,
expected_redirect_when_logged_in,
):
mocker.patch("app.main.views.feedback.in_business_hours", return_value=False)
feedback_page = url_for(
"main.feedback", ticket_type=GENERAL_TICKET_TYPE, severe=severe
)
client_request.logout()
client_request.get_url(
feedback_page,
_expected_status=expected_status_code,
_expected_redirect=expected_redirect(),
)
# logged in users should never be redirected to the bat email page
client_request.login(active_user_with_permissions)
client_request.get_url(
feedback_page,
_expected_status=expected_status_code_when_logged_in,
_expected_redirect=expected_redirect_when_logged_in(),
)
def test_bat_email_page(
client_request,
active_user_with_permissions,
mocker,
service_one,
):
bat_phone_page = "main.bat_phone"
client_request.logout()
page = client_request.get(bat_phone_page)
assert page.select_one(".usa-back-link").text == "Back"
assert page.select_one(".usa-back-link")["href"] == url_for("main.support")
assert page.select("main a")[1].text == "Fill in this form"
assert page.select("main a")[1]["href"] == url_for(
"main.feedback", ticket_type=PROBLEM_TICKET_TYPE, severe="no"
)
next_page = client_request.get_url(page.select("main a")[1]["href"])
assert next_page.h1.text.strip() == "Report a problem"
client_request.login(active_user_with_permissions)
client_request.get(
bat_phone_page,
_expected_redirect=url_for("main.feedback", ticket_type=PROBLEM_TICKET_TYPE),
)
@pytest.mark.parametrize(
("out_of_hours_emergency", "email_address_provided", "out_of_hours", "message"),
[
# Out of hours emergencies trump everything else
(
True,
True,
True,
"Well reply in the next 30 minutes.",
),
(
True,
False,
False, # Not a real scenario
"Well reply in the next 30 minutes.",
),
# Anonymous tickets dont promise a reply
(
False,
False,
False,
"Well aim to read your message in the next 30 minutes.",
),
(
False,
False,
True,
"Well read your message when were back in the office.",
),
# When we look at your ticket depends on whether were in normal
# business hours
(
False,
True,
False,
"Well aim to read your message in the next 30 minutes and well reply within one working day.",
),
(False, True, True, "Well reply within one working day."),
],
)
def test_thanks(
client_request,
mocker,
api_user_active,
mock_get_user,
out_of_hours_emergency,
email_address_provided,
out_of_hours,
message,
):
mocker.patch(
"app.main.views.feedback.in_business_hours", return_value=(not out_of_hours)
)
page = client_request.get(
"main.thanks",
out_of_hours_emergency=out_of_hours_emergency,
email_address_provided=email_address_provided,
)
assert normalize_spaces(page.find("main").find("p").text) == message
assert normalize_spaces(page.select("h1")) == ("Contact us")
+1 -41
View File
@@ -5,7 +5,7 @@ from bs4 import BeautifulSoup
from flask import url_for
from freezegun import freeze_time
from tests.conftest import SERVICE_ONE_ID, normalize_spaces, sample_uuid
from tests.conftest import SERVICE_ONE_ID, normalize_spaces
def test_non_logged_in_user_can_see_homepage(
@@ -65,14 +65,6 @@ def test_robots(client_request):
("endpoint", "kwargs"),
[
("sign_in", {}),
("support", {}),
("support_public", {}),
("triage", {}),
("feedback", {"ticket_type": "ask-question-give-feedback"}),
("feedback", {"ticket_type": "general"}),
("feedback", {"ticket_type": "report-problem"}),
("bat_phone", {}),
("thanks", {}),
("register", {}),
pytest.param("index", {}, marks=pytest.mark.xfail(raises=AssertionError)),
],
@@ -104,12 +96,10 @@ def test_hiding_pages_from_search_engines(
"documentation",
"security",
"message_status",
"features_email",
"features_sms",
"how_to_pay",
"get_started",
"guidance_index",
"branding_and_customisation",
"create_and_send_messages",
"edit_and_format_messages",
"send_files_by_email",
@@ -265,36 +255,6 @@ def test_css_is_served_from_correct_path(client_request):
# assert logo_svg_fallback['src'].startswith('https://static.example.com/images/us-notify-color.png')
@pytest.mark.parametrize(
("extra_args", "email_branding_retrieved"),
[
(
{},
False,
),
(
{"branding_style": "__NONE__"},
False,
),
(
{"branding_style": sample_uuid()},
True,
),
],
)
def test_email_branding_preview(
client_request,
mock_get_email_branding,
extra_args,
email_branding_retrieved,
):
page = client_request.get(
"main.email_template", _test_page_title=False, **extra_args
)
assert page.title.text == "Email branding preview"
assert mock_get_email_branding.called is email_branding_retrieved
@pytest.mark.parametrize(
("current_date", "expected_rate"),
[
+31 -1
View File
@@ -1157,6 +1157,35 @@ def test_invite_user_with_email_auth_service(
)
def test_resend_expired_invitation(
client_request,
mock_get_invites_for_service,
expired_invite,
active_user_with_permissions,
mock_get_users_by_service,
mock_get_template_folders,
mocker,
):
mock_resend = mocker.patch("app.invite_api_client.resend_invite")
mocker.patch(
"app.invite_api_client.get_invited_user_for_service",
return_value=expired_invite,
)
page = client_request.get(
"main.resend_invite",
service_id=SERVICE_ONE_ID,
invited_user_id=expired_invite["id"],
_follow_redirects=True,
)
assert normalize_spaces(page.h1.text) == "Team members"
assert mock_resend.called
called_args = set(mock_resend.call_args.args) | set(
mock_resend.call_args.kwargs.values()
)
assert SERVICE_ONE_ID in called_args
assert expired_invite["id"] in called_args
def test_cancel_invited_user_cancels_user_invitations(
client_request,
mock_get_invites_for_service,
@@ -1168,7 +1197,8 @@ def test_cancel_invited_user_cancels_user_invitations(
):
mock_cancel = mocker.patch("app.invite_api_client.cancel_invited_user")
mocker.patch(
"app.invite_api_client.get_invited_user_for_service", return_value=sample_invite
"app.invite_api_client.get_invited_user_for_service",
return_value=sample_invite,
)
page = client_request.get(
@@ -757,7 +757,6 @@ def test_clear_cache_shows_form(
"user",
"service",
"template",
"email_branding",
"organization",
}
+120 -29
View File
@@ -30,6 +30,63 @@ from tests.conftest import (
normalize_spaces,
)
FAKE_ONE_OFF_NOTIFICATION = {
"links": {},
"notifications": [
{
"api_key": None,
"billable_units": 0,
"carrier": None,
"client_reference": None,
"created_at": "2023-12-14T20:35:55+00:00",
"created_by": {
"email_address": "grsrbsrgsrf@fake.gov",
"id": "de059e0a-42e5-48bb-939e-4f76804ab739",
"name": "grsrbsrgsrf",
},
"document_download_count": None,
"id": "a3442b43-0ba1-4854-9e0a-d2fba1cc9b81",
"international": False,
"job": {
"id": "55b242b5-9f62-4271-aff7-039e9c320578",
"original_file_name": "1127b78e-a4a8-4b70-8f4f-9f4fbf03ece2.csv",
},
"job_row_number": 0,
"key_name": None,
"key_type": "normal",
"normalised_to": "+16615555555",
"notification_type": "sms",
"personalisation": {
"dayofweek": "2",
"favecolor": "3",
"phonenumber": "+16615555555",
},
"phone_prefix": "1",
"provider_response": None,
"rate_multiplier": 1.0,
"reference": None,
"reply_to_text": "development",
"sent_at": None,
"sent_by": None,
"service": "f62d840f-8bcb-4b36-b959-4687e16dd1a1",
"status": "created",
"template": {
"content": "((day of week)) and ((fave color))",
"id": "bd9caa7e-00ee-4c5a-839e-10ae1a7e6f73",
"name": "personalized",
"redact_personalisation": False,
"subject": None,
"template_type": "sms",
"version": 1,
},
"to": "+16615555555",
"updated_at": None,
}
],
"page_size": 50,
"total": 1,
}
template_types = ["email", "sms"]
unchanging_fake_uuid = uuid.uuid4()
@@ -2060,10 +2117,19 @@ def test_route_permissions_send_check_notifications(
route,
response_code,
method,
mock_create_job,
mock_s3_upload,
):
with client_request.session_transaction() as session:
session["recipient"] = "2028675301"
session["placeholders"] = {"name": "a"}
mocker.patch("app.main.views.send.check_messages")
mocker.patch(
"app.notification_api_client.get_notifications_for_service",
return_value=FAKE_ONE_OFF_NOTIFICATION,
)
validate_route_permission_with_client(
mocker,
client_request,
@@ -2578,28 +2644,31 @@ def test_check_notification_shows_preview(
def test_send_notification_submits_data(
client_request,
fake_uuid,
mock_send_notification,
mock_get_service_template,
template,
recipient,
placeholders,
expected_personalisation,
mocker,
mock_create_job,
mock_s3_upload,
):
with client_request.session_transaction() as session:
session["recipient"] = recipient
session["placeholders"] = placeholders
mocker.patch(
"app.notification_api_client.get_notifications_for_service",
return_value=FAKE_ONE_OFF_NOTIFICATION,
)
mocker.patch("app.main.views.send.check_messages", return_value="")
client_request.post(
"main.send_notification", service_id=SERVICE_ONE_ID, template_id=fake_uuid
)
mock_send_notification.assert_called_once_with(
SERVICE_ONE_ID,
template_id=fake_uuid,
recipient=recipient,
personalisation=expected_personalisation,
sender_id=None,
)
mock_create_job.assert_called_once()
def test_send_notification_clears_session(
@@ -2608,11 +2677,20 @@ def test_send_notification_clears_session(
fake_uuid,
mock_send_notification,
mock_get_service_template,
mocker,
mock_create_job,
mock_s3_upload,
):
with client_request.session_transaction() as session:
session["recipient"] = "2028675301"
session["placeholders"] = {"a": "b"}
mocker.patch("app.main.views.send.check_messages")
mocker.patch(
"app.notification_api_client.get_notifications_for_service",
return_value=FAKE_ONE_OFF_NOTIFICATION,
)
client_request.post(
"main.send_notification", service_id=service_one["id"], template_id=fake_uuid
)
@@ -2661,22 +2739,26 @@ def test_send_notification_redirects_to_view_page(
mock_get_service_template,
extra_args,
extra_redirect_args,
mocker,
mock_create_job,
mock_s3_upload,
):
with client_request.session_transaction() as session:
session["recipient"] = "2028675301"
session["placeholders"] = {"a": "b"}
mocker.patch("app.main.views.send.check_messages")
mocker.patch(
"app.notification_api_client.get_notifications_for_service",
return_value=FAKE_ONE_OFF_NOTIFICATION,
)
client_request.post(
"main.send_notification",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
_expected_status=302,
_expected_redirect=url_for(
".view_notification",
service_id=SERVICE_ONE_ID,
notification_id=fake_uuid,
**extra_redirect_args,
),
**extra_args,
)
@@ -2715,13 +2797,24 @@ def test_send_notification_shows_error_if_400(
fake_uuid,
mocker,
mock_get_service_template_with_placeholders,
mock_create_job,
exception_msg,
expected_h1,
expected_err_details,
mock_s3_upload,
):
class MockHTTPError(HTTPError):
message = exception_msg
mocker.patch(
"app.main.views.send.check_messages",
)
mocker.patch(
"app.notification_api_client.get_notifications_for_service",
return_value=FAKE_ONE_OFF_NOTIFICATION,
)
mocker.patch(
"app.notification_api_client.send_notification",
side_effect=MockHTTPError(),
@@ -2730,18 +2823,14 @@ def test_send_notification_shows_error_if_400(
session["recipient"] = "2028675301"
session["placeholders"] = {"name": "a" * 900}
# This now redirects to the jobs results page
page = client_request.post(
"main.send_notification",
service_id=service_one["id"],
template_id=fake_uuid,
_expected_status=200,
_expected_status=302,
)
assert normalize_spaces(page.select(".banner-dangerous h1")[0].text) == expected_h1
assert (
normalize_spaces(page.select(".banner-dangerous p")[0].text)
== expected_err_details
)
assert not page.find("input[type=submit]")
@@ -2750,11 +2839,19 @@ def test_send_notification_shows_email_error_in_trial_mode(
fake_uuid,
mocker,
mock_get_service_email_template,
mock_create_job,
mock_s3_upload,
):
class MockHTTPError(HTTPError):
message = TRIAL_MODE_MSG
status_code = 400
mocker.patch("app.main.views.send.check_messages")
mocker.patch(
"app.notification_api_client.get_notifications_for_service",
return_value=FAKE_ONE_OFF_NOTIFICATION,
)
mocker.patch(
"app.notification_api_client.send_notification",
side_effect=MockHTTPError(),
@@ -2763,18 +2860,12 @@ def test_send_notification_shows_email_error_in_trial_mode(
session["recipient"] = "test@example.com"
session["placeholders"] = {"date": "foo", "thing": "bar"}
page = client_request.post(
# Calling this means we successful ran a job so we will be redirect to the jobs page
client_request.post(
"main.send_notification",
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
_expected_status=200,
)
assert normalize_spaces(page.select(".banner-dangerous h1")[0].text) == (
"You cannot send to this email address"
)
assert normalize_spaces(page.select(".banner-dangerous p")[0].text) == (
"In trial mode you can only send to yourself and members of your team"
_expected_status=302,
)
+2 -2
View File
@@ -631,8 +631,8 @@ def test_should_show_sms_template_with_downgraded_unicode_characters(
mock_get_template_folders,
fake_uuid,
):
msg = "hey"
rendered_msg = "hey"
msg = "here:\tare some “fancy quotes” and zero\u200Bwidth\u200Bspaces"
rendered_msg = "here: are some “fancy quotes” and zerowidthspaces"
mocker.patch(
"app.service_api_client.get_service_template",