From a93a35de8d3b3c0e295d033a17d7e2e2e18fa7c6 Mon Sep 17 00:00:00 2001 From: Pea Tyczynska Date: Tue, 26 Jan 2021 16:50:34 +0000 Subject: [PATCH 1/3] Add 'stubbed' column to broadcast_message table This is a boolean column. It will be set to True for broadcasts created from training broadcast accounts. This will help us debug, for example by excluding all the stubbed broadcasts when we have some trouble with real broadcasts. --- app/models.py | 2 ++ .../versions/0340_stub_training_broadcasts.py | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 migrations/versions/0340_stub_training_broadcasts.py diff --git a/app/models.py b/app/models.py index 7dac89327..91e2f35b9 100644 --- a/app/models.py +++ b/app/models.py @@ -2269,6 +2269,8 @@ class BroadcastMessage(db.Model): reference = db.Column(db.String(255), nullable=True) + stubbed = db.Column(db.Boolean, nullable=True) + CheckConstraint("created_by_id is not null or api_key_id is not null") @property diff --git a/migrations/versions/0340_stub_training_broadcasts.py b/migrations/versions/0340_stub_training_broadcasts.py new file mode 100644 index 000000000..beb2ac8cc --- /dev/null +++ b/migrations/versions/0340_stub_training_broadcasts.py @@ -0,0 +1,25 @@ +""" + +Revision ID: 0340_stub_training_broadcasts +Revises: 0339_service_billing_details +Create Date: 2021-01-26 16:48:44.921065 + +""" +from alembic import op +import sqlalchemy as sa + + +revision = '0340_stub_training_broadcasts' +down_revision = '0339_service_billing_details' + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('broadcast_message', sa.Column('stubbed', sa.Boolean(), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('broadcast_message', 'stubbed') + # ### end Alembic commands ### From 26d6b4a958a6ec4fcd9078f93fafb6842ac617c7 Mon Sep 17 00:00:00 2001 From: Pea Tyczynska Date: Tue, 26 Jan 2021 17:39:38 +0000 Subject: [PATCH 2/3] Mark broadcast message as stubbed when sent from training account --- app/broadcast_message/rest.py | 1 + tests/app/broadcast_message/test_rest.py | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/broadcast_message/rest.py b/app/broadcast_message/rest.py index b88b48d7b..e7c05d931 100644 --- a/app/broadcast_message/rest.py +++ b/app/broadcast_message/rest.py @@ -121,6 +121,7 @@ def create_broadcast_message(service_id): created_by_id=user.id, content=content, reference=reference, + stubbed=service.restricted ) dao_save_object(broadcast_message) diff --git a/tests/app/broadcast_message/test_rest.py b/tests/app/broadcast_message/test_rest.py index 2ec082267..47802cee5 100644 --- a/tests/app/broadcast_message/test_rest.py +++ b/tests/app/broadcast_message/test_rest.py @@ -4,6 +4,7 @@ import uuid from freezegun import freeze_time import pytest +from app.dao.broadcast_message_dao import dao_get_broadcast_message_by_id_and_service_id from app.models import BROADCAST_TYPE, BroadcastStatusType, BroadcastEventMessageType from tests.app.db import create_broadcast_message, create_template, create_service, create_user @@ -117,7 +118,9 @@ def test_get_broadcast_messages_for_service(admin_request, sample_broadcast_serv @freeze_time('2020-01-01') -def test_create_broadcast_message(admin_request, sample_broadcast_service): +@pytest.mark.parametrize('training_mode_service', [True, False]) +def test_create_broadcast_message(admin_request, sample_broadcast_service, training_mode_service): + sample_broadcast_service.restricted = training_mode_service t = create_template(sample_broadcast_service, BROADCAST_TYPE) response = admin_request.post( @@ -138,6 +141,8 @@ def test_create_broadcast_message(admin_request, sample_broadcast_service): assert response['personalisation'] == {} assert response['areas'] == [] + broadcast_message = dao_get_broadcast_message_by_id_and_service_id(response["id"], sample_broadcast_service.id) + assert broadcast_message.stubbed == training_mode_service @pytest.mark.parametrize('data, expected_errors', [ ( From d4cc25051029d12a657c3a109caf9fec9ffba0b3 Mon Sep 17 00:00:00 2001 From: Pea Tyczynska Date: Tue, 26 Jan 2021 17:50:56 +0000 Subject: [PATCH 3/3] Don't create broadcast provider messages for stubbed broadcasts --- app/broadcast_message/rest.py | 9 +++--- tests/app/broadcast_message/test_rest.py | 41 ++++++++++++++++++++++++ tests/app/db.py | 4 ++- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/app/broadcast_message/rest.py b/app/broadcast_message/rest.py index e7c05d931..48f0a6e0f 100644 --- a/app/broadcast_message/rest.py +++ b/app/broadcast_message/rest.py @@ -215,7 +215,8 @@ def _create_broadcast_event(broadcast_message): dao_save_object(event) - send_broadcast_event.apply_async( - kwargs={'broadcast_event_id': str(event.id)}, - queue=QueueNames.BROADCASTS - ) + if not broadcast_message.stubbed: + send_broadcast_event.apply_async( + kwargs={'broadcast_event_id': str(event.id)}, + queue=QueueNames.BROADCASTS + ) diff --git a/tests/app/broadcast_message/test_rest.py b/tests/app/broadcast_message/test_rest.py index 47802cee5..28c79e487 100644 --- a/tests/app/broadcast_message/test_rest.py +++ b/tests/app/broadcast_message/test_rest.py @@ -551,6 +551,47 @@ def test_update_broadcast_message_status_stores_approved_by_and_approved_at_and_ assert alert_event.transmitted_content == {"body": "emergency broadcast"} +def test_update_broadcast_message_status_updates_details_but_does_not_queue_task_for_stubbed_broadcast_message( + admin_request, + sample_broadcast_service, + mocker +): + sample_broadcast_service.restricted = True + t = create_template(sample_broadcast_service, BROADCAST_TYPE, content='emergency broadcast') + bm = create_broadcast_message( + t, + status=BroadcastStatusType.PENDING_APPROVAL, + areas={"areas": ["london"], "simple_polygons": [[[51.30, 0.7], [51.28, 0.8], [51.25, -0.7]]]}, + stubbed=True + ) + approver = create_user(email='approver@gov.uk') + sample_broadcast_service.users.append(approver) + mock_task = mocker.patch('app.celery.broadcast_message_tasks.send_broadcast_event.apply_async') + + response = admin_request.post( + 'broadcast_message.update_broadcast_message_status', + _data={'status': BroadcastStatusType.BROADCASTING, 'created_by': str(approver.id)}, + service_id=t.service_id, + broadcast_message_id=bm.id, + _expected_status=200 + ) + + assert response['status'] == BroadcastStatusType.BROADCASTING + assert response['approved_at'] is not None + assert response['approved_by_id'] == str(approver.id) + + assert len(bm.events) == 1 + alert_event = bm.events[0] + + assert len(mock_task.mock_calls) == 0 + + assert alert_event.service_id == sample_broadcast_service.id + assert alert_event.transmitted_areas == bm.areas + assert alert_event.message_type == BroadcastEventMessageType.ALERT + assert alert_event.transmitted_finishes_at == bm.finishes_at + assert alert_event.transmitted_content == {"body": "emergency broadcast"} + + def test_update_broadcast_message_status_creates_event_with_correct_content_if_broadcast_has_no_template( admin_request, sample_broadcast_service, diff --git a/tests/app/db.py b/tests/app/db.py index 72824a24d..d1124764d 100644 --- a/tests/app/db.py +++ b/tests/app/db.py @@ -1022,6 +1022,7 @@ def create_broadcast_message( starts_at=None, finishes_at=None, areas=None, + stubbed=False ): if template: service = template.service @@ -1049,7 +1050,8 @@ def create_broadcast_message( finishes_at=finishes_at, created_by_id=created_by.id if created_by else service.created_by_id, areas=areas or {}, - content=content + content=content, + stubbed=stubbed ) db.session.add(broadcast_message) db.session.commit()