mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-02-08 20:33:47 -05:00
Add link to cancel letters
Added a link to cancel letters from the letter notification pages if the letter is still able to be cancelled. Clicking on this link will show a confirmation box, and will then cancel the letter if the user confirms.
This commit is contained in:
@@ -51,6 +51,10 @@
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.page-footer-delete-link-without-button {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.notification-status {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,9 @@ from dateutil import parser
|
||||
from flask import (
|
||||
Response,
|
||||
abort,
|
||||
flash,
|
||||
jsonify,
|
||||
redirect,
|
||||
render_template,
|
||||
request,
|
||||
stream_with_context,
|
||||
@@ -83,6 +85,11 @@ def view_notification(service_id, notification_id):
|
||||
|
||||
letter_print_day = get_letter_printing_statement(notification['status'], notification['created_at'])
|
||||
|
||||
notification_created = parser.parse(notification['created_at']).replace(tzinfo=None)
|
||||
|
||||
show_cancel_button = notification['notification_type'] == 'letter' and \
|
||||
letter_can_be_cancelled(notification['status'], notification_created)
|
||||
|
||||
return render_template(
|
||||
'views/notifications/notification.html',
|
||||
finished=(notification['status'] in (DELIVERED_STATUSES + FAILURE_STATUSES)),
|
||||
@@ -110,10 +117,24 @@ def view_notification(service_id, notification_id):
|
||||
postage=notification['postage'],
|
||||
can_receive_inbound=(current_service.has_permission('inbound_sms')),
|
||||
is_precompiled_letter=notification['template']['is_precompiled_letter'],
|
||||
letter_print_day=letter_print_day
|
||||
letter_print_day=letter_print_day,
|
||||
show_cancel_button=show_cancel_button
|
||||
)
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/notification/<uuid:notification_id>/cancel", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@user_has_permissions('view_activity', 'send_messages')
|
||||
def cancel_letter(service_id, notification_id):
|
||||
|
||||
if request.method == 'POST':
|
||||
notification_api_client.update_notification_to_cancelled(current_service.id, notification_id)
|
||||
return redirect(url_for('main.view_notification', service_id=service_id, notification_id=notification_id))
|
||||
|
||||
flash("Are you sure you want to cancel sending this letter?", 'cancel')
|
||||
return view_notification(service_id, notification_id)
|
||||
|
||||
|
||||
def get_letter_printing_statement(status, created_at):
|
||||
created_at_dt = parser.parse(created_at).replace(tzinfo=None)
|
||||
|
||||
|
||||
@@ -121,6 +121,7 @@ class HeaderNavigation(Navigation):
|
||||
'cancel_invited_org_user',
|
||||
'cancel_invited_user',
|
||||
'cancel_job',
|
||||
'cancel_letter',
|
||||
'check_and_resend_text_code',
|
||||
'check_and_resend_verification_code',
|
||||
'check_messages',
|
||||
@@ -397,6 +398,7 @@ class MainNavigation(Navigation):
|
||||
'cancel_invited_org_user',
|
||||
'cancel_invited_user',
|
||||
'cancel_job',
|
||||
'cancel_letter',
|
||||
'check_and_resend_text_code',
|
||||
'check_and_resend_verification_code',
|
||||
'check_messages_preview',
|
||||
@@ -569,6 +571,7 @@ class CaseworkNavigation(Navigation):
|
||||
'cancel_invited_org_user',
|
||||
'cancel_invited_user',
|
||||
'cancel_job',
|
||||
'cancel_letter',
|
||||
'check_and_resend_text_code',
|
||||
'check_and_resend_verification_code',
|
||||
'check_messages',
|
||||
@@ -806,6 +809,7 @@ class OrgNavigation(Navigation):
|
||||
'cancel_invited_org_user',
|
||||
'cancel_invited_user',
|
||||
'cancel_job',
|
||||
'cancel_letter',
|
||||
'check_and_resend_text_code',
|
||||
'check_and_resend_verification_code',
|
||||
'check_messages',
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
{{ banner(
|
||||
message if message is string else message[0],
|
||||
'default' if ((category == 'default') or (category == 'default_with_tick')) else 'dangerous',
|
||||
delete_button="Yes, {}".format(category) if category in ['delete', 'suspend', 'resume', 'remove', 'revoke this API key'] else None,
|
||||
delete_button="Yes, {}".format(category) if category in ['cancel', 'delete', 'suspend', 'resume', 'remove', 'revoke this API key'] else None,
|
||||
with_tick=True if category == 'default_with_tick' else False,
|
||||
context=message[1] if message is not string
|
||||
)}}
|
||||
|
||||
@@ -64,7 +64,13 @@
|
||||
{% if template.template_type == 'letter' %}
|
||||
<div class="js-stick-at-bottom-when-scrolling">
|
||||
<div class="page-footer">
|
||||
<div> </div>
|
||||
{% if show_cancel_button %}
|
||||
<span class="page-footer-delete-link page-footer-delete-link-without-button">
|
||||
<a href="{{ url_for('main.cancel_letter', service_id=current_service.id, notification_id=notification_id) }}">Cancel sending this letter</a>
|
||||
</span>
|
||||
{% else %}
|
||||
<div> </div>
|
||||
{% endif %}
|
||||
<a class="page-footer-right-aligned-link" href="{{ url_for('main.view_letter_notification_as_preview', service_id=current_service.id, notification_id=notification_id, filetype='pdf') }}" download>Download as a PDF</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -241,6 +241,82 @@ def test_notification_page_shows_cancelled_letter(
|
||||
assert page.select_one('main img')['src'].endswith('.png?page=1')
|
||||
|
||||
|
||||
@pytest.mark.parametrize('notification_type', ['email', 'sms'])
|
||||
@freeze_time('2016-01-01 15:00')
|
||||
def test_notification_page_does_not_show_cancel_link_for_sms_or_email_notifications(
|
||||
client_request,
|
||||
mocker,
|
||||
fake_uuid,
|
||||
notification_type,
|
||||
):
|
||||
mock_get_notification(
|
||||
mocker,
|
||||
fake_uuid,
|
||||
template_type=notification_type,
|
||||
notification_status='created',
|
||||
)
|
||||
|
||||
page = client_request.get(
|
||||
'main.view_notification',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
notification_id=fake_uuid,
|
||||
)
|
||||
|
||||
assert 'Cancel sending this letter' not in normalize_spaces(page.text)
|
||||
|
||||
|
||||
@freeze_time('2016-01-01 15:00')
|
||||
def test_notification_page_shows_cancel_link_for_letter_which_can_be_cancelled(
|
||||
client_request,
|
||||
mocker,
|
||||
fake_uuid,
|
||||
):
|
||||
mock_get_notification(
|
||||
mocker,
|
||||
fake_uuid,
|
||||
template_type='letter',
|
||||
notification_status='created',
|
||||
)
|
||||
mocker.patch(
|
||||
'app.main.views.notifications.get_page_count_for_letter',
|
||||
return_value=1
|
||||
)
|
||||
|
||||
page = client_request.get(
|
||||
'main.view_notification',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
notification_id=fake_uuid,
|
||||
)
|
||||
|
||||
assert 'Cancel sending this letter' in normalize_spaces(page.text)
|
||||
|
||||
|
||||
@freeze_time('2016-01-01 15:00')
|
||||
def test_notification_page_does_not_show_cancel_link_for_letter_which_cannot_be_cancelled(
|
||||
client_request,
|
||||
mocker,
|
||||
fake_uuid,
|
||||
):
|
||||
mock_get_notification(
|
||||
mocker,
|
||||
fake_uuid,
|
||||
template_type='letter',
|
||||
notification_status='delivered',
|
||||
)
|
||||
mocker.patch(
|
||||
'app.main.views.notifications.get_page_count_for_letter',
|
||||
return_value=1
|
||||
)
|
||||
|
||||
page = client_request.get(
|
||||
'main.view_notification',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
notification_id=fake_uuid,
|
||||
)
|
||||
|
||||
assert 'Cancel sending this letter' not in normalize_spaces(page.text)
|
||||
|
||||
|
||||
@freeze_time("2016-01-01 18:00")
|
||||
def test_notification_page_shows_page_for_first_class_letter_notification(
|
||||
client_request,
|
||||
@@ -531,3 +607,62 @@ def test_get_letter_printing_statement_for_letter_that_has_been_sent(created_at,
|
||||
statement = get_letter_printing_statement('delivered', created_at)
|
||||
|
||||
assert statement == 'Printed on {}'.format(print_day)
|
||||
|
||||
|
||||
@freeze_time('2016-01-01 15:00')
|
||||
def test_show_cancel_letter_confirmation(
|
||||
client_request,
|
||||
mocker,
|
||||
fake_uuid,
|
||||
):
|
||||
mock_get_notification(
|
||||
mocker,
|
||||
fake_uuid,
|
||||
template_type='letter',
|
||||
notification_status='created',
|
||||
)
|
||||
mocker.patch(
|
||||
'app.main.views.notifications.get_page_count_for_letter',
|
||||
return_value=1
|
||||
)
|
||||
|
||||
page = client_request.get(
|
||||
'main.cancel_letter',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
notification_id=fake_uuid,
|
||||
)
|
||||
|
||||
flash_message = normalize_spaces(page.find('div', class_='banner-dangerous').text)
|
||||
|
||||
assert 'Are you sure you want to cancel sending this letter?' in flash_message
|
||||
|
||||
|
||||
@freeze_time('2016-01-01 15:00')
|
||||
def test_cancelling_a_letter_calls_the_api(
|
||||
client_request,
|
||||
mocker,
|
||||
fake_uuid,
|
||||
):
|
||||
mock_get_notification(
|
||||
mocker,
|
||||
fake_uuid,
|
||||
template_type='letter',
|
||||
notification_status='created',
|
||||
)
|
||||
mocker.patch(
|
||||
'app.main.views.notifications.get_page_count_for_letter',
|
||||
return_value=1
|
||||
)
|
||||
cancel_endpoint = mocker.patch(
|
||||
'app.main.views.notifications.notification_api_client.update_notification_to_cancelled'
|
||||
)
|
||||
|
||||
client_request.post(
|
||||
'main.cancel_letter',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
notification_id=fake_uuid,
|
||||
_follow_redirects=True,
|
||||
_expected_redirect=None,
|
||||
)
|
||||
|
||||
assert cancel_endpoint.called
|
||||
|
||||
Reference in New Issue
Block a user