diff --git a/app/notifications/rest.py b/app/notifications/rest.py index 22e616f69..246ee5efc 100644 --- a/app/notifications/rest.py +++ b/app/notifications/rest.py @@ -196,6 +196,12 @@ def send_notification(notification_type): sms_template_notification_schema if notification_type == SMS_TYPE else email_notification_schema ).load(request.get_json()) + if all((api_user.key_type != KEY_TYPE_TEST, service.restricted)): + service_stats = sum(row.count for row in dao_fetch_todays_stats_for_service(service.id)) + if service_stats >= service.message_limit: + error = 'Exceeded send limits ({}) for today'.format(service.message_limit) + raise InvalidRequest(error, status_code=429) + if errors: raise InvalidRequest(errors, status_code=400) @@ -224,8 +230,8 @@ def send_notification(notification_type): raise InvalidRequest(errors, status_code=400) if ( - template_object.template_type == SMS_TYPE and - template_object.replaced_content_count > current_app.config.get('SMS_CHAR_COUNT_LIMIT') + template_object.template_type == SMS_TYPE and + template_object.replaced_content_count > current_app.config.get('SMS_CHAR_COUNT_LIMIT') ): char_count = current_app.config.get('SMS_CHAR_COUNT_LIMIT') message = 'Content has a character count greater than the limit of {}'.format(char_count) diff --git a/tests/app/notifications/rest/test_send_notification.py b/tests/app/notifications/rest/test_send_notification.py index 0a456b6de..d4e649d95 100644 --- a/tests/app/notifications/rest/test_send_notification.py +++ b/tests/app/notifications/rest/test_send_notification.py @@ -568,6 +568,106 @@ def test_should_allow_valid_email_notification(notify_api, sample_email_template assert response_data['template_version'] == sample_email_template.version +@freeze_time("2016-01-01 12:00:00.061258") +def test_should_not_block_api_call_if_over_day_limit_for_live_service( + notify_db, + notify_db_session, + notify_api, + mocker): + with notify_api.test_request_context(): + with notify_api.test_client() as client: + mocker.patch('app.celery.tasks.send_email.apply_async') + mocker.patch('app.encryption.encrypt', return_value="something_encrypted") + + service = create_sample_service(notify_db, notify_db_session, limit=1, restricted=False) + email_template = create_sample_email_template(notify_db, notify_db_session, service=service) + create_sample_notification( + notify_db, notify_db_session, template=email_template, service=service, created_at=datetime.utcnow() + ) + + data = { + 'to': 'ok@ok.com', + 'template': str(email_template.id) + } + + auth_header = create_authorization_header(service_id=service.id) + + response = client.post( + path='/notifications/email', + data=json.dumps(data), + headers=[('Content-Type', 'application/json'), auth_header]) + json.loads(response.get_data(as_text=True)) + + assert response.status_code == 201 + + +@freeze_time("2016-01-01 12:00:00.061258") +def test_should_block_api_call_if_over_day_limit_for_restricted_service( + notify_db, + notify_db_session, + notify_api, + mocker): + with notify_api.test_request_context(): + with notify_api.test_client() as client: + mocker.patch('app.celery.tasks.send_email.apply_async') + mocker.patch('app.encryption.encrypt', return_value="something_encrypted") + + service = create_sample_service(notify_db, notify_db_session, limit=1, restricted=True) + email_template = create_sample_email_template(notify_db, notify_db_session, service=service) + create_sample_notification( + notify_db, notify_db_session, template=email_template, service=service, created_at=datetime.utcnow() + ) + + data = { + 'to': 'ok@ok.com', + 'template': str(email_template.id) + } + + auth_header = create_authorization_header(service_id=service.id) + + response = client.post( + path='/notifications/email', + data=json.dumps(data), + headers=[('Content-Type', 'application/json'), auth_header]) + json.loads(response.get_data(as_text=True)) + + assert response.status_code == 429 + + +@pytest.mark.parametrize('restricted', [True, False]) +@freeze_time("2016-01-01 12:00:00.061258") +def test_should_allow_api_call_if_under_day_limit_regardless_of_type( + notify_db, + notify_db_session, + notify_api, + sample_user, + mocker, + restricted): + with notify_api.test_request_context(): + with notify_api.test_client() as client: + mocker.patch('app.celery.tasks.send_sms.apply_async') + mocker.patch('app.encryption.encrypt', return_value="something_encrypted") + + service = create_sample_service(notify_db, notify_db_session, limit=2, restricted=restricted) + email_template = create_sample_email_template(notify_db, notify_db_session, service=service) + sms_template = create_sample_template(notify_db, notify_db_session, service=service) + create_sample_notification(notify_db, notify_db_session, template=email_template, service=service) + + data = { + 'to': sample_user.mobile_number, + 'template': str(sms_template.id) + } + + auth_header = create_authorization_header(service_id=service.id) + + response = client.post( + path='/notifications/sms', + data=json.dumps(data), + headers=[('Content-Type', 'application/json'), auth_header]) + + assert response.status_code == 201 + + def test_should_not_return_html_in_body(notify_api, notify_db, notify_db_session, mocker): with notify_api.test_request_context(): with notify_api.test_client() as client: