mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-07-10 11:24:10 -04:00
Add a confirmation step to cancelling a broadcast
It’s an irreversible action if you do click it, so it feels like an ‘Are you sure?’ step is sensible. Follows the same pattern for deleting templates, etc.
This commit is contained in:
@@ -1,4 +1,12 @@
|
||||
from flask import abort, jsonify, redirect, render_template, url_for
|
||||
from flask import (
|
||||
abort,
|
||||
flash,
|
||||
jsonify,
|
||||
redirect,
|
||||
render_template,
|
||||
request,
|
||||
url_for,
|
||||
)
|
||||
|
||||
from app import current_service
|
||||
from app.main import main
|
||||
@@ -228,16 +236,39 @@ def reject_broadcast_message(service_id, broadcast_message_id):
|
||||
))
|
||||
|
||||
|
||||
@main.route('/services/<uuid:service_id>/broadcast/<uuid:broadcast_message_id>/cancel')
|
||||
@main.route(
|
||||
'/services/<uuid:service_id>/broadcast/<uuid:broadcast_message_id>/cancel',
|
||||
methods=['GET', 'POST'],
|
||||
)
|
||||
@user_has_permissions('send_messages')
|
||||
@service_has_permission('broadcast')
|
||||
def cancel_broadcast_message(service_id, broadcast_message_id):
|
||||
BroadcastMessage.from_id(
|
||||
broadcast_message = BroadcastMessage.from_id(
|
||||
broadcast_message_id,
|
||||
service_id=current_service.id,
|
||||
).cancel_broadcast()
|
||||
return redirect(url_for(
|
||||
'.view_broadcast_message',
|
||||
service_id=current_service.id,
|
||||
broadcast_message_id=broadcast_message_id,
|
||||
))
|
||||
)
|
||||
|
||||
if broadcast_message.status != 'broadcasting':
|
||||
return redirect(url_for(
|
||||
'.view_broadcast_message',
|
||||
service_id=current_service.id,
|
||||
broadcast_message_id=broadcast_message.id,
|
||||
))
|
||||
|
||||
if request.method == 'POST':
|
||||
broadcast_message.cancel_broadcast()
|
||||
return redirect(url_for(
|
||||
'.view_broadcast_message',
|
||||
service_id=current_service.id,
|
||||
broadcast_message_id=broadcast_message.id,
|
||||
))
|
||||
|
||||
flash([
|
||||
'Are you sure you want to stop this broadcast now?'
|
||||
], 'stop broadcasting')
|
||||
|
||||
return render_template(
|
||||
'views/broadcast/view-message.html',
|
||||
broadcast_message=broadcast_message,
|
||||
hide_stop_link=True,
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
{% if category in ['cancel', 'delete', 'suspend', 'resume', 'remove', 'revoke this API key'] %}
|
||||
{% if category in ['cancel', 'delete', 'suspend', 'resume', 'remove', 'revoke this API key', 'stop broadcasting'] %}
|
||||
{% set delete_button_text = "Yes, {}".format(category) %}
|
||||
{% elif category == 'try again' %}
|
||||
{% set delete_button_text = category|capitalize %}
|
||||
|
||||
@@ -43,7 +43,10 @@
|
||||
{% if broadcast_message.status == 'pending-approval' %}
|
||||
Will broadcast until {{ broadcast_message.finishes_at|format_datetime_relative }}.
|
||||
{% elif broadcast_message.status == 'broadcasting' %}
|
||||
Live until {{ broadcast_message.finishes_at|format_datetime_relative }} <a href="{{ url_for('.cancel_broadcast_message', service_id=current_service.id, broadcast_message_id=broadcast_message.id) }}" class="destructive-link destructive-link--no-visited-state">Stop broadcast early</a>
|
||||
Live until {{ broadcast_message.finishes_at|format_datetime_relative }} 
|
||||
{%- if not hide_stop_link %}
|
||||
<a href="{{ url_for('.cancel_broadcast_message', service_id=current_service.id, broadcast_message_id=broadcast_message.id) }}" class="destructive-link destructive-link--no-visited-state">Stop broadcast early</a>
|
||||
{% endif %}
|
||||
{% elif broadcast_message.status == 'cancelled' %}
|
||||
Stopped by {{ broadcast_message.cancelled_by.name }}
|
||||
{{ broadcast_message.cancelled_at|format_datetime_human }}.
|
||||
|
||||
@@ -704,12 +704,45 @@ def test_no_view_page_for_draft(
|
||||
def test_cancel_broadcast(
|
||||
client_request,
|
||||
service_one,
|
||||
mock_get_draft_broadcast_message,
|
||||
mock_get_live_broadcast_message,
|
||||
mock_get_broadcast_template,
|
||||
mock_update_broadcast_message_status,
|
||||
fake_uuid,
|
||||
):
|
||||
service_one['permissions'] += ['broadcast']
|
||||
client_request.get(
|
||||
page = client_request.get(
|
||||
'.cancel_broadcast_message',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
broadcast_message_id=fake_uuid,
|
||||
)
|
||||
assert normalize_spaces(page.select_one('.banner-dangerous').text) == (
|
||||
'Are you sure you want to stop this broadcast now? '
|
||||
'Yes, stop broadcasting'
|
||||
)
|
||||
form = page.select_one('form')
|
||||
assert form['method'] == 'post'
|
||||
assert 'action' not in form
|
||||
assert normalize_spaces(form.select_one('button[type=submit]').text) == (
|
||||
'Yes, stop broadcasting'
|
||||
)
|
||||
assert mock_update_broadcast_message_status.called is False
|
||||
assert url_for(
|
||||
'.cancel_broadcast_message',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
broadcast_message_id=fake_uuid,
|
||||
) not in page
|
||||
|
||||
|
||||
def test_confirm_cancel_broadcast(
|
||||
client_request,
|
||||
service_one,
|
||||
mock_get_live_broadcast_message,
|
||||
mock_get_broadcast_template,
|
||||
mock_update_broadcast_message_status,
|
||||
fake_uuid,
|
||||
):
|
||||
service_one['permissions'] += ['broadcast']
|
||||
client_request.post(
|
||||
'.cancel_broadcast_message',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
broadcast_message_id=fake_uuid,
|
||||
@@ -719,9 +752,33 @@ def test_cancel_broadcast(
|
||||
broadcast_message_id=fake_uuid,
|
||||
_external=True,
|
||||
),
|
||||
),
|
||||
)
|
||||
mock_update_broadcast_message_status.assert_called_once_with(
|
||||
'cancelled',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
broadcast_message_id=fake_uuid,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('method', ('post', 'get'))
|
||||
def test_cant_cancel_broadcast_in_a_different_state(
|
||||
client_request,
|
||||
service_one,
|
||||
mock_get_draft_broadcast_message,
|
||||
mock_update_broadcast_message_status,
|
||||
fake_uuid,
|
||||
method,
|
||||
):
|
||||
service_one['permissions'] += ['broadcast']
|
||||
getattr(client_request, method)(
|
||||
'.cancel_broadcast_message',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
broadcast_message_id=fake_uuid,
|
||||
_expected_redirect=url_for(
|
||||
'.view_broadcast_message',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
broadcast_message_id=fake_uuid,
|
||||
_external=True,
|
||||
),
|
||||
)
|
||||
assert mock_update_broadcast_message_status.called is False
|
||||
|
||||
Reference in New Issue
Block a user