Skip to content

Commit

Permalink
WIP: Add API endpoints for interacting with TemplateCategories
Browse files Browse the repository at this point in the history
- Added a schema for TemplateCategory
- Added from_json and serialize to the TemplateCategory model
- Added the template/category Blueprint
- Add some initial CRUD api endpoints
  • Loading branch information
whabanks committed Jun 13, 2024
1 parent 28637f2 commit b76744e
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 13 deletions.
3 changes: 2 additions & 1 deletion app/dao/template_categories_dao.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import uuid

from flask import current_app
from sqlalchemy import asc

from app import db
from app.dao.dao_utils import transactional
from app.models import TemplateCategory


@transactional
def dao_create_template_category(template_category: TemplateCategory):
template_category.id = uuid.uuid4()
db.session.add(template_category)


@transactional
def dao_update_template_category(template_category: TemplateCategory):
db.session.add(template_category)

Expand Down
34 changes: 34 additions & 0 deletions app/dao/templates_dao.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,40 @@ def dao_update_template_reply_to(template_id, reply_to):
return template


@transactional
def dao_update_template_category(template_id, category_id):
Template.query.filter_by(id=template_id).update(
{
"template_category_id": category_id,
"updated_at": datetime.utcnow(),
"version": Template.version + 1,
}
)

template = Template.query.filter_by(id=template_id).one()

history = TemplateHistory(
**{
"id": template.id,
"name": template.name,
"template_type": template.template_type,
"created_at": template.created_at,
"updated_at": template.updated_at,
"content": template.content,
"service_id": template.service_id,
"subject": template.subject,
"postage": template.postage,
"created_by_id": template.created_by_id,
"version": template.version,
"archived": template.archived,
"process_type": template.process_type,
"service_letter_contact_id": template.service_letter_contact_id,
}
)
db.session.add(history)
return template


@transactional
def dao_redact_template(template, user_id):
template.template_redacted.redact_personalisation = True
Expand Down
19 changes: 18 additions & 1 deletion app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1045,6 +1045,23 @@ class TemplateCategory(BaseModel):
email_process_type = db.Column(db.String(200), nullable=False)
hidden = db.Column(db.Boolean, nullable=False, default=False)

def serialize(self):
return {
"id": self.id,
"name_en": self.name_en,
"name_fr": self.name_fr,
"description_en": self.description_en,
"description_fr": self.description_fr,
"sms_process_type": self.sms_process_type,
"email_process_type": self.email_process_type,
"hidden": self.hidden,
}

@classmethod
def from_json(cls, data):
fields = data.copy()
return cls(**fields)


class TemplateBase(BaseModel):
__abstract__ = True
Expand Down Expand Up @@ -1196,7 +1213,7 @@ class Template(TemplateBase):

service = db.relationship("Service", backref="templates")
version = db.Column(db.Integer, default=0, nullable=False)
template_category = db.relationship("TemplateCategory", backref="templates")
category = db.relationship("TemplateCategory", backref="templates")

folder = db.relationship(
"TemplateFolder",
Expand Down
27 changes: 27 additions & 0 deletions app/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,32 @@ def make_instance(self, data, **kwargs):
return super(BaseSchema, self).make_instance(data)


class TemplateCategorySchema(BaseSchema):
class Meta(BaseSchema.Meta):
model = models.TemplateCategory
exclude = ("id",)

@validates("name_en")
def validate_name_en(self, value):
if not value:
raise ValidationError("Invalid name")

@validates("name_fr")
def validate_name_fr(self, value):
if not value:
raise ValidationError("Invalid name")

@validates("sms_process_type")
def validate_sms_process_type(self, value):
if value not in models.TEMPLATE_PROCESS_TYPE:
raise ValidationError("Invalid SMS process type")

@validates("email_process_type")
def validate_email_process_type(self, value):
if value not in models.TEMPLATE_PROCESS_TYPE:
raise ValidationError("Invalid email process type")


class UserSchema(BaseSchema):
permissions = fields.Method("user_permissions", dump_only=True)
password_changed_at = field_for(models.User, "password_changed_at", format="%Y-%m-%d %H:%M:%S.%f")
Expand Down Expand Up @@ -805,6 +831,7 @@ def validate_archived(self, data, **kwargs):
service_history_schema = ServiceHistorySchema()
api_key_history_schema = ApiKeyHistorySchema()
template_history_schema = TemplateHistorySchema()
template_category_schema = TemplateCategorySchema()
event_schema = EventSchema()
provider_details_schema = ProviderDetailsSchema()
provider_details_history_schema = ProviderDetailsHistorySchema()
Expand Down
20 changes: 20 additions & 0 deletions app/template/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
dao_get_template_versions,
dao_redact_template,
dao_update_template,
dao_update_template_category,
dao_update_template_reply_to,
get_precompiled_letter_template,
)
Expand Down Expand Up @@ -132,6 +133,25 @@ def create_template(service_id):
return jsonify(data=template_schema.dump(new_template)), 201


@template_blueprint.route("/<uuid:template_id>/template-category/<uuid:template_category_id>", methods=["POST"])
def update_templates_category(template_id, template_category_id):
updated = dao_update_template_category(template_id, template_category_id)
return jsonify(data=template_schema.dump(updated)), 200


@template_blueprint.route("/<uuid:template_id>/process-type", methods=["POST"])
def update_template_process_type(template_id):
data = request.get_json()
if "process_type" not in data:
message = "Field is required"
errors = {"process_type": [message]}
raise InvalidRequest(errors, status_code=400)

# updated = dao_update_template_process_type(template_id=template_id, process_type=data.get("process_type"))
# return jsonify(data=template_schema.dump(updated)), 200
pass

Check warning

Code scanning / CodeQL

Unnecessary pass Warning

Unnecessary 'pass' statement.


@template_blueprint.route("/<uuid:template_id>", methods=["POST"])
def update_template(service_id, template_id):
fetched_template = dao_get_template_by_id_and_service_id(template_id=template_id, service_id=service_id)
Expand Down
49 changes: 49 additions & 0 deletions app/template/template_category_rest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from flask import Blueprint, jsonify, request

from app.dao.template_categories_dao import (
dao_create_template_category,
dao_get_all_template_categories,
dao_get_template_category_by_id,
dao_update_template_category,
)
from app.models import TemplateCategory
from app.schemas import template_category_schema

template_category_blueprint = Blueprint(
"template_category",
__name__,
url_prefix="template/category",
)


@template_category_blueprint.route("", methods=["POST"])
def create_template_category():
data = request.get_json()

template_category_schema.load(data)
template_category = TemplateCategory.from_json(data)

dao_create_template_category(template_category)

return jsonify(data=template_category_schema.dump(template_category)), 201


@template_category_blueprint.route("/<template_category_id>", methods=["POST"])
def update_template_category(template_category_id):
request_json = request.get_json()
update_dict = template_category_schema.load(request_json)

category_to_update = dao_get_template_category_by_id(template_category_id)

for key in request_json:
setattr(category_to_update, key, update_dict[key])

dao_update_template_category(category_to_update)

return jsonify(data=category_to_update.serialize()), 200


@template_category_blueprint.route("", methods=["GET"])
def get_template_categories():
template_categories = dao_get_all_template_categories()
return jsonify(data=template_category_schema.dump(template_categories, many=True)), 200
10 changes: 7 additions & 3 deletions migrations/versions/0454_add_template_category.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
DEFAULT_MEDIUM = "f75d6706-21b7-437e-b93a-2c0ab771e28e"
DEFAULT_HIGH = "c4f87d7c-a55b-4c0f-91fe-e56c65bb1871"


def upgrade():
op.create_table(
"template_categories",
Expand Down Expand Up @@ -57,17 +58,20 @@ def upgrade():
op.create_foreign_key("fk_template_template_categories", "templates", "template_categories", ["template_category_id"], ["id"])

# Insert the generic low, medium, and high categories
op.execute(f"""
op.execute(
f"""
INSERT INTO template_category (id, name_en, name_fr, sms_process_type, email_process_type, hidden)
VALUES ({DEFAULT_LOW}, 'Low Category (Bulk)', 'Catégorie Basse (En Vrac)', true
"""
)
op.execute(f"""
op.execute(
f"""
INSERT INTO template_category (id, name_en, name_fr, sms_process_type, email_process_type, hidden)
VALUES ({DEFAULT_MEDIUM}, 'Medium Category (Normal)', 'Catégorie Moyenne (Normale)', true
"""
)
op.execute(f"""
op.execute(
f"""
INSERT INTO template_category (id, name_en, name_fr, sms_process_type, email_process_type, hidden)
VALUES ({DEFAULT_HIGH}, 'High Category (Priority)', 'Catégorie Haute (Priorité)', true
"""
Expand Down
14 changes: 6 additions & 8 deletions tests/app/dao/test_template_categories_dao.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import pytest

from app.dao.template_categories_dao import (
dao_create_template_category,
dao_get_all_template_categories,
Expand All @@ -8,7 +6,7 @@
dao_update_template_category,
)
from app.dao.templates_dao import dao_create_template
from app.models import BULK, NORMAL, PRIORITY, Template, TemplateCategory
from app.models import BULK, NORMAL, Template, TemplateCategory


def test_create_template_category(notify_db_session):
Expand Down Expand Up @@ -60,7 +58,7 @@ def test_update_template_category(notify_db_session):
assert dao_get_all_template_categories()[0].description_fr == "new french description"
assert dao_get_all_template_categories()[0].sms_process_type == BULK
assert dao_get_all_template_categories()[0].email_process_type == BULK
assert dao_get_all_template_categories()[0].hidden == True
assert dao_get_all_template_categories()[0].hidden
assert dao_get_all_template_categories()[0].id == template_category.id


Expand Down Expand Up @@ -116,8 +114,8 @@ def test_get_all_template_categories(notify_db_session):
"name_fr": "french",
"description_en": "english description",
"description_fr": "french description",
"sms_process_type": NORMAL,
"email_process_type": NORMAL,
"sms_process_type": "normal",
"email_process_type": "normal",
"hidden": False,
}

Expand All @@ -143,11 +141,11 @@ def test_get_all_template_categories(notify_db_session):
assert dao_get_all_template_categories()[0].description_fr == "french description"
assert dao_get_all_template_categories()[0].sms_process_type == NORMAL
assert dao_get_all_template_categories()[0].email_process_type == NORMAL
assert dao_get_all_template_categories()[0].hidden == False
assert not dao_get_all_template_categories()[0].hidden
assert dao_get_all_template_categories()[1].name_en == "english2"
assert dao_get_all_template_categories()[1].name_fr == "french2"
assert dao_get_all_template_categories()[1].description_en == "english description2"
assert dao_get_all_template_categories()[1].description_fr == "french description2"
assert dao_get_all_template_categories()[1].sms_process_type == BULK
assert dao_get_all_template_categories()[1].email_process_type == BULK
assert dao_get_all_template_categories()[1].hidden == True
assert dao_get_all_template_categories()[1].hidden

0 comments on commit b76744e

Please sign in to comment.