Chore: Move the four duplicated parser sample PDFs into a shared paperless_testing location

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Trenton HandClaude Sonnet 5.5 committed 2026-10-22 10:40:01 -07:00
1 parent d872e456ab
commit 28255668b9
10 files changed
+99 -78

No files matched your search

+2 -2
View File
@@ -256,8 +256,8 @@ isort.force-single-line = true
[tool.codespell]
ignore-words-list = "criterias,afterall,valeu,ureue,equest,ure,assertIn,Oktober,commitish,NIN,nin,reprot"
skip = """\
src-ui/src/locale/*,src-ui/pnpm-lock.yaml,src-ui/e2e/*,src/paperless_mail/tests/samples/*,src/paperless/tests/samples\
/mail/*,src/documents/tests/samples/*,*.po,*.json\
src-ui/src/locale/*,src-ui/pnpm-lock.yaml,src-ui/e2e/*,src/paperless/tests/samples/mail/*,src/documents/tests/samples\
/*,src/paperless_testing/sample_files/*,*.po,*.json\
"""
write-changes = true
+32
View File
@@ -11,6 +11,8 @@ from typing import TYPE_CHECKING
import pytest
from paperless_testing import samples
if TYPE_CHECKING:
from collections.abc import Generator
from pathlib import Path
@@ -149,3 +151,33 @@ def fake_progress_manager(
monkeypatch.setattr("documents.tasks.ProgressManager", FakeProgressManager)
return FakeProgressManager
@pytest.fixture(scope="session")
def shared_samples_dir() -> Path:
"""Directory of sample files used by more than one app's tests."""
return samples.SHARED_SAMPLES_DIR
@pytest.fixture(scope="session")
def simple_digital_pdf_file() -> Path:
"""One-page PDF with a text layer."""
return samples.SIMPLE_DIGITAL_PDF
@pytest.fixture(scope="session")
def multi_page_digital_pdf_file() -> Path:
"""Three-page PDF with a text layer."""
return samples.MULTI_PAGE_DIGITAL_PDF
@pytest.fixture(scope="session")
def with_form_pdf_file() -> Path:
"""PDF containing a fillable form."""
return samples.WITH_FORM_PDF
@pytest.fixture(scope="session")
def multi_page_images_pdf_file() -> Path:
"""Multi-page PDF of scanned images, no text layer."""
return samples.MULTI_PAGE_IMAGES_PDF
-24
View File
@@ -432,30 +432,6 @@ def tesseract_samples_dir(parser_samples_dir: Path) -> Path:
return parser_samples_dir / "tesseract"
@pytest.fixture(scope="session")
def multi_page_images_pdf_file(tesseract_samples_dir: Path) -> Path:
"""Path to a multi-page PDF with images.
Returns
-------
Path
Absolute path to ``tesseract/multi-page-images.pdf``.
"""
return tesseract_samples_dir / "multi-page-images.pdf"
@pytest.fixture(scope="session")
def simple_digital_pdf_file(tesseract_samples_dir: Path) -> Path:
"""Path to a simple digital PDF sample file.
Returns
-------
Path
Absolute path to ``tesseract/simple-digital.pdf``.
"""
return tesseract_samples_dir / "simple-digital.pdf"
@pytest.fixture(scope="session")
def simple_no_dpi_png_file(tesseract_samples_dir: Path) -> Path:
"""Path to a simple PNG without DPI information.
@@ -161,11 +161,11 @@ class TestGetPageCount:
def test_single_page_pdf(
self,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
simple_digital_pdf_file: Path,
) -> None:
assert (
tesseract_parser.get_page_count(
tesseract_samples_dir / "simple-digital.pdf",
simple_digital_pdf_file,
"application/pdf",
)
== 1
@@ -188,7 +188,7 @@ class TestGetPageCount:
self,
mocker: MockerFixture,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
simple_digital_pdf_file: Path,
caplog,
) -> None:
"""
@@ -204,7 +204,7 @@ class TestGetPageCount:
with caplog.at_level(logging.WARNING):
page_count = tesseract_parser.get_page_count(
tesseract_samples_dir / "simple-digital.pdf",
simple_digital_pdf_file,
"application/pdf",
)
assert page_count is None
@@ -273,10 +273,10 @@ class TestGetThumbnail:
def test_thumbnail_is_file(
self,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
simple_digital_pdf_file: Path,
) -> None:
thumb = tesseract_parser.get_thumbnail(
tesseract_samples_dir / "simple-digital.pdf",
simple_digital_pdf_file,
"application/pdf",
)
assert thumb.is_file()
@@ -316,7 +316,7 @@ class TestGetThumbnail:
self,
mocker: MockerFixture,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
simple_digital_pdf_file: Path,
) -> None:
"""
GIVEN:
@@ -326,7 +326,7 @@ class TestGetThumbnail:
THEN:
- The PDF is repaired with qpdf and a real thumbnail is rendered
"""
original = tesseract_samples_dir / "simple-digital.pdf"
original = simple_digital_pdf_file
def _fail_on_original(in_path: Path, out_path: Path, **kwargs) -> None:
if in_path == original:
@@ -368,11 +368,11 @@ class TestExtractText:
def test_extract_text_from_digital_pdf(
self,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
simple_digital_pdf_file: Path,
) -> None:
text = tesseract_parser.extract_text(
None,
tesseract_samples_dir / "simple-digital.pdf",
simple_digital_pdf_file,
)
assert text is not None
assert "This is a test document." in text.strip()
@@ -387,7 +387,7 @@ class TestParsePdf:
def test_simple_digital_creates_archive(
self,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
multi_page_digital_pdf_file: Path,
) -> None:
"""
GIVEN:
@@ -401,7 +401,7 @@ class TestParsePdf:
- Text is extracted
"""
tesseract_parser.parse(
tesseract_samples_dir / "multi-page-digital.pdf",
multi_page_digital_pdf_file,
"application/pdf",
)
assert tesseract_parser.archive_path is not None
@@ -416,10 +416,10 @@ class TestParsePdf:
def test_with_form_default(
self,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
with_form_pdf_file: Path,
) -> None:
tesseract_parser.parse(
tesseract_samples_dir / "with-form.pdf",
with_form_pdf_file,
"application/pdf",
)
assert tesseract_parser.archive_path is not None
@@ -432,11 +432,11 @@ class TestParsePdf:
def test_with_form_redo_no_archive_when_not_requested(
self,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
with_form_pdf_file: Path,
) -> None:
tesseract_parser.settings.mode = ModeChoices.REDO
tesseract_parser.parse(
tesseract_samples_dir / "with-form.pdf",
with_form_pdf_file,
"application/pdf",
produce_archive=False,
)
@@ -449,11 +449,11 @@ class TestParsePdf:
def test_with_form_force(
self,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
with_form_pdf_file: Path,
) -> None:
tesseract_parser.settings.mode = ModeChoices.FORCE
tesseract_parser.parse(
tesseract_samples_dir / "with-form.pdf",
with_form_pdf_file,
"application/pdf",
)
assert_ordered_substrings(
@@ -494,7 +494,7 @@ class TestParsePdf:
self,
mocker: MockerFixture,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
simple_digital_pdf_file: Path,
) -> None:
mocker.patch(
"ocrmypdf.ocr",
@@ -502,7 +502,7 @@ class TestParsePdf:
)
with pytest.raises(ParseError):
tesseract_parser.parse(
tesseract_samples_dir / "simple-digital.pdf",
simple_digital_pdf_file,
"application/pdf",
)
@@ -578,10 +578,10 @@ class TestParseMultiPage:
def test_multi_page_digital(
self,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
multi_page_digital_pdf_file: Path,
) -> None:
tesseract_parser.parse(
tesseract_samples_dir / "multi-page-digital.pdf",
multi_page_digital_pdf_file,
"application/pdf",
)
assert tesseract_parser.archive_path is not None
@@ -605,12 +605,12 @@ class TestParseMultiPage:
self,
mode: str,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
multi_page_digital_pdf_file: Path,
) -> None:
tesseract_parser.settings.pages = 2
tesseract_parser.settings.mode = mode
tesseract_parser.parse(
tesseract_samples_dir / "multi-page-digital.pdf",
multi_page_digital_pdf_file,
"application/pdf",
)
assert tesseract_parser.archive_path is not None
@@ -624,11 +624,11 @@ class TestParseMultiPage:
def test_multi_page_images_skip(
self,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
multi_page_images_pdf_file: Path,
) -> None:
tesseract_parser.settings.mode = ModeChoices.AUTO
tesseract_parser.parse(
tesseract_samples_dir / "multi-page-images.pdf",
multi_page_images_pdf_file,
"application/pdf",
)
assert tesseract_parser.archive_path is not None
@@ -642,7 +642,7 @@ class TestParseMultiPage:
def test_multi_page_images_redo_pages_2(
self,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
multi_page_images_pdf_file: Path,
) -> None:
"""
GIVEN:
@@ -657,7 +657,7 @@ class TestParseMultiPage:
tesseract_parser.settings.pages = 2
tesseract_parser.settings.mode = ModeChoices.REDO
tesseract_parser.parse(
tesseract_samples_dir / "multi-page-images.pdf",
multi_page_images_pdf_file,
"application/pdf",
)
assert tesseract_parser.archive_path is not None
@@ -670,7 +670,7 @@ class TestParseMultiPage:
def test_multi_page_images_force_page_1(
self,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
multi_page_images_pdf_file: Path,
) -> None:
"""
GIVEN:
@@ -685,7 +685,7 @@ class TestParseMultiPage:
tesseract_parser.settings.pages = 1
tesseract_parser.settings.mode = ModeChoices.FORCE
tesseract_parser.parse(
tesseract_samples_dir / "multi-page-images.pdf",
multi_page_images_pdf_file,
"application/pdf",
)
assert tesseract_parser.archive_path is not None
@@ -781,7 +781,7 @@ class TestSkipArchive:
def test_skip_noarchive_with_text_layer(
self,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
multi_page_digital_pdf_file: Path,
) -> None:
"""
GIVEN:
@@ -795,7 +795,7 @@ class TestSkipArchive:
"""
tesseract_parser.settings.mode = ModeChoices.AUTO
tesseract_parser.parse(
tesseract_samples_dir / "multi-page-digital.pdf",
multi_page_digital_pdf_file,
"application/pdf",
produce_archive=False,
)
@@ -810,7 +810,7 @@ class TestSkipArchive:
def test_skip_noarchive_image_only_creates_archive(
self,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
multi_page_images_pdf_file: Path,
) -> None:
"""
GIVEN:
@@ -823,7 +823,7 @@ class TestSkipArchive:
"""
tesseract_parser.settings.mode = ModeChoices.AUTO
tesseract_parser.parse(
tesseract_samples_dir / "multi-page-images.pdf",
multi_page_images_pdf_file,
"application/pdf",
)
assert tesseract_parser.archive_path is not None
@@ -835,29 +835,29 @@ class TestSkipArchive:
)
@pytest.mark.parametrize(
("produce_archive", "filename", "expect_archive"),
("produce_archive", "sample_fixture", "expect_archive"),
[
pytest.param(
True,
"multi-page-digital.pdf",
"multi_page_digital_pdf_file",
True,
id="produce-archive-with-text",
),
pytest.param(
True,
"multi-page-images.pdf",
"multi_page_images_pdf_file",
True,
id="produce-archive-no-text",
),
pytest.param(
False,
"multi-page-digital.pdf",
"multi_page_digital_pdf_file",
False,
id="no-archive-with-text-layer",
),
pytest.param(
False,
"multi-page-images.pdf",
"multi_page_images_pdf_file",
False,
id="no-archive-no-text-layer",
),
@@ -866,10 +866,10 @@ class TestSkipArchive:
def test_produce_archive_flag(
self,
produce_archive: bool, # noqa: FBT001
filename: str,
sample_fixture: str,
expect_archive: bool, # noqa: FBT001
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
request: pytest.FixtureRequest,
) -> None:
"""
GIVEN:
@@ -882,8 +882,9 @@ class TestSkipArchive:
- Text is always extracted
"""
tesseract_parser.settings.mode = ModeChoices.AUTO
sample = request.getfixturevalue(sample_fixture)
tesseract_parser.parse(
tesseract_samples_dir / filename,
sample,
"application/pdf",
produce_archive=produce_archive,
)
@@ -900,7 +901,7 @@ class TestSkipArchive:
self,
mocker: MockerFixture,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
simple_digital_pdf_file: Path,
) -> None:
"""
GIVEN:
@@ -916,7 +917,7 @@ class TestSkipArchive:
tesseract_parser.settings.mode = ModeChoices.AUTO
mock_ocr = mocker.patch("ocrmypdf.ocr")
tesseract_parser.parse(
tesseract_samples_dir / "simple-digital.pdf",
simple_digital_pdf_file,
"application/pdf",
produce_archive=False,
)
@@ -955,7 +956,7 @@ class TestSkipArchive:
def test_tagged_pdf_produces_pdfa_archive_without_ocr(
self,
tesseract_parser: RasterisedDocumentParser,
tesseract_samples_dir: Path,
simple_digital_pdf_file: Path,
) -> None:
"""
GIVEN:
@@ -970,7 +971,7 @@ class TestSkipArchive:
"""
tesseract_parser.settings.mode = ModeChoices.AUTO
tesseract_parser.parse(
tesseract_samples_dir / "simple-digital.pdf",
simple_digital_pdf_file,
"application/pdf",
produce_archive=True,
)
+4 -6
View File
@@ -18,8 +18,6 @@ from paperless.parsers.utils import read_file_handle_unicode_errors
if TYPE_CHECKING:
from pytest_mock import MockerFixture
SAMPLES = Path(__file__).parent / "samples" / "tesseract"
class TestReadFileHandleUnicodeErrors:
def test_plain_utf8(self, tmp_path: Path) -> None:
@@ -57,11 +55,11 @@ class TestReadFileHandleUnicodeErrors:
class TestIsTaggedPdf:
def test_tagged_pdf_returns_true(self) -> None:
assert is_tagged_pdf(SAMPLES / "simple-digital.pdf") is True
def test_tagged_pdf_returns_true(self, simple_digital_pdf_file: Path) -> None:
assert is_tagged_pdf(simple_digital_pdf_file) is True
def test_untagged_pdf_returns_false(self) -> None:
assert is_tagged_pdf(SAMPLES / "multi-page-images.pdf") is False
def test_untagged_pdf_returns_false(self, multi_page_images_pdf_file: Path) -> None:
assert is_tagged_pdf(multi_page_images_pdf_file) is False
def test_nonexistent_path_returns_false(self) -> None:
assert is_tagged_pdf(Path("/nonexistent/file.pdf")) is False
+14
View File
@@ -0,0 +1,14 @@
"""Test sample files that more than one app's tests need.
A sample used by a single app stays in that app's ``tests/samples`` tree.
Only a file that two or more apps need lives here, exactly once.
"""
from pathlib import Path
SHARED_SAMPLES_DIR = (Path(__file__).parent / "sample_files").resolve()
SIMPLE_DIGITAL_PDF = SHARED_SAMPLES_DIR / "simple-digital.pdf"
MULTI_PAGE_DIGITAL_PDF = SHARED_SAMPLES_DIR / "multi-page-digital.pdf"
WITH_FORM_PDF = SHARED_SAMPLES_DIR / "with-form.pdf"
MULTI_PAGE_IMAGES_PDF = SHARED_SAMPLES_DIR / "multi-page-images.pdf"