Merge pull request #1509 from gov-cjwaszczuk/master

Allow user to add multiple reply-to addresses
This commit is contained in:
Chris Waszczuk
2017-09-26 09:48:45 +01:00
committed by GitHub
12 changed files with 533 additions and 75 deletions

View File

@@ -467,8 +467,9 @@ class ProviderForm(Form):
priority = IntegerField('Priority', [validators.NumberRange(min=1, max=100, message="Must be between 1 and 100")]) 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') email_address = email_address(label='Email reply to address')
is_default = BooleanField("Make this address the default")
class ServiceSmsSender(Form): class ServiceSmsSender(Form):

View File

@@ -27,7 +27,7 @@ from app.main.forms import (
ConfirmPasswordForm, ConfirmPasswordForm,
ServiceNameForm, ServiceNameForm,
RequestToGoLiveForm, RequestToGoLiveForm,
ServiceReplyToEmailFrom, ServiceReplyToEmailForm,
ServiceSmsSender, ServiceSmsSender,
ServiceLetterContactBlock, ServiceLetterContactBlock,
ServiceBrandingOrg, ServiceBrandingOrg,
@@ -67,7 +67,11 @@ def service_settings(service_id):
inbound_number = inbound_number_client.get_inbound_sms_number_for_service(service_id) inbound_number = inbound_number_client.get_inbound_sms_number_for_service(service_id)
disp_inbound_number = inbound_number['data'].get('number', '') 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( return render_template(
'views/service-settings.html', 'views/service-settings.html',
organisation=organisation, organisation=organisation,
@@ -77,7 +81,9 @@ def service_settings(service_id):
can_receive_inbound=('inbound_sms' in current_service['permissions']), can_receive_inbound=('inbound_sms' in current_service['permissions']),
inbound_api_url=inbound_api_url, inbound_api_url=inbound_api_url,
letter_contact_block=Field(current_service['letter_contact_block'], html='escape'), 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 @login_required
@user_has_permissions('manage_settings', admin_override=True) @user_has_permissions('manage_settings', admin_override=True)
def service_set_reply_to_email(service_id): def service_set_reply_to_email(service_id):
form = ServiceReplyToEmailFrom() return redirect(url_for('.service_email_reply_to', service_id=service_id))
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))
@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( return render_template(
'views/service-settings/set-reply-to-email.html', 'views/service-settings/email_reply_to.html',
form=form) 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']) @main.route("/services/<service_id>/service-settings/set-sms-sender", methods=['GET', 'POST'])

View File

@@ -282,6 +282,42 @@ class ServiceAPIClient(NotifyAdminAPIClient):
) )
)['data'] )['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): class ServicesBrowsableItem(BrowsableItem):
@property @property

View File

@@ -25,7 +25,6 @@
{%- endmacro %} {%- endmacro %}
{% macro list_table(items, caption='', empty_message='', field_headings=[], field_headings_visible=True, caption_visible=True) -%} {% macro list_table(items, caption='', empty_message='', field_headings=[], field_headings_visible=True, caption_visible=True) -%}
{% set parent_caller = caller %} {% set parent_caller = caller %}
{% call mapping_table(caption, field_headings, field_headings_visible, caption_visible) %} {% call mapping_table(caption, field_headings, field_headings_visible, caption_visible) %}

View File

@@ -45,11 +45,15 @@
{% call row() %} {% call row() %}
{{ text_field('Email reply to address') }} {{ text_field('Email reply to address') }}
{{ text_field( {% call field() %}
current_service.reply_to_email_address, {{ default_reply_to_email_address }}
status='' if current_service.reply_to_email_address else 'default' {% if reply_to_email_address_count > 1 %}
) }} <div class="hint">
{{ edit_field('Change', url_for('.service_set_reply_to_email', service_id=current_service.id)) }} {{ '…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 %} {% endcall %}
{% endif %} {% endif %}

View 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 %}

View File

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

View 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 havent 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
View File

@@ -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": { "govuk-elements-sass": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/govuk-elements-sass/-/govuk-elements-sass-3.0.3.tgz", "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": { "graceful-fs": {
"version": "3.0.11", "version": "3.0.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", "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": { "string-length": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz",
@@ -5801,11 +5806,6 @@
"strip-ansi": "3.0.1" "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": { "stringstream": {
"version": "0.0.5", "version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",

View File

@@ -26,6 +26,7 @@ def test_get_inbound_number_in_service_settings(
logged_in_client, logged_in_client,
mock_update_service, mock_update_service,
mock_get_letter_organisations, mock_get_letter_organisations,
single_reply_to_email_addresses,
service_one, service_one,
mocker mocker
): ):

View File

@@ -10,8 +10,17 @@ import app
from app.main.views.service_settings import dummy_bearer_token from app.main.views.service_settings import dummy_bearer_token
from app.utils import email_safe from app.utils import email_safe
from tests import validate_route_permission, service_json from tests import validate_route_permission, service_json
from tests.conftest import active_user_with_permissions, platform_admin_user from tests.conftest import (
from tests.conftest import normalize_spaces 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', [ @pytest.mark.parametrize('user, expected_rows', [
@@ -64,6 +73,7 @@ def test_should_show_overview(
service_one, service_one,
fake_uuid, fake_uuid,
mock_get_letter_organisations, mock_get_letter_organisations,
no_reply_to_email_addresses,
user, user,
expected_rows, expected_rows,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
@@ -115,7 +125,7 @@ def test_should_show_overview(
'Label Value Action', 'Label Value Action',
'Send text messages On Change', 'Send text messages On Change',
'Text message sender elevenchars Change', 'Text message sender GOVUK Change',
'International text messages Off Change', 'International text messages Off Change',
'Receive 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, client,
active_user_with_permissions, active_user_with_permissions,
mocker, mocker,
service_with_reply_to_addresses, service_one,
single_reply_to_email_addresses,
mock_get_organisation, mock_get_organisation,
mock_get_letter_organisations, mock_get_letter_organisations,
mock_get_inbound_number_for_service, mock_get_inbound_number_for_service,
permissions, permissions,
expected_rows expected_rows
): ):
client.login(active_user_with_permissions, mocker, service_with_reply_to_addresses) client.login(active_user_with_permissions, mocker, service_one)
service_with_reply_to_addresses['permissions'] = permissions service_one['permissions'] = permissions
response = client.get(url_for( 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') page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
for index, row in enumerate(expected_rows): 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, logged_in_platform_admin_client,
service_one, service_one,
mock_get_letter_organisations, mock_get_letter_organisations,
single_reply_to_email_addresses,
mocker, mocker,
fake_uuid, fake_uuid,
url, url,
@@ -198,6 +210,7 @@ def test_if_can_receive_inbound_then_cant_change_sms_sender(
logged_in_client, logged_in_client,
service_one, service_one,
mock_get_letter_organisations, mock_get_letter_organisations,
single_reply_to_email_addresses,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
): ):
service_one['permissions'] = ['email', 'sms', 'inbound_sms'] service_one['permissions'] = ['email', 'sms', 'inbound_sms']
@@ -216,6 +229,7 @@ def test_letter_contact_block_shows_none_if_not_set(
logged_in_client, logged_in_client,
service_one, service_one,
mocker, mocker,
single_reply_to_email_addresses,
mock_get_letter_organisations, mock_get_letter_organisations,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
): ):
@@ -234,6 +248,7 @@ def test_escapes_letter_contact_block(
logged_in_client, logged_in_client,
service_one, service_one,
mocker, mocker,
single_reply_to_email_addresses,
mock_get_letter_organisations, mock_get_letter_organisations,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
): ):
@@ -283,6 +298,7 @@ def test_show_restricted_service(
logged_in_client, logged_in_client,
service_one, service_one,
mock_get_letter_organisations, mock_get_letter_organisations,
single_reply_to_email_addresses,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
): ):
response = logged_in_client.get(url_for('main.service_settings', service_id=service_one['id'])) 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, logged_in_client,
service_one, service_one,
mock_get_live_service, mock_get_live_service,
single_reply_to_email_addresses,
mock_get_letter_organisations, mock_get_letter_organisations,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
): ):
@@ -435,6 +452,7 @@ def test_should_redirect_after_request_to_go_live(
active_user_with_permissions, active_user_with_permissions,
service_one, service_one,
mocker, mocker,
single_reply_to_email_addresses,
mock_get_letter_organisations, mock_get_letter_organisations,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
): ):
@@ -528,6 +546,7 @@ def test_route_permissions(
client, client,
api_user_active, api_user_active,
service_one, service_one,
single_reply_to_email_addresses,
mock_get_letter_organisations, mock_get_letter_organisations,
route, route,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
@@ -585,6 +604,7 @@ def test_route_for_platform_admin(
client, client,
platform_admin_user, platform_admin_user,
service_one, service_one,
single_reply_to_email_addresses,
mock_get_letter_organisations, mock_get_letter_organisations,
route, route,
mock_get_inbound_number_for_service 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}) assert mocked_fn.call_args == call(service_one['id'], {'permissions': permissions_after_switch})
def test_set_reply_to_email_address( def test_reply_to_hint_appears_when_service_has_multiple_reply_to_addresses(
logged_in_client, client_request,
mock_update_service, multiple_reply_to_email_addresses,
service_one, service_one,
mock_get_letter_organisations, mock_get_letter_organisations,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
): ):
service_one['permissions'] = ['email'] page = client_request.get(
data = {"email_address": "test@someservice.gov.uk"} 'main.service_settings',
response = logged_in_client.post(url_for('main.service_set_reply_to_email', service_id=service_one['id']), service_id=service_one['id']
data=data, )
follow_redirects=True)
assert response.status_code == 200 assert normalize_spaces(
mock_update_service.assert_called_with( page.select('tbody tr')[2].text
service_one['id'], ) == "Email reply to address test@example.com …and 2 more Change"
reply_to_email_address="test@someservice.gov.uk"
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 havent added any email addresses yet."
assert len(page.select('tbody tr')) == 1
@pytest.mark.parametrize('reply_to_input, expected_error', [
('', 'Cant 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( @pytest.mark.parametrize('fixture, checkbox_present', [
logged_in_client, (no_reply_to_email_addresses, False),
service_one, (multiple_reply_to_email_addresses, True)
mock_get_inbound_number_for_service ])
def test_default_box_shows_on_first_email_address(
fixture,
mocker,
checkbox_present,
client_request
): ):
service_one['permissions'] = ['email'] fixture(mocker)
service_one['reply_to_email_address'] = 'test@service.gov.uk' page = client_request.get(
response = logged_in_client.get(url_for('main.service_set_reply_to_email', service_id=service_one['id'])) 'main.service_add_email_reply_to',
service_id=SERVICE_ONE_ID
)
assert response.status_code == 200 assert bool(page.select_one('[name=is_default]')) == checkbox_present
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
assert page.find(id='email_address')['value'] == 'test@service.gov.uk'
@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( def test_switch_service_to_research_mode(
@@ -731,6 +887,7 @@ def test_shows_research_mode_indicator(
service_one, service_one,
mocker, mocker,
mock_get_letter_organisations, mock_get_letter_organisations,
single_reply_to_email_addresses,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
): ):
service_one['research_mode'] = True service_one['research_mode'] = True
@@ -748,6 +905,7 @@ def test_does_not_show_research_mode_indicator(
logged_in_client, logged_in_client,
service_one, service_one,
mock_get_letter_organisations, mock_get_letter_organisations,
single_reply_to_email_addresses,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
): ):
response = logged_in_client.get(url_for('main.service_settings', service_id=service_one['id'])) 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, logged_in_platform_admin_client,
service_one, service_one,
mocker, mocker,
single_reply_to_email_addresses,
mock_get_letter_organisations, mock_get_letter_organisations,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
): ):
@@ -1192,6 +1351,7 @@ def test_archive_service_prompts_user(
def test_cant_archive_inactive_service( def test_cant_archive_inactive_service(
logged_in_platform_admin_client, logged_in_platform_admin_client,
service_one, service_one,
single_reply_to_email_addresses,
mock_get_letter_organisations, mock_get_letter_organisations,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
): ):
@@ -1223,6 +1383,7 @@ def test_suspend_service_prompts_user(
logged_in_platform_admin_client, logged_in_platform_admin_client,
service_one, service_one,
mocker, mocker,
single_reply_to_email_addresses,
mock_get_letter_organisations, mock_get_letter_organisations,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
): ):
@@ -1240,6 +1401,7 @@ def test_suspend_service_prompts_user(
def test_cant_suspend_inactive_service( def test_cant_suspend_inactive_service(
logged_in_platform_admin_client, logged_in_platform_admin_client,
service_one, service_one,
single_reply_to_email_addresses,
mock_get_letter_organisations, mock_get_letter_organisations,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
): ):
@@ -1255,6 +1417,7 @@ def test_cant_suspend_inactive_service(
def test_resume_service_after_confirm( def test_resume_service_after_confirm(
logged_in_platform_admin_client, logged_in_platform_admin_client,
service_one, service_one,
single_reply_to_email_addresses,
mocker, mocker,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
): ):
@@ -1271,6 +1434,7 @@ def test_resume_service_after_confirm(
def test_resume_service_prompts_user( def test_resume_service_prompts_user(
logged_in_platform_admin_client, logged_in_platform_admin_client,
service_one, service_one,
single_reply_to_email_addresses,
mocker, mocker,
mock_get_letter_organisations, mock_get_letter_organisations,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
@@ -1290,6 +1454,7 @@ def test_resume_service_prompts_user(
def test_cant_resume_active_service( def test_cant_resume_active_service(
logged_in_platform_admin_client, logged_in_platform_admin_client,
service_one, service_one,
single_reply_to_email_addresses,
mock_get_letter_organisations, mock_get_letter_organisations,
mock_get_inbound_number_for_service mock_get_inbound_number_for_service
): ):
@@ -1365,6 +1530,7 @@ def test_invitation_pages(
def test_service_settings_when_inbound_number_is_not_set( def test_service_settings_when_inbound_number_is_not_set(
logged_in_client, logged_in_client,
service_one, service_one,
single_reply_to_email_addresses,
mocker, mocker,
mock_get_letter_organisations, 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( def test_set_inbound_sms_when_inbound_number_is_not_set(
logged_in_client, logged_in_client,
service_one, service_one,
single_reply_to_email_addresses,
mocker, mocker,
mock_get_letter_organisations, mock_get_letter_organisations,
): ):

View File

@@ -50,14 +50,105 @@ def service_one(api_user_active):
@pytest.fixture(scope='function') @pytest.fixture(scope='function')
def service_with_reply_to_addresses(api_user_active): def multiple_reply_to_email_addresses(mocker):
return service_json( def _get(service_id):
SERVICE_ONE_ID, return [
'service one', {
[api_user_active.id], 'id': '1234',
reply_to_email_address='test@example.com', 'service_id': service_id,
sms_sender='elevenchars', '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') @pytest.fixture(scope='function')
@@ -206,7 +297,6 @@ def mock_update_service(mocker):
'active', 'active',
'restricted', 'restricted',
'email_from', 'email_from',
'reply_to_email_address',
'sms_sender', 'sms_sender',
'permissions' 'permissions'
]} ]}