diff --git a/app/schema_validation/__init__.py b/app/schema_validation/__init__.py index b530a17b0..2dff49519 100644 --- a/app/schema_validation/__init__.py +++ b/app/schema_validation/__init__.py @@ -1,5 +1,5 @@ import json -from datetime import datetime +from datetime import datetime, timedelta from jsonschema import (Draft4Validator, ValidationError, FormatChecker) from notifications_utils.recipients import (validate_phone_number, validate_email_address, InvalidPhoneError, @@ -25,7 +25,11 @@ def validate(json_to_validate, schema): def validate_schema_date_with_hour(instance): if isinstance(instance, str): try: - datetime.strptime(instance, "%Y-%m-%d %H:%M") + dt = datetime.strptime(instance, "%Y-%m-%d %H:%M") + if dt < datetime.utcnow(): + raise ValidationError("datetime can not be in the past") + if dt > datetime.utcnow() + timedelta(hours=24): + raise ValidationError("datetime can only be 24 hours in the future") except ValueError as e: raise ValidationError("datetime format is invalid. Use the format: " "YYYY-MM-DD HH:MI, for example 2017-05-30 13:15") diff --git a/tests/app/v2/notifications/test_notification_schemas.py b/tests/app/v2/notifications/test_notification_schemas.py index 90139c7c2..bbccd81d5 100644 --- a/tests/app/v2/notifications/test_notification_schemas.py +++ b/tests/app/v2/notifications/test_notification_schemas.py @@ -2,6 +2,7 @@ import uuid import pytest from flask import json +from freezegun import freeze_time from jsonschema import ValidationError from app.v2.notifications.notification_schemas import ( @@ -357,6 +358,7 @@ def test_get_notifications_response_with_email_and_phone_number(): @pytest.mark.parametrize("schema", [post_email_request_schema, post_sms_request_schema]) +@freeze_time("2017-05-12 13:00:00") def test_post_schema_valid_scheduled_for(schema): j = {"template_id": str(uuid.uuid4()), "email_address": "joe@gmail.com", @@ -386,3 +388,29 @@ def test_post_email_schema_invalid_scheduled_for(invalid_datetime, schema): assert error['errors'] == [{'error': 'ValidationError', 'message': "scheduled_for datetime format is invalid. Use the format: " "YYYY-MM-DD HH:MI, for example 2017-05-30 13:15"}] + + +@freeze_time("2017-05-12 13:00:00") +def test_scheduled_for_raises_validation_error_when_in_the_past(): + j = {"phone_number": "07515111111", + "template_id": str(uuid.uuid4()), + "scheduled_for": "2017-05-12 10:00"} + with pytest.raises(ValidationError) as e: + validate(j, post_sms_request_schema) + error = json.loads(str(e.value)) + assert error['status_code'] == 400 + assert error['errors'] == [{'error': 'ValidationError', + 'message': "scheduled_for datetime can not be in the past"}] + + +@freeze_time("2017-05-12 13:00:00") +def test_scheduled_for_raises_validation_error_when_more_than_24_hours_in_the_future(): + j = {"phone_number": "07515111111", + "template_id": str(uuid.uuid4()), + "scheduled_for": "2017-05-13 14:00"} + with pytest.raises(ValidationError) as e: + validate(j, post_sms_request_schema) + error = json.loads(str(e.value)) + assert error['status_code'] == 400 + assert error['errors'] == [{'error': 'ValidationError', + 'message': "scheduled_for datetime can only be 24 hours in the future"}] diff --git a/tests/app/v2/notifications/test_post_notifications.py b/tests/app/v2/notifications/test_post_notifications.py index 114e2e8aa..305d224b8 100644 --- a/tests/app/v2/notifications/test_post_notifications.py +++ b/tests/app/v2/notifications/test_post_notifications.py @@ -2,6 +2,7 @@ import uuid import pytest from flask import json +from freezegun import freeze_time from app.models import Notification, ScheduledNotification from app.v2.errors import RateLimitError @@ -353,6 +354,7 @@ def test_post_sms_should_persist_supplied_sms_number(client, sample_template_wit @pytest.mark.parametrize("notification_type, key_send_to, send_to", [("sms", "phone_number", "07700 900 855"), ("email", "email_address", "sample@email.com")]) +@freeze_time("2017-05-14 14:00:00") def test_post_notification_with_scheduled_for(client, sample_template, sample_email_template, notification_type, key_send_to, send_to): data = {