2020-11-16 12:47:38 +00:00
|
|
|
import uuid
|
retry sending broadcasts
Retry tasks if they fail to send a broadcast event. Note that each task
tries the regular proxy and the failover proxy for that provider. This
runs a bit differently than our other retries:
Retry with exponential backoff. Our other tasks retry with a fixed delay
of 5 minutes between tries. If we can't send a broadcast, we want to try
immediately. So instead, implement an exponential backoff (1, 2, 4, 8,
... seconds delay). We can't delay for longer than 310 seconds due to
visibility timeout settings in SQS, so cap the delay at that amount.
Normally we give up retrying after a set amount of retries (often 4
hours). As broadcast content is much more important than normal
notifications, we don't ever want to give up on sending them to phones...
...UNLESS WE DO!
Sometimes we do want to give up sending a broadcast though! Broadcasts
have an expiry time, when they stop showing up on peoples devices, so if
that has passed then we don't need to send the broadcast out.
Broadcast events can also be superceded by updates or cancels. Check
that the event is the most recent event for that broadcast message, if
not, give up, as we don't want to accidentally send out two conflicting
events for the same message.
2021-01-19 10:05:48 +00:00
|
|
|
from datetime import datetime
|
2020-11-16 18:48:00 +00:00
|
|
|
from unittest.mock import call, ANY
|
2020-11-16 12:47:38 +00:00
|
|
|
|
2020-08-04 19:21:22 +01:00
|
|
|
from freezegun import freeze_time
|
retry sending broadcasts
Retry tasks if they fail to send a broadcast event. Note that each task
tries the regular proxy and the failover proxy for that provider. This
runs a bit differently than our other retries:
Retry with exponential backoff. Our other tasks retry with a fixed delay
of 5 minutes between tries. If we can't send a broadcast, we want to try
immediately. So instead, implement an exponential backoff (1, 2, 4, 8,
... seconds delay). We can't delay for longer than 310 seconds due to
visibility timeout settings in SQS, so cap the delay at that amount.
Normally we give up retrying after a set amount of retries (often 4
hours). As broadcast content is much more important than normal
notifications, we don't ever want to give up on sending them to phones...
...UNLESS WE DO!
Sometimes we do want to give up sending a broadcast though! Broadcasts
have an expiry time, when they stop showing up on peoples devices, so if
that has passed then we don't need to send the broadcast out.
Broadcast events can also be superceded by updates or cancels. Check
that the event is the most recent event for that broadcast message, if
not, give up, as we don't want to accidentally send out two conflicting
events for the same message.
2021-01-19 10:05:48 +00:00
|
|
|
from celery.exceptions import MaxRetriesExceededError
|
2020-07-09 18:22:29 +01:00
|
|
|
import pytest
|
|
|
|
|
|
2020-12-02 14:10:46 +00:00
|
|
|
from app.models import (
|
|
|
|
|
BROADCAST_TYPE,
|
|
|
|
|
BroadcastStatusType,
|
|
|
|
|
BroadcastEventMessageType,
|
|
|
|
|
BroadcastProviderMessageStatus,
|
2021-01-29 14:14:15 +00:00
|
|
|
ServiceBroadcastProviderRestriction,
|
|
|
|
|
ServiceBroadcastSettings,
|
2020-12-02 14:10:46 +00:00
|
|
|
)
|
retry sending broadcasts
Retry tasks if they fail to send a broadcast event. Note that each task
tries the regular proxy and the failover proxy for that provider. This
runs a bit differently than our other retries:
Retry with exponential backoff. Our other tasks retry with a fixed delay
of 5 minutes between tries. If we can't send a broadcast, we want to try
immediately. So instead, implement an exponential backoff (1, 2, 4, 8,
... seconds delay). We can't delay for longer than 310 seconds due to
visibility timeout settings in SQS, so cap the delay at that amount.
Normally we give up retrying after a set amount of retries (often 4
hours). As broadcast content is much more important than normal
notifications, we don't ever want to give up on sending them to phones...
...UNLESS WE DO!
Sometimes we do want to give up sending a broadcast though! Broadcasts
have an expiry time, when they stop showing up on peoples devices, so if
that has passed then we don't need to send the broadcast out.
Broadcast events can also be superceded by updates or cancels. Check
that the event is the most recent event for that broadcast message, if
not, give up, as we don't want to accidentally send out two conflicting
events for the same message.
2021-01-19 10:05:48 +00:00
|
|
|
from app.clients.cbc_proxy import CBCProxyRetryableException
|
|
|
|
|
from app.celery.broadcast_message_tasks import (
|
|
|
|
|
check_provider_message_should_retry,
|
|
|
|
|
get_retry_delay,
|
|
|
|
|
send_broadcast_event,
|
|
|
|
|
send_broadcast_provider_message,
|
|
|
|
|
trigger_link_test,
|
|
|
|
|
)
|
2020-11-16 12:47:38 +00:00
|
|
|
|
2020-11-17 12:35:10 +00:00
|
|
|
from tests.app.db import (
|
|
|
|
|
create_template,
|
|
|
|
|
create_broadcast_message,
|
|
|
|
|
create_broadcast_event,
|
|
|
|
|
create_broadcast_provider_message
|
|
|
|
|
)
|
2020-11-16 12:47:38 +00:00
|
|
|
from tests.conftest import set_config
|
|
|
|
|
|
|
|
|
|
|
2020-12-02 14:10:46 +00:00
|
|
|
def test_send_broadcast_event_queues_up_for_active_providers(mocker, notify_api, sample_service):
|
|
|
|
|
template = create_template(sample_service, BROADCAST_TYPE)
|
|
|
|
|
broadcast_message = create_broadcast_message(template, status=BroadcastStatusType.BROADCASTING)
|
|
|
|
|
event = create_broadcast_event(broadcast_message)
|
|
|
|
|
|
2020-11-16 12:47:38 +00:00
|
|
|
mock_send_broadcast_provider_message = mocker.patch(
|
|
|
|
|
'app.celery.broadcast_message_tasks.send_broadcast_provider_message',
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
with set_config(notify_api, 'ENABLED_CBCS', ['ee', 'vodafone']):
|
2020-12-02 14:10:46 +00:00
|
|
|
send_broadcast_event(event.id)
|
2020-11-16 12:47:38 +00:00
|
|
|
|
|
|
|
|
assert mock_send_broadcast_provider_message.apply_async.call_args_list == [
|
2021-01-13 17:21:40 +00:00
|
|
|
call(kwargs={'broadcast_event_id': event.id, 'provider': 'ee'}, queue='broadcast-tasks'),
|
|
|
|
|
call(kwargs={'broadcast_event_id': event.id, 'provider': 'vodafone'}, queue='broadcast-tasks')
|
2020-11-16 12:47:38 +00:00
|
|
|
]
|
2020-07-09 18:22:29 +01:00
|
|
|
|
|
|
|
|
|
2020-12-02 14:10:46 +00:00
|
|
|
def test_send_broadcast_event_only_sends_to_one_provider_if_set_on_service(
|
|
|
|
|
mocker,
|
|
|
|
|
notify_db,
|
|
|
|
|
notify_api,
|
|
|
|
|
sample_service
|
|
|
|
|
):
|
|
|
|
|
notify_db.session.add(ServiceBroadcastProviderRestriction(
|
|
|
|
|
service=sample_service,
|
|
|
|
|
provider='vodafone'
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
template = create_template(sample_service, BROADCAST_TYPE)
|
|
|
|
|
broadcast_message = create_broadcast_message(template, status=BroadcastStatusType.BROADCASTING)
|
|
|
|
|
event = create_broadcast_event(broadcast_message)
|
|
|
|
|
|
|
|
|
|
mock_send_broadcast_provider_message = mocker.patch(
|
|
|
|
|
'app.celery.broadcast_message_tasks.send_broadcast_provider_message',
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
with set_config(notify_api, 'ENABLED_CBCS', ['ee', 'vodafone']):
|
|
|
|
|
send_broadcast_event(event.id)
|
|
|
|
|
|
|
|
|
|
assert mock_send_broadcast_provider_message.apply_async.call_args_list == [
|
2021-01-13 17:21:40 +00:00
|
|
|
call(kwargs={'broadcast_event_id': event.id, 'provider': 'vodafone'}, queue='broadcast-tasks')
|
2020-12-02 14:10:46 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_send_broadcast_event_does_nothing_if_provider_set_on_service_isnt_enabled_globally(
|
|
|
|
|
mocker,
|
|
|
|
|
notify_db,
|
|
|
|
|
notify_api,
|
|
|
|
|
sample_service
|
|
|
|
|
):
|
|
|
|
|
notify_db.session.add(ServiceBroadcastProviderRestriction(
|
|
|
|
|
service=sample_service,
|
|
|
|
|
provider='three'
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
template = create_template(sample_service, BROADCAST_TYPE)
|
|
|
|
|
broadcast_message = create_broadcast_message(template, status=BroadcastStatusType.BROADCASTING)
|
|
|
|
|
event = create_broadcast_event(broadcast_message)
|
|
|
|
|
|
|
|
|
|
mock_send_broadcast_provider_message = mocker.patch(
|
|
|
|
|
'app.celery.broadcast_message_tasks.send_broadcast_provider_message',
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
with set_config(notify_api, 'ENABLED_CBCS', ['ee', 'vodafone']):
|
|
|
|
|
send_broadcast_event(event.id)
|
|
|
|
|
|
|
|
|
|
assert mock_send_broadcast_provider_message.apply_async.called is False
|
|
|
|
|
|
|
|
|
|
|
2020-11-25 17:39:32 +00:00
|
|
|
def test_send_broadcast_event_does_nothing_if_cbc_proxy_disabled(mocker, notify_api):
|
|
|
|
|
mock_send_broadcast_provider_message = mocker.patch(
|
|
|
|
|
'app.celery.broadcast_message_tasks.send_broadcast_provider_message',
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
event_id = uuid.uuid4()
|
|
|
|
|
with set_config(notify_api, 'ENABLED_CBCS', ['ee', 'vodafone']), set_config(notify_api, 'CBC_PROXY_ENABLED', False):
|
|
|
|
|
send_broadcast_event(event_id)
|
|
|
|
|
|
|
|
|
|
assert mock_send_broadcast_provider_message.apply_async.called is False
|
|
|
|
|
|
|
|
|
|
|
2020-08-04 19:21:22 +01:00
|
|
|
@freeze_time('2020-08-01 12:00')
|
2020-12-09 11:13:50 +00:00
|
|
|
@pytest.mark.parametrize('provider,provider_capitalised', [
|
|
|
|
|
['ee', 'EE'],
|
2021-01-29 12:18:54 +00:00
|
|
|
['three', 'Three'],
|
|
|
|
|
['o2', 'O2'],
|
2020-12-09 11:13:50 +00:00
|
|
|
['vodafone', 'Vodafone'],
|
2020-12-08 11:12:48 +00:00
|
|
|
])
|
|
|
|
|
def test_send_broadcast_provider_message_sends_data_correctly(
|
2020-12-09 11:13:50 +00:00
|
|
|
mocker, sample_service, provider, provider_capitalised
|
2020-12-08 11:12:48 +00:00
|
|
|
):
|
2020-08-04 19:21:22 +01:00
|
|
|
template = create_template(sample_service, BROADCAST_TYPE)
|
2020-09-14 15:21:55 +01:00
|
|
|
broadcast_message = create_broadcast_message(
|
|
|
|
|
template,
|
2020-10-26 15:14:26 +00:00
|
|
|
areas={
|
|
|
|
|
'areas': ['london', 'glasgow'],
|
|
|
|
|
'simple_polygons': [
|
|
|
|
|
[[50.12, 1.2], [50.13, 1.2], [50.14, 1.21]],
|
|
|
|
|
[[-4.53, 55.72], [-3.88, 55.72], [-3.88, 55.96], [-4.53, 55.96]],
|
|
|
|
|
],
|
|
|
|
|
},
|
2020-09-14 15:21:55 +01:00
|
|
|
status=BroadcastStatusType.BROADCASTING
|
|
|
|
|
)
|
2020-08-04 19:21:22 +01:00
|
|
|
event = create_broadcast_event(broadcast_message)
|
|
|
|
|
|
2020-10-20 11:57:26 +01:00
|
|
|
mock_create_broadcast = mocker.patch(
|
2020-12-08 11:12:48 +00:00
|
|
|
f'app.clients.cbc_proxy.CBCProxy{provider_capitalised}.create_and_send_broadcast',
|
2020-10-20 11:57:26 +01:00
|
|
|
)
|
|
|
|
|
|
2020-12-08 11:12:48 +00:00
|
|
|
assert event.get_provider_message(provider) is None
|
2020-11-16 18:48:00 +00:00
|
|
|
|
2020-12-08 11:12:48 +00:00
|
|
|
send_broadcast_provider_message(provider=provider, broadcast_event_id=str(event.id))
|
2020-08-04 19:21:22 +01:00
|
|
|
|
2020-12-08 11:12:48 +00:00
|
|
|
broadcast_provider_message = event.get_provider_message(provider)
|
2020-11-16 18:48:00 +00:00
|
|
|
assert broadcast_provider_message.status == BroadcastProviderMessageStatus.SENDING
|
|
|
|
|
|
2020-10-20 11:57:26 +01:00
|
|
|
mock_create_broadcast.assert_called_once_with(
|
2020-11-16 18:48:00 +00:00
|
|
|
identifier=str(broadcast_provider_message.id),
|
2020-12-04 17:07:08 +00:00
|
|
|
message_number=mocker.ANY,
|
2020-10-26 15:14:26 +00:00
|
|
|
headline='GOV.UK Notify Broadcast',
|
2020-10-20 11:57:26 +01:00
|
|
|
description='this is an emergency broadcast message',
|
2020-10-23 16:44:11 +01:00
|
|
|
areas=[{
|
2020-10-26 15:14:26 +00:00
|
|
|
'polygon': [
|
|
|
|
|
[50.12, 1.2], [50.13, 1.2], [50.14, 1.21],
|
|
|
|
|
],
|
|
|
|
|
}, {
|
|
|
|
|
'polygon': [
|
|
|
|
|
[-4.53, 55.72], [-3.88, 55.72], [-3.88, 55.96], [-4.53, 55.96],
|
|
|
|
|
],
|
2020-10-23 17:54:33 +01:00
|
|
|
}],
|
2020-10-28 11:26:38 +00:00
|
|
|
sent=event.sent_at_as_cap_datetime_string,
|
|
|
|
|
expires=event.transmitted_finishes_at_as_cap_datetime_string,
|
2021-01-29 11:54:12 +00:00
|
|
|
channel="test",
|
2020-10-23 17:54:33 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2021-01-29 14:14:15 +00:00
|
|
|
@freeze_time('2020-08-01 12:00')
|
|
|
|
|
@pytest.mark.parametrize('provider,provider_capitalised', [
|
|
|
|
|
['ee', 'EE'],
|
|
|
|
|
['three', 'Three'],
|
|
|
|
|
['o2', 'O2'],
|
|
|
|
|
['vodafone', 'Vodafone'],
|
|
|
|
|
])
|
|
|
|
|
@pytest.mark.parametrize('channel', ['test', 'severe'])
|
|
|
|
|
def test_send_broadcast_provider_message_uses_channel_set_on_broadcast_service(
|
|
|
|
|
notify_db, mocker, sample_service, provider, provider_capitalised, channel
|
|
|
|
|
):
|
|
|
|
|
template = create_template(sample_service, BROADCAST_TYPE)
|
|
|
|
|
broadcast_message = create_broadcast_message(
|
|
|
|
|
template,
|
|
|
|
|
areas={
|
|
|
|
|
'areas': ['london', 'glasgow'],
|
|
|
|
|
'simple_polygons': [
|
|
|
|
|
[[50.12, 1.2], [50.13, 1.2], [50.14, 1.21]],
|
|
|
|
|
[[-4.53, 55.72], [-3.88, 55.72], [-3.88, 55.96], [-4.53, 55.96]],
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
status=BroadcastStatusType.BROADCASTING
|
|
|
|
|
)
|
|
|
|
|
event = create_broadcast_event(broadcast_message)
|
|
|
|
|
notify_db.session.add(ServiceBroadcastSettings(service=sample_service, channel=channel))
|
|
|
|
|
|
|
|
|
|
mock_create_broadcast = mocker.patch(
|
|
|
|
|
f'app.clients.cbc_proxy.CBCProxy{provider_capitalised}.create_and_send_broadcast',
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
send_broadcast_provider_message(provider=provider, broadcast_event_id=str(event.id))
|
|
|
|
|
|
|
|
|
|
mock_create_broadcast.assert_called_once_with(
|
|
|
|
|
identifier=mocker.ANY,
|
|
|
|
|
message_number=mocker.ANY,
|
|
|
|
|
headline='GOV.UK Notify Broadcast',
|
|
|
|
|
description='this is an emergency broadcast message',
|
|
|
|
|
areas=mocker.ANY,
|
|
|
|
|
sent=mocker.ANY,
|
|
|
|
|
expires=mocker.ANY,
|
|
|
|
|
channel=channel,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@freeze_time('2020-08-01 12:00')
|
|
|
|
|
@pytest.mark.parametrize('provider,provider_capitalised', [
|
|
|
|
|
['ee', 'EE'],
|
|
|
|
|
['three', 'Three'],
|
|
|
|
|
['o2', 'O2'],
|
|
|
|
|
['vodafone', 'Vodafone'],
|
|
|
|
|
])
|
|
|
|
|
def test_send_broadcast_provider_message_defaults_to_test_channel_if_no_service_broadcast_settings(
|
|
|
|
|
notify_db, mocker, sample_service, provider, provider_capitalised
|
|
|
|
|
):
|
|
|
|
|
template = create_template(sample_service, BROADCAST_TYPE)
|
|
|
|
|
broadcast_message = create_broadcast_message(
|
|
|
|
|
template,
|
|
|
|
|
areas={
|
|
|
|
|
'areas': ['london', 'glasgow'],
|
|
|
|
|
'simple_polygons': [
|
|
|
|
|
[[50.12, 1.2], [50.13, 1.2], [50.14, 1.21]],
|
|
|
|
|
[[-4.53, 55.72], [-3.88, 55.72], [-3.88, 55.96], [-4.53, 55.96]],
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
status=BroadcastStatusType.BROADCASTING
|
|
|
|
|
)
|
|
|
|
|
event = create_broadcast_event(broadcast_message)
|
|
|
|
|
mock_create_broadcast = mocker.patch(
|
|
|
|
|
f'app.clients.cbc_proxy.CBCProxy{provider_capitalised}.create_and_send_broadcast',
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
send_broadcast_provider_message(provider=provider, broadcast_event_id=str(event.id))
|
|
|
|
|
|
|
|
|
|
mock_create_broadcast.assert_called_once_with(
|
|
|
|
|
identifier=mocker.ANY,
|
|
|
|
|
message_number=mocker.ANY,
|
|
|
|
|
headline='GOV.UK Notify Broadcast',
|
|
|
|
|
description='this is an emergency broadcast message',
|
|
|
|
|
areas=mocker.ANY,
|
|
|
|
|
sent=mocker.ANY,
|
|
|
|
|
expires=mocker.ANY,
|
|
|
|
|
channel="test",
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2021-02-01 11:24:19 +00:00
|
|
|
def test_send_broadcast_provider_message_works_if_we_retried_previously(mocker, sample_service):
|
|
|
|
|
template = create_template(sample_service, BROADCAST_TYPE)
|
|
|
|
|
broadcast_message = create_broadcast_message(
|
|
|
|
|
template,
|
|
|
|
|
areas={'areas': [], 'simple_polygons': [],},
|
|
|
|
|
status=BroadcastStatusType.BROADCASTING
|
|
|
|
|
)
|
|
|
|
|
event = create_broadcast_event(broadcast_message)
|
|
|
|
|
|
|
|
|
|
# an existing provider message already exists, and previously failed
|
|
|
|
|
existing_provider_message = create_broadcast_provider_message(
|
|
|
|
|
broadcast_event=event,
|
|
|
|
|
provider='ee',
|
|
|
|
|
status=BroadcastProviderMessageStatus.TECHNICAL_FAILURE
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
mock_create_broadcast = mocker.patch(
|
|
|
|
|
f'app.clients.cbc_proxy.CBCProxyEE.create_and_send_broadcast',
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
send_broadcast_provider_message(provider='ee', broadcast_event_id=str(event.id))
|
|
|
|
|
|
|
|
|
|
# make sure we haven't completed a duplicate event - we shouldn't record the failure
|
|
|
|
|
assert len(event.provider_messages) == 1
|
|
|
|
|
|
|
|
|
|
broadcast_provider_message = event.get_provider_message('ee')
|
|
|
|
|
# TODO: Should be ACK, and should have an updated_at
|
|
|
|
|
assert broadcast_provider_message.status == BroadcastProviderMessageStatus.TECHNICAL_FAILURE
|
|
|
|
|
assert broadcast_provider_message.updated_at is None
|
|
|
|
|
|
|
|
|
|
mock_create_broadcast.assert_called_once_with(
|
|
|
|
|
identifier=str(broadcast_provider_message.id),
|
|
|
|
|
message_number=mocker.ANY,
|
|
|
|
|
headline='GOV.UK Notify Broadcast',
|
|
|
|
|
description='this is an emergency broadcast message',
|
|
|
|
|
areas=[],
|
|
|
|
|
sent=event.sent_at_as_cap_datetime_string,
|
|
|
|
|
expires=event.transmitted_finishes_at_as_cap_datetime_string,
|
|
|
|
|
channel='test',
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2021-01-08 16:38:51 +00:00
|
|
|
@freeze_time('2020-08-01 12:00')
|
2021-01-29 12:18:54 +00:00
|
|
|
@pytest.mark.parametrize('provider,provider_capitalised', [
|
|
|
|
|
['ee', 'EE'],
|
|
|
|
|
['three', 'Three'],
|
|
|
|
|
['o2', 'O2'],
|
|
|
|
|
['vodafone', 'Vodafone'],
|
|
|
|
|
])
|
2021-01-08 16:38:51 +00:00
|
|
|
def test_send_broadcast_provider_message_sends_data_correctly_when_broadcast_message_has_no_template(
|
2021-01-29 12:18:54 +00:00
|
|
|
mocker, sample_service, provider, provider_capitalised
|
2021-01-08 16:38:51 +00:00
|
|
|
):
|
|
|
|
|
broadcast_message = create_broadcast_message(
|
|
|
|
|
service=sample_service,
|
|
|
|
|
template=None,
|
|
|
|
|
content='this is an emergency broadcast message',
|
|
|
|
|
areas={
|
|
|
|
|
'areas': ['london', 'glasgow'],
|
|
|
|
|
'simple_polygons': [
|
|
|
|
|
[[50.12, 1.2], [50.13, 1.2], [50.14, 1.21]],
|
|
|
|
|
[[-4.53, 55.72], [-3.88, 55.72], [-3.88, 55.96], [-4.53, 55.96]],
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
status=BroadcastStatusType.BROADCASTING
|
|
|
|
|
)
|
|
|
|
|
event = create_broadcast_event(broadcast_message)
|
|
|
|
|
|
|
|
|
|
mock_create_broadcast = mocker.patch(
|
2021-01-29 12:18:54 +00:00
|
|
|
f'app.clients.cbc_proxy.CBCProxy{provider_capitalised}.create_and_send_broadcast',
|
2021-01-08 16:38:51 +00:00
|
|
|
)
|
|
|
|
|
|
2021-01-29 12:18:54 +00:00
|
|
|
send_broadcast_provider_message(provider=provider, broadcast_event_id=str(event.id))
|
2021-01-08 16:38:51 +00:00
|
|
|
|
2021-01-29 12:18:54 +00:00
|
|
|
broadcast_provider_message = event.get_provider_message(provider)
|
2021-01-08 16:38:51 +00:00
|
|
|
|
|
|
|
|
mock_create_broadcast.assert_called_once_with(
|
|
|
|
|
identifier=str(broadcast_provider_message.id),
|
|
|
|
|
message_number=mocker.ANY,
|
|
|
|
|
headline='GOV.UK Notify Broadcast',
|
|
|
|
|
description='this is an emergency broadcast message',
|
|
|
|
|
areas=mocker.ANY,
|
|
|
|
|
sent=mocker.ANY,
|
|
|
|
|
expires=mocker.ANY,
|
2021-01-29 11:54:12 +00:00
|
|
|
channel="test"
|
2021-01-08 16:38:51 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2020-12-09 11:13:50 +00:00
|
|
|
@pytest.mark.parametrize('provider,provider_capitalised', [
|
|
|
|
|
['ee', 'EE'],
|
2021-01-29 12:18:54 +00:00
|
|
|
['three', 'Three'],
|
|
|
|
|
['o2', 'O2'],
|
2020-12-09 11:13:50 +00:00
|
|
|
['vodafone', 'Vodafone'],
|
2020-12-08 11:12:48 +00:00
|
|
|
])
|
|
|
|
|
def test_send_broadcast_provider_message_sends_update_with_references(
|
2020-12-09 11:13:50 +00:00
|
|
|
mocker, sample_service, provider, provider_capitalised
|
2020-12-08 11:12:48 +00:00
|
|
|
):
|
2020-10-23 17:54:33 +01:00
|
|
|
template = create_template(sample_service, BROADCAST_TYPE, content='content')
|
2020-10-26 15:14:26 +00:00
|
|
|
|
|
|
|
|
broadcast_message = create_broadcast_message(
|
|
|
|
|
template,
|
|
|
|
|
areas={
|
|
|
|
|
'areas': ['london'],
|
|
|
|
|
'simple_polygons': [
|
|
|
|
|
[[50.12, 1.2], [50.13, 1.2], [50.14, 1.21]],
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
status=BroadcastStatusType.BROADCASTING
|
|
|
|
|
)
|
|
|
|
|
|
2020-10-23 17:54:33 +01:00
|
|
|
alert_event = create_broadcast_event(broadcast_message, message_type=BroadcastEventMessageType.ALERT)
|
2020-12-08 11:12:48 +00:00
|
|
|
create_broadcast_provider_message(alert_event, provider)
|
2020-10-23 17:54:33 +01:00
|
|
|
update_event = create_broadcast_event(broadcast_message, message_type=BroadcastEventMessageType.UPDATE)
|
|
|
|
|
|
|
|
|
|
mock_update_broadcast = mocker.patch(
|
2020-12-08 11:12:48 +00:00
|
|
|
f'app.clients.cbc_proxy.CBCProxy{provider_capitalised}.update_and_send_broadcast',
|
2020-10-20 11:57:26 +01:00
|
|
|
)
|
|
|
|
|
|
2020-12-08 11:12:48 +00:00
|
|
|
send_broadcast_provider_message(provider=provider, broadcast_event_id=str(update_event.id))
|
2020-08-04 19:21:22 +01:00
|
|
|
|
2020-12-08 11:12:48 +00:00
|
|
|
broadcast_provider_message = update_event.get_provider_message(provider)
|
2020-11-17 12:35:10 +00:00
|
|
|
assert broadcast_provider_message.status == BroadcastProviderMessageStatus.SENDING
|
2020-11-16 18:48:00 +00:00
|
|
|
|
2020-10-23 17:54:33 +01:00
|
|
|
mock_update_broadcast.assert_called_once_with(
|
2020-11-16 18:48:00 +00:00
|
|
|
identifier=str(broadcast_provider_message.id),
|
2020-12-04 17:07:08 +00:00
|
|
|
message_number=mocker.ANY,
|
2020-10-23 17:54:33 +01:00
|
|
|
headline="GOV.UK Notify Broadcast",
|
|
|
|
|
description='this is an emergency broadcast message',
|
|
|
|
|
areas=[{
|
|
|
|
|
"polygon": [[50.12, 1.2], [50.13, 1.2], [50.14, 1.21]],
|
|
|
|
|
}],
|
2020-11-17 12:35:10 +00:00
|
|
|
previous_provider_messages=[
|
2020-12-08 11:12:48 +00:00
|
|
|
alert_event.get_provider_message(provider)
|
2020-11-17 12:35:10 +00:00
|
|
|
],
|
2020-10-28 11:26:38 +00:00
|
|
|
sent=update_event.sent_at_as_cap_datetime_string,
|
|
|
|
|
expires=update_event.transmitted_finishes_at_as_cap_datetime_string,
|
2021-01-29 11:54:12 +00:00
|
|
|
channel="test"
|
2020-10-23 17:54:33 +01:00
|
|
|
)
|
2020-08-04 19:21:22 +01:00
|
|
|
|
|
|
|
|
|
2020-12-09 11:13:50 +00:00
|
|
|
@pytest.mark.parametrize('provider,provider_capitalised', [
|
|
|
|
|
['ee', 'EE'],
|
2021-01-29 12:18:54 +00:00
|
|
|
['three', 'Three'],
|
|
|
|
|
['o2', 'O2'],
|
2020-12-09 11:13:50 +00:00
|
|
|
['vodafone', 'Vodafone'],
|
2020-12-08 11:12:48 +00:00
|
|
|
])
|
|
|
|
|
def test_send_broadcast_provider_message_sends_cancel_with_references(
|
2020-12-09 11:13:50 +00:00
|
|
|
mocker, sample_service, provider, provider_capitalised
|
2020-12-08 11:12:48 +00:00
|
|
|
):
|
2020-08-04 19:21:22 +01:00
|
|
|
template = create_template(sample_service, BROADCAST_TYPE, content='content')
|
2020-10-26 15:14:26 +00:00
|
|
|
|
|
|
|
|
broadcast_message = create_broadcast_message(
|
|
|
|
|
template,
|
|
|
|
|
areas={
|
|
|
|
|
'areas': ['london'],
|
|
|
|
|
'simple_polygons': [
|
|
|
|
|
[[50.12, 1.2], [50.13, 1.2], [50.14, 1.21]],
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
status=BroadcastStatusType.BROADCASTING
|
|
|
|
|
)
|
|
|
|
|
|
2020-08-04 19:21:22 +01:00
|
|
|
alert_event = create_broadcast_event(broadcast_message, message_type=BroadcastEventMessageType.ALERT)
|
2020-10-23 17:54:33 +01:00
|
|
|
update_event = create_broadcast_event(broadcast_message, message_type=BroadcastEventMessageType.UPDATE)
|
2020-08-04 19:21:22 +01:00
|
|
|
cancel_event = create_broadcast_event(broadcast_message, message_type=BroadcastEventMessageType.CANCEL)
|
|
|
|
|
|
2020-12-08 11:12:48 +00:00
|
|
|
create_broadcast_provider_message(alert_event, provider)
|
|
|
|
|
create_broadcast_provider_message(update_event, provider)
|
2020-11-17 12:35:10 +00:00
|
|
|
|
2020-10-23 17:54:33 +01:00
|
|
|
mock_cancel_broadcast = mocker.patch(
|
2020-12-08 11:12:48 +00:00
|
|
|
f'app.clients.cbc_proxy.CBCProxy{provider_capitalised}.cancel_broadcast',
|
2020-10-20 11:57:26 +01:00
|
|
|
)
|
|
|
|
|
|
2020-12-08 11:12:48 +00:00
|
|
|
send_broadcast_provider_message(provider=provider, broadcast_event_id=str(cancel_event.id))
|
2020-08-04 19:21:22 +01:00
|
|
|
|
2020-12-08 11:12:48 +00:00
|
|
|
broadcast_provider_message = cancel_event.get_provider_message(provider)
|
2020-11-17 12:35:10 +00:00
|
|
|
assert broadcast_provider_message.status == BroadcastProviderMessageStatus.SENDING
|
2020-11-16 18:48:00 +00:00
|
|
|
|
2020-10-23 17:54:33 +01:00
|
|
|
mock_cancel_broadcast.assert_called_once_with(
|
2020-11-16 18:48:00 +00:00
|
|
|
identifier=str(broadcast_provider_message.id),
|
2020-12-04 17:07:08 +00:00
|
|
|
message_number=mocker.ANY,
|
2020-11-17 12:35:10 +00:00
|
|
|
previous_provider_messages=[
|
2020-12-08 11:12:48 +00:00
|
|
|
alert_event.get_provider_message(provider),
|
|
|
|
|
update_event.get_provider_message(provider)
|
2020-11-17 12:35:10 +00:00
|
|
|
],
|
2020-10-28 11:26:38 +00:00
|
|
|
sent=cancel_event.sent_at_as_cap_datetime_string,
|
2020-10-23 17:54:33 +01:00
|
|
|
)
|
2020-08-04 19:21:22 +01:00
|
|
|
|
|
|
|
|
|
2021-01-29 12:18:54 +00:00
|
|
|
@pytest.mark.parametrize("provider,provider_capitalised", [
|
|
|
|
|
['ee', 'EE'],
|
|
|
|
|
['three', 'Three'],
|
|
|
|
|
['o2', 'O2'],
|
|
|
|
|
['vodafone', 'Vodafone'],
|
|
|
|
|
])
|
|
|
|
|
def test_send_broadcast_provider_message_errors(mocker, sample_service, provider, provider_capitalised):
|
2020-08-04 19:21:22 +01:00
|
|
|
template = create_template(sample_service, BROADCAST_TYPE)
|
2020-10-26 15:14:26 +00:00
|
|
|
|
|
|
|
|
broadcast_message = create_broadcast_message(
|
|
|
|
|
template,
|
|
|
|
|
areas={
|
|
|
|
|
'areas': ['london'],
|
|
|
|
|
'simple_polygons': [
|
|
|
|
|
[[50.12, 1.2], [50.13, 1.2], [50.14, 1.21]],
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
status=BroadcastStatusType.BROADCASTING
|
|
|
|
|
)
|
|
|
|
|
|
2020-08-04 19:21:22 +01:00
|
|
|
event = create_broadcast_event(broadcast_message)
|
|
|
|
|
|
2020-10-20 11:57:26 +01:00
|
|
|
mock_create_broadcast = mocker.patch(
|
2021-01-29 12:18:54 +00:00
|
|
|
f'app.clients.cbc_proxy.CBCProxy{provider_capitalised}.create_and_send_broadcast',
|
retry sending broadcasts
Retry tasks if they fail to send a broadcast event. Note that each task
tries the regular proxy and the failover proxy for that provider. This
runs a bit differently than our other retries:
Retry with exponential backoff. Our other tasks retry with a fixed delay
of 5 minutes between tries. If we can't send a broadcast, we want to try
immediately. So instead, implement an exponential backoff (1, 2, 4, 8,
... seconds delay). We can't delay for longer than 310 seconds due to
visibility timeout settings in SQS, so cap the delay at that amount.
Normally we give up retrying after a set amount of retries (often 4
hours). As broadcast content is much more important than normal
notifications, we don't ever want to give up on sending them to phones...
...UNLESS WE DO!
Sometimes we do want to give up sending a broadcast though! Broadcasts
have an expiry time, when they stop showing up on peoples devices, so if
that has passed then we don't need to send the broadcast out.
Broadcast events can also be superceded by updates or cancels. Check
that the event is the most recent event for that broadcast message, if
not, give up, as we don't want to accidentally send out two conflicting
events for the same message.
2021-01-19 10:05:48 +00:00
|
|
|
side_effect=CBCProxyRetryableException('oh no'),
|
2020-10-20 11:57:26 +01:00
|
|
|
)
|
retry sending broadcasts
Retry tasks if they fail to send a broadcast event. Note that each task
tries the regular proxy and the failover proxy for that provider. This
runs a bit differently than our other retries:
Retry with exponential backoff. Our other tasks retry with a fixed delay
of 5 minutes between tries. If we can't send a broadcast, we want to try
immediately. So instead, implement an exponential backoff (1, 2, 4, 8,
... seconds delay). We can't delay for longer than 310 seconds due to
visibility timeout settings in SQS, so cap the delay at that amount.
Normally we give up retrying after a set amount of retries (often 4
hours). As broadcast content is much more important than normal
notifications, we don't ever want to give up on sending them to phones...
...UNLESS WE DO!
Sometimes we do want to give up sending a broadcast though! Broadcasts
have an expiry time, when they stop showing up on peoples devices, so if
that has passed then we don't need to send the broadcast out.
Broadcast events can also be superceded by updates or cancels. Check
that the event is the most recent event for that broadcast message, if
not, give up, as we don't want to accidentally send out two conflicting
events for the same message.
2021-01-19 10:05:48 +00:00
|
|
|
mock_retry = mocker.patch('app.celery.broadcast_message_tasks.send_broadcast_provider_message.retry')
|
2020-10-20 11:57:26 +01:00
|
|
|
|
retry sending broadcasts
Retry tasks if they fail to send a broadcast event. Note that each task
tries the regular proxy and the failover proxy for that provider. This
runs a bit differently than our other retries:
Retry with exponential backoff. Our other tasks retry with a fixed delay
of 5 minutes between tries. If we can't send a broadcast, we want to try
immediately. So instead, implement an exponential backoff (1, 2, 4, 8,
... seconds delay). We can't delay for longer than 310 seconds due to
visibility timeout settings in SQS, so cap the delay at that amount.
Normally we give up retrying after a set amount of retries (often 4
hours). As broadcast content is much more important than normal
notifications, we don't ever want to give up on sending them to phones...
...UNLESS WE DO!
Sometimes we do want to give up sending a broadcast though! Broadcasts
have an expiry time, when they stop showing up on peoples devices, so if
that has passed then we don't need to send the broadcast out.
Broadcast events can also be superceded by updates or cancels. Check
that the event is the most recent event for that broadcast message, if
not, give up, as we don't want to accidentally send out two conflicting
events for the same message.
2021-01-19 10:05:48 +00:00
|
|
|
send_broadcast_provider_message(provider=provider, broadcast_event_id=str(event.id))
|
2020-10-20 11:57:26 +01:00
|
|
|
|
|
|
|
|
mock_create_broadcast.assert_called_once_with(
|
2020-11-16 18:48:00 +00:00
|
|
|
identifier=ANY,
|
2020-12-04 17:07:08 +00:00
|
|
|
message_number=mocker.ANY,
|
2020-10-20 11:57:26 +01:00
|
|
|
headline="GOV.UK Notify Broadcast",
|
|
|
|
|
description='this is an emergency broadcast message',
|
2020-10-23 16:44:11 +01:00
|
|
|
areas=[{
|
|
|
|
|
'polygon': [
|
|
|
|
|
[50.12, 1.2],
|
|
|
|
|
[50.13, 1.2],
|
|
|
|
|
[50.14, 1.21],
|
|
|
|
|
],
|
|
|
|
|
}],
|
2020-10-28 11:26:38 +00:00
|
|
|
sent=event.sent_at_as_cap_datetime_string,
|
|
|
|
|
expires=event.transmitted_finishes_at_as_cap_datetime_string,
|
2021-01-29 11:54:12 +00:00
|
|
|
channel="test"
|
2020-10-20 11:57:26 +01:00
|
|
|
)
|
retry sending broadcasts
Retry tasks if they fail to send a broadcast event. Note that each task
tries the regular proxy and the failover proxy for that provider. This
runs a bit differently than our other retries:
Retry with exponential backoff. Our other tasks retry with a fixed delay
of 5 minutes between tries. If we can't send a broadcast, we want to try
immediately. So instead, implement an exponential backoff (1, 2, 4, 8,
... seconds delay). We can't delay for longer than 310 seconds due to
visibility timeout settings in SQS, so cap the delay at that amount.
Normally we give up retrying after a set amount of retries (often 4
hours). As broadcast content is much more important than normal
notifications, we don't ever want to give up on sending them to phones...
...UNLESS WE DO!
Sometimes we do want to give up sending a broadcast though! Broadcasts
have an expiry time, when they stop showing up on peoples devices, so if
that has passed then we don't need to send the broadcast out.
Broadcast events can also be superceded by updates or cancels. Check
that the event is the most recent event for that broadcast message, if
not, give up, as we don't want to accidentally send out two conflicting
events for the same message.
2021-01-19 10:05:48 +00:00
|
|
|
mock_retry.assert_called_once_with(
|
|
|
|
|
countdown=1,
|
|
|
|
|
exc=mock_create_broadcast.side_effect,
|
|
|
|
|
queue='broadcast-tasks'
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('num_retries, expected_countdown', [
|
|
|
|
|
(0, 1),
|
|
|
|
|
(5, 32),
|
|
|
|
|
(20, 300),
|
|
|
|
|
])
|
|
|
|
|
def test_send_broadcast_provider_message_delays_retry_exponentially(
|
|
|
|
|
mocker,
|
|
|
|
|
sample_service,
|
|
|
|
|
num_retries,
|
|
|
|
|
expected_countdown
|
|
|
|
|
):
|
|
|
|
|
template = create_template(sample_service, BROADCAST_TYPE)
|
|
|
|
|
|
|
|
|
|
broadcast_message = create_broadcast_message(template, status=BroadcastStatusType.BROADCASTING)
|
|
|
|
|
event = create_broadcast_event(broadcast_message)
|
|
|
|
|
|
|
|
|
|
mock_create_broadcast = mocker.patch(
|
|
|
|
|
'app.clients.cbc_proxy.CBCProxyEE.create_and_send_broadcast',
|
|
|
|
|
side_effect=CBCProxyRetryableException('oh no'),
|
|
|
|
|
)
|
|
|
|
|
mock_retry = mocker.patch('app.celery.broadcast_message_tasks.send_broadcast_provider_message.retry')
|
|
|
|
|
|
|
|
|
|
# patch celery request context as shown here: https://stackoverflow.com/a/59870468
|
|
|
|
|
mock_celery_task_request_context = mocker.patch("celery.app.task.Task.request")
|
|
|
|
|
mock_celery_task_request_context.retries = num_retries
|
|
|
|
|
|
|
|
|
|
send_broadcast_provider_message(provider='ee', broadcast_event_id=str(event.id))
|
|
|
|
|
|
|
|
|
|
mock_create_broadcast.assert_called_once_with(
|
|
|
|
|
identifier=ANY,
|
|
|
|
|
message_number=mocker.ANY,
|
|
|
|
|
headline="GOV.UK Notify Broadcast",
|
|
|
|
|
description='this is an emergency broadcast message',
|
|
|
|
|
areas=[],
|
|
|
|
|
sent=event.sent_at_as_cap_datetime_string,
|
|
|
|
|
expires=event.transmitted_finishes_at_as_cap_datetime_string,
|
|
|
|
|
channel='test',
|
|
|
|
|
)
|
|
|
|
|
mock_retry.assert_called_once_with(
|
|
|
|
|
countdown=expected_countdown,
|
|
|
|
|
exc=mock_create_broadcast.side_effect,
|
|
|
|
|
queue='broadcast-tasks'
|
|
|
|
|
)
|
2020-11-16 12:47:38 +00:00
|
|
|
|
|
|
|
|
|
2020-12-04 15:49:50 +00:00
|
|
|
@pytest.mark.parametrize("provider,provider_capitalised", [
|
2021-01-29 12:18:54 +00:00
|
|
|
['ee', 'EE'],
|
|
|
|
|
['three', 'Three'],
|
|
|
|
|
['o2', 'O2'],
|
|
|
|
|
['vodafone', 'Vodafone'],
|
2020-12-04 15:49:50 +00:00
|
|
|
])
|
2020-11-16 12:47:38 +00:00
|
|
|
def test_trigger_link_tests_invokes_cbc_proxy_client(
|
2020-12-04 15:49:50 +00:00
|
|
|
mocker, provider, provider_capitalised
|
2020-11-16 12:47:38 +00:00
|
|
|
):
|
|
|
|
|
mock_send_link_test = mocker.patch(
|
2020-12-04 15:49:50 +00:00
|
|
|
f'app.clients.cbc_proxy.CBCProxy{provider_capitalised}.send_link_test',
|
2020-11-16 12:47:38 +00:00
|
|
|
)
|
|
|
|
|
|
2020-12-04 15:49:50 +00:00
|
|
|
trigger_link_test(provider)
|
2020-11-16 12:47:38 +00:00
|
|
|
|
|
|
|
|
assert mock_send_link_test.called
|
|
|
|
|
# the 0th argument of the call to send_link_test
|
|
|
|
|
identifier = mock_send_link_test.mock_calls[0][1][0]
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
uuid.UUID(identifier)
|
|
|
|
|
except BaseException:
|
|
|
|
|
pytest.fail(f"{identifier} is not a valid uuid")
|
2020-12-04 15:49:50 +00:00
|
|
|
|
|
|
|
|
# testing sequential number:
|
|
|
|
|
if provider == 'vodafone':
|
2020-12-04 16:00:20 +00:00
|
|
|
assert type(mock_send_link_test.mock_calls[0][1][1]) is str
|
|
|
|
|
assert len(mock_send_link_test.mock_calls[0][1][1]) == 8
|
2020-12-04 15:49:50 +00:00
|
|
|
else:
|
|
|
|
|
assert not mock_send_link_test.mock_calls[0][1][1]
|
retry sending broadcasts
Retry tasks if they fail to send a broadcast event. Note that each task
tries the regular proxy and the failover proxy for that provider. This
runs a bit differently than our other retries:
Retry with exponential backoff. Our other tasks retry with a fixed delay
of 5 minutes between tries. If we can't send a broadcast, we want to try
immediately. So instead, implement an exponential backoff (1, 2, 4, 8,
... seconds delay). We can't delay for longer than 310 seconds due to
visibility timeout settings in SQS, so cap the delay at that amount.
Normally we give up retrying after a set amount of retries (often 4
hours). As broadcast content is much more important than normal
notifications, we don't ever want to give up on sending them to phones...
...UNLESS WE DO!
Sometimes we do want to give up sending a broadcast though! Broadcasts
have an expiry time, when they stop showing up on peoples devices, so if
that has passed then we don't need to send the broadcast out.
Broadcast events can also be superceded by updates or cancels. Check
that the event is the most recent event for that broadcast message, if
not, give up, as we don't want to accidentally send out two conflicting
events for the same message.
2021-01-19 10:05:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('retry_count, expected_delay', [
|
|
|
|
|
(0, 1),
|
|
|
|
|
(1, 2),
|
|
|
|
|
(2, 4),
|
|
|
|
|
(8, 256),
|
|
|
|
|
(9, 300),
|
|
|
|
|
(10, 300),
|
|
|
|
|
(1000, 300),
|
|
|
|
|
])
|
|
|
|
|
def test_get_retry_delay_has_capped_backoff(retry_count, expected_delay):
|
|
|
|
|
assert get_retry_delay(retry_count) == expected_delay
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@freeze_time('2021-01-01 12:00')
|
|
|
|
|
def test_check_provider_message_should_retry_doesnt_raise_if_event_hasnt_expired_yet(sample_template):
|
|
|
|
|
broadcast_message = create_broadcast_message(sample_template)
|
|
|
|
|
current_event = create_broadcast_event(
|
|
|
|
|
broadcast_message,
|
|
|
|
|
transmitted_starts_at=datetime(2021, 1, 1, 0, 0),
|
|
|
|
|
transmitted_finishes_at=datetime(2021, 1, 1, 12, 1),
|
|
|
|
|
)
|
|
|
|
|
provider_message = create_broadcast_provider_message(current_event, 'ee')
|
|
|
|
|
|
|
|
|
|
check_provider_message_should_retry(provider_message)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@freeze_time('2021-01-01 12:00')
|
|
|
|
|
def test_check_provider_message_should_retry_raises_if_event_has_expired(sample_template):
|
|
|
|
|
broadcast_message = create_broadcast_message(sample_template)
|
|
|
|
|
current_event = create_broadcast_event(
|
|
|
|
|
broadcast_message,
|
|
|
|
|
transmitted_starts_at=datetime(2021, 1, 1, 0, 0),
|
|
|
|
|
transmitted_finishes_at=datetime(2021, 1, 1, 11, 59),
|
|
|
|
|
)
|
|
|
|
|
provider_message = create_broadcast_provider_message(current_event, 'ee')
|
|
|
|
|
|
|
|
|
|
with pytest.raises(MaxRetriesExceededError) as exc:
|
|
|
|
|
check_provider_message_should_retry(provider_message)
|
|
|
|
|
assert 'The expiry time of 2021-01-01 11:59:00 has already passed' in str(exc.value)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@freeze_time('2021-01-01 12:00')
|
|
|
|
|
def test_check_provider_message_should_retry_raises_if_a_newer_event_exists(sample_template):
|
|
|
|
|
broadcast_message = create_broadcast_message(sample_template)
|
|
|
|
|
# event approved at midnight
|
|
|
|
|
past_event = create_broadcast_event(
|
|
|
|
|
broadcast_message,
|
|
|
|
|
message_type='alert',
|
|
|
|
|
sent_at=datetime(2021, 1, 1, 0, 0),
|
|
|
|
|
transmitted_starts_at=datetime(2021, 1, 1, 0, 0),
|
|
|
|
|
transmitted_finishes_at=datetime(2021, 1, 2, 0, 0),
|
|
|
|
|
)
|
|
|
|
|
# event updated at 5am (this is the event we're currently trying to send)
|
|
|
|
|
current_event = create_broadcast_event(
|
|
|
|
|
broadcast_message,
|
|
|
|
|
message_type='update',
|
|
|
|
|
sent_at=datetime(2021, 1, 1, 5, 0),
|
|
|
|
|
transmitted_starts_at=datetime(2021, 1, 1, 0, 0),
|
|
|
|
|
transmitted_finishes_at=datetime(2021, 1, 2, 0, 0),
|
|
|
|
|
)
|
|
|
|
|
# event updated at 7am
|
|
|
|
|
future_event = create_broadcast_event(
|
|
|
|
|
broadcast_message,
|
|
|
|
|
message_type='update',
|
|
|
|
|
sent_at=datetime(2021, 1, 1, 7, 0),
|
|
|
|
|
transmitted_starts_at=datetime(2021, 1, 1, 0, 0),
|
|
|
|
|
transmitted_finishes_at=datetime(2021, 1, 2, 0, 0),
|
|
|
|
|
)
|
|
|
|
|
# event cancelled at 10am
|
|
|
|
|
futurest_event = create_broadcast_event(
|
|
|
|
|
broadcast_message,
|
|
|
|
|
message_type='cancel',
|
|
|
|
|
sent_at=datetime(2021, 1, 1, 10, 0),
|
|
|
|
|
transmitted_starts_at=datetime(2021, 1, 1, 0, 0),
|
|
|
|
|
transmitted_finishes_at=datetime(2021, 1, 2, 0, 0),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
provider_message = create_broadcast_provider_message(current_event, 'ee')
|
|
|
|
|
|
|
|
|
|
# even though the task is going on until midnight tomorrow, we shouldn't send the update now, because the cancel
|
|
|
|
|
# message will be in the pipeline somewhere.
|
|
|
|
|
with pytest.raises(MaxRetriesExceededError) as exc:
|
|
|
|
|
check_provider_message_should_retry(provider_message)
|
|
|
|
|
|
|
|
|
|
assert f'This event has been superceeded by cancel broadcast_event {futurest_event.id}' in str(exc.value)
|