mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-06-21 13:43:14 -04:00
Merge pull request #1509 from gov-cjwaszczuk/master
Allow user to add multiple reply-to addresses
This commit is contained in:
@@ -467,8 +467,9 @@ class ProviderForm(Form):
|
||||
priority = IntegerField('Priority', [validators.NumberRange(min=1, max=100, message="Must be between 1 and 100")])
|
||||
|
||||
|
||||
class ServiceReplyToEmailFrom(Form):
|
||||
class ServiceReplyToEmailForm(Form):
|
||||
email_address = email_address(label='Email reply to address')
|
||||
is_default = BooleanField("Make this address the default")
|
||||
|
||||
|
||||
class ServiceSmsSender(Form):
|
||||
|
||||
@@ -27,7 +27,7 @@ from app.main.forms import (
|
||||
ConfirmPasswordForm,
|
||||
ServiceNameForm,
|
||||
RequestToGoLiveForm,
|
||||
ServiceReplyToEmailFrom,
|
||||
ServiceReplyToEmailForm,
|
||||
ServiceSmsSender,
|
||||
ServiceLetterContactBlock,
|
||||
ServiceBrandingOrg,
|
||||
@@ -67,7 +67,11 @@ def service_settings(service_id):
|
||||
|
||||
inbound_number = inbound_number_client.get_inbound_sms_number_for_service(service_id)
|
||||
disp_inbound_number = inbound_number['data'].get('number', '')
|
||||
|
||||
reply_to_email_addresses = service_api_client.get_reply_to_email_addresses(service_id)
|
||||
reply_to_email_address_count = len(reply_to_email_addresses)
|
||||
default_reply_to_email_address = next(
|
||||
(x['email_address'] for x in reply_to_email_addresses if x['is_default']), "None"
|
||||
)
|
||||
return render_template(
|
||||
'views/service-settings.html',
|
||||
organisation=organisation,
|
||||
@@ -77,7 +81,9 @@ def service_settings(service_id):
|
||||
can_receive_inbound=('inbound_sms' in current_service['permissions']),
|
||||
inbound_api_url=inbound_api_url,
|
||||
letter_contact_block=Field(current_service['letter_contact_block'], html='escape'),
|
||||
inbound_number=disp_inbound_number
|
||||
inbound_number=disp_inbound_number,
|
||||
default_reply_to_email_address=default_reply_to_email_address,
|
||||
reply_to_email_address_count=reply_to_email_address_count
|
||||
)
|
||||
|
||||
|
||||
@@ -308,23 +314,64 @@ def service_set_email(service_id):
|
||||
)
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/service-settings/set-reply-to-email", methods=['GET', 'POST'])
|
||||
@main.route("/services/<service_id>/service-settings/set-reply-to-email", methods=['GET'])
|
||||
@login_required
|
||||
@user_has_permissions('manage_settings', admin_override=True)
|
||||
def service_set_reply_to_email(service_id):
|
||||
form = ServiceReplyToEmailFrom()
|
||||
if request.method == 'GET':
|
||||
form.email_address.data = current_service.get('reply_to_email_address')
|
||||
if form.validate_on_submit():
|
||||
service_api_client.update_service(
|
||||
current_service['id'],
|
||||
reply_to_email_address=form.email_address.data
|
||||
)
|
||||
return redirect(url_for('.service_settings', service_id=service_id))
|
||||
return redirect(url_for('.service_email_reply_to', service_id=service_id))
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/service-settings/email-reply-to", methods=['GET'])
|
||||
@login_required
|
||||
@user_has_permissions('manage_settings', admin_override=True)
|
||||
def service_email_reply_to(service_id):
|
||||
reply_to_email_addresses = service_api_client.get_reply_to_email_addresses(service_id)
|
||||
return render_template(
|
||||
'views/service-settings/set-reply-to-email.html',
|
||||
form=form)
|
||||
'views/service-settings/email_reply_to.html',
|
||||
reply_to_email_addresses=reply_to_email_addresses)
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/service-settings/email-reply-to/add", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@user_has_permissions('manage_settings', admin_override=True)
|
||||
def service_add_email_reply_to(service_id):
|
||||
form = ServiceReplyToEmailForm()
|
||||
reply_to_email_address_count = len(service_api_client.get_reply_to_email_addresses(service_id))
|
||||
first_email_address = reply_to_email_address_count == 0
|
||||
if form.validate_on_submit():
|
||||
service_api_client.add_reply_to_email_address(
|
||||
current_service['id'],
|
||||
email_address=form.email_address.data,
|
||||
is_default=first_email_address if first_email_address else form.is_default.data
|
||||
)
|
||||
return redirect(url_for('.service_email_reply_to', service_id=service_id))
|
||||
return render_template(
|
||||
'views/service-settings/email-reply-to/add.html',
|
||||
form=form,
|
||||
first_email_address=first_email_address)
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/service-settings/email-reply-to/<reply_to_email_id>/edit", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@user_has_permissions('manage_settings', admin_override=True)
|
||||
def service_edit_email_reply_to(service_id, reply_to_email_id):
|
||||
form = ServiceReplyToEmailForm()
|
||||
reply_to_email_address = service_api_client.get_reply_to_email_address(service_id, reply_to_email_id)
|
||||
if request.method == 'GET':
|
||||
form.email_address.data = reply_to_email_address['email_address']
|
||||
form.is_default.data = reply_to_email_address['is_default']
|
||||
if form.validate_on_submit():
|
||||
service_api_client.update_reply_to_email_address(
|
||||
current_service['id'],
|
||||
reply_to_email_id=reply_to_email_id,
|
||||
email_address=form.email_address.data,
|
||||
is_default=True if reply_to_email_address['is_default'] else form.is_default.data
|
||||
)
|
||||
return redirect(url_for('.service_email_reply_to', service_id=service_id))
|
||||
return render_template(
|
||||
'views/service-settings/email-reply-to/edit.html',
|
||||
form=form,
|
||||
reply_to_email_address_id=reply_to_email_address['id'])
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/service-settings/set-sms-sender", methods=['GET', 'POST'])
|
||||
|
||||
@@ -282,6 +282,42 @@ class ServiceAPIClient(NotifyAdminAPIClient):
|
||||
)
|
||||
)['data']
|
||||
|
||||
def get_reply_to_email_addresses(self, service_id):
|
||||
return self.get(
|
||||
"/service/{}/email-reply-to".format(
|
||||
service_id
|
||||
)
|
||||
)
|
||||
|
||||
def get_reply_to_email_address(self, service_id, reply_to_email_id):
|
||||
return self.get(
|
||||
"/service/{}/email-reply-to/{}".format(
|
||||
service_id,
|
||||
reply_to_email_id
|
||||
)
|
||||
)
|
||||
|
||||
def add_reply_to_email_address(self, service_id, email_address, is_default=False):
|
||||
return self.post(
|
||||
"/service/{}/email-reply-to".format(service_id),
|
||||
data={
|
||||
"email_address": email_address,
|
||||
"is_default": is_default
|
||||
}
|
||||
)
|
||||
|
||||
def update_reply_to_email_address(self, service_id, reply_to_email_id, email_address, is_default=False):
|
||||
return self.post(
|
||||
"/service/{}/email-reply-to/{}".format(
|
||||
service_id,
|
||||
reply_to_email_id,
|
||||
),
|
||||
data={
|
||||
"email_address": email_address,
|
||||
"is_default": is_default
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class ServicesBrowsableItem(BrowsableItem):
|
||||
@property
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro list_table(items, caption='', empty_message='', field_headings=[], field_headings_visible=True, caption_visible=True) -%}
|
||||
|
||||
{% set parent_caller = caller %}
|
||||
|
||||
{% call mapping_table(caption, field_headings, field_headings_visible, caption_visible) %}
|
||||
|
||||
@@ -45,11 +45,15 @@
|
||||
|
||||
{% call row() %}
|
||||
{{ text_field('Email reply to address') }}
|
||||
{{ text_field(
|
||||
current_service.reply_to_email_address,
|
||||
status='' if current_service.reply_to_email_address else 'default'
|
||||
) }}
|
||||
{{ edit_field('Change', url_for('.service_set_reply_to_email', service_id=current_service.id)) }}
|
||||
{% call field() %}
|
||||
{{ default_reply_to_email_address }}
|
||||
{% if reply_to_email_address_count > 1 %}
|
||||
<div class="hint">
|
||||
{{ '…and %d more' | format(reply_to_email_address_count - 1) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
{{ edit_field('Change', url_for('.service_email_reply_to', service_id=current_service.id)) }}
|
||||
{% endcall %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
33
app/templates/views/service-settings/email-reply-to/add.html
Normal file
33
app/templates/views/service-settings/email-reply-to/add.html
Normal file
@@ -0,0 +1,33 @@
|
||||
{% extends "withnav_template.html" %}
|
||||
{% from "components/textbox.html" import textbox %}
|
||||
{% from "components/checkbox.html" import checkbox %}
|
||||
{% from "components/page-footer.html" import page_footer %}
|
||||
|
||||
{% block service_page_title %}
|
||||
Add email reply to address
|
||||
{% endblock %}
|
||||
|
||||
{% block maincolumn_content %}
|
||||
|
||||
<h1 class="heading-large">
|
||||
Add email reply to address
|
||||
</h1>
|
||||
<form method="post" novalidate>
|
||||
{{ textbox(
|
||||
form.email_address,
|
||||
width='2-3',
|
||||
safe_error_message=True
|
||||
) }}
|
||||
{% if not first_email_address %}
|
||||
<div class="form-group">
|
||||
{{ checkbox(form.is_default) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{{ page_footer(
|
||||
'Add',
|
||||
back_link=url_for('.service_email_reply_to', service_id=current_service.id),
|
||||
back_link_text='Back'
|
||||
) }}
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,35 @@
|
||||
{% extends "withnav_template.html" %}
|
||||
{% from "components/textbox.html" import textbox %}
|
||||
{% from "components/checkbox.html" import checkbox %}
|
||||
{% from "components/page-footer.html" import page_footer %}
|
||||
|
||||
{% block service_page_title %}
|
||||
Edit email reply to address
|
||||
{% endblock %}
|
||||
|
||||
{% block maincolumn_content %}
|
||||
|
||||
<h1 class="heading-large">
|
||||
Edit email reply to address
|
||||
</h1>
|
||||
<form method="post">
|
||||
{{ textbox(
|
||||
form.email_address,
|
||||
width='2-3',
|
||||
safe_error_message=True
|
||||
) }}
|
||||
{% if form.is_default.data %}
|
||||
<p> This email address is the default </p>
|
||||
{% else %}
|
||||
<div class="form-group">
|
||||
{{ checkbox(form.is_default) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{{ page_footer(
|
||||
'Save',
|
||||
back_link=url_for('.service_email_reply_to', service_id=current_service.id),
|
||||
back_link_text='Back'
|
||||
) }}
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
45
app/templates/views/service-settings/email_reply_to.html
Normal file
45
app/templates/views/service-settings/email_reply_to.html
Normal file
@@ -0,0 +1,45 @@
|
||||
{% extends "withnav_template.html" %}
|
||||
{% from "components/textbox.html" import textbox %}
|
||||
{% from "components/page-footer.html" import page_footer %}
|
||||
{% from "components/table.html" import row_group, row, text_field, edit_field, field, boolean_field, list_table %}
|
||||
|
||||
{% block service_page_title %}
|
||||
Email reply to addresses
|
||||
{% endblock %}
|
||||
|
||||
{% block maincolumn_content %}
|
||||
|
||||
<div class="grid-row bottom-gutter">
|
||||
<div class="column-two-thirds">
|
||||
<h1 class="heading-large">
|
||||
Email reply to addresses
|
||||
</h1>
|
||||
</div>
|
||||
<div class="column-one-third">
|
||||
<a href="{{ url_for('.service_add_email_reply_to', service_id=current_service.id) }}" class="button align-with-heading">Add email address</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-gutter-3-2 body-copy-table">
|
||||
{% call(item, row_number) list_table(
|
||||
reply_to_email_addresses,
|
||||
empty_message="You haven’t added any email addresses yet.",
|
||||
caption="Reply to email addresses",
|
||||
caption_visible=false,
|
||||
field_headings=[
|
||||
'Email addresses',
|
||||
'Action'
|
||||
],
|
||||
field_headings_visible=False
|
||||
) %}
|
||||
{% call field() %}
|
||||
{{ item.email_address }}
|
||||
{% if item.is_default %}
|
||||
<span class="hint">
|
||||
{{ "(default)" }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
{{ edit_field('Change', url_for('.service_edit_email_reply_to', service_id =current_service.id, reply_to_email_id = item.id)) }}
|
||||
{% endcall %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
30
package-lock.json
generated
30
package-lock.json
generated
@@ -2597,6 +2597,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"govuk_frontend_toolkit": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/govuk_frontend_toolkit/-/govuk_frontend_toolkit-5.2.0.tgz",
|
||||
"integrity": "sha1-9fbFrkjkMey5fYuAix6Nt3gqvH8="
|
||||
},
|
||||
"govuk_template_jinja": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/govuk_template_jinja/-/govuk_template_jinja-0.19.2.tgz",
|
||||
"integrity": "sha1-oNCTHJrLnYgtXsRGvocyxWxTarU="
|
||||
},
|
||||
"govuk-elements-sass": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/govuk-elements-sass/-/govuk-elements-sass-3.0.3.tgz",
|
||||
@@ -2612,16 +2622,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"govuk_frontend_toolkit": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/govuk_frontend_toolkit/-/govuk_frontend_toolkit-5.2.0.tgz",
|
||||
"integrity": "sha1-9fbFrkjkMey5fYuAix6Nt3gqvH8="
|
||||
},
|
||||
"govuk_template_jinja": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/govuk_template_jinja/-/govuk_template_jinja-0.19.2.tgz",
|
||||
"integrity": "sha1-oNCTHJrLnYgtXsRGvocyxWxTarU="
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "3.0.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz",
|
||||
@@ -5782,6 +5782,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
},
|
||||
"string-length": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz",
|
||||
@@ -5801,11 +5806,6 @@
|
||||
"strip-ansi": "3.0.1"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
},
|
||||
"stringstream": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
|
||||
|
||||
@@ -26,6 +26,7 @@ def test_get_inbound_number_in_service_settings(
|
||||
logged_in_client,
|
||||
mock_update_service,
|
||||
mock_get_letter_organisations,
|
||||
single_reply_to_email_addresses,
|
||||
service_one,
|
||||
mocker
|
||||
):
|
||||
|
||||
@@ -10,8 +10,17 @@ import app
|
||||
from app.main.views.service_settings import dummy_bearer_token
|
||||
from app.utils import email_safe
|
||||
from tests import validate_route_permission, service_json
|
||||
from tests.conftest import active_user_with_permissions, platform_admin_user
|
||||
from tests.conftest import normalize_spaces
|
||||
from tests.conftest import (
|
||||
active_user_with_permissions,
|
||||
platform_admin_user,
|
||||
normalize_spaces,
|
||||
no_reply_to_email_addresses,
|
||||
single_reply_to_email_addresses,
|
||||
multiple_reply_to_email_addresses,
|
||||
get_default_reply_to_email_address,
|
||||
get_non_default_reply_to_email_address,
|
||||
SERVICE_ONE_ID
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('user, expected_rows', [
|
||||
@@ -64,6 +73,7 @@ def test_should_show_overview(
|
||||
service_one,
|
||||
fake_uuid,
|
||||
mock_get_letter_organisations,
|
||||
no_reply_to_email_addresses,
|
||||
user,
|
||||
expected_rows,
|
||||
mock_get_inbound_number_for_service
|
||||
@@ -115,7 +125,7 @@ def test_should_show_overview(
|
||||
|
||||
'Label Value Action',
|
||||
'Send text messages On Change',
|
||||
'Text message sender elevenchars Change',
|
||||
'Text message sender GOVUK Change',
|
||||
'International text messages Off Change',
|
||||
'Receive text messages Off Change',
|
||||
|
||||
@@ -128,17 +138,18 @@ def test_should_show_overview_for_service_with_more_things_set(
|
||||
client,
|
||||
active_user_with_permissions,
|
||||
mocker,
|
||||
service_with_reply_to_addresses,
|
||||
service_one,
|
||||
single_reply_to_email_addresses,
|
||||
mock_get_organisation,
|
||||
mock_get_letter_organisations,
|
||||
mock_get_inbound_number_for_service,
|
||||
permissions,
|
||||
expected_rows
|
||||
):
|
||||
client.login(active_user_with_permissions, mocker, service_with_reply_to_addresses)
|
||||
service_with_reply_to_addresses['permissions'] = permissions
|
||||
client.login(active_user_with_permissions, mocker, service_one)
|
||||
service_one['permissions'] = permissions
|
||||
response = client.get(url_for(
|
||||
'main.service_settings', service_id=service_with_reply_to_addresses['id']
|
||||
'main.service_settings', service_id=service_one['id']
|
||||
))
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
for index, row in enumerate(expected_rows):
|
||||
@@ -154,6 +165,7 @@ def test_service_settings_show_elided_api_url_if_needed(
|
||||
logged_in_platform_admin_client,
|
||||
service_one,
|
||||
mock_get_letter_organisations,
|
||||
single_reply_to_email_addresses,
|
||||
mocker,
|
||||
fake_uuid,
|
||||
url,
|
||||
@@ -198,6 +210,7 @@ def test_if_can_receive_inbound_then_cant_change_sms_sender(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
mock_get_letter_organisations,
|
||||
single_reply_to_email_addresses,
|
||||
mock_get_inbound_number_for_service
|
||||
):
|
||||
service_one['permissions'] = ['email', 'sms', 'inbound_sms']
|
||||
@@ -216,6 +229,7 @@ def test_letter_contact_block_shows_none_if_not_set(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
mocker,
|
||||
single_reply_to_email_addresses,
|
||||
mock_get_letter_organisations,
|
||||
mock_get_inbound_number_for_service
|
||||
):
|
||||
@@ -234,6 +248,7 @@ def test_escapes_letter_contact_block(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
mocker,
|
||||
single_reply_to_email_addresses,
|
||||
mock_get_letter_organisations,
|
||||
mock_get_inbound_number_for_service
|
||||
):
|
||||
@@ -283,6 +298,7 @@ def test_show_restricted_service(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
mock_get_letter_organisations,
|
||||
single_reply_to_email_addresses,
|
||||
mock_get_inbound_number_for_service
|
||||
):
|
||||
response = logged_in_client.get(url_for('main.service_settings', service_id=service_one['id']))
|
||||
@@ -314,6 +330,7 @@ def test_show_live_service(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
mock_get_live_service,
|
||||
single_reply_to_email_addresses,
|
||||
mock_get_letter_organisations,
|
||||
mock_get_inbound_number_for_service
|
||||
):
|
||||
@@ -435,6 +452,7 @@ def test_should_redirect_after_request_to_go_live(
|
||||
active_user_with_permissions,
|
||||
service_one,
|
||||
mocker,
|
||||
single_reply_to_email_addresses,
|
||||
mock_get_letter_organisations,
|
||||
mock_get_inbound_number_for_service
|
||||
):
|
||||
@@ -528,6 +546,7 @@ def test_route_permissions(
|
||||
client,
|
||||
api_user_active,
|
||||
service_one,
|
||||
single_reply_to_email_addresses,
|
||||
mock_get_letter_organisations,
|
||||
route,
|
||||
mock_get_inbound_number_for_service
|
||||
@@ -585,6 +604,7 @@ def test_route_for_platform_admin(
|
||||
client,
|
||||
platform_admin_user,
|
||||
service_one,
|
||||
single_reply_to_email_addresses,
|
||||
mock_get_letter_organisations,
|
||||
route,
|
||||
mock_get_inbound_number_for_service
|
||||
@@ -652,37 +672,173 @@ def test_enabling_and_disabling_email_and_sms(
|
||||
assert mocked_fn.call_args == call(service_one['id'], {'permissions': permissions_after_switch})
|
||||
|
||||
|
||||
def test_set_reply_to_email_address(
|
||||
logged_in_client,
|
||||
mock_update_service,
|
||||
def test_reply_to_hint_appears_when_service_has_multiple_reply_to_addresses(
|
||||
client_request,
|
||||
multiple_reply_to_email_addresses,
|
||||
service_one,
|
||||
mock_get_letter_organisations,
|
||||
mock_get_inbound_number_for_service
|
||||
):
|
||||
service_one['permissions'] = ['email']
|
||||
data = {"email_address": "test@someservice.gov.uk"}
|
||||
response = logged_in_client.post(url_for('main.service_set_reply_to_email', service_id=service_one['id']),
|
||||
data=data,
|
||||
follow_redirects=True)
|
||||
assert response.status_code == 200
|
||||
mock_update_service.assert_called_with(
|
||||
service_one['id'],
|
||||
reply_to_email_address="test@someservice.gov.uk"
|
||||
page = client_request.get(
|
||||
'main.service_settings',
|
||||
service_id=service_one['id']
|
||||
)
|
||||
|
||||
assert normalize_spaces(
|
||||
page.select('tbody tr')[2].text
|
||||
) == "Email reply to address test@example.com …and 2 more Change"
|
||||
|
||||
|
||||
def test_default_email_reply_to_address_has_default_hint(
|
||||
client_request,
|
||||
multiple_reply_to_email_addresses
|
||||
):
|
||||
page = client_request.get(
|
||||
'main.service_email_reply_to',
|
||||
service_id=SERVICE_ONE_ID
|
||||
)
|
||||
|
||||
assert normalize_spaces(page.select('tbody tr')[0].text) == "test@example.com (default) Change"
|
||||
assert normalize_spaces(page.select('tbody tr')[1].text) == "test2@example.com Change"
|
||||
assert normalize_spaces(page.select('tbody tr')[2].text) == "test3@example.com Change"
|
||||
assert len(page.select('tbody tr')) == 3
|
||||
|
||||
|
||||
def test_no_reply_to_email_addresses_message_shows(
|
||||
client_request,
|
||||
no_reply_to_email_addresses
|
||||
):
|
||||
page = client_request.get(
|
||||
'main.service_email_reply_to',
|
||||
service_id=SERVICE_ONE_ID
|
||||
)
|
||||
|
||||
assert normalize_spaces(page.select('tbody tr')[0].text) == "You haven’t added any email addresses yet."
|
||||
assert len(page.select('tbody tr')) == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize('reply_to_input, expected_error', [
|
||||
('', 'Can’t be empty'),
|
||||
('testtest', 'Enter a valid email address'),
|
||||
('test@hello.com', 'Enter a government email address. If you think you should have access contact us')
|
||||
])
|
||||
def test_incorrect_reply_to_email_address(
|
||||
reply_to_input,
|
||||
expected_error,
|
||||
client_request,
|
||||
no_reply_to_email_addresses
|
||||
):
|
||||
page = client_request.post(
|
||||
'main.service_add_email_reply_to',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
_data={'email_address': reply_to_input},
|
||||
_expected_status=200
|
||||
)
|
||||
|
||||
assert normalize_spaces(page.select_one('.error-message').text) == expected_error
|
||||
|
||||
|
||||
@pytest.mark.parametrize('fixture, data, api_default_args', [
|
||||
(no_reply_to_email_addresses, {}, True),
|
||||
(multiple_reply_to_email_addresses, {}, False),
|
||||
(multiple_reply_to_email_addresses, {"is_default": "y"}, True)
|
||||
])
|
||||
def test_add_reply_to_email_address(
|
||||
fixture,
|
||||
data,
|
||||
api_default_args,
|
||||
mocker,
|
||||
client_request,
|
||||
mock_add_reply_to_email_address
|
||||
):
|
||||
fixture(mocker)
|
||||
data['email_address'] = "test@example.gov.uk"
|
||||
page = client_request.post(
|
||||
'main.service_add_email_reply_to',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
_data=data
|
||||
)
|
||||
|
||||
mock_add_reply_to_email_address.assert_called_once_with(
|
||||
SERVICE_ONE_ID,
|
||||
email_address="test@example.gov.uk",
|
||||
is_default=api_default_args
|
||||
)
|
||||
|
||||
|
||||
def test_if_reply_to_email_address_set_then_form_populated(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
mock_get_inbound_number_for_service
|
||||
@pytest.mark.parametrize('fixture, checkbox_present', [
|
||||
(no_reply_to_email_addresses, False),
|
||||
(multiple_reply_to_email_addresses, True)
|
||||
])
|
||||
def test_default_box_shows_on_first_email_address(
|
||||
fixture,
|
||||
mocker,
|
||||
checkbox_present,
|
||||
client_request
|
||||
):
|
||||
service_one['permissions'] = ['email']
|
||||
service_one['reply_to_email_address'] = 'test@service.gov.uk'
|
||||
response = logged_in_client.get(url_for('main.service_set_reply_to_email', service_id=service_one['id']))
|
||||
fixture(mocker)
|
||||
page = client_request.get(
|
||||
'main.service_add_email_reply_to',
|
||||
service_id=SERVICE_ONE_ID
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
assert page.find(id='email_address')['value'] == 'test@service.gov.uk'
|
||||
assert bool(page.select_one('[name=is_default]')) == checkbox_present
|
||||
|
||||
|
||||
@pytest.mark.parametrize('fixture, data, api_default_args', [
|
||||
(get_default_reply_to_email_address, {"is_default": "y"}, True),
|
||||
(get_default_reply_to_email_address, {}, True),
|
||||
(get_non_default_reply_to_email_address, {}, False),
|
||||
(get_non_default_reply_to_email_address, {"is_default": "y"}, True)
|
||||
])
|
||||
def test_edit_reply_to_email_address(
|
||||
fixture,
|
||||
data,
|
||||
api_default_args,
|
||||
mocker,
|
||||
fake_uuid,
|
||||
client_request,
|
||||
mock_update_reply_to_email_address
|
||||
):
|
||||
fixture(mocker)
|
||||
data['email_address'] = "test@example.gov.uk"
|
||||
page = client_request.post(
|
||||
'main.service_edit_email_reply_to',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
reply_to_email_id=fake_uuid,
|
||||
_data=data
|
||||
)
|
||||
|
||||
mock_update_reply_to_email_address.assert_called_once_with(
|
||||
SERVICE_ONE_ID,
|
||||
reply_to_email_id=fake_uuid,
|
||||
email_address="test@example.gov.uk",
|
||||
is_default=api_default_args
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('fixture, checkbox_present', [
|
||||
(get_default_reply_to_email_address, False),
|
||||
(get_non_default_reply_to_email_address, True)
|
||||
])
|
||||
def test_default_box_shows_on_non_default_email_addresses_while_editing(
|
||||
fixture,
|
||||
fake_uuid,
|
||||
mocker,
|
||||
checkbox_present,
|
||||
client_request
|
||||
):
|
||||
fixture(mocker)
|
||||
page = client_request.get(
|
||||
'main.service_edit_email_reply_to',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
reply_to_email_id=fake_uuid
|
||||
)
|
||||
|
||||
if checkbox_present:
|
||||
assert page.select_one('[name=is_default]')
|
||||
else:
|
||||
assert normalize_spaces(page.select_one('form p').text) == "This email address is the default"
|
||||
|
||||
|
||||
def test_switch_service_to_research_mode(
|
||||
@@ -731,6 +887,7 @@ def test_shows_research_mode_indicator(
|
||||
service_one,
|
||||
mocker,
|
||||
mock_get_letter_organisations,
|
||||
single_reply_to_email_addresses,
|
||||
mock_get_inbound_number_for_service
|
||||
):
|
||||
service_one['research_mode'] = True
|
||||
@@ -748,6 +905,7 @@ def test_does_not_show_research_mode_indicator(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
mock_get_letter_organisations,
|
||||
single_reply_to_email_addresses,
|
||||
mock_get_inbound_number_for_service
|
||||
):
|
||||
response = logged_in_client.get(url_for('main.service_settings', service_id=service_one['id']))
|
||||
@@ -1176,6 +1334,7 @@ def test_archive_service_prompts_user(
|
||||
logged_in_platform_admin_client,
|
||||
service_one,
|
||||
mocker,
|
||||
single_reply_to_email_addresses,
|
||||
mock_get_letter_organisations,
|
||||
mock_get_inbound_number_for_service
|
||||
):
|
||||
@@ -1192,6 +1351,7 @@ def test_archive_service_prompts_user(
|
||||
def test_cant_archive_inactive_service(
|
||||
logged_in_platform_admin_client,
|
||||
service_one,
|
||||
single_reply_to_email_addresses,
|
||||
mock_get_letter_organisations,
|
||||
mock_get_inbound_number_for_service
|
||||
):
|
||||
@@ -1223,6 +1383,7 @@ def test_suspend_service_prompts_user(
|
||||
logged_in_platform_admin_client,
|
||||
service_one,
|
||||
mocker,
|
||||
single_reply_to_email_addresses,
|
||||
mock_get_letter_organisations,
|
||||
mock_get_inbound_number_for_service
|
||||
):
|
||||
@@ -1240,6 +1401,7 @@ def test_suspend_service_prompts_user(
|
||||
def test_cant_suspend_inactive_service(
|
||||
logged_in_platform_admin_client,
|
||||
service_one,
|
||||
single_reply_to_email_addresses,
|
||||
mock_get_letter_organisations,
|
||||
mock_get_inbound_number_for_service
|
||||
):
|
||||
@@ -1255,6 +1417,7 @@ def test_cant_suspend_inactive_service(
|
||||
def test_resume_service_after_confirm(
|
||||
logged_in_platform_admin_client,
|
||||
service_one,
|
||||
single_reply_to_email_addresses,
|
||||
mocker,
|
||||
mock_get_inbound_number_for_service
|
||||
):
|
||||
@@ -1271,6 +1434,7 @@ def test_resume_service_after_confirm(
|
||||
def test_resume_service_prompts_user(
|
||||
logged_in_platform_admin_client,
|
||||
service_one,
|
||||
single_reply_to_email_addresses,
|
||||
mocker,
|
||||
mock_get_letter_organisations,
|
||||
mock_get_inbound_number_for_service
|
||||
@@ -1290,6 +1454,7 @@ def test_resume_service_prompts_user(
|
||||
def test_cant_resume_active_service(
|
||||
logged_in_platform_admin_client,
|
||||
service_one,
|
||||
single_reply_to_email_addresses,
|
||||
mock_get_letter_organisations,
|
||||
mock_get_inbound_number_for_service
|
||||
):
|
||||
@@ -1365,6 +1530,7 @@ def test_invitation_pages(
|
||||
def test_service_settings_when_inbound_number_is_not_set(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
single_reply_to_email_addresses,
|
||||
mocker,
|
||||
mock_get_letter_organisations,
|
||||
):
|
||||
@@ -1379,6 +1545,7 @@ def test_service_settings_when_inbound_number_is_not_set(
|
||||
def test_set_inbound_sms_when_inbound_number_is_not_set(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
single_reply_to_email_addresses,
|
||||
mocker,
|
||||
mock_get_letter_organisations,
|
||||
):
|
||||
|
||||
@@ -50,14 +50,105 @@ def service_one(api_user_active):
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def service_with_reply_to_addresses(api_user_active):
|
||||
return service_json(
|
||||
SERVICE_ONE_ID,
|
||||
'service one',
|
||||
[api_user_active.id],
|
||||
reply_to_email_address='test@example.com',
|
||||
sms_sender='elevenchars',
|
||||
)
|
||||
def multiple_reply_to_email_addresses(mocker):
|
||||
def _get(service_id):
|
||||
return [
|
||||
{
|
||||
'id': '1234',
|
||||
'service_id': service_id,
|
||||
'email_address': 'test@example.com',
|
||||
'is_default': True,
|
||||
'created_at': datetime.utcnow(),
|
||||
'updated_at': None
|
||||
}, {
|
||||
'id': '5678',
|
||||
'service_id': service_id,
|
||||
'email_address': 'test2@example.com',
|
||||
'is_default': False,
|
||||
'created_at': datetime.utcnow(),
|
||||
'updated_at': None
|
||||
}, {
|
||||
'id': '9457',
|
||||
'service_id': service_id,
|
||||
'email_address': 'test3@example.com',
|
||||
'is_default': False,
|
||||
'created_at': datetime.utcnow(),
|
||||
'updated_at': None
|
||||
}
|
||||
]
|
||||
|
||||
return mocker.patch('app.service_api_client.get_reply_to_email_addresses', side_effect=_get)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def no_reply_to_email_addresses(mocker):
|
||||
def _get(service_id):
|
||||
return []
|
||||
|
||||
return mocker.patch('app.service_api_client.get_reply_to_email_addresses', side_effect=_get)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def single_reply_to_email_addresses(mocker):
|
||||
def _get(service_id):
|
||||
return [
|
||||
{
|
||||
'id': '1234',
|
||||
'service_id': service_id,
|
||||
'email_address': 'test@example.com',
|
||||
'is_default': True,
|
||||
'created_at': datetime.utcnow(),
|
||||
'updated_at': None
|
||||
}
|
||||
]
|
||||
|
||||
return mocker.patch('app.service_api_client.get_reply_to_email_addresses', side_effect=_get)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def get_default_reply_to_email_address(mocker):
|
||||
def _get(service_id, reply_to_email_id):
|
||||
return {
|
||||
'id': '1234',
|
||||
'service_id': service_id,
|
||||
'email_address': 'test@example.com',
|
||||
'is_default': True,
|
||||
'created_at': datetime.utcnow(),
|
||||
'updated_at': None
|
||||
}
|
||||
|
||||
return mocker.patch('app.service_api_client.get_reply_to_email_address', side_effect=_get)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def get_non_default_reply_to_email_address(mocker):
|
||||
def _get(service_id, reply_to_email_id):
|
||||
return {
|
||||
'id': '1234',
|
||||
'service_id': service_id,
|
||||
'email_address': 'test@example.com',
|
||||
'is_default': False,
|
||||
'created_at': datetime.utcnow(),
|
||||
'updated_at': None
|
||||
}
|
||||
|
||||
return mocker.patch('app.service_api_client.get_reply_to_email_address', side_effect=_get)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def mock_add_reply_to_email_address(mocker):
|
||||
def _add_reply_to(service_id, email_address, is_default=False):
|
||||
return
|
||||
|
||||
return mocker.patch('app.service_api_client.add_reply_to_email_address', side_effect=_add_reply_to)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def mock_update_reply_to_email_address(mocker):
|
||||
def _update_reply_to(service_id, reply_to_email_id, email_address, is_default=False):
|
||||
return
|
||||
|
||||
return mocker.patch('app.service_api_client.update_reply_to_email_address', side_effect=_update_reply_to)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
@@ -206,7 +297,6 @@ def mock_update_service(mocker):
|
||||
'active',
|
||||
'restricted',
|
||||
'email_from',
|
||||
'reply_to_email_address',
|
||||
'sms_sender',
|
||||
'permissions'
|
||||
]}
|
||||
|
||||
Reference in New Issue
Block a user