mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-03-16 22:15:58 +00:00
Compare commits
4 Commits
fix-dont-u
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
470018c011 | ||
|
|
54679a093a | ||
|
|
58ebcc21be | ||
|
|
1caa3eb8aa |
@@ -205,7 +205,7 @@ class Command(CryptMixin, PaperlessCommand):
|
||||
ContentType.objects.all().delete()
|
||||
Permission.objects.all().delete()
|
||||
for manifest_path in self.manifest_paths:
|
||||
call_command("loaddata", manifest_path)
|
||||
call_command("loaddata", manifest_path, skip_checks=True)
|
||||
except (FieldDoesNotExist, DeserializationError, IntegrityError) as e:
|
||||
self.stdout.write(self.style.ERROR("Database import failed"))
|
||||
if (
|
||||
|
||||
@@ -163,13 +163,23 @@ class TestRenderResultsSummary:
|
||||
class TestDocumentSanityCheckerCommand:
|
||||
def test_no_issues(self, sample_doc: Document) -> None:
|
||||
out = StringIO()
|
||||
call_command("document_sanity_checker", "--no-progress-bar", stdout=out)
|
||||
call_command(
|
||||
"document_sanity_checker",
|
||||
"--no-progress-bar",
|
||||
stdout=out,
|
||||
skip_checks=True,
|
||||
)
|
||||
assert "No issues detected" in out.getvalue()
|
||||
|
||||
def test_missing_original(self, sample_doc: Document) -> None:
|
||||
Path(sample_doc.source_path).unlink()
|
||||
out = StringIO()
|
||||
call_command("document_sanity_checker", "--no-progress-bar", stdout=out)
|
||||
call_command(
|
||||
"document_sanity_checker",
|
||||
"--no-progress-bar",
|
||||
stdout=out,
|
||||
skip_checks=True,
|
||||
)
|
||||
output = out.getvalue()
|
||||
assert "ERROR" in output
|
||||
assert "Original of document does not exist" in output
|
||||
@@ -187,7 +197,12 @@ class TestDocumentSanityCheckerCommand:
|
||||
Path(doc.thumbnail_path).touch()
|
||||
|
||||
out = StringIO()
|
||||
call_command("document_sanity_checker", "--no-progress-bar", stdout=out)
|
||||
call_command(
|
||||
"document_sanity_checker",
|
||||
"--no-progress-bar",
|
||||
stdout=out,
|
||||
skip_checks=True,
|
||||
)
|
||||
output = out.getvalue()
|
||||
assert "ERROR" in output
|
||||
assert "Checksum mismatch. Stored: abc, actual:" in output
|
||||
|
||||
@@ -12,7 +12,12 @@ class TestApiSchema(APITestCase):
|
||||
Test that the schema is valid
|
||||
"""
|
||||
try:
|
||||
call_command("spectacular", "--validate", "--fail-on-warn")
|
||||
call_command(
|
||||
"spectacular",
|
||||
"--validate",
|
||||
"--fail-on-warn",
|
||||
skip_checks=True,
|
||||
)
|
||||
except CommandError as e:
|
||||
self.fail(f"Schema validation failed: {e}")
|
||||
|
||||
|
||||
@@ -26,6 +26,23 @@ class TestSystemStatus(APITestCase):
|
||||
self.override = override_settings(MEDIA_ROOT=self.tmp_dir)
|
||||
self.override.enable()
|
||||
|
||||
# Mock slow network calls so tests don't block on real Redis/Celery timeouts.
|
||||
# Individual tests that care about specific behaviour override these with
|
||||
# their own @mock.patch decorators (which take precedence).
|
||||
redis_patcher = mock.patch(
|
||||
"redis.Redis.execute_command",
|
||||
side_effect=Exception("Redis not available"),
|
||||
)
|
||||
self.mock_redis = redis_patcher.start()
|
||||
self.addCleanup(redis_patcher.stop)
|
||||
|
||||
celery_patcher = mock.patch(
|
||||
"celery.app.control.Inspect.ping",
|
||||
side_effect=Exception("Celery not available"),
|
||||
)
|
||||
self.mock_celery_ping = celery_patcher.start()
|
||||
self.addCleanup(celery_patcher.stop)
|
||||
|
||||
def tearDown(self) -> None:
|
||||
super().tearDown()
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ class TestArchiver(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
|
||||
doc = self.make_models()
|
||||
shutil.copy(sample_file, Path(self.dirs.originals_dir) / f"{doc.id:07}.pdf")
|
||||
|
||||
call_command("document_archiver", "--processes", "1")
|
||||
call_command("document_archiver", "--processes", "1", skip_checks=True)
|
||||
|
||||
def test_handle_document(self) -> None:
|
||||
doc = self.make_models()
|
||||
@@ -106,12 +106,12 @@ class TestArchiver(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
|
||||
class TestMakeIndex(TestCase):
|
||||
@mock.patch("documents.management.commands.document_index.index_reindex")
|
||||
def test_reindex(self, m) -> None:
|
||||
call_command("document_index", "reindex")
|
||||
call_command("document_index", "reindex", skip_checks=True)
|
||||
m.assert_called_once()
|
||||
|
||||
@mock.patch("documents.management.commands.document_index.index_optimize")
|
||||
def test_optimize(self, m) -> None:
|
||||
call_command("document_index", "optimize")
|
||||
call_command("document_index", "optimize", skip_checks=True)
|
||||
m.assert_called_once()
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ class TestRenamer(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
|
||||
Path(doc.archive_path).touch()
|
||||
|
||||
with override_settings(FILENAME_FORMAT="{correspondent}/{title}"):
|
||||
call_command("document_renamer")
|
||||
call_command("document_renamer", skip_checks=True)
|
||||
|
||||
doc2 = Document.objects.get(id=doc.id)
|
||||
|
||||
@@ -147,7 +147,7 @@ class TestCreateClassifier:
|
||||
"documents.management.commands.document_create_classifier.train_classifier",
|
||||
)
|
||||
|
||||
call_command("document_create_classifier", "--skip-checks")
|
||||
call_command("document_create_classifier", skip_checks=True)
|
||||
|
||||
m.assert_called_once_with(scheduled=False, status_callback=mocker.ANY)
|
||||
assert callable(m.call_args.kwargs["status_callback"])
|
||||
@@ -164,7 +164,7 @@ class TestCreateClassifier:
|
||||
m.side_effect = invoke_callback
|
||||
|
||||
stdout = StringIO()
|
||||
call_command("document_create_classifier", "--skip-checks", stdout=stdout)
|
||||
call_command("document_create_classifier", skip_checks=True, stdout=stdout)
|
||||
|
||||
assert "Vectorizing document content..." in stdout.getvalue()
|
||||
|
||||
@@ -176,7 +176,7 @@ class TestConvertMariaDBUUID(TestCase):
|
||||
m.alter_field.return_value = None
|
||||
|
||||
stdout = StringIO()
|
||||
call_command("convert_mariadb_uuid", stdout=stdout)
|
||||
call_command("convert_mariadb_uuid", stdout=stdout, skip_checks=True)
|
||||
|
||||
m.assert_called_once()
|
||||
|
||||
@@ -191,6 +191,6 @@ class TestPruneAuditLogs(TestCase):
|
||||
object_id=1,
|
||||
action=LogEntry.Action.CREATE,
|
||||
)
|
||||
call_command("prune_audit_logs")
|
||||
call_command("prune_audit_logs", skip_checks=True)
|
||||
|
||||
self.assertEqual(LogEntry.objects.count(), 0)
|
||||
|
||||
@@ -180,7 +180,7 @@ class TestExportImport(
|
||||
if data_only:
|
||||
args += ["--data-only"]
|
||||
|
||||
call_command(*args)
|
||||
call_command(*args, skip_checks=True)
|
||||
|
||||
with (self.target / "manifest.json").open() as f:
|
||||
manifest = json.load(f)
|
||||
@@ -272,7 +272,12 @@ class TestExportImport(
|
||||
GroupObjectPermission.objects.all().delete()
|
||||
self.assertEqual(Document.objects.count(), 0)
|
||||
|
||||
call_command("document_importer", "--no-progress-bar", self.target)
|
||||
call_command(
|
||||
"document_importer",
|
||||
"--no-progress-bar",
|
||||
self.target,
|
||||
skip_checks=True,
|
||||
)
|
||||
self.assertEqual(Document.objects.count(), 4)
|
||||
self.assertEqual(Tag.objects.count(), 1)
|
||||
self.assertEqual(Correspondent.objects.count(), 1)
|
||||
@@ -438,7 +443,8 @@ class TestExportImport(
|
||||
filename="0000010.pdf",
|
||||
mime_type="application/pdf",
|
||||
)
|
||||
self.assertRaises(FileNotFoundError, call_command, "document_exporter", target)
|
||||
with self.assertRaises(FileNotFoundError):
|
||||
call_command("document_exporter", target, skip_checks=True)
|
||||
|
||||
def test_export_zipped(self) -> None:
|
||||
"""
|
||||
@@ -458,7 +464,7 @@ class TestExportImport(
|
||||
|
||||
args = ["document_exporter", self.target, "--zip"]
|
||||
|
||||
call_command(*args)
|
||||
call_command(*args, skip_checks=True)
|
||||
|
||||
expected_file = str(
|
||||
self.target / f"export-{timezone.localdate().isoformat()}.zip",
|
||||
@@ -493,7 +499,7 @@ class TestExportImport(
|
||||
with override_settings(
|
||||
FILENAME_FORMAT="{created_year}/{correspondent}/{title}",
|
||||
):
|
||||
call_command(*args)
|
||||
call_command(*args, skip_checks=True)
|
||||
|
||||
expected_file = str(
|
||||
self.target / f"export-{timezone.localdate().isoformat()}.zip",
|
||||
@@ -538,7 +544,7 @@ class TestExportImport(
|
||||
|
||||
args = ["document_exporter", self.target, "--zip", "--delete"]
|
||||
|
||||
call_command(*args)
|
||||
call_command(*args, skip_checks=True)
|
||||
|
||||
expected_file = str(
|
||||
self.target / f"export-{timezone.localdate().isoformat()}.zip",
|
||||
@@ -565,7 +571,7 @@ class TestExportImport(
|
||||
args = ["document_exporter", "/tmp/foo/bar"]
|
||||
|
||||
with self.assertRaises(CommandError) as e:
|
||||
call_command(*args)
|
||||
call_command(*args, skip_checks=True)
|
||||
|
||||
self.assertEqual("That path doesn't exist", str(e.exception))
|
||||
|
||||
@@ -583,7 +589,7 @@ class TestExportImport(
|
||||
args = ["document_exporter", tmp_file.name]
|
||||
|
||||
with self.assertRaises(CommandError) as e:
|
||||
call_command(*args)
|
||||
call_command(*args, skip_checks=True)
|
||||
|
||||
self.assertEqual("That path isn't a directory", str(e.exception))
|
||||
|
||||
@@ -602,7 +608,7 @@ class TestExportImport(
|
||||
args = ["document_exporter", tmp_dir]
|
||||
|
||||
with self.assertRaises(CommandError) as e:
|
||||
call_command(*args)
|
||||
call_command(*args, skip_checks=True)
|
||||
|
||||
self.assertEqual(
|
||||
"That path doesn't appear to be writable",
|
||||
@@ -647,7 +653,12 @@ class TestExportImport(
|
||||
self.assertEqual(Document.objects.count(), 4)
|
||||
Document.objects.all().delete()
|
||||
self.assertEqual(Document.objects.count(), 0)
|
||||
call_command("document_importer", "--no-progress-bar", self.target)
|
||||
call_command(
|
||||
"document_importer",
|
||||
"--no-progress-bar",
|
||||
self.target,
|
||||
skip_checks=True,
|
||||
)
|
||||
self.assertEqual(Document.objects.count(), 4)
|
||||
|
||||
def test_no_thumbnail(self) -> None:
|
||||
@@ -690,7 +701,12 @@ class TestExportImport(
|
||||
self.assertEqual(Document.objects.count(), 4)
|
||||
Document.objects.all().delete()
|
||||
self.assertEqual(Document.objects.count(), 0)
|
||||
call_command("document_importer", "--no-progress-bar", self.target)
|
||||
call_command(
|
||||
"document_importer",
|
||||
"--no-progress-bar",
|
||||
self.target,
|
||||
skip_checks=True,
|
||||
)
|
||||
self.assertEqual(Document.objects.count(), 4)
|
||||
|
||||
def test_split_manifest(self) -> None:
|
||||
@@ -721,7 +737,12 @@ class TestExportImport(
|
||||
Document.objects.all().delete()
|
||||
CustomFieldInstance.objects.all().delete()
|
||||
self.assertEqual(Document.objects.count(), 0)
|
||||
call_command("document_importer", "--no-progress-bar", self.target)
|
||||
call_command(
|
||||
"document_importer",
|
||||
"--no-progress-bar",
|
||||
self.target,
|
||||
skip_checks=True,
|
||||
)
|
||||
self.assertEqual(Document.objects.count(), 4)
|
||||
self.assertEqual(CustomFieldInstance.objects.count(), 1)
|
||||
|
||||
@@ -746,7 +767,12 @@ class TestExportImport(
|
||||
self.assertEqual(Document.objects.count(), 4)
|
||||
Document.objects.all().delete()
|
||||
self.assertEqual(Document.objects.count(), 0)
|
||||
call_command("document_importer", "--no-progress-bar", self.target)
|
||||
call_command(
|
||||
"document_importer",
|
||||
"--no-progress-bar",
|
||||
self.target,
|
||||
skip_checks=True,
|
||||
)
|
||||
self.assertEqual(Document.objects.count(), 4)
|
||||
|
||||
def test_folder_prefix_with_split(self) -> None:
|
||||
@@ -771,7 +797,12 @@ class TestExportImport(
|
||||
self.assertEqual(Document.objects.count(), 4)
|
||||
Document.objects.all().delete()
|
||||
self.assertEqual(Document.objects.count(), 0)
|
||||
call_command("document_importer", "--no-progress-bar", self.target)
|
||||
call_command(
|
||||
"document_importer",
|
||||
"--no-progress-bar",
|
||||
self.target,
|
||||
skip_checks=True,
|
||||
)
|
||||
self.assertEqual(Document.objects.count(), 4)
|
||||
|
||||
def test_import_db_transaction_failed(self) -> None:
|
||||
@@ -813,7 +844,12 @@ class TestExportImport(
|
||||
self.user = User.objects.create(username="temp_admin")
|
||||
|
||||
with self.assertRaises(IntegrityError):
|
||||
call_command("document_importer", "--no-progress-bar", self.target)
|
||||
call_command(
|
||||
"document_importer",
|
||||
"--no-progress-bar",
|
||||
self.target,
|
||||
skip_checks=True,
|
||||
)
|
||||
|
||||
self.assertEqual(ContentType.objects.count(), num_content_type_objects)
|
||||
self.assertEqual(Permission.objects.count(), num_permission_objects + 1)
|
||||
@@ -864,6 +900,7 @@ class TestExportImport(
|
||||
"--no-progress-bar",
|
||||
"--data-only",
|
||||
self.target,
|
||||
skip_checks=True,
|
||||
)
|
||||
|
||||
self.assertEqual(Document.objects.all().count(), 4)
|
||||
@@ -923,6 +960,7 @@ class TestCryptExportImport(
|
||||
"--passphrase",
|
||||
"securepassword",
|
||||
self.target,
|
||||
skip_checks=True,
|
||||
)
|
||||
|
||||
self.assertIsFile(self.target / "metadata.json")
|
||||
@@ -948,6 +986,7 @@ class TestCryptExportImport(
|
||||
"--passphrase",
|
||||
"securepassword",
|
||||
self.target,
|
||||
skip_checks=True,
|
||||
)
|
||||
|
||||
account = MailAccount.objects.first()
|
||||
@@ -976,6 +1015,7 @@ class TestCryptExportImport(
|
||||
"--passphrase",
|
||||
"securepassword",
|
||||
self.target,
|
||||
skip_checks=True,
|
||||
)
|
||||
|
||||
with self.assertRaises(CommandError) as err:
|
||||
@@ -983,6 +1023,7 @@ class TestCryptExportImport(
|
||||
"document_importer",
|
||||
"--no-progress-bar",
|
||||
self.target,
|
||||
skip_checks=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
err.msg,
|
||||
@@ -1014,6 +1055,7 @@ class TestCryptExportImport(
|
||||
"--no-progress-bar",
|
||||
str(self.target),
|
||||
stdout=stdout,
|
||||
skip_checks=True,
|
||||
)
|
||||
stdout.seek(0)
|
||||
self.assertIn(
|
||||
|
||||
@@ -21,6 +21,7 @@ class TestFuzzyMatchCommand(TestCase):
|
||||
*args,
|
||||
stdout=stdout,
|
||||
stderr=stderr,
|
||||
skip_checks=True,
|
||||
**kwargs,
|
||||
)
|
||||
return stdout.getvalue(), stderr.getvalue()
|
||||
|
||||
@@ -41,6 +41,7 @@ class TestCommandImport(
|
||||
"document_importer",
|
||||
"--no-progress-bar",
|
||||
str(self.dirs.scratch_dir),
|
||||
skip_checks=True,
|
||||
)
|
||||
self.assertIn(
|
||||
"That directory doesn't appear to contain a manifest.json file.",
|
||||
@@ -67,6 +68,7 @@ class TestCommandImport(
|
||||
"document_importer",
|
||||
"--no-progress-bar",
|
||||
str(self.dirs.scratch_dir),
|
||||
skip_checks=True,
|
||||
)
|
||||
self.assertIn(
|
||||
"The manifest file contains a record which does not refer to an actual document file.",
|
||||
@@ -96,6 +98,7 @@ class TestCommandImport(
|
||||
"document_importer",
|
||||
"--no-progress-bar",
|
||||
str(self.dirs.scratch_dir),
|
||||
skip_checks=True,
|
||||
)
|
||||
self.assertIn('The manifest file refers to "noexist.pdf"', str(e.exception))
|
||||
|
||||
@@ -157,7 +160,7 @@ class TestCommandImport(
|
||||
- CommandError is raised indicating the issue
|
||||
"""
|
||||
with self.assertRaises(CommandError) as cm:
|
||||
call_command("document_importer", Path("/tmp/notapath"))
|
||||
call_command("document_importer", Path("/tmp/notapath"), skip_checks=True)
|
||||
self.assertIn("That path doesn't exist", str(cm.exception))
|
||||
|
||||
def test_import_source_not_readable(self) -> None:
|
||||
@@ -173,7 +176,7 @@ class TestCommandImport(
|
||||
path = Path(temp_dir)
|
||||
path.chmod(0o222)
|
||||
with self.assertRaises(CommandError) as cm:
|
||||
call_command("document_importer", path)
|
||||
call_command("document_importer", path, skip_checks=True)
|
||||
self.assertIn(
|
||||
"That path doesn't appear to be readable",
|
||||
str(cm.exception),
|
||||
@@ -193,7 +196,12 @@ class TestCommandImport(
|
||||
self.assertIsNotFile(path)
|
||||
|
||||
with self.assertRaises(CommandError) as e:
|
||||
call_command("document_importer", "--no-progress-bar", str(path))
|
||||
call_command(
|
||||
"document_importer",
|
||||
"--no-progress-bar",
|
||||
str(path),
|
||||
skip_checks=True,
|
||||
)
|
||||
self.assertIn("That path doesn't exist", str(e.exception))
|
||||
|
||||
def test_import_files_exist(self) -> None:
|
||||
@@ -218,6 +226,7 @@ class TestCommandImport(
|
||||
"--no-progress-bar",
|
||||
str(self.dirs.scratch_dir),
|
||||
stdout=stdout,
|
||||
skip_checks=True,
|
||||
)
|
||||
stdout.seek(0)
|
||||
self.assertIn(
|
||||
@@ -246,6 +255,7 @@ class TestCommandImport(
|
||||
"--no-progress-bar",
|
||||
str(self.dirs.scratch_dir),
|
||||
stdout=stdout,
|
||||
skip_checks=True,
|
||||
)
|
||||
stdout.seek(0)
|
||||
self.assertIn(
|
||||
@@ -282,6 +292,7 @@ class TestCommandImport(
|
||||
"--no-progress-bar",
|
||||
str(self.dirs.scratch_dir),
|
||||
stdout=stdout,
|
||||
skip_checks=True,
|
||||
)
|
||||
stdout.seek(0)
|
||||
self.assertIn(
|
||||
@@ -309,6 +320,7 @@ class TestCommandImport(
|
||||
"--no-progress-bar",
|
||||
str(self.dirs.scratch_dir),
|
||||
stdout=stdout,
|
||||
skip_checks=True,
|
||||
)
|
||||
stdout.seek(0)
|
||||
stdout_str = str(stdout.read())
|
||||
@@ -338,6 +350,7 @@ class TestCommandImport(
|
||||
"--no-progress-bar",
|
||||
str(self.dirs.scratch_dir),
|
||||
stdout=stdout,
|
||||
skip_checks=True,
|
||||
)
|
||||
stdout.seek(0)
|
||||
stdout_str = str(stdout.read())
|
||||
@@ -377,6 +390,7 @@ class TestCommandImport(
|
||||
"--no-progress-bar",
|
||||
str(zip_path),
|
||||
stdout=stdout,
|
||||
skip_checks=True,
|
||||
)
|
||||
stdout.seek(0)
|
||||
stdout_str = str(stdout.read())
|
||||
|
||||
@@ -139,7 +139,7 @@ class TestRetaggerTags(DirectoriesMixin):
|
||||
@pytest.mark.usefixtures("documents")
|
||||
def test_add_tags(self, tags: TagTuple) -> None:
|
||||
tag_first, tag_second, *_ = tags
|
||||
call_command("document_retagger", "--tags")
|
||||
call_command("document_retagger", "--tags", skip_checks=True)
|
||||
d_first, d_second, d_unrelated, d_auto = _get_docs()
|
||||
|
||||
assert d_first.tags.count() == 1
|
||||
@@ -158,7 +158,7 @@ class TestRetaggerTags(DirectoriesMixin):
|
||||
tag_first, tag_second, tag_inbox, tag_no_match, _ = tags
|
||||
d1.tags.add(tag_second)
|
||||
|
||||
call_command("document_retagger", "--tags", "--overwrite")
|
||||
call_command("document_retagger", "--tags", "--overwrite", skip_checks=True)
|
||||
|
||||
d_first, d_second, d_unrelated, d_auto = _get_docs()
|
||||
|
||||
@@ -180,7 +180,13 @@ class TestRetaggerTags(DirectoriesMixin):
|
||||
],
|
||||
)
|
||||
def test_suggest_does_not_apply_tags(self, extra_args: list[str]) -> None:
|
||||
call_command("document_retagger", "--tags", "--suggest", *extra_args)
|
||||
call_command(
|
||||
"document_retagger",
|
||||
"--tags",
|
||||
"--suggest",
|
||||
*extra_args,
|
||||
skip_checks=True,
|
||||
)
|
||||
d_first, d_second, _, d_auto = _get_docs()
|
||||
|
||||
assert d_first.tags.count() == 0
|
||||
@@ -199,7 +205,7 @@ class TestRetaggerDocumentType(DirectoriesMixin):
|
||||
@pytest.mark.usefixtures("documents")
|
||||
def test_add_type(self, document_types: DocumentTypeTuple) -> None:
|
||||
dt_first, dt_second = document_types
|
||||
call_command("document_retagger", "--document_type")
|
||||
call_command("document_retagger", "--document_type", skip_checks=True)
|
||||
d_first, d_second, _, _ = _get_docs()
|
||||
|
||||
assert d_first.document_type == dt_first
|
||||
@@ -214,7 +220,13 @@ class TestRetaggerDocumentType(DirectoriesMixin):
|
||||
],
|
||||
)
|
||||
def test_suggest_does_not_apply_document_type(self, extra_args: list[str]) -> None:
|
||||
call_command("document_retagger", "--document_type", "--suggest", *extra_args)
|
||||
call_command(
|
||||
"document_retagger",
|
||||
"--document_type",
|
||||
"--suggest",
|
||||
*extra_args,
|
||||
skip_checks=True,
|
||||
)
|
||||
d_first, d_second, _, _ = _get_docs()
|
||||
|
||||
assert d_first.document_type is None
|
||||
@@ -243,7 +255,12 @@ class TestRetaggerDocumentType(DirectoriesMixin):
|
||||
)
|
||||
doc = DocumentFactory(content="ambiguous content")
|
||||
|
||||
call_command("document_retagger", "--document_type", *use_first_flag)
|
||||
call_command(
|
||||
"document_retagger",
|
||||
"--document_type",
|
||||
*use_first_flag,
|
||||
skip_checks=True,
|
||||
)
|
||||
|
||||
doc.refresh_from_db()
|
||||
assert (doc.document_type is not None) is expects_assignment
|
||||
@@ -260,7 +277,7 @@ class TestRetaggerCorrespondent(DirectoriesMixin):
|
||||
@pytest.mark.usefixtures("documents")
|
||||
def test_add_correspondent(self, correspondents: CorrespondentTuple) -> None:
|
||||
c_first, c_second = correspondents
|
||||
call_command("document_retagger", "--correspondent")
|
||||
call_command("document_retagger", "--correspondent", skip_checks=True)
|
||||
d_first, d_second, _, _ = _get_docs()
|
||||
|
||||
assert d_first.correspondent == c_first
|
||||
@@ -275,7 +292,13 @@ class TestRetaggerCorrespondent(DirectoriesMixin):
|
||||
],
|
||||
)
|
||||
def test_suggest_does_not_apply_correspondent(self, extra_args: list[str]) -> None:
|
||||
call_command("document_retagger", "--correspondent", "--suggest", *extra_args)
|
||||
call_command(
|
||||
"document_retagger",
|
||||
"--correspondent",
|
||||
"--suggest",
|
||||
*extra_args,
|
||||
skip_checks=True,
|
||||
)
|
||||
d_first, d_second, _, _ = _get_docs()
|
||||
|
||||
assert d_first.correspondent is None
|
||||
@@ -304,7 +327,12 @@ class TestRetaggerCorrespondent(DirectoriesMixin):
|
||||
)
|
||||
doc = DocumentFactory(content="ambiguous content")
|
||||
|
||||
call_command("document_retagger", "--correspondent", *use_first_flag)
|
||||
call_command(
|
||||
"document_retagger",
|
||||
"--correspondent",
|
||||
*use_first_flag,
|
||||
skip_checks=True,
|
||||
)
|
||||
|
||||
doc.refresh_from_db()
|
||||
assert (doc.correspondent is not None) is expects_assignment
|
||||
@@ -326,7 +354,7 @@ class TestRetaggerStoragePath(DirectoriesMixin):
|
||||
THEN matching documents get the correct path; existing path is unchanged
|
||||
"""
|
||||
sp1, sp2, sp3 = storage_paths
|
||||
call_command("document_retagger", "--storage_path")
|
||||
call_command("document_retagger", "--storage_path", skip_checks=True)
|
||||
d_first, d_second, d_unrelated, d_auto = _get_docs()
|
||||
|
||||
assert d_first.storage_path == sp2
|
||||
@@ -342,7 +370,12 @@ class TestRetaggerStoragePath(DirectoriesMixin):
|
||||
THEN the existing path is replaced by the newly matched path
|
||||
"""
|
||||
sp1, sp2, _ = storage_paths
|
||||
call_command("document_retagger", "--storage_path", "--overwrite")
|
||||
call_command(
|
||||
"document_retagger",
|
||||
"--storage_path",
|
||||
"--overwrite",
|
||||
skip_checks=True,
|
||||
)
|
||||
d_first, d_second, d_unrelated, d_auto = _get_docs()
|
||||
|
||||
assert d_first.storage_path == sp2
|
||||
@@ -373,7 +406,12 @@ class TestRetaggerStoragePath(DirectoriesMixin):
|
||||
)
|
||||
doc = DocumentFactory(content="ambiguous content")
|
||||
|
||||
call_command("document_retagger", "--storage_path", *use_first_flag)
|
||||
call_command(
|
||||
"document_retagger",
|
||||
"--storage_path",
|
||||
*use_first_flag,
|
||||
skip_checks=True,
|
||||
)
|
||||
|
||||
doc.refresh_from_db()
|
||||
assert (doc.storage_path is not None) is expects_assignment
|
||||
@@ -402,7 +440,13 @@ class TestRetaggerIdRange(DirectoriesMixin):
|
||||
expected_count: int,
|
||||
) -> None:
|
||||
DocumentFactory(content="NOT the first document")
|
||||
call_command("document_retagger", "--tags", "--id-range", *id_range_args)
|
||||
call_command(
|
||||
"document_retagger",
|
||||
"--tags",
|
||||
"--id-range",
|
||||
*id_range_args,
|
||||
skip_checks=True,
|
||||
)
|
||||
tag_first, *_ = tags
|
||||
assert Document.objects.filter(tags__id=tag_first.id).count() == expected_count
|
||||
|
||||
@@ -416,7 +460,7 @@ class TestRetaggerIdRange(DirectoriesMixin):
|
||||
)
|
||||
def test_id_range_invalid_arguments_raise(self, args: list[str]) -> None:
|
||||
with pytest.raises((CommandError, SystemExit)):
|
||||
call_command("document_retagger", *args)
|
||||
call_command("document_retagger", *args, skip_checks=True)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -430,12 +474,12 @@ class TestRetaggerEdgeCases(DirectoriesMixin):
|
||||
@pytest.mark.usefixtures("documents")
|
||||
def test_no_targets_exits_cleanly(self) -> None:
|
||||
"""Calling the retagger with no classifier targets should not raise."""
|
||||
call_command("document_retagger")
|
||||
call_command("document_retagger", skip_checks=True)
|
||||
|
||||
@pytest.mark.usefixtures("documents")
|
||||
def test_inbox_only_skips_non_inbox_documents(self) -> None:
|
||||
"""--inbox-only must restrict processing to documents with an inbox tag."""
|
||||
call_command("document_retagger", "--tags", "--inbox-only")
|
||||
call_command("document_retagger", "--tags", "--inbox-only", skip_checks=True)
|
||||
d_first, _, d_unrelated, _ = _get_docs()
|
||||
|
||||
assert d_first.tags.count() == 0
|
||||
|
||||
@@ -20,6 +20,7 @@ class TestManageSuperUser(DirectoriesMixin, TestCase):
|
||||
"--no-color",
|
||||
stdout=out,
|
||||
stderr=StringIO(),
|
||||
skip_checks=True,
|
||||
)
|
||||
return out.getvalue()
|
||||
|
||||
|
||||
@@ -85,13 +85,20 @@ class TestMakeThumbnails(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
|
||||
def test_command(self) -> None:
|
||||
self.assertIsNotFile(self.d1.thumbnail_path)
|
||||
self.assertIsNotFile(self.d2.thumbnail_path)
|
||||
call_command("document_thumbnails", "--processes", "1")
|
||||
call_command("document_thumbnails", "--processes", "1", skip_checks=True)
|
||||
self.assertIsFile(self.d1.thumbnail_path)
|
||||
self.assertIsFile(self.d2.thumbnail_path)
|
||||
|
||||
def test_command_documentid(self) -> None:
|
||||
self.assertIsNotFile(self.d1.thumbnail_path)
|
||||
self.assertIsNotFile(self.d2.thumbnail_path)
|
||||
call_command("document_thumbnails", "--processes", "1", "-d", f"{self.d1.id}")
|
||||
call_command(
|
||||
"document_thumbnails",
|
||||
"--processes",
|
||||
"1",
|
||||
"-d",
|
||||
f"{self.d1.id}",
|
||||
skip_checks=True,
|
||||
)
|
||||
self.assertIsFile(self.d1.thumbnail_path)
|
||||
self.assertIsNotFile(self.d2.thumbnail_path)
|
||||
|
||||
@@ -1665,7 +1665,7 @@ class TestManagementCommand(TestCase):
|
||||
"paperless_mail.management.commands.mail_fetcher.tasks.process_mail_accounts",
|
||||
)
|
||||
def test_mail_fetcher(self, m) -> None:
|
||||
call_command("mail_fetcher")
|
||||
call_command("mail_fetcher", skip_checks=True)
|
||||
|
||||
m.assert_called_once()
|
||||
|
||||
|
||||
12
uv.lock
generated
12
uv.lock
generated
@@ -3683,11 +3683,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "pyjwt"
|
||||
version = "2.10.1"
|
||||
version = "2.12.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e7/46/bd74733ff231675599650d3e47f361794b22ef3e3770998dda30d3b63726/pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", size = 87785, upload-time = "2024-11-28T03:43:29.933Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a8/10/e8192be5f38f3e8e7e046716de4cae33d56fd5ae08927a823bb916be36c1/pyjwt-2.12.0.tar.gz", hash = "sha256:2f62390b667cd8257de560b850bb5a883102a388829274147f1d724453f8fb02", size = 102511, upload-time = "2026-03-12T17:15:30.831Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997, upload-time = "2024-11-28T03:43:27.893Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/15/70/70f895f404d363d291dcf62c12c85fdd47619ad9674ac0f53364d035925a/pyjwt-2.12.0-py3-none-any.whl", hash = "sha256:9bb459d1bdd0387967d287f5656bf7ec2b9a26645d1961628cda1764e087fd6e", size = 29700, upload-time = "2026-03-12T17:15:29.257Z" },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
@@ -3710,15 +3710,15 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "pyopenssl"
|
||||
version = "25.3.0"
|
||||
version = "26.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "cryptography", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
|
||||
{ name = "typing-extensions", marker = "(python_full_version < '3.13' and sys_platform == 'darwin') or (python_full_version < '3.13' and sys_platform == 'linux')" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/80/be/97b83a464498a79103036bc74d1038df4a7ef0e402cfaf4d5e113fb14759/pyopenssl-25.3.0.tar.gz", hash = "sha256:c981cb0a3fd84e8602d7afc209522773b94c1c2446a3c710a75b06fe1beae329", size = 184073, upload-time = "2025-09-17T00:32:21.037Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/8e/11/a62e1d33b373da2b2c2cd9eb508147871c80f12b1cacde3c5d314922afdd/pyopenssl-26.0.0.tar.gz", hash = "sha256:f293934e52936f2e3413b89c6ce36df66a0b34ae1ea3a053b8c5020ff2f513fc", size = 185534, upload-time = "2026-03-15T14:28:26.353Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/81/ef2b1dfd1862567d573a4fdbc9f969067621764fbb74338496840a1d2977/pyopenssl-25.3.0-py3-none-any.whl", hash = "sha256:1fda6fc034d5e3d179d39e59c1895c9faeaf40a79de5fc4cbbfbe0d36f4a77b6", size = 57268, upload-time = "2025-09-17T00:32:19.474Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/7d/d4f7d908fa8415571771b30669251d57c3cf313b36a856e6d7548ae01619/pyopenssl-26.0.0-py3-none-any.whl", hash = "sha256:df94d28498848b98cc1c0ffb8ef1e71e40210d3b0a8064c9d29571ed2904bf81", size = 57969, upload-time = "2026-03-15T14:28:24.864Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Reference in New Issue
Block a user