diff --git a/app/dao/broadcast_message_dao.py b/app/dao/broadcast_message_dao.py index 087702eb4..1281c0e75 100644 --- a/app/dao/broadcast_message_dao.py +++ b/app/dao/broadcast_message_dao.py @@ -26,6 +26,10 @@ def dao_get_broadcast_message_by_id_and_service_id(broadcast_message_id, service def dao_get_broadcast_message_by_references_and_service_id(references_to_original_broadcast, service_id): return BroadcastMessage.query.filter( + BroadcastMessage.status.in_(( + BroadcastStatusType.PENDING_APPROVAL, + BroadcastStatusType.BROADCASTING, + )), BroadcastMessage.reference.in_(references_to_original_broadcast), BroadcastMessage.service_id == service_id ).one() diff --git a/tests/app/v2/broadcast/test_post_broadcast.py b/tests/app/v2/broadcast/test_post_broadcast.py index e6e2c89be..fcf8aad78 100644 --- a/tests/app/v2/broadcast/test_post_broadcast.py +++ b/tests/app/v2/broadcast/test_post_broadcast.py @@ -253,6 +253,56 @@ def test_cancel_request_does_not_cancel_broadcast_if_service_id_does_not_match( assert response_for_cancel.status_code == 404 +@pytest.mark.parametrize("is_approved, expected_cancel_tasks", ( + (True, 1), + (False, 0), +)) +def test_same_broadcast_cant_be_cancelled_twice( + mocker, + client, + sample_broadcast_service, + is_approved, + expected_cancel_tasks, +): + mock_send_broadcast_event_task = mocker.patch( + 'app.celery.broadcast_message_tasks.send_broadcast_event.apply_async' + ) + auth_header = create_service_authorization_header(service_id=sample_broadcast_service.id) + + # create a broadcast + response_for_create = client.post( + path='/v2/broadcast', + data=sample_cap_xml_documents.WAINFLEET, + headers=[('Content-Type', 'application/cap+xml'), auth_header], + ) + assert response_for_create.status_code == 201 + + response_json_for_create = json.loads(response_for_create.get_data(as_text=True)) + + broadcast_message = dao_get_broadcast_message_by_id_and_service_id( + response_json_for_create["id"], response_json_for_create["service_id"] + ) + # approve broadcast + if is_approved: + broadcast_message.status = 'broadcasting' + + first_response_for_cancel = client.post( + path='/v2/broadcast', + data=sample_cap_xml_documents.WAINFLEET_CANCEL_WITH_REFERENCES, + headers=[('Content-Type', 'application/cap+xml'), auth_header], + ) + assert first_response_for_cancel.status_code == 201 + + second_response_for_cancel = client.post( + path='/v2/broadcast', + data=sample_cap_xml_documents.WAINFLEET_CANCEL_WITH_REFERENCES, + headers=[('Content-Type', 'application/cap+xml'), auth_header], + ) + assert second_response_for_cancel.status_code == 404 + + assert len(mock_send_broadcast_event_task.call_args_list) == expected_cancel_tasks + + def test_large_polygon_is_simplified( client, sample_broadcast_service,