def test_template_merge_jinja_filters_docx(
    db,
    client,
    template,
    snapshot,
    settings,
    tmp_path,
    missing_file,
    wrong_mime,
    status_code,
):
    settings.LANGUAGE_CODE = "de-ch"
    url = reverse("template-merge", args=[template.pk])

    # Couldn't put this into `parametrize`. For some reason, in the second run, the
    # template name is extended with a seemingly random string.
    template.template = django_file("docx-template-filters.docx")
    template.save()

    data = {
        "data":
        json.dumps({
            "test_date": "1984-09-15",
            "test_time": "23:24",
            "test_datetime": "1984-09-15 23:23",
            "test_datetime2": "23:23-1984-09-15",
            "test_none": None,
            "test_nested": {
                "multiline": "This is\na test."
            },
        }),
    }

    if not missing_file:
        file = django_file("black.png").file
        if wrong_mime:
            # create a file with the correct filename (black.png) but with
            # the contents of a docx.
            file = tmp_path / "black.png"
            for line in template.template.file:
                file.write_bytes(line)
            file = file.open("rb")

        data["files"] = [file]

    response = client.post(url, data=data, format="multipart")
    assert response.status_code == status_code

    if status_code == status.HTTP_200_OK:
        assert (
            response._headers["content-type"][1] ==
            "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
        )

        docx = Document(io.BytesIO(response.content))
        xml = etree.tostring(docx._element.body,
                             encoding="unicode",
                             pretty_print=True)
        snapshot.assert_match(xml)
def test_disable_validation(
    db,
    status_code,
    admin_client,
    settings,
    disable_validation,
):
    settings.REQUIRE_AUTHENTICATION = False
    url = reverse("template-list")

    template_file = django_file("docx-template-syntax.docx")
    data = {
        "slug": "test-slug",
        "template": template_file.file,
        "engine": models.Template.DOCX_TEMPLATE,
    }
    if disable_validation:
        data["disable_template_validation"] = disable_validation

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

    if status_code == status.HTTP_201_CREATED:
        data = response.json()
        template_link = data["template"]
        response = admin_client.get(template_link)
        assert response.status_code == status.HTTP_200_OK
        Document(io.BytesIO(response.content))
def test_template_create_with_available_placeholders(
    db,
    admin_client,
    engine,
    template_name,
    available_placeholders,
    sample_data,
    files,
    status_code,
    settings,
    expect_missing_placeholders,
):

    settings.DOCXTEMPLATE_JINJA_EXTENSIONS = ["jinja2.ext.loopcontrols"]
    url = reverse("template-list")

    template_file = django_file(template_name)
    data = {
        "slug": "test-slug",
        "template": template_file.file,
        "files": files,
        "engine": engine,
    }
    if sample_data:
        data["sample_data"] = json.dumps(sample_data)
    if available_placeholders:
        data["available_placeholders"] = available_placeholders

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

    if status_code == status.HTTP_400_BAD_REQUEST:
        resp = response.json()
        expect_missing_str = "; ".join(expect_missing_placeholders)

        if sample_data and available_placeholders:
            # validation only allows one of these two params
            assert (
                resp["non_field_errors"][0] ==
                "Only one of available_placeholders and sample_data is allowed"
            )
        elif engine == models.Template.DOCX_MAILMERGE and files:
            assert (resp["non_field_errors"][0] ==
                    'Files are only accepted with the "docx-template" engine')
        elif not sample_data and files:
            assert (resp["non_field_errors"][0] ==
                    "Files are only accepted when also providing sample_data")
        else:
            # we expect some missing placeholders
            assert (
                resp["non_field_errors"][0] ==
                f"Template uses unavailable placeholders: {expect_missing_str}"
            )

    if status_code == status.HTTP_201_CREATED:
        data = response.json()
        template_link = data["template"]
        response = admin_client.get(template_link)
        assert response.status_code == status.HTTP_200_OK
        Document(io.BytesIO(response.content))
def test_template_create(
    db,
    client,
    admin_client,
    engine,
    template_name,
    status_code,
    group,
    require_authentication,
    settings,
    authenticated,
):
    if authenticated:
        client = admin_client

    settings.REQUIRE_AUTHENTICATION = require_authentication
    url = reverse("template-list")

    template_file = django_file(template_name)
    data = {
        "slug": "test-slug",
        "template": template_file.file,
        "engine": engine
    }
    if group:
        data["group"] = group
    response = client.post(url, data=data, format="multipart")
    assert response.status_code == status_code

    if status_code == status.HTTP_201_CREATED:
        data = response.json()
        template_link = data["template"]
        response = client.get(template_link)
        assert response.status_code == status.HTTP_200_OK
        Document(io.BytesIO(response.content))
Exemplo n.º 5
0
def test_template_merge_file_reset(
    db,
    client,
    template,
    settings,
    file_value,
):
    settings.LANGUAGE_CODE = "de-ch"
    url = reverse("template-merge", args=[template.pk])

    # Couldn't put this into `parametrize`. For some reason, in the second run, the
    # template name is extended with a seemingly random string.
    template.template = django_file("docx-template-filters.docx")
    template.save()

    data = {
        "data": {
            "test_date": "1984-09-15",
            "test_time": "23:24",
            "test_datetime": "1984-09-15 23:23",
            "test_datetime2": "23:23-1984-09-15",
            "test_none": None,
            "test_nested": {"multiline": "This is\na test."},
            "black.png": file_value,
        }
    }

    response = client.post(url, data=data, format="json")
    assert response.status_code == status.HTTP_200_OK

    assert (
        response._headers["content-type"][1]
        == "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
    )
Exemplo n.º 6
0
 def make_template(placeholder):
     engine = engines.get_engine(template.engine,
                                 django_file("docx-template.docx"))
     binary = BytesIO()
     engine.merge({"test": placeholder}, binary)
     binary.seek(0)
     template.template.save("foo.docx", binary)
     template.save()
     return template
Exemplo n.º 7
0
def test_clean_dangling_files(db, dry, settings, template_factory):
    templates = [
        template_factory(template=django_file("docx-template.docx")),
        template_factory(template=django_file("docx-template-syntax.docx")),
    ]
    dangling_files = [
        django_file("docx-template-filters.docx"),
        django_file("docx-template-loopcontrols.docx"),
    ]

    call_command("clean_dangling_files", dry=dry)

    assert (all([
        os.path.isfile(os.path.join(settings.MEDIA_ROOT, file.name)) is dry
        for file in dangling_files
    ]) is True)
    assert (all([
        os.path.isfile(template.template.path) is True
        for template in templates
    ]) is True)
def test_template_update(db, client, template, template_name, status_code):
    url = reverse("template-detail", args=[template.pk])

    template_file = django_file(template_name)
    data = {"description": "Test description", "template": template_file.file}
    response = client.patch(url, data=data, format="multipart")
    assert response.status_code == status_code

    if status_code == status.HTTP_200_OK:
        template.refresh_from_db()
        assert template.description == "Test description"
Exemplo n.º 9
0
def docx_template_with_placeholder(admin_client, template):
    """Return a factory function to build a docx template with a given placeholder."""

    engine = engines.get_engine(template.engine,
                                django_file("docx-template.docx"))

    def make_template(placeholder):
        binary = BytesIO()
        engine.merge({"test": placeholder}, binary)
        binary.seek(0)
        template.template.save("foo.docx", binary)
        template.save()
        return template

    return make_template
    def validate_template_syntax(self,
                                 available_placeholders=None,
                                 sample_data=None):

        try:
            doc = DocxTemplate(self.template)
            root = _MagicPlaceholder()
            env = get_jinja_env()
            ph = {
                name: root[name]
                for name in doc.get_undeclared_template_variables(env)
            }

            xml = doc.get_xml()
            xml = doc.patch_xml(xml)
            image_match = re.match(r".*{{\s?(\S*)\s?\|\s?image\(.*", xml)
            images = image_match.groups() if image_match else []
            for image in images:
                cleaned_image = image.strip('"').strip("'")
                ph[root[cleaned_image]] = django_file("black.png").file

            ph["_tpl"] = doc

            doc.render(ph, env)

            if sample_data:
                sample_data["_tpl"] = doc
                doc.render(sample_data, env)

            self.validate_available_placeholders(
                used_placeholders=root.reports,
                available_placeholders=available_placeholders,
            )

        except TemplateSyntaxError as exc:
            arg_str = ";".join(exc.args)
            raise exceptions.ValidationError(
                f"Syntax error in template: {arg_str}")

        finally:
            self.template.seek(0)
Exemplo n.º 11
0
     {
         "foo": "hello",
         "bar": {
             "some_attr": True,
             "list": [{
                 "attribute": "value"
             }, {
                 "attribute": "value2"
             }],
         },
         "baz": "1234",
         "list": [{
             "attribute": "value"
         }],
     },
     [django_file("black.png").file],
     [],
     models.Template.DOCX_TEMPLATE,
     status.HTTP_201_CREATED,
 ),
 (
     "docx-template-placeholdercheck.docx",
     None,
     {},
     [django_file("black.png").file],
     [],
     models.Template.DOCX_TEMPLATE,
     status.HTTP_400_BAD_REQUEST,
 ),
 (
     "docx-template-placeholdercheck.docx",