mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-08-12 00:19:48 +00:00
![dependabot[bot]](/assets/img/avatar_default.png)
* Chore(deps): Bump the django group across 1 directory with 9 updates Bumps the django group with 9 updates in the / directory: | Package | From | To | | --- | --- | --- | | [django](https://github.com/django/django) | `5.1.8` | `5.2.5` | | [django-auditlog](https://github.com/jazzband/django-auditlog) | `3.1.2` | `3.2.1` | | [django-guardian](https://github.com/django-guardian/django-guardian) | `2.4.0` | `3.0.3` | | [django-multiselectfield](https://github.com/goinnn/django-multiselectfield) | `0.1.13` | `1.0.1` | | [django-soft-delete](https://github.com/san4ezy/django_softdelete) | `1.0.18` | `1.0.19` | | [djangorestframework](https://github.com/encode/django-rest-framework) | `3.16.0` | `3.16.1` | | [djangorestframework-guardian](https://github.com/rpkilby/django-rest-framework-guardian) | `0.3.0` | `0.4.0` | | [drf-spectacular-sidecar](https://github.com/tfranzel/drf-spectacular-sidecar) | `2025.4.1` | `2025.8.1` | | [pytest-django](https://github.com/pytest-dev/pytest-django) | `4.10.0` | `4.11.1` | Updates `django` from 5.1.8 to 5.2.5 - [Commits](https://github.com/django/django/compare/5.1.8...5.2.5) Updates `django-auditlog` from 3.1.2 to 3.2.1 - [Release notes](https://github.com/jazzband/django-auditlog/releases) - [Changelog](https://github.com/jazzband/django-auditlog/blob/master/CHANGELOG.md) - [Commits](https://github.com/jazzband/django-auditlog/compare/v3.1.2...v3.2.1) Updates `django-guardian` from 2.4.0 to 3.0.3 - [Release notes](https://github.com/django-guardian/django-guardian/releases) - [Commits](https://github.com/django-guardian/django-guardian/compare/v2.4.0...3.0.3) Updates `django-multiselectfield` from 0.1.13 to 1.0.1 - [Release notes](https://github.com/goinnn/django-multiselectfield/releases) - [Changelog](https://github.com/goinnn/django-multiselectfield/blob/master/CHANGES.rst) - [Commits](https://github.com/goinnn/django-multiselectfield/compare/v0.1.13...v1.0.1) Updates `django-soft-delete` from 1.0.18 to 1.0.19 - [Changelog](https://github.com/san4ezy/django_softdelete/blob/master/CHANGELOG.md) - [Commits](https://github.com/san4ezy/django_softdelete/commits) Updates `djangorestframework` from 3.16.0 to 3.16.1 - [Release notes](https://github.com/encode/django-rest-framework/releases) - [Commits](https://github.com/encode/django-rest-framework/compare/3.16.0...3.16.1) Updates `djangorestframework-guardian` from 0.3.0 to 0.4.0 - [Changelog](https://github.com/rpkilby/django-rest-framework-guardian/blob/master/CHANGELOG) - [Commits](https://github.com/rpkilby/django-rest-framework-guardian/compare/0.3.0...0.4.0) Updates `drf-spectacular-sidecar` from 2025.4.1 to 2025.8.1 - [Commits](https://github.com/tfranzel/drf-spectacular-sidecar/compare/2025.4.1...2025.8.1) Updates `pytest-django` from 4.10.0 to 4.11.1 - [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.10.0...v4.11.1) --- updated-dependencies: - dependency-name: django dependency-version: 5.2.5 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: django - dependency-name: django-auditlog dependency-version: 3.2.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: django - dependency-name: django-guardian dependency-version: 3.0.3 dependency-type: direct:production update-type: version-update:semver-major dependency-group: django - dependency-name: django-multiselectfield dependency-version: 1.0.1 dependency-type: direct:production update-type: version-update:semver-major dependency-group: django - dependency-name: django-soft-delete dependency-version: 1.0.19 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: django - dependency-name: djangorestframework dependency-version: 3.16.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: django - dependency-name: djangorestframework-guardian dependency-version: 0.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: django - dependency-name: drf-spectacular-sidecar dependency-version: 2025.8.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: django - dependency-name: pytest-django dependency-version: 4.11.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: django ... Signed-off-by: dependabot[bot] <support@github.com> * Fix log matches related to newlines, add newlines to stdout.writelines * Fix disable api remote auth test, Django 5.2 no longer uses process_request * Remove postgres version check * Update administration.md * Handle django-multiselectfield v1.0 changes * Update administration.md --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
265 lines
7.6 KiB
Python
265 lines
7.6 KiB
Python
import os
|
|
from pathlib import Path
|
|
from unittest import mock
|
|
|
|
from django.test import TestCase
|
|
from django.test import override_settings
|
|
|
|
from documents.tests.utils import DirectoriesMixin
|
|
from documents.tests.utils import FileSystemAssertsMixin
|
|
from paperless.checks import audit_log_check
|
|
from paperless.checks import binaries_check
|
|
from paperless.checks import debug_mode_check
|
|
from paperless.checks import paths_check
|
|
from paperless.checks import settings_values_check
|
|
|
|
|
|
class TestChecks(DirectoriesMixin, TestCase):
|
|
def test_binaries(self):
|
|
self.assertEqual(binaries_check(None), [])
|
|
|
|
@override_settings(CONVERT_BINARY="uuuhh")
|
|
def test_binaries_fail(self):
|
|
self.assertEqual(len(binaries_check(None)), 1)
|
|
|
|
def test_paths_check(self):
|
|
self.assertEqual(paths_check(None), [])
|
|
|
|
@override_settings(
|
|
MEDIA_ROOT=Path("uuh"),
|
|
DATA_DIR=Path("whatever"),
|
|
CONSUMPTION_DIR=Path("idontcare"),
|
|
)
|
|
def test_paths_check_dont_exist(self):
|
|
msgs = paths_check(None)
|
|
self.assertEqual(len(msgs), 3, str(msgs))
|
|
|
|
for msg in msgs:
|
|
self.assertTrue(msg.msg.endswith("is set but doesn't exist."))
|
|
|
|
def test_paths_check_no_access(self):
|
|
Path(self.dirs.data_dir).chmod(0o000)
|
|
Path(self.dirs.media_dir).chmod(0o000)
|
|
Path(self.dirs.consumption_dir).chmod(0o000)
|
|
|
|
self.addCleanup(os.chmod, self.dirs.data_dir, 0o777)
|
|
self.addCleanup(os.chmod, self.dirs.media_dir, 0o777)
|
|
self.addCleanup(os.chmod, self.dirs.consumption_dir, 0o777)
|
|
|
|
msgs = paths_check(None)
|
|
self.assertEqual(len(msgs), 3)
|
|
|
|
for msg in msgs:
|
|
self.assertTrue(msg.msg.endswith("is not writeable"))
|
|
|
|
@override_settings(DEBUG=False)
|
|
def test_debug_disabled(self):
|
|
self.assertEqual(debug_mode_check(None), [])
|
|
|
|
@override_settings(DEBUG=True)
|
|
def test_debug_enabled(self):
|
|
self.assertEqual(len(debug_mode_check(None)), 1)
|
|
|
|
|
|
class TestSettingsChecksAgainstDefaults(DirectoriesMixin, TestCase):
|
|
def test_all_valid(self):
|
|
"""
|
|
GIVEN:
|
|
- Default settings
|
|
WHEN:
|
|
- Settings are validated
|
|
THEN:
|
|
- No system check errors reported
|
|
"""
|
|
msgs = settings_values_check(None)
|
|
self.assertEqual(len(msgs), 0)
|
|
|
|
|
|
class TestOcrSettingsChecks(DirectoriesMixin, TestCase):
|
|
@override_settings(OCR_OUTPUT_TYPE="notapdf")
|
|
def test_invalid_output_type(self):
|
|
"""
|
|
GIVEN:
|
|
- Default settings
|
|
- OCR output type is invalid
|
|
WHEN:
|
|
- Settings are validated
|
|
THEN:
|
|
- system check error reported for OCR output type
|
|
"""
|
|
msgs = settings_values_check(None)
|
|
self.assertEqual(len(msgs), 1)
|
|
|
|
msg = msgs[0]
|
|
|
|
self.assertIn('OCR output type "notapdf"', msg.msg)
|
|
|
|
@override_settings(OCR_MODE="makeitso")
|
|
def test_invalid_ocr_type(self):
|
|
"""
|
|
GIVEN:
|
|
- Default settings
|
|
- OCR type is invalid
|
|
WHEN:
|
|
- Settings are validated
|
|
THEN:
|
|
- system check error reported for OCR type
|
|
"""
|
|
msgs = settings_values_check(None)
|
|
self.assertEqual(len(msgs), 1)
|
|
|
|
msg = msgs[0]
|
|
|
|
self.assertIn('OCR output mode "makeitso"', msg.msg)
|
|
|
|
@override_settings(OCR_MODE="skip_noarchive")
|
|
def test_deprecated_ocr_type(self):
|
|
"""
|
|
GIVEN:
|
|
- Default settings
|
|
- OCR type is deprecated
|
|
WHEN:
|
|
- Settings are validated
|
|
THEN:
|
|
- deprecation warning reported for OCR type
|
|
"""
|
|
msgs = settings_values_check(None)
|
|
self.assertEqual(len(msgs), 1)
|
|
|
|
msg = msgs[0]
|
|
|
|
self.assertIn("deprecated", msg.msg)
|
|
|
|
@override_settings(OCR_SKIP_ARCHIVE_FILE="invalid")
|
|
def test_invalid_ocr_skip_archive_file(self):
|
|
"""
|
|
GIVEN:
|
|
- Default settings
|
|
- OCR_SKIP_ARCHIVE_FILE is invalid
|
|
WHEN:
|
|
- Settings are validated
|
|
THEN:
|
|
- system check error reported for OCR_SKIP_ARCHIVE_FILE
|
|
"""
|
|
msgs = settings_values_check(None)
|
|
self.assertEqual(len(msgs), 1)
|
|
|
|
msg = msgs[0]
|
|
|
|
self.assertIn('OCR_SKIP_ARCHIVE_FILE setting "invalid"', msg.msg)
|
|
|
|
@override_settings(OCR_CLEAN="cleanme")
|
|
def test_invalid_ocr_clean(self):
|
|
"""
|
|
GIVEN:
|
|
- Default settings
|
|
- OCR cleaning type is invalid
|
|
WHEN:
|
|
- Settings are validated
|
|
THEN:
|
|
- system check error reported for OCR cleaning type
|
|
"""
|
|
msgs = settings_values_check(None)
|
|
self.assertEqual(len(msgs), 1)
|
|
|
|
msg = msgs[0]
|
|
|
|
self.assertIn('OCR clean mode "cleanme"', msg.msg)
|
|
|
|
|
|
class TestTimezoneSettingsChecks(DirectoriesMixin, TestCase):
|
|
@override_settings(TIME_ZONE="TheMoon\\MyCrater")
|
|
def test_invalid_timezone(self):
|
|
"""
|
|
GIVEN:
|
|
- Default settings
|
|
- Timezone is invalid
|
|
WHEN:
|
|
- Settings are validated
|
|
THEN:
|
|
- system check error reported for timezone
|
|
"""
|
|
msgs = settings_values_check(None)
|
|
self.assertEqual(len(msgs), 1)
|
|
|
|
msg = msgs[0]
|
|
|
|
self.assertIn('Timezone "TheMoon\\MyCrater"', msg.msg)
|
|
|
|
|
|
class TestBarcodeSettingsChecks(DirectoriesMixin, TestCase):
|
|
@override_settings(CONSUMER_BARCODE_SCANNER="Invalid")
|
|
def test_barcode_scanner_invalid(self):
|
|
msgs = settings_values_check(None)
|
|
self.assertEqual(len(msgs), 1)
|
|
|
|
msg = msgs[0]
|
|
|
|
self.assertIn('Invalid Barcode Scanner "Invalid"', msg.msg)
|
|
|
|
@override_settings(CONSUMER_BARCODE_SCANNER="")
|
|
def test_barcode_scanner_empty(self):
|
|
msgs = settings_values_check(None)
|
|
self.assertEqual(len(msgs), 1)
|
|
|
|
msg = msgs[0]
|
|
|
|
self.assertIn('Invalid Barcode Scanner ""', msg.msg)
|
|
|
|
@override_settings(CONSUMER_BARCODE_SCANNER="PYZBAR")
|
|
def test_barcode_scanner_valid(self):
|
|
msgs = settings_values_check(None)
|
|
self.assertEqual(len(msgs), 0)
|
|
|
|
|
|
class TestEmailCertSettingsChecks(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
|
|
@override_settings(EMAIL_CERTIFICATE_FILE=Path("/tmp/not_actually_here.pem"))
|
|
def test_not_valid_file(self):
|
|
"""
|
|
GIVEN:
|
|
- Default settings
|
|
- Email certificate is set
|
|
WHEN:
|
|
- Email certificate file doesn't exist
|
|
THEN:
|
|
- system check error reported for email certificate
|
|
"""
|
|
self.assertIsNotFile("/tmp/not_actually_here.pem")
|
|
|
|
msgs = settings_values_check(None)
|
|
|
|
self.assertEqual(len(msgs), 1)
|
|
|
|
msg = msgs[0]
|
|
|
|
self.assertIn("Email cert /tmp/not_actually_here.pem is not a file", msg.msg)
|
|
|
|
|
|
class TestAuditLogChecks(TestCase):
|
|
def test_was_enabled_once(self):
|
|
"""
|
|
GIVEN:
|
|
- Audit log is not enabled
|
|
WHEN:
|
|
- Database tables contain audit log entry
|
|
THEN:
|
|
- system check error reported for disabling audit log
|
|
"""
|
|
introspect_mock = mock.MagicMock()
|
|
introspect_mock.introspection.table_names.return_value = ["auditlog_logentry"]
|
|
with override_settings(AUDIT_LOG_ENABLED=False):
|
|
with mock.patch.dict(
|
|
"paperless.checks.connections",
|
|
{"default": introspect_mock},
|
|
):
|
|
msgs = audit_log_check(None)
|
|
|
|
self.assertEqual(len(msgs), 1)
|
|
|
|
msg = msgs[0]
|
|
|
|
self.assertIn(
|
|
("auditlog table was found but audit log is disabled."),
|
|
msg.msg,
|
|
)
|