Compare commits

...

2 Commits

11 changed files with 179 additions and 50 deletions

View File

@@ -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 (

View File

@@ -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

View File

@@ -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}")

View File

@@ -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)

View File

@@ -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(

View File

@@ -21,6 +21,7 @@ class TestFuzzyMatchCommand(TestCase):
*args,
stdout=stdout,
stderr=stderr,
skip_checks=True,
**kwargs,
)
return stdout.getvalue(), stderr.getvalue()

View File

@@ -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())

View File

@@ -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

View File

@@ -20,6 +20,7 @@ class TestManageSuperUser(DirectoriesMixin, TestCase):
"--no-color",
stdout=out,
stderr=StringIO(),
skip_checks=True,
)
return out.getvalue()

View File

@@ -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)

View File

@@ -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()