diff --git a/app/broadcast_message/rest.py b/app/broadcast_message/rest.py index e75a19079..38783e099 100644 --- a/app/broadcast_message/rest.py +++ b/app/broadcast_message/rest.py @@ -1,7 +1,7 @@ from datetime import datetime import iso8601 -from flask import Blueprint, jsonify, request, current_app +from flask import Blueprint, jsonify, request, current_app, abort from app.config import QueueNames from app.dao.templates_dao import dao_get_template_by_id_and_service_id @@ -85,6 +85,12 @@ def update_broadcast_message(service_id, broadcast_message_id): broadcast_message = dao_get_broadcast_message_by_id_and_service_id(broadcast_message_id, service_id) + if broadcast_message.status not in BroadcastStatusType.PRE_BROADCAST_STATUSES: + abort( + 400, + f'Cannot update broadcast_message {broadcast_message.id} while it has status {broadcast_message.status}' + ) + if 'personalisation' in data: broadcast_message.personalisation = data['personalisation'] if 'starts_at' in data: diff --git a/app/models.py b/app/models.py index d447505b2..6f5b9a2b7 100644 --- a/app/models.py +++ b/app/models.py @@ -2172,6 +2172,10 @@ class BroadcastStatusType(db.Model): STATUSES = [DRAFT, PENDING_APPROVAL, REJECTED, BROADCASTING, COMPLETED, CANCELLED, TECHNICAL_FAILURE] + # a broadcast message can be edited while in one of these states + PRE_BROADCAST_STATUSES = [DRAFT, PENDING_APPROVAL, REJECTED] + LIVE_STATUSES = [BROADCASTING, COMPLETED, CANCELLED] + name = db.Column(db.String, primary_key=True) diff --git a/tests/app/broadcast_message/test_rest.py b/tests/app/broadcast_message/test_rest.py index 39627e9b1..baa14834a 100644 --- a/tests/app/broadcast_message/test_rest.py +++ b/tests/app/broadcast_message/test_rest.py @@ -132,9 +132,14 @@ def test_create_broadcast_message_400s_if_json_schema_fails_validation( assert response['errors'] == expected_errors -def test_update_broadcast_message(admin_request, sample_service): +@pytest.mark.parametrize('status', [ + BroadcastStatusType.DRAFT, + BroadcastStatusType.PENDING_APPROVAL, + BroadcastStatusType.REJECTED, +]) +def test_update_broadcast_message_allows_edit_while_not_yet_live(admin_request, sample_service, status): t = create_template(sample_service, BROADCAST_TYPE) - bm = create_broadcast_message(t, areas=['manchester']) + bm = create_broadcast_message(t, areas=['manchester'], status=status) response = admin_request.post( 'broadcast_message.update_broadcast_message', @@ -149,6 +154,26 @@ def test_update_broadcast_message(admin_request, sample_service): assert response['updated_at'] is not None +@pytest.mark.parametrize('status', [ + BroadcastStatusType.BROADCASTING, + BroadcastStatusType.CANCELLED, + BroadcastStatusType.COMPLETED, + BroadcastStatusType.TECHNICAL_FAILURE, +]) +def test_update_broadcast_message_doesnt_allow_edits_after_broadcast_goes_live(admin_request, sample_service, status): + t = create_template(sample_service, BROADCAST_TYPE) + bm = create_broadcast_message(t, areas=['manchester'], status=status) + + response = admin_request.post( + 'broadcast_message.update_broadcast_message', + _data={'areas': ['london', 'glasgow']}, + service_id=t.service_id, + broadcast_message_id=bm.id, + _expected_status=400 + ) + assert f'status {status}' in response['message'] + + def test_update_broadcast_message_sets_finishes_at_separately(admin_request, sample_service): t = create_template(sample_service, BROADCAST_TYPE) bm = create_broadcast_message(t, areas=['manchester']) diff --git a/tests/app/db.py b/tests/app/db.py index 190ef0c0c..0fc430102 100644 --- a/tests/app/db.py +++ b/tests/app/db.py @@ -1011,7 +1011,7 @@ def create_broadcast_message( template_id=template.id, template_version=template.version, personalisation=personalisation, - status=BroadcastStatusType.DRAFT, + status=status, starts_at=starts_at, finishes_at=finishes_at, created_by_id=created_by.id if created_by else template.created_by_id,