mirror of
https://github.com/GSA/notifications-api.git
synced 2026-02-02 09:26:08 -05:00
Merge pull request #3325 from alphagov/prevent-empty-areas-178986763
Add validation to prevent blank area names
This commit is contained in:
@@ -76,6 +76,7 @@ post_broadcast_schema = {
|
|||||||
"properties": {
|
"properties": {
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
"pattern": "([a-zA-Z1-9]+ )*[a-zA-Z1-9]+",
|
||||||
},
|
},
|
||||||
"polygons": {
|
"polygons": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
|||||||
@@ -41,27 +41,12 @@ def create_broadcast():
|
|||||||
broadcast_json = cap_xml_to_dict(cap_xml)
|
broadcast_json = cap_xml_to_dict(cap_xml)
|
||||||
|
|
||||||
validate(broadcast_json, post_broadcast_schema)
|
validate(broadcast_json, post_broadcast_schema)
|
||||||
|
_validate_template(broadcast_json)
|
||||||
|
|
||||||
polygons = Polygons(list(chain.from_iterable((
|
polygons = Polygons(list(chain.from_iterable((
|
||||||
area['polygons'] for area in broadcast_json['areas']
|
area['polygons'] for area in broadcast_json['areas']
|
||||||
))))
|
))))
|
||||||
|
|
||||||
template = BroadcastMessageTemplate.from_content(
|
|
||||||
broadcast_json['content']
|
|
||||||
)
|
|
||||||
|
|
||||||
if template.content_too_long:
|
|
||||||
raise ValidationError(
|
|
||||||
message=(
|
|
||||||
f'description must be {template.max_content_count:,.0f} '
|
|
||||||
f'characters or fewer'
|
|
||||||
) + (
|
|
||||||
' (because it could not be GSM7 encoded)'
|
|
||||||
if template.non_gsm_characters else ''
|
|
||||||
),
|
|
||||||
status_code=400,
|
|
||||||
)
|
|
||||||
|
|
||||||
broadcast_message = BroadcastMessage(
|
broadcast_message = BroadcastMessage(
|
||||||
service_id=authenticated_service.id,
|
service_id=authenticated_service.id,
|
||||||
content=broadcast_json['content'],
|
content=broadcast_json['content'],
|
||||||
@@ -89,3 +74,21 @@ def create_broadcast():
|
|||||||
)
|
)
|
||||||
|
|
||||||
return jsonify(broadcast_message.serialize()), 201
|
return jsonify(broadcast_message.serialize()), 201
|
||||||
|
|
||||||
|
|
||||||
|
def _validate_template(broadcast_json):
|
||||||
|
template = BroadcastMessageTemplate.from_content(
|
||||||
|
broadcast_json['content']
|
||||||
|
)
|
||||||
|
|
||||||
|
if template.content_too_long:
|
||||||
|
raise ValidationError(
|
||||||
|
message=(
|
||||||
|
f'description must be {template.max_content_count:,.0f} '
|
||||||
|
f'characters or fewer'
|
||||||
|
) + (
|
||||||
|
' (because it could not be GSM7 encoded)'
|
||||||
|
if template.non_gsm_characters else ''
|
||||||
|
),
|
||||||
|
status_code=400,
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
WAINFLEET = """
|
WAINFLEET = """
|
||||||
<alert xmlns="urn:oasis:names:tc:emergency:cap:1.2">
|
<alert xmlns="urn:oasis:names:tc:emergency:cap:1.2">
|
||||||
<identifier>50385fcb0ab7aa447bbd46d848ce8466E</identifier>
|
<identifier>50385fcb0ab7aa447bbd46d848ce8466E</identifier>
|
||||||
@@ -235,3 +237,4 @@ WITH_PLACEHOLDER_FOR_CONTENT = """
|
|||||||
|
|
||||||
LONG_GSM7 = WITH_PLACEHOLDER_FOR_CONTENT.format('a' * 1396)
|
LONG_GSM7 = WITH_PLACEHOLDER_FOR_CONTENT.format('a' * 1396)
|
||||||
LONG_UCS2 = WITH_PLACEHOLDER_FOR_CONTENT.format('ŵ' * 616)
|
LONG_UCS2 = WITH_PLACEHOLDER_FOR_CONTENT.format('ŵ' * 616)
|
||||||
|
MISSING_AREA_NAMES = re.sub("<areaDesc>.*</areaDesc>", "<areaDesc> </areaDesc>", WAINFLEET)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ def test_broadcast_for_service_without_permission_returns_400(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_valid_post_broadcast_returns_201(
|
def test_post_broadcast_non_cap_xml_returns_415(
|
||||||
client,
|
client,
|
||||||
sample_broadcast_service,
|
sample_broadcast_service,
|
||||||
):
|
):
|
||||||
@@ -229,3 +229,24 @@ def test_content_too_long_returns_400(
|
|||||||
}],
|
}],
|
||||||
'status_code': 400,
|
'status_code': 400,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_invalid_areas_returns_400(
|
||||||
|
client,
|
||||||
|
sample_broadcast_service
|
||||||
|
):
|
||||||
|
auth_header = create_service_authorization_header(service_id=sample_broadcast_service.id)
|
||||||
|
response = client.post(
|
||||||
|
path='/v2/broadcast',
|
||||||
|
data=sample_cap_xml_documents.MISSING_AREA_NAMES,
|
||||||
|
headers=[('Content-Type', 'application/cap+xml'), auth_header],
|
||||||
|
)
|
||||||
|
|
||||||
|
assert json.loads(response.get_data(as_text=True)) == {
|
||||||
|
'errors': [{
|
||||||
|
'error': 'ValidationError',
|
||||||
|
# the blank spaces represent the blank areaDesc in the XML
|
||||||
|
'message': 'areas does not match ([a-zA-Z1-9]+ )*[a-zA-Z1-9]+',
|
||||||
|
}],
|
||||||
|
'status_code': 400,
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user