Skip to content

Commit

Permalink
Add tests for PDF export
Browse files Browse the repository at this point in the history
  • Loading branch information
timobrembeck committed Apr 18, 2022
1 parent c7d15da commit 0d6fa42
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 0 deletions.
3 changes: 3 additions & 0 deletions tests/pdf/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""
This package contains tests for the PDF export of both the :mod:`integreat_cms.cms` and the :mod:`integreat_cms.api` app
"""
3 changes: 3 additions & 0 deletions tests/pdf/dummy_django_app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""
This package contains a dummy Django app to simulate the serving of static files during tests with DEBUG=False
"""
24 changes: 24 additions & 0 deletions tests/pdf/dummy_django_app/static_urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from django.conf import settings
from django.urls import include, path
from django.views.static import serve

from integreat_cms.core.urls import urlpatterns

#: Add the debug serve view to test the download of PDF files
urlpatterns += [
path(
"",
include(
(
[
path(
f"{settings.PDF_URL}<path:path>".lstrip("/"),
serve,
{"document_root": settings.PDF_ROOT},
)
],
"pdf_files",
)
),
),
]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
140 changes: 140 additions & 0 deletions tests/pdf/test_pdf_export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import io

from urllib.parse import urlencode, quote

import pytest
import PyPDF3

from django.urls import reverse


# pylint: disable=unused-argument,too-many-locals
@pytest.mark.django_db
# Override urls to serve PDF files
@pytest.mark.urls("tests.pdf.dummy_django_app.static_urls")
@pytest.mark.parametrize(
"language_slug,page_ids,url,expected_filename",
[
(
"de",
[1, 2, 3, 4, 5, 6],
"/augsburg/de/willkommen/",
"6262976c99/Integreat - Deutsch - Willkommen.pdf",
),
(
"de",
[1, 2, 3, 4, 5, 6, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23],
"",
"2861aa8c8d/Integreat - Deutsch - Augsburg.pdf",
),
(
"en",
[1, 2, 3, 4, 5, 6],
"/augsburg/en/welcome/",
"e155c5e38b/Integreat - Englisch - Welcome.pdf",
),
(
"ar",
[1, 2, 3, 4, 5, 6],
"/augsburg/ar/معلومات-الوصول/",
"3b02f5ea5b/Integreat - Arabisch - معلومات الوصول.pdf",
),
],
)
def test_pdf_export(
load_test_data,
client,
admin_client,
language_slug,
page_ids,
url,
expected_filename,
):
"""
Test whether the PDF export works as expected
:param load_test_data: The fixture providing the test data (see :meth:`~tests.conftest.load_test_data`)
:type load_test_data: tuple
:param client: The fixture providing the anonymous user
:type client: :fixture:`client`
:param admin_client: The fixture providing the logged in admin
:type admin_client: :fixture:`admin_client`
:param language_slug: The language slug of this export
:type language_slug: str
:param page_ids: The pages that should be exported
:type page_ids: list
:param url: The url query param for the API request
:type url: str
:param expected_filename: What filename to expect
:type expected_filename: str
"""
kwargs = {"region_slug": "augsburg", "language_slug": language_slug}
export_pdf = reverse("export_pdf", kwargs=kwargs)
response_cms = admin_client.post(export_pdf, data={"selected_ids[]": page_ids})
export_pdf_api = reverse("api:pdf_export", kwargs=kwargs)
response_api = client.get(f"{export_pdf_api}?{urlencode({'url': url})}")
# Test both the PDF generation of the CMS as well as the API
for response in [response_cms, response_api]:
print(response.headers)
assert response.status_code == 302
expected_url = f"/pdf/{quote(expected_filename)}"
assert response.headers.get("Location") == expected_url
response = admin_client.get(expected_url)
print(response.headers)
assert response.headers.get("Content-Type") == "application/pdf"
# Compare file content
result_pdf = PyPDF3.PdfFileReader(
io.BytesIO(b"".join(response.streaming_content))
)
# pylint: disable=consider-using-with
expected_pdf = PyPDF3.PdfFileReader(
open(f"tests/pdf/files/{expected_filename}", "rb")
)
# Assert that both documents have same number of pages
assert result_pdf.numPages == expected_pdf.numPages
# Assert that the content is identical
for page_number in range(result_pdf.numPages):
result_page = result_pdf.getPage(page_number)
expected_page = expected_pdf.getPage(page_number)
assert result_page.artBox == expected_page.artBox
assert result_page.bleedBox == expected_page.bleedBox
assert result_page.cropBox == expected_page.cropBox
assert result_page.mediaBox == expected_page.mediaBox
assert result_page.extractText() == expected_page.extractText()
assert result_page.getContents() == expected_page.getContents()


# pylint: disable=unused-argument,too-many-locals
@pytest.mark.django_db
# Override urls to serve PDF files
@pytest.mark.urls("tests.pdf.dummy_django_app.static_urls")
def test_pdf_export_invalid(load_test_data, client, admin_client):
"""
Test whether the PDF export throws the correct errors
:param load_test_data: The fixture providing the test data (see :meth:`~tests.conftest.load_test_data`)
:type load_test_data: tuple
:param client: The fixture providing the anonymous user
:type client: :fixture:`client`
:param admin_client: The fixture providing the logged in admin
:type admin_client: :fixture:`admin_client`
"""
kwargs = {"region_slug": "augsburg", "language_slug": "de"}
# Test error when PDF is exported via page tree
export_pdf_cms = reverse("export_pdf", kwargs=kwargs)
response_cms = admin_client.post(export_pdf_cms, data={"selected_ids[]": [9999]})
# Test error when PDF is exported via API
export_pdf_api = reverse("api:pdf_export", kwargs=kwargs)
response_api = client.get(f"{export_pdf_api}?url=/augsburg/de/non-existing-page/")
# Test both the PDF generation of the CMS as well as the API
for response in [response_cms, response_api]:
print(response.headers)
assert response.status_code == 404

0 comments on commit 0d6fa42

Please sign in to comment.