Show broadcasts created by the API

Broadcasts created by the API are different in that:
- they aren’t created by any user, so don’t have a `created_by_id`
- they are created instantly, not in steps, so don’t have an
  `updated_at` time

This commit alters the views to account for when these pieces of
information aren’t present.
This commit is contained in:
Chris Hill-Scott
2021-01-27 11:24:22 +00:00
parent 60aa2d2b42
commit 5ae53b625b
4 changed files with 95 additions and 15 deletions

View File

@@ -45,6 +45,10 @@ class BroadcastMessage(JSONModel):
return True return True
if not self.starts_at and other.starts_at: if not self.starts_at and other.starts_at:
return False return False
if self.updated_at and not other.updated_at:
return self.updated_at < other.created_at
if not self.updated_at and other.updated_at:
return self.created_at < other.updated_at
return self.updated_at < other.updated_at return self.updated_at < other.updated_at
@classmethod @classmethod
@@ -129,7 +133,7 @@ class BroadcastMessage(JSONModel):
@cached_property @cached_property
def created_by(self): def created_by(self):
return User.from_id(self.created_by_id) return User.from_id(self.created_by_id) if self.created_by_id else None
@cached_property @cached_property
def approved_by(self): def approved_by(self):

View File

@@ -20,7 +20,9 @@
alert alert
</li> </li>
<li class="area-list-key area-list-key--phone-estimate"> <li class="area-list-key area-list-key--phone-estimate">
{% if broadcast_message.count_of_phones == broadcast_message.count_of_phones_likely %} {% if broadcast_message.count_of_phones == 0 %}
Unknown number of phones
{% elif broadcast_message.count_of_phones == broadcast_message.count_of_phones_likely %}
{{ broadcast_message.count_of_phones|format_thousands }} phones estimated {{ broadcast_message.count_of_phones|format_thousands }} phones estimated
{% else %} {% else %}
{{ broadcast_message.count_of_phones|format_thousands }} to {{ broadcast_message.count_of_phones_likely|format_thousands }} phones {{ broadcast_message.count_of_phones|format_thousands }} to {{ broadcast_message.count_of_phones_likely|format_thousands }} phones

View File

@@ -19,10 +19,15 @@
{% block service_page_title %} {% block service_page_title %}
{% if broadcast_message.status == 'pending-approval' %} {% if broadcast_message.status == 'pending-approval' %}
{% if broadcast_message.created_by == current_user and current_user.has_permissions('send_messages') %} {% if broadcast_message.created_by and broadcast_message.created_by == current_user and current_user.has_permissions('send_messages') %}
{{ broadcast_message.template.name }} is waiting for approval {{ broadcast_message.template.name }} is waiting for approval
{% elif current_user.has_permissions('send_messages') %} {% elif current_user.has_permissions('send_messages') %}
{{ broadcast_message.created_by.name }} wants to broadcast {% if broadcast_message.created_by %}
{{ broadcast_message.created_by.name }}
{% else %}
An API call
{% endif %}
wants to broadcast
{{ broadcast_message.template.name }} {{ broadcast_message.template.name }}
{% else %} {% else %}
This alert is waiting for approval This alert is waiting for approval
@@ -37,7 +42,7 @@
{{ govukBackLink({ "href": back_link }) }} {{ govukBackLink({ "href": back_link }) }}
{% if broadcast_message.status == 'pending-approval' %} {% if broadcast_message.status == 'pending-approval' %}
{% if broadcast_message.created_by == current_user and current_user.has_permissions('send_messages') %} {% if broadcast_message.created_by and broadcast_message.created_by == current_user and current_user.has_permissions('send_messages') %}
<div class="banner govuk-!-margin-bottom-6"> <div class="banner govuk-!-margin-bottom-6">
<h1 class="govuk-heading-m govuk-!-margin-bottom-3"> <h1 class="govuk-heading-m govuk-!-margin-bottom-3">
{{ broadcast_message.template.name }} is waiting for approval {{ broadcast_message.template.name }} is waiting for approval
@@ -79,7 +84,12 @@
{% elif current_user.has_permissions('send_messages') %} {% elif current_user.has_permissions('send_messages') %}
{% call form_wrapper(class="banner govuk-!-margin-bottom-6") %} {% call form_wrapper(class="banner govuk-!-margin-bottom-6") %}
<h1 class="govuk-heading-m govuk-!-margin-top-0 govuk-!-margin-bottom-3"> <h1 class="govuk-heading-m govuk-!-margin-top-0 govuk-!-margin-bottom-3">
{{ broadcast_message.created_by.name }} wants to broadcast {% if broadcast_message.created_by %}
{{ broadcast_message.created_by.name }}
{% else %}
An API call
{% endif %}
wants to broadcast
{{ broadcast_message.template.name }} {{ broadcast_message.template.name }}
</h1> </h1>
{{ page_footer( {{ page_footer(
@@ -138,8 +148,12 @@
{% if broadcast_message.status != 'pending-approval' %} {% if broadcast_message.status != 'pending-approval' %}
<p class="govuk-body govuk-!-margin-bottom-3"> <p class="govuk-body govuk-!-margin-bottom-3">
Prepared by {{ broadcast_message.created_by.name }} and approved by {% if broadcast_message.created_by %}
{{ broadcast_message.approved_by.name }}. Prepared by {{ broadcast_message.created_by.name }}
{% else %}
Created from an API call
{% endif %}
and approved by {{ broadcast_message.approved_by.name }}.
</p> </p>
{% endif %} {% endif %}

View File

@@ -727,7 +727,7 @@ def test_preview_broadcast_areas_page_with_custom_polygons(
] == [ ] == [
'An area of 722.3 square miles Will get the alert', 'An area of 722.3 square miles Will get the alert',
'An extra area of 1,402.5 square miles is Likely to get the alert', 'An extra area of 1,402.5 square miles is Likely to get the alert',
'0 phones estimated', 'Unknown number of phones',
] ]
@@ -1307,8 +1307,8 @@ def test_start_broadcasting(
) )
@pytest.mark.parametrize('endpoint, extra_fields, expected_paragraphs', ( @pytest.mark.parametrize('endpoint, created_by_api, extra_fields, expected_paragraphs', (
('.view_current_broadcast', { ('.view_current_broadcast', False, {
'status': 'broadcasting', 'status': 'broadcasting',
'finishes_at': '2020-02-23T23:23:23.000000', 'finishes_at': '2020-02-23T23:23:23.000000',
}, [ }, [
@@ -1316,7 +1316,15 @@ def test_start_broadcasting(
'Prepared by Alice and approved by Bob.', 'Prepared by Alice and approved by Bob.',
'Broadcasting stops tomorrow at 11:23pm.' 'Broadcasting stops tomorrow at 11:23pm.'
]), ]),
('.view_previous_broadcast', { ('.view_current_broadcast', True, {
'status': 'broadcasting',
'finishes_at': '2020-02-23T23:23:23.000000',
}, [
'Live since 20 February at 8:20pm Stop broadcasting',
'Created from an API call and approved by Alice.',
'Broadcasting stops tomorrow at 11:23pm.'
]),
('.view_previous_broadcast', False, {
'status': 'broadcasting', 'status': 'broadcasting',
'finishes_at': '2020-02-22T22:20:20.000000', # 2 mins before now() 'finishes_at': '2020-02-22T22:20:20.000000', # 2 mins before now()
}, [ }, [
@@ -1324,7 +1332,15 @@ def test_start_broadcasting(
'Prepared by Alice and approved by Bob.', 'Prepared by Alice and approved by Bob.',
'Finished broadcasting today at 10:20pm.' 'Finished broadcasting today at 10:20pm.'
]), ]),
('.view_previous_broadcast', { ('.view_previous_broadcast', True, {
'status': 'broadcasting',
'finishes_at': '2020-02-22T22:20:20.000000', # 2 mins before now()
}, [
'Broadcast on 20 February at 8:20pm.',
'Created from an API call and approved by Alice.',
'Finished broadcasting today at 10:20pm.'
]),
('.view_previous_broadcast', False, {
'status': 'completed', 'status': 'completed',
'finishes_at': '2020-02-21T21:21:21.000000', 'finishes_at': '2020-02-21T21:21:21.000000',
}, [ }, [
@@ -1332,7 +1348,7 @@ def test_start_broadcasting(
'Prepared by Alice and approved by Bob.', 'Prepared by Alice and approved by Bob.',
'Finished broadcasting yesterday at 9:21pm.', 'Finished broadcasting yesterday at 9:21pm.',
]), ]),
('.view_previous_broadcast', { ('.view_previous_broadcast', False, {
'status': 'cancelled', 'status': 'cancelled',
'cancelled_by_id': sample_uuid, 'cancelled_by_id': sample_uuid,
'cancelled_at': '2020-02-21T21:21:21.000000', 'cancelled_at': '2020-02-21T21:21:21.000000',
@@ -1351,6 +1367,7 @@ def test_view_broadcast_message_page(
mock_get_broadcast_template, mock_get_broadcast_template,
fake_uuid, fake_uuid,
endpoint, endpoint,
created_by_api,
extra_fields, extra_fields,
expected_paragraphs, expected_paragraphs,
): ):
@@ -1360,7 +1377,7 @@ def test_view_broadcast_message_page(
id_=fake_uuid, id_=fake_uuid,
service_id=SERVICE_ONE_ID, service_id=SERVICE_ONE_ID,
template_id=fake_uuid, template_id=fake_uuid,
created_by_id=fake_uuid, created_by_id=None if created_by_api else fake_uuid,
approved_by_id=fake_uuid, approved_by_id=fake_uuid,
starts_at='2020-02-20T20:20:20.000000', starts_at='2020-02-20T20:20:20.000000',
**extra_fields **extra_fields
@@ -1564,6 +1581,49 @@ def test_view_pending_broadcast_without_template(
) )
@freeze_time('2020-02-22T22:22:22.000000')
def test_view_pending_broadcast_from_api_call(
mocker,
client_request,
service_one,
active_user_with_permissions,
fake_uuid,
):
mocker.patch(
'app.broadcast_message_api_client.get_broadcast_message',
return_value=broadcast_message_json(
id_=fake_uuid,
service_id=SERVICE_ONE_ID,
template_id=None,
created_by_id=None, # No user created this broadcast
finishes_at=None,
status='pending-approval',
reference='abc123',
content='Uh-oh',
),
)
service_one['permissions'] += ['broadcast']
page = client_request.get(
'.view_current_broadcast',
service_id=SERVICE_ONE_ID,
broadcast_message_id=fake_uuid,
)
assert (
normalize_spaces(page.select_one('.banner').text)
) == (
'An API call wants to broadcast abc123 '
'Start broadcasting now Reject this alert'
)
assert (
normalize_spaces(page.select_one('.broadcast-message-wrapper').text)
) == (
'Emergency alert '
'Uh-oh'
)
@freeze_time('2020-02-22T22:22:22.000000') @freeze_time('2020-02-22T22:22:22.000000')
def test_cant_approve_own_broadcast( def test_cant_approve_own_broadcast(
mocker, mocker,