Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Template_Categories table #2193

Merged
merged 38 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4bab291
Draft migration to add TemplateCategories table
whabanks Jun 11, 2024
da56d60
Fix prop logic for template_process_type
whabanks Jun 11, 2024
e7346fd
Add indexes, unique constraints
whabanks Jun 12, 2024
70334b0
Add CRUD methods for TemplateCategories
whabanks Jun 13, 2024
0430b4b
Insert low, med, high default categories during migration
whabanks Jun 13, 2024
28637f2
Fix prop logic for template_process_type again
whabanks Jun 13, 2024
b76744e
WIP: Add API endpoints for interacting with TemplateCategories
whabanks Jun 13, 2024
e34dc4a
Implement dao and api to update process_type
whabanks Jun 17, 2024
6a291fc
Address PR comments
whabanks Jun 17, 2024
fcb3550
Finish adding needed api endpoints
whabanks Jun 17, 2024
d8799ac
Chore: logic cleanup
whabanks Jun 17, 2024
6da3eaa
First batch of unit tests & bug fixes
whabanks Jun 18, 2024
a0fd757
Implement filtering when fetching all categories
whabanks Jun 19, 2024
e172bb7
Add lazy join on TemplateCategory
whabanks Jun 19, 2024
8a374c2
Clean up dao tests
whabanks Jun 19, 2024
46d0130
Add tests for deleting a template category
whabanks Jun 19, 2024
98c93bf
Add API tests, squash bugs
whabanks Jun 20, 2024
c7cab45
Fix pre-existing tests
whabanks Jun 24, 2024
6055586
Misc. fixes
whabanks Jun 24, 2024
231128f
We definitely didn't want that FK on templatehistory...
whabanks Jun 24, 2024
654d6b3
Merge branch 'main' into feat/add-template-categories-table
whabanks Jun 24, 2024
33006d7
Logic cleanups
whabanks Jun 24, 2024
8e0afa2
Rename migration
whabanks Jun 25, 2024
f927c99
Add tests for models
whabanks Jun 25, 2024
041a647
Add tests that were missed for template rest and dao
whabanks Jun 25, 2024
0be6d19
Rename /template/category to /template-category
whabanks Jun 25, 2024
44ad1f1
various fixes
whabanks Jun 25, 2024
d1c5c4e
Merge branch 'main' into feat/add-template-categories-table
jzbahrai Jun 27, 2024
1c84439
Re-word dao_delete_template_category_by_id
whabanks Jul 2, 2024
b7f33df
Merge branch 'main' into feat/add-template-categories-table
whabanks Jul 2, 2024
119cac4
Merge branch 'main' into feat/add-template-categories-table
whabanks Jul 2, 2024
1c342e1
Merge branch 'main' into feat/add-template-categories-table
jzbahrai Jul 3, 2024
3c37d1d
Add created_at and updated_at fields
whabanks Jul 3, 2024
38bc4e6
Add default value for created at, fix tests
whabanks Jul 3, 2024
5e1a947
Quick fix
whabanks Jul 3, 2024
ce80c82
Fix column defaults
whabanks Jul 3, 2024
ac90f0d
Fix silly typo..
whabanks Jul 3, 2024
d182ffe
Remove unneeded assert
whabanks Jul 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions app/dao/template_categories_dao.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import uuid

from flask import current_app
Fixed Show fixed Hide fixed
from sqlalchemy import asc
Fixed Show fixed Hide fixed

from app import db
from app.dao.dao_utils import transactional
Fixed Show fixed Hide fixed
from app.models import TemplateCategory


def dao_create_template_category(template_category: TemplateCategory):
jzbahrai marked this conversation as resolved.
Show resolved Hide resolved
template_category.id = uuid.uuid4()
db.session.add(template_category)


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


def dao_get_template_category_by_id(template_category_id):
return TemplateCategory.query.filter_by(id=template_category_id).one()


def dao_get_template_category_by_template_id(template_id):
return TemplateCategory.query.join(TemplateCategory.templates).filter_by(id=template_id).one()
whabanks marked this conversation as resolved.
Show resolved Hide resolved


def dao_get_all_template_categories():
whabanks marked this conversation as resolved.
Show resolved Hide resolved
return TemplateCategory.query.order_by(asc(TemplateCategory.name_en)).all()
26 changes: 26 additions & 0 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,19 @@ def get_users_with_permission(self):
PRECOMPILED_TEMPLATE_NAME = "Pre-compiled PDF"


class TemplateCategory(BaseModel):
__tablename__ = "template_categories"

id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
name_en = db.Column(db.String(255), unique=True, nullable=False)
name_fr = db.Column(db.String(255), unique=True, nullable=False)
description_en = db.Column(db.String(200), nullable=True)
description_fr = db.Column(db.String(200), nullable=True)
sms_process_type = db.Column(db.String(200), nullable=False)
email_process_type = db.Column(db.String(200), nullable=False)
hidden = db.Column(db.Boolean, nullable=False, default=False)


class TemplateBase(BaseModel):
__abstract__ = True

Expand Down Expand Up @@ -1078,6 +1091,10 @@ def service_id(cls):
def created_by_id(cls):
return db.Column(UUID(as_uuid=True), db.ForeignKey("users.id"), index=True, nullable=False)

@declared_attr
def template_category_id(cls):
return db.Column(UUID(as_uuid=True), db.ForeignKey("template_categories.id"), index=True, nullable=True)

@declared_attr
def created_by(cls):
return db.relationship("User")
Expand Down Expand Up @@ -1179,6 +1196,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")

folder = db.relationship(
"TemplateFolder",
Expand All @@ -1198,6 +1216,14 @@ def get_link(self):
_external=True,
)

@property
def template_process_type(self):
if self.template_type == SMS_TYPE and self.template_categories.sms_process_type:
whabanks marked this conversation as resolved.
Show resolved Hide resolved
return self.template_categories.sms_process_type
elif self.template_type == EMAIL_TYPE and self.template_categories.email_process_type:
return self.template_categories.email_process_type
return self.process_type

@classmethod
def from_json(cls, data, folder=None):
"""
Expand Down
70 changes: 70 additions & 0 deletions migrations/versions/0454_add_template_category.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""

Revision ID: 0454_add_template_categories
Revises: 0453_add_callback_failure_email
Create Date: 2024-06-11 13:32:00
"""

from datetime import datetime

import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql

revision = "0454_add_template_categories"
down_revision = "0452_set_pgaudit_config"


def upgrade():
op.create_table(
"template_categories",
sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True, nullable=False),
sa.Column("name_en", sa.String(length=255), nullable=False),
sa.Column("name_fr", sa.String(length=255), nullable=False),
sa.Column("description_en", sa.String(length=255), nullable=True),
sa.Column("description_fr", sa.String(length=255), nullable=True),
sa.Column("sms_process_type", sa.String(length=255), nullable=False),
sa.Column("email_process_type", sa.String(length=255), nullable=False),
sa.Column("hidden", sa.Boolean(), nullable=False),
sa.UniqueConstraint("name_en"),
sa.UniqueConstraint("name_fr"),
)

op.add_column("templates", sa.Column("template_category_id", postgresql.UUID(as_uuid=True), nullable=True))
op.add_column("templates_history", sa.Column("template_category_id", postgresql.UUID(as_uuid=True), nullable=True))
op.create_index(
op.f("ix_template_category_id"),
"templates",
["template_category_id"],
unique=False,
)
op.create_index(
op.f("ix_template_categories_name_en"),
"template_categories",
["name_en"],
unique=False,
)
op.create_index(
op.f("ix_template_categories_name_fr"),
"template_categories",
["name_fr"],
unique=False,
)
op.create_foreign_key("fk_template_template_categories", "templates", "template_categories", ["template_category_id"], ["id"])

# Insert the generic Low priority (bulk) category
whabanks marked this conversation as resolved.
Show resolved Hide resolved
# op.execute("""
# INSERT INTO template_category (id, name_en, name_fr, sms_process_type, email_process_type, hidden)
# VALUES ('00000000-0000-0000-0000-000000000000', 'Low Category (Bulk)', 'Catégorie Basse (En Vrac)', true
# """
# )


def downgrade():
op.drop_constraint("fk_template_template_categories", "templates", type_="foreignkey")
op.drop_index(op.f("ix_template_category_id"), table_name="templates")
op.drop_index(op.f("ix_template_categories_name_en"), table_name="template_categories")
op.drop_index(op.f("ix_template_categories_name_fr"), table_name="template_categories")
op.drop_column("templates", "template_category_id")
op.drop_column("templates_history", "template_category_id")
op.drop_table("template_categories")
153 changes: 153 additions & 0 deletions tests/app/dao/test_template_categories_dao.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import pytest
Fixed Show fixed Hide fixed

from app.dao.template_categories_dao import (
dao_create_template_category,
dao_get_all_template_categories,
dao_get_template_category_by_id,
dao_get_template_category_by_template_id,
dao_update_template_category,
)
from app.dao.templates_dao import dao_create_template
from app.models import BULK, NORMAL, PRIORITY, Template, TemplateCategory
Fixed Show fixed Hide fixed


def test_create_template_category(notify_db_session):
data = {
"name_en": "english",
"name_fr": "french",
"description_en": "english description",
"description_fr": "french description",
"sms_process_type": NORMAL,
"email_process_type": NORMAL,
"hidden": False,
}

template_category = TemplateCategory(**data)
dao_create_template_category(template_category)

assert TemplateCategory.query.count() == 1
assert len(dao_get_all_template_categories()) == 1


def test_update_template_category(notify_db_session):
data = {
"name_en": "english",
"name_fr": "french",
"description_en": "english description",
"description_fr": "french description",
"sms_process_type": NORMAL,
"email_process_type": NORMAL,
"hidden": False,
}

template_category = TemplateCategory(**data)
dao_create_template_category(template_category)

template_category.name_en = "new english"
template_category.name_fr = "new french"
template_category.description_en = "new english description"
template_category.description_fr = "new french description"
template_category.sms_process_type = BULK
template_category.email_process_type = BULK
template_category.hidden = True
dao_update_template_category(template_category)

assert TemplateCategory.query.count() == 1
assert len(dao_get_all_template_categories()) == 1
assert dao_get_all_template_categories()[0].name_en == "new english"
assert dao_get_all_template_categories()[0].name_fr == "new french"
assert dao_get_all_template_categories()[0].description_en == "new english description"
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].id == template_category.id


def test_get_template_category_by_template_id(notify_db_session, sample_service, sample_user):
category_data = {
"name_en": "english",
"name_fr": "french",
"description_en": "english description",
"description_fr": "french description",
"sms_process_type": NORMAL,
"email_process_type": NORMAL,
"hidden": False,
}

template_category = TemplateCategory(**category_data)
dao_create_template_category(template_category)

template_data = {
"name": "Sample Template",
"template_type": "email",
"content": "Template content",
"service": sample_service,
"created_by": sample_user,
}

template = Template(**template_data)
template.template_category = template_category
dao_create_template(template)

assert dao_get_template_category_by_template_id(template.id) == template_category


def test_get_template_category_by_id(notify_db_session):
data = {
"name_en": "english",
"name_fr": "french",
"description_en": "english description",
"description_fr": "french description",
"sms_process_type": NORMAL,
"email_process_type": NORMAL,
"hidden": False,
}

template_category = TemplateCategory(**data)
dao_create_template_category(template_category)

assert dao_get_template_category_by_id(template_category.id) == template_category


def test_get_all_template_categories(notify_db_session):
data1 = {
"name_en": "english",
"name_fr": "french",
"description_en": "english description",
"description_fr": "french description",
"sms_process_type": NORMAL,
"email_process_type": NORMAL,
"hidden": False,
}

data2 = {
"name_en": "english2",
"name_fr": "french2",
"description_en": "english description2",
"description_fr": "french description2",
"sms_process_type": BULK,
"email_process_type": BULK,
"hidden": True,
}

template_category1 = TemplateCategory(**data1)
template_category2 = TemplateCategory(**data2)
dao_create_template_category(template_category1)
dao_create_template_category(template_category2)

assert len(dao_get_all_template_categories()) == 2
assert dao_get_all_template_categories()[0].name_en == "english"
assert dao_get_all_template_categories()[0].name_fr == "french"
assert dao_get_all_template_categories()[0].description_en == "english description"
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 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
Loading