mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-07-16 11:20:12 -04:00
Merge pull request #2968 from alphagov/require-approval-on-go-live
Allow custom notes when service goes live
This commit is contained in:
@@ -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],
|
||||
)
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
@@ -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: 'Can’t tell',
|
||||
@@ -50,7 +50,12 @@ class Organisation(JSONModel):
|
||||
}.get(self.crown),
|
||||
)
|
||||
else:
|
||||
return 'Can’t tell (domain is {})'.format(fallback_domain)
|
||||
agreement_statement = 'Can’t 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 'Can’t tell (domain is {})'.format(fallback_domain)
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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 %}
|
||||
@@ -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) }}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -1380,7 +1380,7 @@ def test_should_redirect_after_request_to_go_live(
|
||||
'\n'
|
||||
'---\n'
|
||||
'Organisation type: Central\n'
|
||||
'Agreement signed: Can’t tell (domain is user.gov.uk)\n'
|
||||
'Agreement signed: Can’t 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,
|
||||
|
||||
Reference in New Issue
Block a user