mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-23 08:51:30 -05:00
New package structure for the version 2 of the public api.
Start building up the validators required for post notificaiton. The app/v2/errors.py is a rough sketch, will be passed a code, the error can look up the message and link for the error message.
This commit is contained in:
14
app/notifications/process_notifications.py
Normal file
14
app/notifications/process_notifications.py
Normal file
@@ -0,0 +1,14 @@
|
||||
def persist_notification():
|
||||
'''
|
||||
persist the notification
|
||||
:return:
|
||||
'''
|
||||
pass
|
||||
|
||||
|
||||
def send_notificaiton_to_queue():
|
||||
'''
|
||||
send the notification to the queue
|
||||
:return:
|
||||
'''
|
||||
pass
|
||||
25
app/notifications/validators.py
Normal file
25
app/notifications/validators.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from app.dao import services_dao
|
||||
from app.errors import InvalidRequest
|
||||
from app.models import KEY_TYPE_TEST
|
||||
|
||||
|
||||
def check_service_message_limit(key_type, service):
|
||||
if all((key_type != KEY_TYPE_TEST,
|
||||
service.restricted)):
|
||||
service_stats = services_dao.fetch_todays_total_message_count(service.id)
|
||||
if service_stats >= service.message_limit:
|
||||
error = 'Exceeded send limits ({}) for today'.format(service.message_limit)
|
||||
|
||||
raise InvalidRequest(error, status_code=429)
|
||||
|
||||
|
||||
def check_template_is_for_notification_type(notification_type, template_type):
|
||||
if notification_type != template_type:
|
||||
raise InvalidRequest("{0} template is not suitable for {1} notification".format(template_type,
|
||||
notification_type),
|
||||
status_code=400)
|
||||
|
||||
|
||||
def check_template_is_active(template):
|
||||
if template.archived:
|
||||
raise InvalidRequest('Template has been deleted', status_code=400)
|
||||
0
app/v2/__init__.py
Normal file
0
app/v2/__init__.py
Normal file
29
app/v2/errors.py
Normal file
29
app/v2/errors.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from flask import jsonify
|
||||
|
||||
from app.errors import InvalidRequest
|
||||
|
||||
|
||||
class BadRequestError(Exception):
|
||||
status_code = 400
|
||||
|
||||
def __init__(self, message, fields, code):
|
||||
self.code = code
|
||||
self.message = message
|
||||
self.fields = fields
|
||||
|
||||
|
||||
def register_errors(blueprint):
|
||||
@blueprint.app_errorhandler(Exception)
|
||||
def authentication_error(error):
|
||||
# v2 error format - NOT this
|
||||
return jsonify(result='error', message=error.message), error.code
|
||||
|
||||
@blueprint.app_errorhandler(InvalidRequest)
|
||||
def handle_invalid_request(error):
|
||||
# {
|
||||
# "code",
|
||||
# "link",
|
||||
# "message" ,
|
||||
# "fields":
|
||||
# }
|
||||
return "build_error_message"
|
||||
7
app/v2/notifications/__init__.py
Normal file
7
app/v2/notifications/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from flask import Blueprint
|
||||
|
||||
from app.v2.errors import register_errors
|
||||
|
||||
notification_blueprint = Blueprint(__name__, __name__, url_prefix='/v2/notifications')
|
||||
|
||||
register_errors(notification_blueprint)
|
||||
14
app/v2/notifications/get_notifications.py
Normal file
14
app/v2/notifications/get_notifications.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from app.v2.notifications import notification_blueprint
|
||||
|
||||
|
||||
@notification_blueprint.route("/<uuid:id>", methods=['GET'])
|
||||
def get_notification_by_id(id):
|
||||
pass
|
||||
|
||||
|
||||
@notification_blueprint.route("/", methods=['GET'])
|
||||
def get_notifications():
|
||||
# validate notifications request arguments
|
||||
# fetch all notifications
|
||||
# return notifications_response schema
|
||||
pass
|
||||
49
app/v2/notifications/post_notifications.py
Normal file
49
app/v2/notifications/post_notifications.py
Normal file
@@ -0,0 +1,49 @@
|
||||
from app.v2.notifications import notification_blueprint
|
||||
|
||||
|
||||
@notification_blueprint.route('/sms', methods=['POST'])
|
||||
def post_sms_notification():
|
||||
# # get service
|
||||
# service = services_dao.dao_fetch_service_by_id(api_user.service_id)
|
||||
# # validate input against json schema (not marshmallow)
|
||||
# form = validate(request.get_json(), post_sms_request)
|
||||
#
|
||||
# # following checks will be in a common function for all versions of the endpoint.
|
||||
# # check service has not exceeded the sending limit
|
||||
# check_service_message_limit(api_user.key_type, service)
|
||||
# template = templates_dao.dao_get_template_by_id_and_service_id(
|
||||
# template_id=form['template_id'],
|
||||
# service_id=service.id
|
||||
# )
|
||||
# # check template is for sms
|
||||
# check_template_is_for_notification_type(SMS_TYPE, template.template_type)
|
||||
# # check template is not archived
|
||||
# check_template_is_active(template)
|
||||
# # check service is allowed to send
|
||||
# service_can_send_to_recipient(form['phone_number'], api_user.key_type, service)
|
||||
# # create body of message (create_template_object_for_notification)
|
||||
# create_template_object_for_notification(template, form.get('personalisation', {}))
|
||||
# # persist notification
|
||||
# # send sms to provider queue for research mode queue
|
||||
#
|
||||
|
||||
# validate post form against post_sms_request schema
|
||||
# validate service
|
||||
# validate template
|
||||
# create content
|
||||
# persist notification
|
||||
# send notification to queue
|
||||
# return post_sms_response schema
|
||||
return "post_sms_response schema", 201
|
||||
|
||||
|
||||
@notification_blueprint.route('/email', methods=['POST'])
|
||||
def post_email_notification():
|
||||
# validate post form against post_email_request schema
|
||||
# validate service
|
||||
# validate template
|
||||
# persist notification
|
||||
# send notification to queue
|
||||
# create content
|
||||
# return post_email_response schema
|
||||
pass
|
||||
60
tests/app/notifications/test_validators.py
Normal file
60
tests/app/notifications/test_validators.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import pytest
|
||||
|
||||
from app.errors import InvalidRequest
|
||||
from app.notifications.validators import check_service_message_limit, check_template_is_for_notification_type, \
|
||||
check_template_is_active
|
||||
from tests.app.conftest import (sample_notification as create_notification,
|
||||
sample_service as create_service)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('key_type', ['test', 'team', 'live'])
|
||||
def test_check_service_message_limit_with_unrestricted_service_passes(key_type,
|
||||
sample_service,
|
||||
sample_notification):
|
||||
assert check_service_message_limit(key_type, sample_service) is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize('key_type', ['test', 'team', 'live'])
|
||||
def test_check_service_message_limit_under_message_limit_passes(key_type,
|
||||
sample_service,
|
||||
sample_notification):
|
||||
assert check_service_message_limit(key_type, sample_service) is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize('key_type', ['team', 'live'])
|
||||
def test_check_service_message_limit_over_message_limit_fails(key_type, notify_db, notify_db_session):
|
||||
service = create_service(notify_db, notify_db_session, restricted=True, limit=4)
|
||||
for x in range(5):
|
||||
create_notification(notify_db, notify_db_session, service=service)
|
||||
with pytest.raises(InvalidRequest):
|
||||
check_service_message_limit(key_type, service)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('template_type, notification_type',
|
||||
[('email', 'email'),
|
||||
('sms', 'sms')])
|
||||
def test_check_template_is_for_notification_type_pass(template_type, notification_type):
|
||||
assert check_template_is_for_notification_type(notification_type=notification_type,
|
||||
template_type=template_type) is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize('template_type, notification_type',
|
||||
[('sms', 'email'),
|
||||
('email', 'sms')])
|
||||
def test_check_template_is_for_notification_type_fails_when_template_type_does_not_match_notification_type(
|
||||
template_type, notification_type):
|
||||
with pytest.raises(InvalidRequest):
|
||||
check_template_is_for_notification_type(notification_type=notification_type,
|
||||
template_type=template_type)
|
||||
|
||||
|
||||
def test_check_template_is_active_passes(sample_template):
|
||||
assert check_template_is_active(sample_template) is None
|
||||
|
||||
|
||||
def test_check_template_is_active_passes(sample_template):
|
||||
sample_template.archived = True
|
||||
from app.dao.templates_dao import dao_update_template
|
||||
dao_update_template(sample_template)
|
||||
with pytest.raises(InvalidRequest):
|
||||
check_template_is_active(sample_template)
|
||||
Reference in New Issue
Block a user