diff --git a/app/broadcast_message/translators.py b/app/broadcast_message/translators.py index c8fde2e58..8461d8649 100644 --- a/app/broadcast_message/translators.py +++ b/app/broadcast_message/translators.py @@ -5,6 +5,7 @@ def cap_xml_to_dict(cap_xml): # This function assumes that it’s being passed valid CAP XML cap = BeautifulSoup(cap_xml, "xml") return { + "msgType": cap.alert.msgType.text, "reference": cap.alert.identifier.text, "category": cap.alert.info.category.text, "expires": cap.alert.info.expires.text, diff --git a/app/v2/broadcast/broadcast_schemas.py b/app/v2/broadcast/broadcast_schemas.py index 1ac2b437d..83fc65607 100644 --- a/app/v2/broadcast/broadcast_schemas.py +++ b/app/v2/broadcast/broadcast_schemas.py @@ -2,6 +2,7 @@ post_broadcast_schema = { "$schema": "http://json-schema.org/draft-07/schema", "type": "object", "required": [ + "msgType", "reference", "category", "content", @@ -52,6 +53,18 @@ post_broadcast_schema = { "$ref": "#/definitions/area", }, }, + "msgType": { + "type": "string", + "enum": [ + "Alert", + # The following are valid CAP but not supported by our + # API at the moment + # "Update", + # "Cancel", + # "Ack", + # "Error", + ], + } }, "definitions": { "area": { diff --git a/tests/app/v2/broadcast/sample_cap_xml_documents.py b/tests/app/v2/broadcast/sample_cap_xml_documents.py index 86dba8bd3..51244e379 100644 --- a/tests/app/v2/broadcast/sample_cap_xml_documents.py +++ b/tests/app/v2/broadcast/sample_cap_xml_documents.py @@ -4,7 +4,7 @@ WAINFLEET = """ www.gov.uk/environment-agency 2020-02-16T23:01:13-00:00 Actual - Update + Alert Flood warning service Public www.gov.uk/environment-agency,4f6d28b10ab7aa447bbd46d85f1e9effE,2020-02-16T19:20:03+00:00 @@ -32,3 +32,169 @@ WAINFLEET = """ """ + +UPDATE = """ + + PAAQ-4-mg5a94 + wcatwc@noaa.gov + 2013-01-05T10:58:23-00:00 + Actual + Update + WCATWC + Public + IPAWSv1.0 + wcatwc@noaa.gov,PAAQ-1-mg5a94,2013-01-05T09:01:16-00:00 wcatwc@noaa.gov,PAAQ-2-mg5a94,2013-01-05T09:30:16-00:00 wcatwc@noaa.gov,PAAQ-3-mg5a94,2013-01-05T10:17:31-00:00 + mg5a94 + + Geo + Tsunami Cancellation + None + Past + Unknown + Unlikely + 2013-01-05T10:58:23-00:00 + 2013-01-05T10:58:23-00:00 + NWS West Coast/Alaska Tsunami Warning Center Palmer AK + The tsunami Warning is canceled for the coastal areas of British Columbia and Alaska from the north tip of Vancouver Island, British Columbia to Cape Fairweather, Alaska (80 miles SE of Yakutat). + The tsunami Warning is canceled for the coastal areas of British Columbia and Alaska from the north tip of Vancouver Island, British Columbia to Cape Fairweather, Alaska (80 miles SE of Yakutat). - Event details: Preliminary magnitude 7.5 (Mw) earthquake / Lat: 55.300, Lon: -134.900 at 2013-01-05T08:58:20Z Tsunami cancellations indicate the end of the damaging tsunami threat. A cancellation is issued after an evaluation of sea level data confirms that a destructive tsunami will not impact the alerted region, or after tsunami levels have subsided to non-damaging levels. + Recommended Actions: Do not re-occupy hazard zones until local emergency officials indicate it is safe to do so. This will be the last West Coast/Alaska Tsunami Warning Center message issued for this event. Refer to the internet site ntwc.arh.noaa.gov for more information. + http://ntwc.arh.noaa.gov/events/PAAQ/2013/01/05/mg5a94/4/WEAK51/WEAK51.txt + + EventLocationName + 95 miles NW of Dixon Entrance, Alaska + + + EventPreliminaryMagnitude + 7.5 + + + EventPreliminaryMagnitudeType + Mw + + + EventOriginTime + 2013-01-05T08:58:20-00:00 + + + EventDepth + 5 kilometers + + + EventLatLon + 55.300,-134.900 0.000 + + + VTEC + /O.CAN.PAAQ.TS.W.0001.000000T0000Z-000000T0000Z/ + + + NWSUGC + BCZ220-210-922-912-921-911-110-AKZ026>029-023-024-019>022-025-051258- + + + ProductDefinition + Tsunami cancellations indicate the end of the damaging tsunami threat. A cancellation is issued after an evaluation of sea level data confirms that a destructive tsunami will not impact the alerted region, or after tsunami levels have subsided to non-damaging levels. + + + WEAK51 + Public Tsunami Warnings, Watches, and Advisories for AK, BC, and US West Coast + + + EAS-ORG + WXR + + + Event Data as a JSON document + application/json + http://ntwc.arh.noaa.gov/events/PAAQ/2013/01/05/mg5a94/4/WEAK51/PAAQ.json + + + 95 miles NW of Dixon Entrance, Alaska + 55.3,-134.9 0.0 + + + +""" + +CANCEL = """ + + PAAQ-4-mg5a94 + wcatwc@noaa.gov + 2013-01-05T10:58:23-00:00 + Actual + Cancel + WCATWC + Public + IPAWSv1.0 + wcatwc@noaa.gov,PAAQ-1-mg5a94,2013-01-05T09:01:16-00:00 wcatwc@noaa.gov,PAAQ-2-mg5a94,2013-01-05T09:30:16-00:00 wcatwc@noaa.gov,PAAQ-3-mg5a94,2013-01-05T10:17:31-00:00 + mg5a94 + + Geo + Tsunami Cancellation + None + Past + Unknown + Unlikely + 2013-01-05T10:58:23-00:00 + 2013-01-05T10:58:23-00:00 + NWS West Coast/Alaska Tsunami Warning Center Palmer AK + The tsunami Warning is canceled for the coastal areas of British Columbia and Alaska from the north tip of Vancouver Island, British Columbia to Cape Fairweather, Alaska (80 miles SE of Yakutat). + The tsunami Warning is canceled for the coastal areas of British Columbia and Alaska from the north tip of Vancouver Island, British Columbia to Cape Fairweather, Alaska (80 miles SE of Yakutat). - Event details: Preliminary magnitude 7.5 (Mw) earthquake / Lat: 55.300, Lon: -134.900 at 2013-01-05T08:58:20Z Tsunami cancellations indicate the end of the damaging tsunami threat. A cancellation is issued after an evaluation of sea level data confirms that a destructive tsunami will not impact the alerted region, or after tsunami levels have subsided to non-damaging levels. + Recommended Actions: Do not re-occupy hazard zones until local emergency officials indicate it is safe to do so. This will be the last West Coast/Alaska Tsunami Warning Center message issued for this event. Refer to the internet site ntwc.arh.noaa.gov for more information. + http://ntwc.arh.noaa.gov/events/PAAQ/2013/01/05/mg5a94/4/WEAK51/WEAK51.txt + + EventLocationName + 95 miles NW of Dixon Entrance, Alaska + + + EventPreliminaryMagnitude + 7.5 + + + EventPreliminaryMagnitudeType + Mw + + + EventOriginTime + 2013-01-05T08:58:20-00:00 + + + EventDepth + 5 kilometers + + + EventLatLon + 55.300,-134.900 0.000 + + + VTEC + /O.CAN.PAAQ.TS.W.0001.000000T0000Z-000000T0000Z/ + + + NWSUGC + BCZ220-210-922-912-921-911-110-AKZ026>029-023-024-019>022-025-051258- + + + ProductDefinition + Tsunami cancellations indicate the end of the damaging tsunami threat. A cancellation is issued after an evaluation of sea level data confirms that a destructive tsunami will not impact the alerted region, or after tsunami levels have subsided to non-damaging levels. + + + WEAK51 + Public Tsunami Warnings, Watches, and Advisories for AK, BC, and US West Coast + + + EAS-ORG + WXR + + + Event Data as a JSON document + application/json + http://ntwc.arh.noaa.gov/events/PAAQ/2013/01/05/mg5a94/4/WEAK51/PAAQ.json + + + 95 miles NW of Dixon Entrance, Alaska + 55.3,-134.9 0.0 + + + +""" diff --git a/tests/app/v2/broadcast/test_post_broadcast.py b/tests/app/v2/broadcast/test_post_broadcast.py index 773622a24..8cd0256d5 100644 --- a/tests/app/v2/broadcast/test_post_broadcast.py +++ b/tests/app/v2/broadcast/test_post_broadcast.py @@ -75,7 +75,6 @@ def test_valid_post_cap_xml_broadcast_returns_201( data=sample_cap_xml_documents.WAINFLEET, headers=[('Content-Type', 'application/cap+xml'), auth_header], ) - assert response.status_code == 201 response_json = json.loads(response.get_data(as_text=True)) @@ -161,3 +160,34 @@ def test_invalid_post_cap_xml_broadcast_returns_400( }], 'status_code': 400, } + + +@pytest.mark.parametrize('xml_document, expected_error_message', ( + (sample_cap_xml_documents.CANCEL, ( + 'msgType Cancel is not one of [Alert]' + )), + (sample_cap_xml_documents.UPDATE, ( + 'msgType Update is not one of [Alert]' + )), +)) +def test_unsupported_message_types_400( + client, + sample_broadcast_service, + xml_document, + expected_error_message, +): + auth_header = create_authorization_header(service_id=sample_broadcast_service.id) + + response = client.post( + path='/v2/broadcast', + data=xml_document, + headers=[('Content-Type', 'application/cap+xml'), auth_header], + ) + + assert response.status_code == 400 + assert { + 'error': 'ValidationError', + 'message': expected_error_message, + } in ( + json.loads(response.get_data(as_text=True))['errors'] + )