merge from main

This commit is contained in:
Kenneth Kehl
2023-12-20 10:26:50 -08:00
101 changed files with 457 additions and 5109 deletions

View File

@@ -931,7 +931,6 @@ def test_organization_settings_for_platform_admin(
"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",
]

View File

@@ -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"
)

View File

@@ -1,7 +1,6 @@
from datetime import datetime
from functools import partial
from unittest.mock import ANY, Mock, PropertyMock, call
from urllib.parse import parse_qs, urlparse
from uuid import uuid4
import pytest
@@ -83,7 +82,6 @@ def _mock_get_service_settings_page_common(
"Rate limit 3,000 per minute Change rate limit",
"Message batch limit 1,000 per send Change message batch limit",
"Free text message allowance 250,000 per year Change free text message allowance",
"Email branding GOV.UK Change email branding (admin view)",
"Custom data retention Email 7 days Change data retention",
"Receive inbound SMS Off Change your settings for Receive inbound SMS",
"Email authentication Off Change your settings for Email authentication",
@@ -256,13 +254,11 @@ def test_should_show_overview_for_service_with_more_things_set(
service_one,
single_reply_to_email_address,
single_sms_sender,
mock_get_email_branding,
permissions,
expected_rows,
):
client_request.login(active_user_with_permissions)
service_one["permissions"] = permissions
service_one["email_branding"] = uuid4()
page = client_request.get("main.service_settings", service_id=service_one["id"])
for index, row in enumerate(expected_rows):
assert row == " ".join(page.find_all("tr")[index + 1].text.split())
@@ -2823,247 +2819,6 @@ def test_does_not_show_research_mode_indicator(
assert not element
@pytest.mark.parametrize(
("current_branding", "expected_values", "expected_labels"),
[
(
None,
[
"__NONE__",
"1",
"2",
"3",
"4",
"5",
],
["GOV.UK", "org 1", "org 2", "org 3", "org 4", "org 5"],
),
(
"5",
[
"5",
"__NONE__",
"1",
"2",
"3",
"4",
],
[
"org 5",
"GOV.UK",
"org 1",
"org 2",
"org 3",
"org 4",
],
),
],
)
@pytest.mark.parametrize(
("endpoint", "extra_args"),
[
(
"main.service_set_email_branding",
{"service_id": SERVICE_ONE_ID},
),
(
"main.edit_organization_email_branding",
{"org_id": ORGANISATION_ID},
),
],
)
def test_should_show_branding_styles(
mocker,
client_request,
platform_admin_user,
service_one,
mock_get_all_email_branding,
current_branding,
expected_values,
expected_labels,
endpoint,
extra_args,
):
service_one["email_branding"] = current_branding
mocker.patch(
"app.organizations_client.get_organization",
side_effect=lambda org_id: organization_json(
org_id,
"Org 1",
email_branding_id=current_branding,
),
)
client_request.login(platform_admin_user)
page = client_request.get(endpoint, **extra_args)
branding_style_choices = page.find_all("input", attrs={"name": "branding_style"})
radio_labels = [
page.find("label", attrs={"for": branding_style_choices[idx]["id"]})
.get_text()
.strip()
for idx, element in enumerate(branding_style_choices)
]
assert len(branding_style_choices) == 6
for index, expected_value in enumerate(expected_values):
assert branding_style_choices[index]["value"] == expected_value
# radios should be in alphabetical order, based on their labels
assert radio_labels == expected_labels
assert "checked" in branding_style_choices[0].attrs
assert "checked" not in branding_style_choices[1].attrs
assert "checked" not in branding_style_choices[2].attrs
assert "checked" not in branding_style_choices[3].attrs
assert "checked" not in branding_style_choices[4].attrs
assert "checked" not in branding_style_choices[5].attrs
app.email_branding_client.get_all_email_branding.assert_called_once_with()
app.service_api_client.get_service.assert_called_once_with(service_one["id"])
@pytest.mark.parametrize(
("endpoint", "extra_args", "expected_redirect"),
[
(
"main.service_set_email_branding",
{"service_id": SERVICE_ONE_ID},
"main.service_preview_email_branding",
),
(
"main.edit_organization_email_branding",
{"org_id": ORGANISATION_ID},
"main.organization_preview_email_branding",
),
],
)
def test_should_send_branding_and_organizations_to_preview(
client_request,
platform_admin_user,
service_one,
mock_get_organization,
mock_get_all_email_branding,
mock_update_service,
endpoint,
extra_args,
expected_redirect,
):
client_request.login(platform_admin_user)
client_request.post(
endpoint,
_data={"branding_type": "org", "branding_style": "1"},
_expected_status=302,
_expected_location=url_for(expected_redirect, branding_style="1", **extra_args),
**extra_args,
)
mock_get_all_email_branding.assert_called_once_with()
@pytest.mark.parametrize(
("endpoint", "extra_args"),
[
(
"main.service_preview_email_branding",
{"service_id": SERVICE_ONE_ID},
),
(
"main.organization_preview_email_branding",
{"org_id": ORGANISATION_ID},
),
],
)
def test_should_preview_email_branding(
client_request,
platform_admin_user,
mock_get_organization,
endpoint,
extra_args,
):
client_request.login(platform_admin_user)
page = client_request.get(
endpoint, branding_type="org", branding_style="1", **extra_args
)
iframe = page.find("iframe", attrs={"class": "branding-preview"})
iframeURLComponents = urlparse(iframe["src"])
iframeQString = parse_qs(iframeURLComponents.query)
assert page.find("input", attrs={"id": "branding_style"})["value"] == "1"
assert iframeURLComponents.path == "/_email"
assert iframeQString["branding_style"] == ["1"]
@pytest.mark.parametrize(
("posted_value", "submitted_value"),
[
("1", "1"),
("__NONE__", None),
pytest.param("None", None, marks=pytest.mark.xfail(raises=AssertionError)),
],
)
@pytest.mark.parametrize(
("endpoint", "extra_args", "expected_redirect"),
[
(
"main.service_preview_email_branding",
{"service_id": SERVICE_ONE_ID},
"main.service_settings",
),
(
"main.organization_preview_email_branding",
{"org_id": ORGANISATION_ID},
"main.organization_settings",
),
],
)
def test_should_set_branding_and_organizations(
client_request,
platform_admin_user,
service_one,
mock_get_organization,
mock_get_organization_services,
mock_update_service,
mock_update_organization,
posted_value,
submitted_value,
endpoint,
extra_args,
expected_redirect,
):
client_request.login(platform_admin_user)
client_request.post(
endpoint,
_data={"branding_style": posted_value},
_expected_status=302,
_expected_redirect=url_for(expected_redirect, **extra_args),
**extra_args,
)
if endpoint == "main.service_preview_email_branding":
mock_update_service.assert_called_once_with(
SERVICE_ONE_ID,
email_branding=submitted_value,
)
assert mock_update_organization.called is False
elif endpoint == "main.organization_preview_email_branding":
mock_update_organization.assert_called_once_with(
ORGANISATION_ID,
email_branding_id=submitted_value,
cached_service_ids=[
"12345",
"67890",
"596364a0-858e-42c8-9062-a8fe822260eb",
],
)
assert mock_update_service.called is False
else:
raise Exception
@pytest.mark.parametrize("method", ["get", "post"])
@pytest.mark.parametrize(
"endpoint",
@@ -4170,33 +3925,6 @@ def test_update_service_organization_does_not_update_if_same_value(
assert mock_update_service_organization.called is False
@pytest.mark.skip(reason="Email currently deactivated")
@pytest.mark.parametrize(
("single_branding_option", "expected_href"),
[
(
True,
f"/services/{SERVICE_ONE_ID}/service-settings/email-branding/something-else",
),
],
)
def test_service_settings_links_to_branding_request_page_for_emails(
service_one,
client_request,
no_reply_to_email_addresses,
single_sms_sender,
single_branding_option,
expected_href,
):
if single_branding_option:
# should only have a "something else" option
# so we go straight to that form
service_one["organization_type"] = "other"
page = client_request.get(".service_settings", service_id=SERVICE_ONE_ID)
assert len(page.find_all("a", attrs={"href": expected_href})) == 1
def test_show_service_data_retention(
client_request,
platform_admin_user,

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)

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,
)

View File

@@ -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

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(
@@ -104,12 +104,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 +263,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"),
[

View File

@@ -757,7 +757,6 @@ def test_clear_cache_shows_form(
"user",
"service",
"template",
"email_branding",
"organization",
}

View File

@@ -3,6 +3,7 @@ import uuid
import pytest
from flask import url_for
from app.main.views.sign_in import _reformat_keystring
from app.models.user import User
from tests.conftest import SERVICE_ONE_ID, normalize_spaces
@@ -39,6 +40,16 @@ def test_render_sign_in_template_with_next_link_for_password_reset(client_reques
)
def test_reformat_keystring():
orig = "-----BEGIN PRIVATE KEY----- blahblahblah -----END PRIVATE KEY-----"
expected = """-----BEGIN PRIVATE KEY-----
blahblahblah
-----END PRIVATE KEY-----
"""
reformatted = _reformat_keystring(orig)
assert reformatted == expected
def test_sign_in_explains_session_timeout(client_request):
client_request.logout()
page = client_request.get("main.sign_in", next="/foo")

View File

@@ -12,7 +12,6 @@ from tests.conftest import sample_uuid
("active", False, True, ("Unsuspended this service")),
("active", True, False, ("Deleted this service")),
("contact_link", "x", "y", ("Set the contact details for this service to y")),
("email_branding", "foo", "bar", ("Updated this services email branding")),
(
"inbound_api",
"foo",

View File

@@ -1,104 +0,0 @@
from unittest.mock import call
from app.notify_client.email_branding_client import EmailBrandingClient
def test_get_email_branding(mocker, fake_uuid):
mock_get = mocker.patch(
"app.notify_client.email_branding_client.EmailBrandingClient.get",
return_value={"foo": "bar"},
)
mock_redis_get = mocker.patch(
"app.extensions.RedisClient.get",
return_value=None,
)
mock_redis_set = mocker.patch(
"app.extensions.RedisClient.set",
)
EmailBrandingClient().get_email_branding(fake_uuid)
mock_get.assert_called_once_with(url="/email-branding/{}".format(fake_uuid))
mock_redis_get.assert_called_once_with("email_branding-{}".format(fake_uuid))
mock_redis_set.assert_called_once_with(
"email_branding-{}".format(fake_uuid),
'{"foo": "bar"}',
ex=604800,
)
def test_get_all_email_branding(mocker):
mock_get = mocker.patch(
"app.notify_client.email_branding_client.EmailBrandingClient.get",
return_value={"email_branding": [1, 2, 3]},
)
mock_redis_get = mocker.patch(
"app.extensions.RedisClient.get",
return_value=None,
)
mock_redis_set = mocker.patch(
"app.extensions.RedisClient.set",
)
EmailBrandingClient().get_all_email_branding()
mock_get.assert_called_once_with(url="/email-branding")
mock_redis_get.assert_called_once_with("email_branding")
mock_redis_set.assert_called_once_with(
"email_branding",
"[1, 2, 3]",
ex=604800,
)
def test_create_email_branding(mocker):
org_data = {
"logo": "test.png",
"name": "test name",
"text": "test name",
"colour": "red",
"brand_type": "org",
}
mock_post = mocker.patch(
"app.notify_client.email_branding_client.EmailBrandingClient.post"
)
mock_redis_delete = mocker.patch("app.extensions.RedisClient.delete")
EmailBrandingClient().create_email_branding(
logo=org_data["logo"],
name=org_data["name"],
text=org_data["text"],
colour=org_data["colour"],
brand_type="org",
)
mock_post.assert_called_once_with(url="/email-branding", data=org_data)
mock_redis_delete.assert_called_once_with("email_branding")
def test_update_email_branding(mocker, fake_uuid):
org_data = {
"logo": "test.png",
"name": "test name",
"text": "test name",
"colour": "red",
"brand_type": "org",
}
mock_post = mocker.patch(
"app.notify_client.email_branding_client.EmailBrandingClient.post"
)
mock_redis_delete = mocker.patch("app.extensions.RedisClient.delete")
EmailBrandingClient().update_email_branding(
branding_id=fake_uuid,
logo=org_data["logo"],
name=org_data["name"],
text=org_data["text"],
colour=org_data["colour"],
brand_type="org",
)
mock_post.assert_called_once_with(
url="/email-branding/{}".format(fake_uuid), data=org_data
)
assert mock_redis_delete.call_args_list == [
call("email_branding-{}".format(fake_uuid)),
call("email_branding"),
]

View File

@@ -632,7 +632,6 @@ def test_client_updates_service_with_allowed_attributes(
"consent_to_research",
"contact_link",
"count_as_live",
"email_branding",
"email_from",
"free_sms_fragment_limit",
"go_live_at",

View File

@@ -34,7 +34,6 @@ EXCLUDED_ENDPOINTS = tuple(
"bat_phone",
"begin_tour",
"billing_details",
"branding_and_customisation",
"callbacks",
"cancel_invited_org_user",
"cancel_invited_user",
@@ -61,7 +60,6 @@ EXCLUDED_ENDPOINTS = tuple(
"count_content_length",
"create_and_send_messages",
"create_api_key",
"create_email_branding",
"data_retention",
"delete_service_template",
"delete_template_folder",
@@ -75,7 +73,6 @@ EXCLUDED_ENDPOINTS = tuple(
"edit_data_retention",
"edit_organization_billing_details",
"edit_organization_domains",
"edit_organization_email_branding",
"edit_organization_go_live_notes",
"edit_organization_name",
"edit_organization_notes",
@@ -87,18 +84,10 @@ EXCLUDED_ENDPOINTS = tuple(
"edit_user_email",
"edit_user_mobile_number",
"edit_user_permissions",
"email_branding",
"email_branding_govuk",
"email_branding_govuk_and_org",
"email_branding_organization",
"email_branding_request",
"email_branding_something_else",
"email_not_received",
"email_template",
"error",
"estimate_usage",
"features",
"features_email",
"features_sms",
"feedback",
"find_services_by_name",
@@ -146,7 +135,6 @@ EXCLUDED_ENDPOINTS = tuple(
"old_using_notify",
"organization_billing",
"organization_dashboard",
"organization_preview_email_branding",
"organization_settings",
"organization_trial_mode_services",
"organizations",
@@ -193,10 +181,8 @@ EXCLUDED_ENDPOINTS = tuple(
"service_edit_sms_sender",
"service_email_reply_to",
"service_name_change",
"service_preview_email_branding",
"service_set_auth_type",
"service_set_channel",
"service_set_email_branding",
"service_set_inbound_number",
"service_set_inbound_sms",
"service_set_international_sms",
@@ -236,7 +222,6 @@ EXCLUDED_ENDPOINTS = tuple(
"two_factor_email",
"two_factor_email_interstitial",
"two_factor_email_sent",
"update_email_branding",
"uploads",
"usage",
"user_information",

View File

@@ -1,189 +0,0 @@
from unittest.mock import PropertyMock
import pytest
from app.models.service import Service
from app.utils.branding import get_email_choices
from tests import organization_json
from tests.conftest import create_email_branding
@pytest.mark.parametrize("function", [get_email_choices])
@pytest.mark.parametrize(
("org_type", "expected_options"),
[
("federal", []),
("state", []),
],
)
def test_get_choices_service_not_assigned_to_org(
service_one,
function,
org_type,
expected_options,
):
service_one["organization_type"] = org_type
service = Service(service_one)
options = function(service)
assert list(options) == expected_options
@pytest.mark.parametrize(
("org_type", "branding_id", "expected_options"),
[
(
"federal",
None,
[
("govuk_and_org", "GOV.UK and Test Organization"),
("organization", "Test Organization"),
],
),
(
"federal",
"some-branding-id",
[
("govuk", "GOV.UK"), # central orgs can switch back to gsa.gov
("govuk_and_org", "GOV.UK and Test Organization"),
("organization", "Test Organization"),
],
),
("state", None, [("organization", "Test Organization")]),
("state", "some-branding-id", [("organization", "Test Organization")]),
# ('nhs_central', None, [
# ('nhs', 'NHS')
# ]),
# ('nhs_central', NHS_EMAIL_BRANDING_ID, [
# # don't show NHS if it's the current branding
# ]),
],
)
@pytest.mark.skip(reason="Update for TTS")
def test_get_email_choices_service_assigned_to_org(
mocker,
service_one,
org_type,
branding_id,
expected_options,
mock_get_service_organization,
mock_get_email_branding,
):
service = Service(service_one)
mocker.patch(
"app.organizations_client.get_organization",
return_value=organization_json(organization_type=org_type),
)
mocker.patch(
"app.models.service.Service.email_branding_id",
new_callable=PropertyMock,
return_value=branding_id,
)
options = get_email_choices(service)
assert list(options) == expected_options
@pytest.mark.parametrize(
("org_type", "branding_id", "expected_options"),
[
(
"federal",
"some-branding-id",
[
# don't show gsa.gov options as org default supersedes it
("organization", "Test Organization"),
],
),
(
"federal",
"org-branding-id",
[
# also don't show org option if it's the current branding
],
),
(
"state",
"org-branding-id",
[
# don't show org option if it's the current branding
],
),
],
)
@pytest.mark.skip(reason="Update for TTS")
def test_get_email_choices_org_has_default_branding(
mocker,
service_one,
org_type,
branding_id,
expected_options,
mock_get_service_organization,
mock_get_email_branding,
):
service = Service(service_one)
mocker.patch(
"app.organizations_client.get_organization",
return_value=organization_json(
organization_type=org_type, email_branding_id="org-branding-id"
),
)
mocker.patch(
"app.models.service.Service.email_branding_id",
new_callable=PropertyMock,
return_value=branding_id,
)
options = get_email_choices(service)
assert list(options) == expected_options
@pytest.mark.parametrize(
("branding_name", "expected_options"),
[
(
"gsa.gov and something else",
[
("govuk", "GOV.UK"),
("govuk_and_org", "GOV.UK and Test Organization"),
("organization", "Test Organization"),
],
),
(
"gsa.gov and test OrganisatioN",
[
("govuk", "GOV.UK"),
("organization", "Test Organization"),
],
),
],
)
@pytest.mark.skip(reason="Update for TTS")
def test_get_email_choices_branding_name_in_use(
mocker,
service_one,
branding_name,
expected_options,
mock_get_service_organization,
):
service = Service(service_one)
mocker.patch(
"app.organizations_client.get_organization",
return_value=organization_json(organization_type="central"),
)
mocker.patch(
"app.models.service.Service.email_branding_id",
new_callable=PropertyMock,
return_value="some-branding-id",
)
mocker.patch(
"app.email_branding_client.get_email_branding",
return_value=create_email_branding("_id", {"name": branding_name}),
)
options = get_email_choices(service)
# don't show option if its name is similar to current branding
assert list(options) == expected_options