Skip to content

Commit

Permalink
Add hybrid_property and expression property for template.process_type (
Browse files Browse the repository at this point in the history
…#2237)

* Add hybrid_property and expression property

* Fixes

* try

* fixes

* fix

---------

Co-authored-by: Jumana Bahrainwala <[email protected]>
Co-authored-by: Jumana B <[email protected]>
  • Loading branch information
3 people authored Jul 31, 2024
1 parent bc7560c commit ec38665
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 43 deletions.
8 changes: 6 additions & 2 deletions app/delivery/send_to_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ def send_sms_to_provider(notification):
template_id=notification.template_id,
)

template_dict = dao_get_template_by_id(notification.template_id, notification.template_version).__dict__
template_obj = dao_get_template_by_id(notification.template_id, notification.template_version)
template_dict = template_obj.__dict__
template_dict["process_type"] = template_obj.process_type

template = SMSMessageTemplate(
template_dict,
Expand Down Expand Up @@ -279,7 +281,9 @@ def send_email_to_provider(notification: Notification):
else:
personalisation_data[key] = personalisation_data[key]["document"]["url"]

template_dict = dao_get_template_by_id(notification.template_id, notification.template_version).__dict__
template_obj = dao_get_template_by_id(notification.template_id, notification.template_version)
template_dict = template_obj.__dict__
template_dict["process_type"] = template_obj.process_type

# Local Jinja support - Add USE_LOCAL_JINJA_TEMPLATES=True to .env
# Add a folder to the project root called 'jinja_templates'
Expand Down
39 changes: 26 additions & 13 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1130,13 +1130,37 @@ def created_by(cls):
return db.relationship("User")

@declared_attr
def process_type(cls):
def process_type_column(cls):
return db.Column(
db.String(255),
db.ForeignKey("template_process_type.name"),
name="process_type",
index=True,
nullable=True,
default=NORMAL,
)

@hybrid_property
def process_type(self):
# The if statement is required as a way to check if FF_TEMPLATE_CATEGORY is enabled
if self.template_category_id:
if self.template_type == SMS_TYPE:
return self.process_type_column if self.process_type_column else self.template_category.sms_process_type
elif self.template_type == EMAIL_TYPE:
return self.process_type_column if self.process_type_column else self.template_category.email_process_type
return self.process_type_column if self.process_type_column else NORMAL

@process_type.setter # type: ignore
def process_type(self, value):
self.process_type_column = value

@process_type.expression
def _process_type(self):
return db.case(
[
(self.template_type == "sms", db.coalesce(self.process_type_column, self.template_category.sms_process_type)),
(self.template_type == "email", db.coalesce(self.process_type_column, self.template_category.email_process_type)),
],
else_=self.process_type_column,
)

redact_personalisation = association_proxy("template_redacted", "redact_personalisation")
Expand Down Expand Up @@ -1245,17 +1269,6 @@ def get_link(self):
_external=True,
)

@property
def template_process_type(self):
"""By default we use the process_type from TemplateCategory, but allow admins to override it on a per-template basis.
Only when overriden do we use the process_type from the template itself.
"""
if self.template_type == SMS_TYPE:
return self.process_type if self.process_type else self.template_categories.sms_process_type
elif self.template_type == EMAIL_TYPE:
return self.process_type if self.process_type else self.template_categories.email_process_type
return self.process_type

@classmethod
def from_json(cls, data, folder=None):
"""
Expand Down
4 changes: 2 additions & 2 deletions app/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ class Meta(BaseSchema.Meta):
class TemplateSchema(BaseTemplateSchema):
created_by = field_for(models.Template, "created_by", required=True)
is_precompiled_letter = fields.Method("get_is_precompiled_letter")
process_type = field_for(models.Template, "process_type")
process_type = field_for(models.Template, "process_type_column")
template_category = fields.Nested(TemplateCategorySchema, dump_only=True)
template_category_id = fields.UUID(required=False, allow_none=True)
redact_personalisation = fields.Method("redact")
Expand Down Expand Up @@ -425,7 +425,7 @@ class Meta(BaseSchema.Meta):
class TemplateHistorySchema(BaseSchema):
reply_to = fields.Method("get_reply_to", allow_none=True)
reply_to_text = fields.Method("get_reply_to_text", allow_none=True)
process_type = field_for(models.Template, "process_type")
process_type = field_for(models.Template, "process_type_column")
template_category = fields.Nested(TemplateCategorySchema, dump_only=True)
created_by = fields.Nested(UserSchema, only=["id", "name", "email_address"], dump_only=True)
created_at = field_for(models.Template, "created_at", format="%Y-%m-%d %H:%M:%S.%f")
Expand Down
6 changes: 5 additions & 1 deletion tests/app/template/test_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1580,17 +1580,19 @@ class TestTemplateCategory:

# ensure that the process_type is overridden when a user changes categories
@pytest.mark.parametrize(
"template_category_id, expected_process_type",
"template_category_id, expected_process_type_column, expected_process_type",
[
# category doesnt change, process_type should remain as priority
(
"unchanged",
"priority",
"priority",
),
# category changes, process_type should be removed
(
DEFAULT_TEMPLATE_CATEGORY_MEDIUM,
None,
"normal",
),
],
)
Expand All @@ -1602,6 +1604,7 @@ def test_process_type_should_be_reset_when_template_category_updated(
admin_request,
populate_generic_categories,
template_category_id,
expected_process_type_column,
expected_process_type,
notify_api,
):
Expand All @@ -1624,4 +1627,5 @@ def test_process_type_should_be_reset_when_template_category_updated(
template = dao_get_template_by_id(sample_template_with_priority_override.id)

assert str(template.template_category_id) == calculated_tc
assert template.process_type_column == expected_process_type_column
assert template.process_type == expected_process_type
52 changes: 27 additions & 25 deletions tests/app/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,32 +358,34 @@ def test_template_folder_is_parent(sample_service):
assert not folders[1].is_parent_of(folders[0])


@pytest.mark.parametrize(
"template_type, process_type, sms_process_type, email_process_type, expected_template_process_type",
[
(SMS_TYPE, None, NORMAL, BULK, NORMAL),
(EMAIL_TYPE, None, BULK, NORMAL, NORMAL),
(SMS_TYPE, BULK, PRIORITY, PRIORITY, BULK),
(EMAIL_TYPE, BULK, PRIORITY, PRIORITY, BULK),
],
)
def test_template_process_type(
notify_db,
notify_db_session,
template_type,
process_type,
sms_process_type,
email_process_type,
expected_template_process_type,
):
template_category = create_template_category(
notify_db, notify_db_session, sms_process_type=sms_process_type, email_process_type=email_process_type
)
template = create_template(
service=create_service(), template_type=template_type, process_type=process_type, template_category=template_category
class TestTemplateProcessType:
@pytest.mark.parametrize(
"template_type, process_type, sms_process_type, email_process_type, expected_template_process_type",
[
(SMS_TYPE, None, NORMAL, BULK, NORMAL),
(EMAIL_TYPE, None, BULK, NORMAL, NORMAL),
(SMS_TYPE, BULK, PRIORITY, PRIORITY, BULK),
(EMAIL_TYPE, BULK, PRIORITY, PRIORITY, BULK),
],
)

assert template.template_process_type == expected_template_process_type
def test_template_process_type(
self,
notify_db,
notify_db_session,
template_type,
process_type,
sms_process_type,
email_process_type,
expected_template_process_type,
):
template_category = create_template_category(
notify_db, notify_db_session, sms_process_type=sms_process_type, email_process_type=email_process_type
)
template = create_template(
service=create_service(), template_type=template_type, process_type=process_type, template_category=template_category
)
assert template.process_type_column == process_type
assert template.process_type == expected_template_process_type


def test_fido2_key_serialization(sample_fido2_key):
Expand Down

0 comments on commit ec38665

Please sign in to comment.