mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-09-11 04:08:00 +00:00
* Chore(deps): Bump the utilities-minor group across 1 directory with 11 updates Bumps the utilities-minor group with 11 updates in the / directory: | Package | From | To | | --- | --- | --- | | [django-guardian](https://github.com/django-guardian/django-guardian) | `3.3.3` | `3.4.0` | | [django-treenode](https://github.com/fabiocaccamo/django-treenode) | `0.24.0` | `0.25.0` | | [drf-spectacular-sidecar](https://github.com/tfranzel/drf-spectacular-sidecar) | `2026.7.1` | `2026.8.1` | | [imap-tools](https://github.com/ikvk/imap_tools) | `1.14.0` | `1.15.0` | | [ocrmypdf](https://github.com/ocrmypdf/OCRmyPDF) | `17.10.0` | `17.11.0` | | [prek](https://github.com/j178/prek) | `0.4.11` | `0.5.0` | | [faker](https://github.com/joke2k/faker) | `40.36.0` | `40.37.0` | | [pytest-django](https://github.com/pytest-dev/pytest-django) | `4.12.0` | `4.14.0` | | [pytest-rerunfailures](https://github.com/pytest-dev/pytest-rerunfailures) | `16.4` | `16.6` | | [time-machine](https://github.com/adamchainz/time-machine) | `3.2.0` | `3.5.0` | | [types-pygments](https://github.com/python/typeshed) | `2.20.0.20260408` | `2.21.0.20260819` | Updates `django-guardian` from 3.3.3 to 3.4.0 - [Release notes](https://github.com/django-guardian/django-guardian/releases) - [Commits](https://github.com/django-guardian/django-guardian/compare/3.3.3...3.4.0) Updates `django-treenode` from 0.24.0 to 0.25.0 - [Release notes](https://github.com/fabiocaccamo/django-treenode/releases) - [Changelog](https://github.com/fabiocaccamo/django-treenode/blob/main/CHANGELOG.md) - [Commits](https://github.com/fabiocaccamo/django-treenode/compare/0.24.0...0.25.0) Updates `drf-spectacular-sidecar` from 2026.7.1 to 2026.8.1 - [Commits](https://github.com/tfranzel/drf-spectacular-sidecar/compare/2026.7.1...2026.8.1) Updates `imap-tools` from 1.14.0 to 1.15.0 - [Release notes](https://github.com/ikvk/imap_tools/releases) - [Changelog](https://github.com/ikvk/imap_tools/blob/master/docs/release_notes.rst) - [Commits](https://github.com/ikvk/imap_tools/compare/v1.14.0...v1.15.0) Updates `ocrmypdf` from 17.10.0 to 17.11.0 - [Release notes](https://github.com/ocrmypdf/OCRmyPDF/releases) - [Commits](https://github.com/ocrmypdf/OCRmyPDF/compare/v17.10.0...v17.11.0) Updates `prek` from 0.4.11 to 0.5.0 - [Release notes](https://github.com/j178/prek/releases) - [Changelog](https://github.com/j178/prek/blob/master/CHANGELOG.md) - [Commits](https://github.com/j178/prek/compare/v0.4.11...v0.5.0) Updates `faker` from 40.36.0 to 40.37.0 - [Release notes](https://github.com/joke2k/faker/releases) - [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) - [Commits](https://github.com/joke2k/faker/compare/v40.36.0...v40.37.0) Updates `pytest-django` from 4.12.0 to 4.14.0 - [Release notes](https://github.com/pytest-dev/pytest-django/releases) - [Changelog](https://github.com/pytest-dev/pytest-django/blob/main/docs/changelog.rst) - [Commits](https://github.com/pytest-dev/pytest-django/compare/v4.12.0...v4.14.0) Updates `pytest-rerunfailures` from 16.4 to 16.6 - [Changelog](https://github.com/pytest-dev/pytest-rerunfailures/blob/master/CHANGES.rst) - [Commits](https://github.com/pytest-dev/pytest-rerunfailures/compare/16.4...16.6) Updates `time-machine` from 3.2.0 to 3.5.0 - [Changelog](https://github.com/adamchainz/time-machine/blob/main/docs/changelog.rst) - [Commits](https://github.com/adamchainz/time-machine/compare/3.2.0...3.5.0) Updates `types-pygments` from 2.20.0.20260408 to 2.21.0.20260819 - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: django-guardian dependency-version: 3.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: utilities-minor - dependency-name: django-treenode dependency-version: 0.25.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: utilities-minor - dependency-name: drf-spectacular-sidecar dependency-version: 2026.8.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: utilities-minor - dependency-name: faker dependency-version: 40.37.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: utilities-minor - dependency-name: imap-tools dependency-version: 1.15.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: utilities-minor - dependency-name: ocrmypdf dependency-version: 17.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: utilities-minor - dependency-name: prek dependency-version: 0.5.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: utilities-minor - dependency-name: pytest-django dependency-version: 4.14.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: utilities-minor - dependency-name: pytest-rerunfailures dependency-version: '16.6' dependency-type: direct:development update-type: version-update:semver-minor dependency-group: utilities-minor - dependency-name: time-machine dependency-version: 3.5.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: utilities-minor - dependency-name: types-pygments dependency-version: 2.21.0.20260819 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: utilities-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Handles pytest-django * Formatting --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Trenton Holmes <797416+stumpylog@users.noreply.github.com>
185 lines
5.6 KiB
Python
185 lines
5.6 KiB
Python
import shutil
|
|
import zoneinfo
|
|
from collections.abc import Generator
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
from typing import TYPE_CHECKING
|
|
|
|
import filelock
|
|
import pytest
|
|
from django.contrib.auth import get_user_model
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from guardian.shortcuts import clear_ct_cache
|
|
from pytest_django.fixtures import Settings
|
|
from rest_framework.test import APIClient
|
|
|
|
from documents.tests.factories import DocumentFactory
|
|
|
|
UserModelT = get_user_model()
|
|
|
|
if TYPE_CHECKING:
|
|
from documents.models import Document
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class PaperlessDirs:
|
|
"""Standard Paperless-ngx directory layout for tests."""
|
|
|
|
media: Path
|
|
originals: Path
|
|
archive: Path
|
|
thumbnails: Path
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def samples_dir() -> Path:
|
|
"""Path to the shared test sample documents."""
|
|
return Path(__file__).parent / "samples" / "documents"
|
|
|
|
|
|
@pytest.fixture()
|
|
def paperless_dirs(tmp_path: Path) -> PaperlessDirs:
|
|
"""Create and return the directory structure for testing."""
|
|
media = tmp_path / "media"
|
|
dirs = PaperlessDirs(
|
|
media=media,
|
|
originals=media / "documents" / "originals",
|
|
archive=media / "documents" / "archive",
|
|
thumbnails=media / "documents" / "thumbnails",
|
|
)
|
|
for d in (dirs.originals, dirs.archive, dirs.thumbnails):
|
|
d.mkdir(parents=True)
|
|
return dirs
|
|
|
|
|
|
@pytest.fixture()
|
|
def _media_settings(paperless_dirs: PaperlessDirs, settings) -> None:
|
|
"""Configure Django settings to point at temp directories."""
|
|
settings.MEDIA_ROOT = paperless_dirs.media
|
|
settings.ORIGINALS_DIR = paperless_dirs.originals
|
|
settings.ARCHIVE_DIR = paperless_dirs.archive
|
|
settings.THUMBNAIL_DIR = paperless_dirs.thumbnails
|
|
settings.MEDIA_LOCK = paperless_dirs.media / "media.lock"
|
|
settings.IGNORABLE_FILES = {".DS_Store", "Thumbs.db", "desktop.ini"}
|
|
settings.APP_LOGO = ""
|
|
|
|
|
|
@pytest.fixture()
|
|
def sample_doc(
|
|
paperless_dirs: PaperlessDirs,
|
|
_media_settings: None,
|
|
samples_dir: Path,
|
|
) -> "Document":
|
|
"""Create a document with valid files and matching checksums."""
|
|
with filelock.FileLock(paperless_dirs.media / "media.lock"):
|
|
shutil.copy(
|
|
samples_dir / "originals" / "0000001.pdf",
|
|
paperless_dirs.originals / "0000001.pdf",
|
|
)
|
|
shutil.copy(
|
|
samples_dir / "archive" / "0000001.pdf",
|
|
paperless_dirs.archive / "0000001.pdf",
|
|
)
|
|
shutil.copy(
|
|
samples_dir / "thumbnails" / "0000001.webp",
|
|
paperless_dirs.thumbnails / "0000001.webp",
|
|
)
|
|
|
|
return DocumentFactory(
|
|
title="test",
|
|
checksum="1093cf6e32adbd16b06969df09215d42c4a3a8938cc18b39455953f08d1ff2ab",
|
|
archive_checksum="706124ecde3c31616992fa979caed17a726b1c9ccdba70e82a4ff796cea97ccf",
|
|
content="test content",
|
|
pk=1,
|
|
filename="0000001.pdf",
|
|
mime_type="application/pdf",
|
|
archive_filename="0000001.pdf",
|
|
)
|
|
|
|
|
|
@pytest.fixture()
|
|
def _search_index(
|
|
tmp_path: Path,
|
|
settings: Settings,
|
|
) -> Generator[None, None, None]:
|
|
"""Create a temp index directory and point INDEX_DIR at it.
|
|
|
|
Resets the backend singleton before and after so each test gets a clean
|
|
index rather than reusing a stale singleton from another test.
|
|
"""
|
|
from documents.search import reset_backend
|
|
|
|
index_dir = tmp_path / "index"
|
|
index_dir.mkdir()
|
|
settings.INDEX_DIR = index_dir
|
|
reset_backend()
|
|
yield
|
|
reset_backend()
|
|
|
|
|
|
@pytest.fixture()
|
|
def settings_timezone(settings: Settings) -> zoneinfo.ZoneInfo:
|
|
return zoneinfo.ZoneInfo(settings.TIME_ZONE)
|
|
|
|
|
|
@pytest.fixture
|
|
def rest_api_client():
|
|
"""
|
|
The basic DRF ApiClient
|
|
"""
|
|
yield APIClient()
|
|
|
|
|
|
@pytest.fixture()
|
|
def regular_user(django_user_model: type[UserModelT]) -> UserModelT:
|
|
"""Unprivileged authenticated user for permission boundary tests."""
|
|
return django_user_model.objects.create_user(username="regular", password="regular")
|
|
|
|
|
|
@pytest.fixture()
|
|
def admin_client(rest_api_client: APIClient, admin_user: UserModelT) -> APIClient:
|
|
"""Admin client pre-authenticated and sending the v10 Accept header."""
|
|
rest_api_client.force_authenticate(user=admin_user)
|
|
rest_api_client.credentials(HTTP_ACCEPT="application/json; version=10")
|
|
return rest_api_client
|
|
|
|
|
|
@pytest.fixture()
|
|
def v9_client(rest_api_client: APIClient, admin_user: UserModelT) -> APIClient:
|
|
"""Admin client pre-authenticated and sending the v9 Accept header."""
|
|
rest_api_client.force_authenticate(user=admin_user)
|
|
rest_api_client.credentials(HTTP_ACCEPT="application/json; version=9")
|
|
return rest_api_client
|
|
|
|
|
|
@pytest.fixture()
|
|
def user_client(rest_api_client: APIClient, regular_user: UserModelT) -> APIClient:
|
|
"""Regular-user client pre-authenticated and sending the v10 Accept header."""
|
|
rest_api_client.force_authenticate(user=regular_user)
|
|
rest_api_client.credentials(HTTP_ACCEPT="application/json; version=10")
|
|
return rest_api_client
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _clear_content_type_caches() -> None:
|
|
"""Clear Django's ContentType cache and guardian's lru_cache before each test.
|
|
|
|
Tests that delete and reinsert ContentType/Permission rows (e.g. the
|
|
importer) corrupt both caches. Without this fixture a subsequent test on
|
|
the same xdist worker sees stale ContentType objects and guardian raises
|
|
MixedContentTypeError.
|
|
"""
|
|
ContentType.objects.clear_cache()
|
|
clear_ct_cache()
|
|
|
|
|
|
@pytest.fixture(scope="session", autouse=True)
|
|
def faker_session_locale():
|
|
"""Set Faker locale for reproducibility."""
|
|
return "en_US"
|
|
|
|
|
|
@pytest.fixture(scope="session", autouse=True)
|
|
def faker_seed():
|
|
return 12345
|