mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-09-09 13:19:49 -04:00
Add '/letter-branding' page to show all letter brands
This is a platform admin page which lists all letter brands and their domain. Once the page to edit a letter brand has been created, each brand will link to its edit page, but for now this is just a list of brand names and domains.
This commit is contained in:
@@ -12,7 +12,7 @@ from app.s3_client.s3_logo_client import (
|
|||||||
persist_logo,
|
persist_logo,
|
||||||
upload_email_logo,
|
upload_email_logo,
|
||||||
)
|
)
|
||||||
from app.utils import AgreementInfo, get_logo_cdn_domain, user_is_platform_admin
|
from app.utils import get_logo_cdn_domain, user_is_platform_admin
|
||||||
|
|
||||||
|
|
||||||
@main.route("/email-branding", methods=['GET', 'POST'])
|
@main.route("/email-branding", methods=['GET', 'POST'])
|
||||||
@@ -24,8 +24,7 @@ def email_branding():
|
|||||||
return render_template(
|
return render_template(
|
||||||
'views/email-branding/select-branding.html',
|
'views/email-branding/select-branding.html',
|
||||||
email_brandings=brandings,
|
email_brandings=brandings,
|
||||||
search_form=SearchByNameForm(),
|
search_form=SearchByNameForm()
|
||||||
agreement_info=AgreementInfo,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,11 @@ from requests import get as requests_get
|
|||||||
|
|
||||||
from app import letter_branding_client
|
from app import letter_branding_client
|
||||||
from app.main import main
|
from app.main import main
|
||||||
from app.main.forms import ServiceLetterBrandingDetails, SVGFileUpload
|
from app.main.forms import (
|
||||||
|
SearchByNameForm,
|
||||||
|
ServiceLetterBrandingDetails,
|
||||||
|
SVGFileUpload,
|
||||||
|
)
|
||||||
from app.s3_client.s3_logo_client import (
|
from app.s3_client.s3_logo_client import (
|
||||||
LETTER_TEMP_TAG,
|
LETTER_TEMP_TAG,
|
||||||
delete_letter_temp_file,
|
delete_letter_temp_file,
|
||||||
@@ -27,6 +31,20 @@ from app.s3_client.s3_logo_client import (
|
|||||||
from app.utils import get_logo_cdn_domain, user_is_platform_admin
|
from app.utils import get_logo_cdn_domain, user_is_platform_admin
|
||||||
|
|
||||||
|
|
||||||
|
@main.route("/letter-branding", methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
@user_is_platform_admin
|
||||||
|
def letter_branding():
|
||||||
|
|
||||||
|
brandings = letter_branding_client.get_all_letter_branding()
|
||||||
|
|
||||||
|
return render_template(
|
||||||
|
'views/letter-branding/select-letter-branding.html',
|
||||||
|
letter_brandings=brandings,
|
||||||
|
search_form=SearchByNameForm()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@main.route("/letter-branding/create", methods=['GET', 'POST'])
|
@main.route("/letter-branding/create", methods=['GET', 'POST'])
|
||||||
@main.route("/letter-branding/create/<path:logo>", methods=['GET', 'POST'])
|
@main.route("/letter-branding/create/<path:logo>", methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
@@ -65,8 +83,7 @@ def create_letter_branding(logo=None):
|
|||||||
|
|
||||||
upload_letter_logos(logo, db_filename, png_file, session['user_id'])
|
upload_letter_logos(logo, db_filename, png_file, session['user_id'])
|
||||||
|
|
||||||
# TODO: redirect to all letter branding page once it exists
|
return redirect(url_for('main.letter_branding'))
|
||||||
return redirect(url_for('main.platform_admin'))
|
|
||||||
|
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
if 'domain' in e.message:
|
if 'domain' in e.message:
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ class HeaderNavigation(Navigation):
|
|||||||
'create_letter_branding',
|
'create_letter_branding',
|
||||||
'email_branding',
|
'email_branding',
|
||||||
'find_users_by_email',
|
'find_users_by_email',
|
||||||
|
'letter_branding',
|
||||||
'live_services',
|
'live_services',
|
||||||
'organisations',
|
'organisations',
|
||||||
'platform_admin',
|
'platform_admin',
|
||||||
@@ -437,6 +438,7 @@ class MainNavigation(Navigation):
|
|||||||
'information_security',
|
'information_security',
|
||||||
'integration_testing',
|
'integration_testing',
|
||||||
'invite_org_user',
|
'invite_org_user',
|
||||||
|
'letter_branding',
|
||||||
'live_services',
|
'live_services',
|
||||||
'manage_org_users',
|
'manage_org_users',
|
||||||
'new_password',
|
'new_password',
|
||||||
@@ -623,6 +625,7 @@ class CaseworkNavigation(Navigation):
|
|||||||
'integration_testing',
|
'integration_testing',
|
||||||
'invite_org_user',
|
'invite_org_user',
|
||||||
'invite_user',
|
'invite_user',
|
||||||
|
'letter_branding',
|
||||||
'link_service_to_organisation',
|
'link_service_to_organisation',
|
||||||
'live_services',
|
'live_services',
|
||||||
'manage_org_users',
|
'manage_org_users',
|
||||||
@@ -855,6 +858,7 @@ class OrgNavigation(Navigation):
|
|||||||
'information_security',
|
'information_security',
|
||||||
'integration_testing',
|
'integration_testing',
|
||||||
'invite_user',
|
'invite_user',
|
||||||
|
'letter_branding',
|
||||||
'link_service_to_organisation',
|
'link_service_to_organisation',
|
||||||
'live_services',
|
'live_services',
|
||||||
'manage_template_folder',
|
'manage_template_folder',
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
{% extends "views/platform-admin/_base_template.html" %}
|
{% extends "views/platform-admin/_base_template.html" %}
|
||||||
{% from "components/radios.html" import radios %}
|
|
||||||
{% from "components/page-footer.html" import page_footer %}
|
|
||||||
{% from "components/live-search.html" import live_search %}
|
{% from "components/live-search.html" import live_search %}
|
||||||
|
|
||||||
{% block per_page_title %}
|
{% block per_page_title %}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
'Save',
|
'Save',
|
||||||
button_name='operation',
|
button_name='operation',
|
||||||
button_value='branding-details',
|
button_value='branding-details',
|
||||||
back_link=url_for('main.platform_admin'),
|
back_link=url_for('main.letter_branding'),
|
||||||
back_link_text='Back to letter branding selection',
|
back_link_text='Back to letter branding selection',
|
||||||
) }}
|
) }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{% extends "views/platform-admin/_base_template.html" %}
|
||||||
|
{% from "components/live-search.html" import live_search %}
|
||||||
|
|
||||||
|
{% block per_page_title %}
|
||||||
|
Letter branding
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block platform_admin_content %}
|
||||||
|
|
||||||
|
<div class="grid-row bottom-gutter-2-3">
|
||||||
|
<div class="column-two-thirds">
|
||||||
|
<h1 class="heading-large">Letter branding</h1>
|
||||||
|
</div>
|
||||||
|
<div class="column-one-third">
|
||||||
|
<a href="{{ url_for('.create_letter_branding') }}" class="button align-with-heading">Add new brand</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ live_search(target_selector='.letter-brand', show=True, form=search_form) }}
|
||||||
|
<nav>
|
||||||
|
{% for brand in letter_brandings %}
|
||||||
|
<div class="letter-brand">
|
||||||
|
<div class="message-name">
|
||||||
|
{{ brand.name }}
|
||||||
|
</div>
|
||||||
|
<p class="message-type">
|
||||||
|
{% if brand.domain %}
|
||||||
|
Default for {{ brand.domain }}
|
||||||
|
{% else %}
|
||||||
|
–
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
('Organisations', url_for('main.organisations')),
|
('Organisations', url_for('main.organisations')),
|
||||||
('Providers', url_for('main.view_providers')),
|
('Providers', url_for('main.view_providers')),
|
||||||
('Email branding', url_for('main.email_branding')),
|
('Email branding', url_for('main.email_branding')),
|
||||||
|
('Letter branding', url_for('main.letter_branding')),
|
||||||
('Inbound SMS numbers', url_for('main.inbound_sms_admin')),
|
('Inbound SMS numbers', url_for('main.inbound_sms_admin')),
|
||||||
('Find users by email', url_for('main.find_users_by_email')),
|
('Find users by email', url_for('main.find_users_by_email')),
|
||||||
('Email Complaints', url_for('main.platform_admin_list_complaints')),
|
('Email Complaints', url_for('main.platform_admin_list_complaints')),
|
||||||
|
|||||||
@@ -8,6 +8,41 @@ from notifications_python_client.errors import HTTPError
|
|||||||
|
|
||||||
from app.main.views.letter_branding import get_png_file_from_svg
|
from app.main.views.letter_branding import get_png_file_from_svg
|
||||||
from app.s3_client.s3_logo_client import LETTER_TEMP_LOGO_LOCATION
|
from app.s3_client.s3_logo_client import LETTER_TEMP_LOGO_LOCATION
|
||||||
|
from tests.conftest import normalize_spaces
|
||||||
|
|
||||||
|
|
||||||
|
def test_letter_branding_page_shows_full_branding_list(
|
||||||
|
mocker,
|
||||||
|
logged_in_platform_admin_client,
|
||||||
|
):
|
||||||
|
letter_brandings = [
|
||||||
|
{'id': '1', 'filename': '1-test', 'domain': None, 'name': 'test brand'},
|
||||||
|
{'id': '2', 'filename': '2-example', 'domain': 'cabinet-office.gov.uk', 'name': 'example brand'}
|
||||||
|
]
|
||||||
|
mocker.patch('app.main.views.letter_branding.letter_branding_client.get_all_letter_branding',
|
||||||
|
return_value=letter_brandings)
|
||||||
|
|
||||||
|
response = logged_in_platform_admin_client.get(
|
||||||
|
url_for('.letter_branding')
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||||
|
brand_names = [normalize_spaces(name.text) for name in page.select('.letter-brand .message-name')]
|
||||||
|
brand_hints = [normalize_spaces(hint.text) for hint in page.select('.letter-brand .message-type')]
|
||||||
|
|
||||||
|
assert normalize_spaces(
|
||||||
|
page.select_one('h1').text
|
||||||
|
) == "Letter branding"
|
||||||
|
|
||||||
|
assert page.select_one('.column-three-quarters a')['href'] == url_for('main.create_letter_branding')
|
||||||
|
|
||||||
|
assert list(zip(
|
||||||
|
brand_names, brand_hints
|
||||||
|
)) == [
|
||||||
|
('test brand', '–'),
|
||||||
|
('example brand', 'Default for cabinet-office.gov.uk'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_create_letter_branding_does_not_show_branding_info(logged_in_platform_admin_client):
|
def test_create_letter_branding_does_not_show_branding_info(logged_in_platform_admin_client):
|
||||||
@@ -154,11 +189,6 @@ def test_create_letter_branding_persists_logo_when_all_data_is_valid(
|
|||||||
mock_upload_png = mocker.patch('app.main.views.letter_branding.upload_letter_png_logo')
|
mock_upload_png = mocker.patch('app.main.views.letter_branding.upload_letter_png_logo')
|
||||||
mock_delete_temp_files = mocker.patch('app.main.views.letter_branding.delete_letter_temp_files_created_by')
|
mock_delete_temp_files = mocker.patch('app.main.views.letter_branding.delete_letter_temp_files_created_by')
|
||||||
|
|
||||||
# TODO: remove platform admin page mocks once we no longer redirect there
|
|
||||||
mocker.patch('app.main.views.platform_admin.make_columns')
|
|
||||||
mocker.patch('app.main.views.platform_admin.platform_stats_api_client.get_aggregate_platform_stats')
|
|
||||||
mocker.patch('app.main.views.platform_admin.complaint_api_client.get_complaint_count')
|
|
||||||
|
|
||||||
response = logged_in_platform_admin_client.post(
|
response = logged_in_platform_admin_client.post(
|
||||||
url_for('.create_letter_branding', logo=temp_logo),
|
url_for('.create_letter_branding', logo=temp_logo),
|
||||||
data={
|
data={
|
||||||
@@ -168,8 +198,10 @@ def test_create_letter_branding_persists_logo_when_all_data_is_valid(
|
|||||||
},
|
},
|
||||||
follow_redirects=True
|
follow_redirects=True
|
||||||
)
|
)
|
||||||
|
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||||
|
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
|
assert page.find('h1').text == 'Letter branding'
|
||||||
|
|
||||||
mock_letter_client.create_letter_branding.assert_called_once_with(
|
mock_letter_client.create_letter_branding.assert_called_once_with(
|
||||||
domain='bl.uk', filename='{}-test'.format(fake_uuid), name='Test brand'
|
domain='bl.uk', filename='{}-test'.format(fake_uuid), name='Test brand'
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ def test_create_letter_branding(mocker):
|
|||||||
new_branding = {'filename': 'uuid-test', 'name': 'my letters', 'domain': 'example.com'}
|
new_branding = {'filename': 'uuid-test', 'name': 'my letters', 'domain': 'example.com'}
|
||||||
|
|
||||||
mock_post = mocker.patch('app.notify_client.letter_branding_client.LetterBrandingClient.post')
|
mock_post = mocker.patch('app.notify_client.letter_branding_client.LetterBrandingClient.post')
|
||||||
|
mock_redis_delete = mocker.patch('app.notify_client.RedisClient.delete')
|
||||||
|
|
||||||
LetterBrandingClient().create_letter_branding(
|
LetterBrandingClient().create_letter_branding(
|
||||||
filename=new_branding['filename'], name=new_branding['name'], domain=new_branding['domain']
|
filename=new_branding['filename'], name=new_branding['name'], domain=new_branding['domain']
|
||||||
@@ -48,3 +49,5 @@ def test_create_letter_branding(mocker):
|
|||||||
url='/letter-branding',
|
url='/letter-branding',
|
||||||
data=new_branding
|
data=new_branding
|
||||||
)
|
)
|
||||||
|
|
||||||
|
mock_redis_delete.assert_called_once_with('letter_branding')
|
||||||
|
|||||||
Reference in New Issue
Block a user