From 44e177b402045a75f5e9ac2d2bb1aabc13a9eda9 Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Fri, 10 Jul 2020 09:16:36 +0100 Subject: [PATCH 1/4] Allow broadcasts to be cancelled Currently this is a `get` request from the dashboard. Once we have a page for viewing an individual broadcast it should probably show there instead and be a `get`/confirm/`post` loop like for deleting a template. --- app/main/views/broadcast.py | 14 ++++++++++ app/models/broadcast_message.py | 7 +++++ app/navigation.py | 4 +++ app/templates/views/broadcast/dashboard.html | 17 +++++++----- tests/app/main/views/test_broadcast.py | 27 +++++++++++++++++++- 5 files changed, 62 insertions(+), 7 deletions(-) diff --git a/app/main/views/broadcast.py b/app/main/views/broadcast.py index 0ae193919..66a8814ec 100644 --- a/app/main/views/broadcast.py +++ b/app/main/views/broadcast.py @@ -124,3 +124,17 @@ def preview_broadcast_message(service_id, broadcast_message_id): 'views/broadcast/preview-message.html', broadcast_message=broadcast_message, ) + + +@main.route('/services//broadcast//cancel') +@user_has_permissions('send_messages') +@service_has_permission('broadcast') +def cancel_broadcast_message(service_id, broadcast_message_id): + BroadcastMessage.from_id( + broadcast_message_id, + service_id=current_service.id, + ).cancel_broadcast() + return redirect(url_for( + '.broadcast_dashboard', + service_id=current_service.id, + )) diff --git a/app/models/broadcast_message.py b/app/models/broadcast_message.py index bdc4c37bf..03677339c 100644 --- a/app/models/broadcast_message.py +++ b/app/models/broadcast_message.py @@ -125,6 +125,13 @@ class BroadcastMessage(JSONModel): service_id=self.service_id, ) + def cancel_broadcast(self): + broadcast_message_api_client.update_broadcast_message_status( + 'cancelled', + broadcast_message_id=self.id, + service_id=self.service_id, + ) + class BroadcastMessages(ModelList): diff --git a/app/navigation.py b/app/navigation.py index d5c90b836..a2a5137cd 100644 --- a/app/navigation.py +++ b/app/navigation.py @@ -358,6 +358,7 @@ class HeaderNavigation(Navigation): 'choose_broadcast_area', 'remove_broadcast_area', 'preview_broadcast_message', + 'cancel_broadcast_message', } # header HTML now comes from GOVUK Frontend so requires a boolean, not an attribute @@ -413,6 +414,7 @@ class MainNavigation(Navigation): 'choose_broadcast_area', 'remove_broadcast_area', 'preview_broadcast_message', + 'cancel_broadcast_message', }, 'uploads': { 'upload_contact_list', @@ -1001,6 +1003,7 @@ class CaseworkNavigation(Navigation): 'choose_broadcast_area', 'remove_broadcast_area', 'preview_broadcast_message', + 'cancel_broadcast_message', } @@ -1318,4 +1321,5 @@ class OrgNavigation(Navigation): 'choose_broadcast_area', 'remove_broadcast_area', 'preview_broadcast_message', + 'cancel_broadcast_message', } diff --git a/app/templates/views/broadcast/dashboard.html b/app/templates/views/broadcast/dashboard.html index 64672943e..011bd756b 100644 --- a/app/templates/views/broadcast/dashboard.html +++ b/app/templates/views/broadcast/dashboard.html @@ -24,15 +24,20 @@ {% endcall %} {% call field(align='right') %} -

- {% if item.status == 'broadcasting' %} + {% if item.status == 'broadcasting' %} +

Live until {{ item.finishes_at|format_datetime_relative }} - {% elif item.status == 'cancelled' %} + Stop broadcasting +

+ {% elif item.status == 'cancelled' %} +

Stopped {{ item.cancelled_at|format_datetime_relative }} - {% else %} +

+ {% else %} +

Finished {{ item.finishes_at|format_datetime_relative }} - {% endif %} -

+

+ {% endif %} {% endcall %} {% endcall %} diff --git a/tests/app/main/views/test_broadcast.py b/tests/app/main/views/test_broadcast.py index 13a933f2e..961b32ac4 100644 --- a/tests/app/main/views/test_broadcast.py +++ b/tests/app/main/views/test_broadcast.py @@ -78,7 +78,7 @@ def test_broadcast_dashboard( assert [ normalize_spaces(row.text) for row in page.select('table')[0].select('tbody tr') ] == [ - 'Example template To England and Scotland Live until tomorrow at 2:20am', + 'Example template To England and Scotland Live until tomorrow at 2:20am Stop broadcasting', ] assert [ normalize_spaces(row.text) for row in page.select('table')[1].select('tbody tr') @@ -275,3 +275,28 @@ def test_start_broadcasting( service_id=SERVICE_ONE_ID, broadcast_message_id=fake_uuid, ) + + +def test_cancel_broadcast( + client_request, + service_one, + mock_get_draft_broadcast_message, + mock_update_broadcast_message_status, + fake_uuid, +): + service_one['permissions'] += ['broadcast'] + client_request.get( + '.cancel_broadcast_message', + service_id=SERVICE_ONE_ID, + broadcast_message_id=fake_uuid, + _expected_redirect=url_for( + '.broadcast_dashboard', + service_id=SERVICE_ONE_ID, + _external=True, + ), + ), + mock_update_broadcast_message_status.assert_called_once_with( + 'cancelled', + service_id=SERVICE_ONE_ID, + broadcast_message_id=fake_uuid, + ) From b57bbd464220ae83fc78b49e6d7ee4ace3ffe407 Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Fri, 10 Jul 2020 09:25:17 +0100 Subject: [PATCH 2/4] Fix back link --- app/main/views/broadcast.py | 1 + app/templates/views/broadcast/areas.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/main/views/broadcast.py b/app/main/views/broadcast.py index 66a8814ec..8cf079752 100644 --- a/app/main/views/broadcast.py +++ b/app/main/views/broadcast.py @@ -83,6 +83,7 @@ def choose_broadcast_area(service_id, broadcast_message_id, library_slug): search_form=SearchByNameForm(), show_search_form=(len(form.areas.choices) > 7), page_title=library.name, + broadcast_message=broadcast_message, ) diff --git a/app/templates/views/broadcast/areas.html b/app/templates/views/broadcast/areas.html index dd63b4d26..5020b587c 100644 --- a/app/templates/views/broadcast/areas.html +++ b/app/templates/views/broadcast/areas.html @@ -14,7 +14,7 @@ {{ page_header( page_title, - back_link=url_for('.choose_broadcast_library', service_id=current_service.id, broadcast_message_id=broadcast_message_id), + back_link=url_for('.choose_broadcast_library', service_id=current_service.id, broadcast_message_id=broadcast_message.id), )}} {{ live_search(target_selector='.multiple-choice', show=show_search_form, form=search_form, label='Search by name') }} From 3136d1a33b4f388d35a9b06a1752346ccf3388d7 Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Fri, 10 Jul 2020 09:26:47 +0100 Subject: [PATCH 3/4] Implement sorting Shows the broadcasts with the longest time still to live at the top. At the moment this will be the same as the newest broadcasts, so we may want to revisit this sort order when we have broadcasts of variable duration. For no-longer-live broadcasts we show the most-recently-finished at the top, whether it finished naturally or was cancelled. --- app/models/broadcast_message.py | 7 +++++++ app/templates/views/broadcast/dashboard.html | 2 +- tests/app/main/views/test_broadcast.py | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/models/broadcast_message.py b/app/models/broadcast_message.py index 03677339c..c3efd2ed1 100644 --- a/app/models/broadcast_message.py +++ b/app/models/broadcast_message.py @@ -36,6 +36,13 @@ class BroadcastMessage(JSONModel): libraries = broadcast_area_libraries + def __lt__(self, other): + return ( + self.cancelled_at or self.finishes_at + ) < ( + other.cancelled_at or other.finishes_at + ) + @classmethod def create(cls, *, service_id, template_id): return cls(broadcast_message_api_client.create_broadcast_message( diff --git a/app/templates/views/broadcast/dashboard.html b/app/templates/views/broadcast/dashboard.html index 011bd756b..7a5267489 100644 --- a/app/templates/views/broadcast/dashboard.html +++ b/app/templates/views/broadcast/dashboard.html @@ -5,7 +5,7 @@ {% macro broadcast_table(broadcasts, empty_message) %}
{% call(item, row_number) list_table( - broadcasts, + broadcasts|sort|reverse|list, caption="Live broadcasts", caption_visible=False, empty_message=empty_message, diff --git a/tests/app/main/views/test_broadcast.py b/tests/app/main/views/test_broadcast.py index 961b32ac4..4b24d74b2 100644 --- a/tests/app/main/views/test_broadcast.py +++ b/tests/app/main/views/test_broadcast.py @@ -83,8 +83,8 @@ def test_broadcast_dashboard( assert [ normalize_spaces(row.text) for row in page.select('table')[1].select('tbody tr') ] == [ - 'Example template To England and Scotland Finished yesterday at 8:20pm', 'Example template To England and Scotland Stopped 10 February at 2:20am', + 'Example template To England and Scotland Finished yesterday at 8:20pm', ] From 9a1f2b2555b7091d0327ae91bd68ef98e7e42459 Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Fri, 10 Jul 2020 09:33:44 +0100 Subject: [PATCH 4/4] Make ended broadcast status less prominent --- app/templates/views/broadcast/dashboard.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/templates/views/broadcast/dashboard.html b/app/templates/views/broadcast/dashboard.html index 7a5267489..24d78a94b 100644 --- a/app/templates/views/broadcast/dashboard.html +++ b/app/templates/views/broadcast/dashboard.html @@ -30,11 +30,11 @@ Stop broadcasting

{% elif item.status == 'cancelled' %} -

+

Stopped {{ item.cancelled_at|format_datetime_relative }}

{% else %} -

+

Finished {{ item.finishes_at|format_datetime_relative }}

{% endif %}