Skip to content

Commit

Permalink
Merge pull request #819 from JohnL17/update-template-model
Browse files Browse the repository at this point in the history
Update template model
  • Loading branch information
JohnL17 authored Aug 21, 2024
2 parents ed95649 + eef255a commit 0531f07
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Generated by Django 4.2.15 on 2024-08-19 07:22

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0006_remove_template_group'),
]

operations = [
migrations.AddField(
model_name='template',
name='created_at',
field=models.DateTimeField(auto_now_add=True, db_index=True, null=True),
),
migrations.AddField(
model_name='template',
name='created_by_group',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AddField(
model_name='template',
name='created_by_user',
field=models.CharField(blank=True, max_length=150, null=True),
),
migrations.AddField(
model_name='template',
name='modified_at',
field=models.DateTimeField(auto_now=True, db_index=True, null=True),
),
migrations.AddField(
model_name='template',
name='modified_by_group',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AddField(
model_name='template',
name='modified_by_user',
field=models.CharField(blank=True, max_length=150, null=True),
),
]
21 changes: 20 additions & 1 deletion document_merge_service/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,33 @@ class Template(models.Model):
engine: models.CharField = models.CharField(
max_length=20, choices=ENGINE_CHOICES_TUPLE
)
created_at: models.DateTimeField = models.DateTimeField(
auto_now_add=True, db_index=True, null=True
)
created_by_user: models.CharField = models.CharField(
max_length=150, blank=True, null=True
)
created_by_group: models.CharField = models.CharField(
max_length=255, blank=True, null=True
)
modified_at: models.DateTimeField = models.DateTimeField(
auto_now=True, db_index=True, null=True
)
modified_by_user: models.CharField = models.CharField(
max_length=150, blank=True, null=True
)
modified_by_group: models.CharField = models.CharField(
max_length=255, blank=True, null=True
)
meta = models.JSONField(default=dict)


@receiver(models.signals.post_delete, sender=Template)
def auto_delete_file_on_delete(sender, instance, **kwargs):
"""Delete template file from filesystem when `Template` object is deleted."""

DefaultStorage().delete(instance.template.name)
if instance.template:
DefaultStorage().delete(instance.template.name)


@receiver(models.signals.pre_save, sender=Template)
Expand Down
22 changes: 22 additions & 0 deletions document_merge_service/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ def _(doc):
return sorted([x.replace(".[]", "[]") for x in _doc(sample_doc)])

def validate(self, data):
user = self.context["request"].user

if self.instance is None:
data["created_by_user"] = user.username
data["created_by_group"] = user.group
data["modified_by_user"] = user.username
data["modified_by_group"] = user.group

if data.pop("disable_template_validation", False):
# Some template structures cannot be validated automatically,
# or it would be impossible or too much effort to provide accurate
Expand Down Expand Up @@ -118,7 +126,21 @@ class Meta:
"files",
"disable_template_validation",
"meta",
"created_at",
"created_by_user",
"created_by_group",
"modified_at",
"modified_by_user",
"modified_by_group",
)
extra_kwargs = {
"created_at": {"read_only": True},
"created_by_user": {"read_only": True},
"created_by_group": {"read_only": True},
"modified_at": {"read_only": True},
"modified_by_user": {"read_only": True},
"modified_by_group": {"read_only": True},
}


class TemplateMergeSerializer(serializers.Serializer):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@
# name: test_template_detail
dict({
'available_placeholders': None,
'created_by_group': None,
'created_by_user': None,
'description': '''
Article star very capital morning option. Interesting station story.
Where during teach country talk across drop. Central meeting anyone remember. There today material minute ago get.
Expand All @@ -146,6 +148,8 @@
'engine': 'docx-mailmerge',
'meta': dict({
}),
'modified_by_group': None,
'modified_by_user': None,
'sample_data': None,
'slug': 'note-act-source',
'template': None,
Expand Down
64 changes: 61 additions & 3 deletions document_merge_service/api/tests/test_template.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import io
import json
import os
from collections import namedtuple

import openpyxl
import pytest
from django.urls import reverse
from docx import Document
from lxml import etree
from rest_framework import status
from syrupy import filters

from document_merge_service.api.authentication import AnonymousUser
from document_merge_service.api.data import django_file

from .. import models, serializers
Expand Down Expand Up @@ -37,7 +40,9 @@ def test_template_detail(db, client, template, snapshot):

response = client.get(url)
assert response.status_code == status.HTTP_200_OK
snapshot.assert_match(response.json())
assert response.json() == snapshot(
exclude=filters.props("created_at", "modified_at")
)


def test_template_download(db, client, template):
Expand Down Expand Up @@ -208,6 +213,56 @@ def test_template_create(
Document(file_)


@pytest.mark.parametrize(
"exists,status_code,method,url",
[
(
True,
status.HTTP_200_OK,
"patch",
reverse("template-detail", args=["foobar"]),
),
(
False,
status.HTTP_201_CREATED,
"post",
reverse("template-list"),
),
],
)
@pytest.mark.parametrize("template__slug", ["foobar"])
def test_created_modified(db, admin_client, exists, template, status_code, method, url):
template_file = django_file("xlsx-template.xlsx")
data = {
"slug": "test-slug",
"template": template_file.file,
"engine": models.Template.XLSX_TEMPLATE,
}

request_method = getattr(admin_client, method)

if not exists:
template.delete()

response = request_method(url, data=data, format="multipart")

assert response.status_code == status_code
data = response.json()

if exists:
assert data["created_by_user"] is None
assert data["created_by_group"] is None
else:
assert data["created_by_user"] == "admin"
assert data["created_by_group"] == "admin"

assert data["modified_by_user"] == "admin"
assert data["modified_by_group"] == "admin"

assert data["modified_at"]
assert data["created_at"]


@pytest.mark.parametrize(
"status_code, disable_validation",
[
Expand Down Expand Up @@ -637,12 +692,15 @@ def test_merge_expression(
[models.Template.DOCX_TEMPLATE],
)
def test_validate_expression(
docx_template_with_placeholder, client, placeholder, template_content
docx_template_with_placeholder, placeholder, template_content
):
"""Test validation of templates with custom expressions."""
template = docx_template_with_placeholder(placeholder)

serializer = serializers.TemplateSerializer()
Request = namedtuple("Request", ["user"])
serializer = serializers.TemplateSerializer(
context={"request": Request(AnonymousUser())}
)
serializer.instance = template

serializer.validate({"data": template_content})
Expand Down

0 comments on commit 0531f07

Please sign in to comment.