Skip to content

Commit

Permalink
Merge pull request #884 from winged/accept_placeholders_json
Browse files Browse the repository at this point in the history
feat(api): accept available placeholders as json list
  • Loading branch information
winged authored Nov 12, 2024
2 parents cb75020 + 88887c4 commit 1ae2769
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 4 deletions.
1 change: 0 additions & 1 deletion docker-compose.override.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
version: "3.4"
services:
document-merge-service:
image: ghcr.io/adfinis/document-merge-service:dev
Expand Down
1 change: 0 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
version: "3.4"
services:
document-merge-service:
image: ghcr.io/adfinis/document-merge-service:latest
Expand Down
26 changes: 25 additions & 1 deletion document_merge_service/api/serializers.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
from functools import singledispatch

from django.conf import settings
Expand Down Expand Up @@ -33,11 +34,34 @@ def to_representation(self, value):
return reverse("template-download", args=[value.pk])


class AvailablePlaceholdersField(serializers.ListField):
"""A list field type that also accepts JSON lists.
Instead of multiple fields with the same name (traditional
form-data lists), we also accept a JSON list for the available
placeholders. This helps reduce the number of fields in the
request, which WAF, Django, and possibly other server-side
web components don't appreciate.
"""

def to_internal_value(self, data):
data = data if isinstance(data, list) else [data]
all_values = []
for value in data:
if value.startswith("["):
# looks like JSON, parse it
all_values.extend(json.loads(value))
else:
all_values.append(value)

return all_values


class TemplateSerializer(ValidatorMixin, serializers.ModelSerializer):
disable_template_validation = serializers.BooleanField(
allow_null=True, default=False
)
available_placeholders = serializers.ListField(allow_null=True, required=False)
available_placeholders = AvailablePlaceholdersField(allow_null=True, required=False)
sample_data = serializers.JSONField(allow_null=True, required=False)
files = serializers.ListField(
child=CustomFileField(write_only=True, allow_empty_file=False), required=False
Expand Down
11 changes: 10 additions & 1 deletion document_merge_service/api/tests/test_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@ def test_disable_validation(
),
],
)
@pytest.mark.parametrize("use_json", [True, False])
def test_template_create_with_available_placeholders(
db,
admin_client,
Expand All @@ -504,12 +505,18 @@ def test_template_create_with_available_placeholders(
files,
status_code,
settings,
use_json,
expect_missing_placeholders,
):
settings.DOCXTEMPLATE_JINJA_EXTENSIONS = ["jinja2.ext.loopcontrols"]
url = reverse("template-list")

template_file = django_file(template_name)

# files are being reused, so make sure they're readable
for f in files:
f.seek(0)

data = {
"slug": "test-slug",
"template": template_file.file,
Expand All @@ -519,7 +526,9 @@ def test_template_create_with_available_placeholders(
if sample_data:
data["sample_data"] = json.dumps(sample_data)
if available_placeholders:
data["available_placeholders"] = available_placeholders
data["available_placeholders"] = (
json.dumps(available_placeholders) if use_json else available_placeholders
)

response = admin_client.post(url, data=data, format="multipart")
assert response.status_code == status_code, response.json()
Expand Down

0 comments on commit 1ae2769

Please sign in to comment.