mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-20 15:31:15 -05:00
Template rest api skeleton added.
This commit is contained in:
@@ -30,9 +30,11 @@ def create_app(config_name):
|
||||
from .main import main as main_blueprint
|
||||
from .service import service as service_blueprint
|
||||
from .user import user as user_blueprint
|
||||
from .template import template as template_blueprint
|
||||
application.register_blueprint(main_blueprint)
|
||||
application.register_blueprint(service_blueprint, url_prefix='/service')
|
||||
application.register_blueprint(user_blueprint, url_prefix='/user')
|
||||
application.register_blueprint(template_blueprint, url_prefix="/template")
|
||||
|
||||
from .status import status as status_blueprint
|
||||
application.register_blueprint(status_blueprint)
|
||||
|
||||
31
app/dao/templates_dao.py
Normal file
31
app/dao/templates_dao.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
from sqlalchemy.orm import load_only
|
||||
from . import DAOException
|
||||
from app import db
|
||||
from app.models import (Template, Service)
|
||||
|
||||
|
||||
def save_model_template(template, update_dict=None):
|
||||
if update_dict:
|
||||
Template.query.filter_by(id=template.id).update(update_dict)
|
||||
else:
|
||||
db.session.add(template)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
def delete_model_template(template):
|
||||
db.session.delete(template)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
def get_model_templates(template_id=None, service_id=None):
|
||||
# TODO need better mapping from function params to sql query.
|
||||
if template_id and service_id:
|
||||
return Template.query.filter_by(
|
||||
id=template_id, service=Service.get(service_id)).one()
|
||||
elif template_id:
|
||||
return Template.query.filter_by(id=template_id).one()
|
||||
elif service_id:
|
||||
return Template.query.filter_by(service=Service.get(service_id)).one()
|
||||
return Template.query.all()
|
||||
@@ -59,3 +59,29 @@ class Service(db.Model):
|
||||
secondary=user_to_service,
|
||||
backref=db.backref('user_to_service', lazy='dynamic'))
|
||||
restricted = db.Column(db.Boolean, index=False, unique=False, nullable=False)
|
||||
|
||||
|
||||
TEMPLATE_TYPES = ['sms', 'email', 'letter']
|
||||
|
||||
|
||||
class Template(db.Model):
|
||||
__tablename__ = 'templates'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String(255), nullable=False)
|
||||
template_type = db.Column(db.Enum(*TEMPLATE_TYPES, name='template_type'), nullable=False)
|
||||
created_at = db.Column(
|
||||
db.DateTime,
|
||||
index=False,
|
||||
unique=False,
|
||||
nullable=False,
|
||||
default=datetime.datetime.now)
|
||||
updated_at = db.Column(
|
||||
db.DateTime,
|
||||
index=False,
|
||||
unique=False,
|
||||
nullable=True,
|
||||
onupdate=datetime.datetime.now)
|
||||
content = db.Column(db.Text, index=False, unique=False, nullable=False)
|
||||
service_id = db.Column(db.BigInteger, db.ForeignKey('services.id'), index=True, unique=False)
|
||||
service = db.relationship('Service', backref=db.backref('templates', lazy='dynamic'))
|
||||
|
||||
@@ -19,6 +19,12 @@ class UserSchema(ma.ModelSchema):
|
||||
class ServiceSchema(ma.ModelSchema):
|
||||
class Meta:
|
||||
model = models.Service
|
||||
exclude = ("updated_at", "created_at", "templates")
|
||||
|
||||
|
||||
class TemplateSchema(ma.ModelSchema):
|
||||
class Meta:
|
||||
model = models.Template
|
||||
exclude = ("updated_at", "created_at")
|
||||
|
||||
|
||||
@@ -26,3 +32,5 @@ user_schema = UserSchema()
|
||||
users_schema = UserSchema(many=True)
|
||||
service_schema = ServiceSchema()
|
||||
services_schema = ServiceSchema(many=True)
|
||||
template_schema = TemplateSchema()
|
||||
templates_schema = TemplateSchema(many=True)
|
||||
|
||||
@@ -67,3 +67,58 @@ def get_service(service_id=None):
|
||||
return jsonify(result="error", message="Service not found"), 404
|
||||
data, errors = services_schema.dump(services) if isinstance(services, list) else service_schema.dump(services)
|
||||
return jsonify(data=data)
|
||||
|
||||
|
||||
# TODO auth to be added.
|
||||
@service.route('/<int:service_id>/template/', methods=['POST'])
|
||||
def create_template():
|
||||
try:
|
||||
service = get_model_services(service_id=service_id)
|
||||
except DataError:
|
||||
return jsonify(result="error", message="Invalid service id"), 400
|
||||
except NoResultFound:
|
||||
return jsonify(result="error", message="Service not found"), 404
|
||||
template, errors = template_schema.load(request.get_json())
|
||||
if errors:
|
||||
return jsonify(result="error", message=errors), 400
|
||||
template.service = service
|
||||
# I believe service is already added to the session but just needs a
|
||||
# db.session.commit
|
||||
save_model_template(template)
|
||||
return jsonify(data=template_schema.dump(template).data), 201
|
||||
|
||||
|
||||
# TODO auth to be added
|
||||
@service.route('/<int:service_id>/template/<int:template_id>', methods=['PUT', 'DELETE'])
|
||||
def update_template(service_id, template_id):
|
||||
try:
|
||||
service = get_model_services(service_id=service_id)
|
||||
except DataError:
|
||||
return jsonify(result="error", message="Invalid service id"), 400
|
||||
except NoResultFound:
|
||||
return jsonify(result="error", message="Service not found"), 404
|
||||
try:
|
||||
template = get_model_templates(template_id=template_id)
|
||||
except DataError:
|
||||
return jsonify(result="error", message="Invalid template id"), 400
|
||||
except NoResultFound:
|
||||
return jsonify(result="error", message="Template not found"), 404
|
||||
if request.method == 'DELETE':
|
||||
status_code = 202
|
||||
delete_model_template(template)
|
||||
else:
|
||||
status_code = 200
|
||||
# TODO there has got to be a better way to do the next three lines
|
||||
upd_temp, errors = template_schema.load(request.get_json())
|
||||
if errors:
|
||||
return jsonify(result="error", message=errors), 400
|
||||
upd_temp.service = service
|
||||
update_dict, errors = template_schema.dump(upd_temp)
|
||||
# TODO FIX ME
|
||||
# Remove update_temp model which is added to db.session
|
||||
db.session.rollback()
|
||||
try:
|
||||
save_model_template(template, update_dict=update_dict)
|
||||
except DAOException as e:
|
||||
return jsonify(result="error", message=str(e)), 400
|
||||
return jsonify(data=service_template.dump(template).data), status_code
|
||||
|
||||
5
app/template/__init__.py
Normal file
5
app/template/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from flask import Blueprint
|
||||
|
||||
template = Blueprint('template', __name__)
|
||||
|
||||
from app.template import rest
|
||||
34
app/template/rest.py
Normal file
34
app/template/rest.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from flask import (jsonify, request)
|
||||
from sqlalchemy.exc import DataError
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
from app.dao.templates_dao import get_model_templates
|
||||
from app.dao.services_dao import get_model_services
|
||||
from app.schemas import (template_schema, templates_schema)
|
||||
from app import db
|
||||
|
||||
from flask import (jsonify, request)
|
||||
from sqlalchemy.exc import DataError
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
from . import template
|
||||
from app import db
|
||||
|
||||
|
||||
# I am going to keep these for admin like operations
|
||||
# Permissions should restrict who can access this endpoint
|
||||
# TODO auth to be added.
|
||||
@template.route('/<int:template_id>', methods=['GET'])
|
||||
@template.route('/', methods=['GET'])
|
||||
def get_template(template_id=None):
|
||||
try:
|
||||
templates = get_model_templates(template_id=template_id)
|
||||
except DataError:
|
||||
return jsonify(result="error", message="Invalid template id"), 400
|
||||
except NoResultFound:
|
||||
return jsonify(result="error", message="Template not found"), 404
|
||||
if isinstance(templates, list):
|
||||
data, errors = templates_schema.dump(templates)
|
||||
else:
|
||||
data, errors = template_schema.dump(templates)
|
||||
if errors:
|
||||
return jsonify(result="error", message=str(errors))
|
||||
return jsonify(data=data)
|
||||
38
migrations/versions/0002_add_templates.py
Normal file
38
migrations/versions/0002_add_templates.py
Normal file
@@ -0,0 +1,38 @@
|
||||
"""empty message
|
||||
|
||||
Revision ID: 0002_add_templates
|
||||
Revises: 0001_initialise_data
|
||||
Create Date: 2016-01-13 10:10:37.303109
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '0002_add_templates'
|
||||
down_revision = '0001_initialise_data'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('templates',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('name', sa.String(length=255), nullable=False),
|
||||
sa.Column('template_type', sa.Enum('sms', 'email', 'letter', name='template_type'), nullable=False),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=False),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('content', sa.Text(), nullable=False),
|
||||
sa.Column('service_id', sa.BigInteger(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['service_id'], ['services.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_templates_service_id'), 'templates', ['service_id'], unique=False)
|
||||
### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_index(op.f('ix_templates_service_id'), table_name='templates')
|
||||
op.drop_table('templates')
|
||||
### end Alembic commands ###
|
||||
@@ -1,7 +1,8 @@
|
||||
import pytest
|
||||
from app.models import (User, Service)
|
||||
from app.models import (User, Service, Template)
|
||||
from app.dao.users_dao import (save_model_user, get_model_users)
|
||||
from app.dao.services_dao import save_model_service
|
||||
from app.dao.templates_dao import save_model_template
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
@@ -29,3 +30,23 @@ def sample_service(notify_db,
|
||||
service = Service(**data)
|
||||
save_model_service(service)
|
||||
return service
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def sample_template(notify_db,
|
||||
notify_db_session,
|
||||
template_name="Template Name",
|
||||
template_type="sms",
|
||||
content="This is a template",
|
||||
service=None):
|
||||
if service is None:
|
||||
service = sample_service(notify_db, notify_db_session)
|
||||
data = {
|
||||
'name': template_name,
|
||||
'template_type': template_type,
|
||||
'content': content,
|
||||
'service': service
|
||||
}
|
||||
template = Template(**data)
|
||||
save_model_template(template)
|
||||
return template
|
||||
|
||||
0
tests/app/template/__init__.py
Normal file
0
tests/app/template/__init__.py
Normal file
31
tests/app/template/test_rest.py
Normal file
31
tests/app/template/test_rest.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import json
|
||||
from app.models import Template
|
||||
from flask import url_for
|
||||
|
||||
|
||||
def test_get_template_list(notify_api, notify_db, notify_db_session, sample_template):
|
||||
"""
|
||||
Tests GET endpoint '/' to retrieve entire template list.
|
||||
"""
|
||||
with notify_api.test_request_context():
|
||||
with notify_api.test_client() as client:
|
||||
response = client.get(url_for('template.get_template'))
|
||||
assert response.status_code == 200
|
||||
json_resp = json.loads(response.get_data(as_text=True))
|
||||
assert len(json_resp['data']) == 1
|
||||
assert json_resp['data'][0]['name'] == sample_template.name
|
||||
assert json_resp['data'][0]['id'] == sample_template.id
|
||||
|
||||
|
||||
def test_get_template(notify_api, notify_db, notify_db_session, sample_template):
|
||||
"""
|
||||
Tests GET endpoint '/<template_id>' to retrieve a single template.
|
||||
"""
|
||||
with notify_api.test_request_context():
|
||||
with notify_api.test_client() as client:
|
||||
resp = client.get(url_for(
|
||||
'template.get_template', template_id=sample_template.id))
|
||||
assert resp.status_code == 200
|
||||
json_resp = json.loads(resp.get_data(as_text=True))
|
||||
assert json_resp['data']['name'] == sample_template.name
|
||||
assert json_resp['data']['id'] == sample_template.id
|
||||
Reference in New Issue
Block a user