mirror of
https://github.com/GSA/notifications-api.git
synced 2026-06-22 14:10:35 -04:00
Store the event field from CAP XML broadcasts
We don’t store everything that comes in the CAP XML when someone creates a broadcast via the API. One thing we do store is `<identifier>` (in a column called `reference`) which is a unique (to the external system) identifier for the broadcast. We show this in the front end instead of the template name, because broadcasts created from the API don’t use templates. However this ID isn’t very friendly – the Environment Agency just supply a UUID. The Environment Agency also populate the `<event>` field with some human readable text, for example: > 013 Issue Severe Flood Warning EA (013 is an area code which will be meaningful to the Flood Warning Service team) We should show this in the UI instead of the reference. The first step towards this is storing it in the database and returning it in the REST endpoints. Later we can have the admin app prefer `cap_event` over `reference`, where `cap_event` is present. We can’t backfill this data because we don’t keep a copy of the original XML. Seems like `<event>` is a mandatory property of `<info>`, so we don’t need to worry about the field being missing (`<info>` is optional in CAP but we require it because it contains stuff like the areas which we need in order to send out the broadcast`). *** https://www.pivotaltracker.com/story/show/176927060
This commit is contained in:
@@ -7,6 +7,7 @@ def cap_xml_to_dict(cap_xml):
|
||||
return {
|
||||
"msgType": cap.alert.msgType.text,
|
||||
"reference": cap.alert.identifier.text,
|
||||
"cap_event": cap.alert.info.event.text,
|
||||
"category": cap.alert.info.category.text,
|
||||
"expires": cap.alert.info.expires.text,
|
||||
"content": cap.alert.info.description.text,
|
||||
|
||||
@@ -2319,6 +2319,7 @@ class BroadcastMessage(db.Model):
|
||||
api_key = db.relationship('ApiKey')
|
||||
|
||||
reference = db.Column(db.String(255), nullable=True)
|
||||
cap_event = db.Column(db.String(255), nullable=True)
|
||||
|
||||
stubbed = db.Column(db.Boolean, nullable=False)
|
||||
|
||||
@@ -2338,6 +2339,7 @@ class BroadcastMessage(db.Model):
|
||||
return {
|
||||
'id': str(self.id),
|
||||
'reference': self.reference,
|
||||
'cap_event': self.cap_event,
|
||||
|
||||
'service_id': str(self.service_id),
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ post_broadcast_schema = {
|
||||
"required": [
|
||||
"msgType",
|
||||
"reference",
|
||||
"cap_event",
|
||||
"category",
|
||||
"content",
|
||||
"areas",
|
||||
@@ -16,6 +17,12 @@ post_broadcast_schema = {
|
||||
"null",
|
||||
],
|
||||
},
|
||||
"cap_event": {
|
||||
"type": [
|
||||
"string",
|
||||
"null",
|
||||
],
|
||||
},
|
||||
"category": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
|
||||
@@ -51,6 +51,7 @@ def create_broadcast():
|
||||
service_id=authenticated_service.id,
|
||||
content=broadcast_json['content'],
|
||||
reference=broadcast_json['reference'],
|
||||
cap_event=broadcast_json['cap_event'],
|
||||
areas={
|
||||
'names': [
|
||||
area['name'] for area in broadcast_json['areas']
|
||||
|
||||
21
migrations/versions/0362_broadcast_msg_event.py
Normal file
21
migrations/versions/0362_broadcast_msg_event.py
Normal file
@@ -0,0 +1,21 @@
|
||||
"""
|
||||
|
||||
Revision ID: 0362_broadcast_msg_event
|
||||
Revises: 0361_new_user_bcast_permissions
|
||||
Create Date: 2020-12-04 15:06:22.544803
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
revision = '0362_broadcast_msg_event'
|
||||
down_revision = '0361_new_user_bcast_permissions'
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.add_column('broadcast_message', sa.Column('cap_event', sa.String(length=255), nullable=True))
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.drop_column('broadcast_message', 'cap_event')
|
||||
@@ -91,6 +91,26 @@ def test_get_broadcast_message_without_template(
|
||||
assert response['personalisation'] is None
|
||||
|
||||
|
||||
def test_get_broadcast_message_with_event(
|
||||
admin_request,
|
||||
sample_broadcast_service
|
||||
):
|
||||
bm = create_broadcast_message(
|
||||
service=sample_broadcast_service,
|
||||
content='emergency broadcast content',
|
||||
cap_event='001 example event',
|
||||
)
|
||||
|
||||
response = admin_request.get(
|
||||
'broadcast_message.get_broadcast_message',
|
||||
service_id=sample_broadcast_service.id,
|
||||
broadcast_message_id=bm.id,
|
||||
_expected_status=200
|
||||
)
|
||||
|
||||
assert response['cap_event'] == '001 example event'
|
||||
|
||||
|
||||
def test_get_broadcast_message_404s_if_message_doesnt_exist(admin_request, sample_broadcast_service):
|
||||
err = admin_request.get(
|
||||
'broadcast_message.get_broadcast_message',
|
||||
@@ -255,6 +275,7 @@ def test_create_broadcast_message_can_be_created_from_content(admin_request, sam
|
||||
assert response['content'] == 'Some content\n€ŷŵ~\n\'\'""---'
|
||||
assert response['reference'] == 'abc123'
|
||||
assert response['template_id'] is None
|
||||
assert response['cap_event'] is None
|
||||
|
||||
|
||||
def test_create_broadcast_message_400s_if_content_and_template_provided(
|
||||
|
||||
@@ -1119,7 +1119,8 @@ def create_broadcast_message(
|
||||
starts_at=None,
|
||||
finishes_at=None,
|
||||
areas=None,
|
||||
stubbed=False
|
||||
stubbed=False,
|
||||
cap_event=None,
|
||||
):
|
||||
if template:
|
||||
service = template.service
|
||||
@@ -1148,7 +1149,8 @@ def create_broadcast_message(
|
||||
created_by_id=created_by.id if created_by else service.created_by_id,
|
||||
areas=areas or {'ids': [], 'simple_polygons': []},
|
||||
content=content,
|
||||
stubbed=stubbed
|
||||
stubbed=stubbed,
|
||||
cap_event=cap_event,
|
||||
)
|
||||
db.session.add(broadcast_message)
|
||||
db.session.commit()
|
||||
|
||||
@@ -96,6 +96,7 @@ def test_valid_post_cap_xml_broadcast_returns_201(
|
||||
'closely monitoring the situation throughout the night. '
|
||||
)
|
||||
assert response_json['reference'] == '50385fcb0ab7aa447bbd46d848ce8466E'
|
||||
assert response_json['cap_event'] == '053/055 Issue Severe Flood Warning EA'
|
||||
assert response_json['created_at'] # datetime generated by the DB so can’t freeze it
|
||||
assert response_json['created_by_id'] is None
|
||||
assert response_json['finishes_at'] is None
|
||||
|
||||
Reference in New Issue
Block a user