Merge pull request #2968 from alphagov/require-approval-on-go-live

Allow custom notes when service goes live
This commit is contained in:
Katie Smith
2019-05-15 10:51:31 +01:00
committed by GitHub
9 changed files with 186 additions and 6 deletions

View File

@@ -1453,3 +1453,10 @@ class ClearCacheForm(StripWhitespaceForm):
'What do you want to clear today',
validators=[DataRequired()]
)
class GoLiveNotesForm(StripWhitespaceForm):
request_to_go_live_notes = TextAreaField(
'Go live notes',
filters=[lambda x: x or None],
)

View File

@@ -17,6 +17,7 @@ from app.main import main
from app.main.forms import (
ConfirmPasswordForm,
CreateOrUpdateOrganisation,
GoLiveNotesForm,
InviteOrgUserForm,
OrganisationAgreementSignedForm,
OrganisationCrownStatusForm,
@@ -464,3 +465,27 @@ def confirm_edit_organisation_name(org_id):
'views/organisations/organisation/settings/edit-name/confirm.html',
new_name=session['organisation_name_change'],
form=form)
@main.route("/organisations/<org_id>/settings/edit-go-live-notes", methods=['GET', 'POST'])
@login_required
@user_has_permissions()
@user_is_platform_admin
def edit_organisation_go_live_notes(org_id):
form = GoLiveNotesForm()
if form.validate_on_submit():
organisations_client.update_organisation(
org_id,
request_to_go_live_notes=form.request_to_go_live_notes.data
)
return redirect(url_for('.organisation_settings', org_id=org_id))
org = organisations_client.get_organisation(org_id)
form.request_to_go_live_notes.data = org['request_to_go_live_notes']
return render_template(
'views/organisations/organisation/settings/edit-go-live-notes.html',
form=form,
)

View File

@@ -18,6 +18,7 @@ class Organisation(JSONModel):
'agreement_signed_by_id',
'agreement_signed_version',
'domains',
'request_to_go_live_notes',
}
def __init__(self, _dict):
@@ -30,14 +31,13 @@ class Organisation(JSONModel):
self.agreement_signed = None
self.domains = []
self.organisation_type = None
self.request_to_go_live_notes = None
def as_human_readable(self, fallback_domain):
if 'dwp.' in ''.join(self.domains):
return 'DWP - Requires OED approval'
if self.agreement_signed:
return 'Yes, on behalf of {}'.format(self.name)
agreement_statement = 'Yes, on behalf of {}.'.format(self.name)
elif self.name:
return '{} (organisation is {}, {})'.format(
agreement_statement = '{} (organisation is {}, {}).'.format(
{
False: 'No',
None: 'Cant tell',
@@ -50,7 +50,12 @@ class Organisation(JSONModel):
}.get(self.crown),
)
else:
return 'Cant tell (domain is {})'.format(fallback_domain)
agreement_statement = 'Cant tell (domain is {}).'.format(fallback_domain)
if self.request_to_go_live_notes:
agreement_statement = agreement_statement + ' ' + self.request_to_go_live_notes
return agreement_statement
def as_info_for_branding_request(self, fallback_domain):
return self.name or 'Cant tell (domain is {})'.format(fallback_domain)

View File

@@ -166,6 +166,7 @@ class HeaderNavigation(Navigation):
'edit_organisation_domains',
'edit_organisation_email_branding',
'edit_organisation_letter_branding',
'edit_organisation_go_live_notes',
'edit_organisation_name',
'edit_organisation_type',
'edit_provider',
@@ -451,6 +452,7 @@ class MainNavigation(Navigation):
'edit_organisation_crown_status',
'edit_organisation_email_branding',
'edit_organisation_domains',
'edit_organisation_go_live_notes',
'edit_organisation_letter_branding',
'edit_organisation_name',
'edit_organisation_type',
@@ -630,6 +632,7 @@ class CaseworkNavigation(Navigation):
'edit_organisation_crown_status',
'edit_organisation_domains',
'edit_organisation_email_branding',
'edit_organisation_go_live_notes',
'edit_organisation_letter_branding',
'confirm_edit_organisation_name',
'confirm_edit_user_email',
@@ -854,6 +857,7 @@ class OrgNavigation(Navigation):
'edit_organisation_email_branding',
'edit_organisation_letter_branding',
'edit_organisation_domains',
'edit_organisation_go_live_notes',
'edit_organisation_name',
'edit_organisation_type',
'organisation_preview_email_branding',

View File

@@ -0,0 +1,25 @@
{% from "components/form.html" import form_wrapper %}
{% from "components/page-footer.html" import page_footer %}
{% from "components/textbox.html" import textbox %}
{% extends "org_template.html" %}
{% block org_page_title %}
Edit request to go live notes
{% endblock %}
{% block maincolumn_content %}
<h1 class="heading-large">Edit request to go live notes</h1>
<div class="grid-row">
<div class="column-five-sixths">
<p>
Text entered here will be displayed in the Zendesk ticket when a service
belonging to this organisation requests to go live.
</p>
{% call form_wrapper() %}
{{ textbox(form.request_to_go_live_notes, width='1-1', rows=3) }}
{{ page_footer('Save') }}
{% endcall %}
</div>
</div>
{% endblock %}

View File

@@ -79,6 +79,15 @@
)
}}
{% endcall %}
{% call row() %}
{{ text_field('Request to go live notes') }}
{{ optional_text_field(current_org.request_to_go_live_notes, default='None') }}
{{ edit_field(
'Change',
url_for('.edit_organisation_go_live_notes', org_id=current_org.id)
)
}}
{% endcall %}
{% call row() %}
{{ text_field('Default email branding') }}
{{ text_field(email_branding) }}

View File

@@ -195,6 +195,7 @@ def organisation_json(
crown=True,
agreement_signed=False,
organisation_type='',
request_to_go_live_notes=None,
):
if users is None:
users = []
@@ -215,6 +216,7 @@ def organisation_json(
'agreement_signed_at': None,
'agreement_signed_by': None,
'domains': domains or [],
'request_to_go_live_notes': request_to_go_live_notes,
}

View File

@@ -503,6 +503,7 @@ def test_organisation_settings_for_platform_admin(
'Organisation type Not set Change',
'Crown organisation Yes Change',
'Data sharing and financial agreement Not signed Change',
'Request to go live notes None Change',
'Default email branding GOV.UK Change',
'Default letter branding No branding Change',
'Known email domains None Change',
@@ -945,3 +946,53 @@ def test_confirm_update_organisation_with_name_already_in_use(
assert response.status_code == 302
assert response.location == url_for('main.edit_organisation_name', org_id=organisation_one['id'], _external=True)
def test_get_edit_organisation_go_live_notes_page(
logged_in_platform_admin_client,
mock_get_organisation,
organisation_one,
):
response = logged_in_platform_admin_client.get(
url_for(
'.edit_organisation_go_live_notes',
org_id=organisation_one['id']
)
)
assert response.status_code == 200
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
assert page.find('textarea', id='request_to_go_live_notes')
@pytest.mark.parametrize('input_note,saved_note', [
('Needs permission', 'Needs permission'),
(' ', None)
])
def test_post_edit_organisation_go_live_notes_updates_go_live_notes(
logged_in_platform_admin_client,
mock_get_organisation,
mock_update_organisation,
organisation_one,
input_note,
saved_note,
):
response = logged_in_platform_admin_client.post(
url_for(
'.edit_organisation_go_live_notes',
org_id=organisation_one['id'],
),
data={'request_to_go_live_notes': input_note}
)
mock_update_organisation.assert_called_once_with(
organisation_one['id'],
request_to_go_live_notes=saved_note
)
assert response.status_code == 302
assert response.location == url_for(
'.organisation_settings',
org_id=organisation_one['id'],
_external=True
)

View File

@@ -1380,7 +1380,7 @@ def test_should_redirect_after_request_to_go_live(
'\n'
'---\n'
'Organisation type: Central\n'
'Agreement signed: Cant tell (domain is user.gov.uk)\n'
'Agreement signed: Cant tell (domain is user.gov.uk).\n'
'{formatted_displayed_volumes}'
'Consent to research: Yes\n'
'Other live services: No\n'
@@ -1405,6 +1405,58 @@ def test_should_redirect_after_request_to_go_live(
)
def test_request_to_go_live_displays_go_live_notes_in_zendesk_ticket(
client_request,
mocker,
active_user_with_permissions,
single_reply_to_email_address,
single_letter_contact_block,
mock_get_organisations_and_services_for_user,
single_sms_sender,
mock_get_service_settings_page_common,
mock_get_service_templates,
mock_get_users_by_service,
mock_update_service,
mock_get_invites_without_manage_permission,
):
go_live_note = 'This service is not allowed to go live'
mocker.patch(
'app.organisations_client.get_service_organisation',
side_effect=lambda org_id: organisation_json(
ORGANISATION_ID,
'Org 1',
request_to_go_live_notes=go_live_note,
)
)
mock_post = mocker.patch('app.main.views.service_settings.zendesk_client.create_ticket', autospec=True)
client_request.post(
'main.request_to_go_live',
service_id=SERVICE_ONE_ID,
_follow_redirects=True
)
assert mock_post.call_args[1]['message'] == (
'Service: service one\n'
'http://localhost/services/{service_id}\n'
'\n'
'---\n'
'Organisation type: Central\n'
'Agreement signed: No (organisation is Org 1, a crown body). {go_live_note}\n'
'Emails in next year: 111,111\n'
'Text messages in next year: 222,222\n'
'Letters in next year: 333,333\n'
'Consent to research: Yes\n'
'Other live services: No\n'
'\n'
'---\n'
'Request sent by test@user.gov.uk\n'
).format(
service_id=SERVICE_ONE_ID,
go_live_note=go_live_note
)
def test_should_be_able_to_request_to_go_live_with_no_organisation(
client_request,
mocker,