mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-08-12 00:19:48 +00:00
Feature: Allow a data only export/import cycle (#6871)
This commit is contained in:
@@ -37,10 +37,16 @@ from documents.sanity_checker import check_sanity
|
||||
from documents.settings import EXPORTER_FILE_NAME
|
||||
from documents.tests.utils import DirectoriesMixin
|
||||
from documents.tests.utils import FileSystemAssertsMixin
|
||||
from documents.tests.utils import SampleDirMixin
|
||||
from documents.tests.utils import paperless_environment
|
||||
|
||||
|
||||
class TestExportImport(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
|
||||
class TestExportImport(
|
||||
DirectoriesMixin,
|
||||
FileSystemAssertsMixin,
|
||||
SampleDirMixin,
|
||||
TestCase,
|
||||
):
|
||||
def setUp(self) -> None:
|
||||
self.target = Path(tempfile.mkdtemp())
|
||||
self.addCleanup(shutil.rmtree, self.target)
|
||||
@@ -139,6 +145,7 @@ class TestExportImport(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
|
||||
@override_settings(PASSPHRASE="test")
|
||||
def _do_export(
|
||||
self,
|
||||
*,
|
||||
use_filename_format=False,
|
||||
compare_checksums=False,
|
||||
delete=False,
|
||||
@@ -146,6 +153,7 @@ class TestExportImport(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
|
||||
no_thumbnail=False,
|
||||
split_manifest=False,
|
||||
use_folder_prefix=False,
|
||||
data_only=False,
|
||||
):
|
||||
args = ["document_exporter", self.target]
|
||||
if use_filename_format:
|
||||
@@ -162,6 +170,8 @@ class TestExportImport(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
|
||||
args += ["--split-manifest"]
|
||||
if use_folder_prefix:
|
||||
args += ["--use-folder-prefix"]
|
||||
if data_only:
|
||||
args += ["--data-only"]
|
||||
|
||||
call_command(*args)
|
||||
|
||||
@@ -794,3 +804,39 @@ class TestExportImport(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
|
||||
manifest = self._do_export(use_filename_format=True)
|
||||
for obj in manifest:
|
||||
self.assertNotEqual(obj["model"], "auditlog.logentry")
|
||||
|
||||
def test_export_data_only(self):
|
||||
"""
|
||||
GIVEN:
|
||||
- Request to export documents with data only
|
||||
WHEN:
|
||||
- Export command is called
|
||||
THEN:
|
||||
- No document files are exported
|
||||
- Manifest and version are exported
|
||||
"""
|
||||
|
||||
shutil.rmtree(self.dirs.media_dir / "documents")
|
||||
shutil.copytree(
|
||||
self.SAMPLE_DIR / "documents",
|
||||
self.dirs.media_dir / "documents",
|
||||
)
|
||||
|
||||
_ = self._do_export(data_only=True)
|
||||
|
||||
# Manifest and version files only should be present in the exported directory
|
||||
self.assertFileCountInDir(self.target, 2)
|
||||
self.assertIsFile(self.target / "manifest.json")
|
||||
self.assertIsFile(self.target / "version.json")
|
||||
|
||||
shutil.rmtree(self.dirs.media_dir / "documents")
|
||||
Document.objects.all().delete()
|
||||
|
||||
call_command(
|
||||
"document_importer",
|
||||
"--no-progress-bar",
|
||||
"--data-only",
|
||||
self.target,
|
||||
)
|
||||
|
||||
self.assertEqual(Document.objects.all().count(), 4)
|
||||
|
@@ -14,9 +14,15 @@ from documents.settings import EXPORTER_ARCHIVE_NAME
|
||||
from documents.settings import EXPORTER_FILE_NAME
|
||||
from documents.tests.utils import DirectoriesMixin
|
||||
from documents.tests.utils import FileSystemAssertsMixin
|
||||
from documents.tests.utils import SampleDirMixin
|
||||
|
||||
|
||||
class TestCommandImport(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
|
||||
class TestCommandImport(
|
||||
DirectoriesMixin,
|
||||
FileSystemAssertsMixin,
|
||||
SampleDirMixin,
|
||||
TestCase,
|
||||
):
|
||||
def test_check_manifest_exists(self):
|
||||
"""
|
||||
GIVEN:
|
||||
@@ -120,14 +126,14 @@ class TestCommandImport(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
|
||||
},
|
||||
]
|
||||
with self.assertRaises(CommandError) as cm:
|
||||
cmd._check_manifest_valid()
|
||||
cmd._check_manifest_files_valid()
|
||||
self.assertInt("Failed to read from original file", str(cm.exception))
|
||||
|
||||
original_path.chmod(0o444)
|
||||
archive_path.chmod(0o222)
|
||||
|
||||
with self.assertRaises(CommandError) as cm:
|
||||
cmd._check_manifest_valid()
|
||||
cmd._check_manifest_files_valid()
|
||||
self.assertInt("Failed to read from archive file", str(cm.exception))
|
||||
|
||||
def test_import_source_not_existing(self):
|
||||
|
@@ -156,10 +156,6 @@ class DirectoriesMixin:
|
||||
they are cleaned up on exit
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.dirs = None
|
||||
|
||||
def setUp(self) -> None:
|
||||
self.dirs = setup_directories()
|
||||
super().setUp()
|
||||
@@ -200,6 +196,16 @@ class FileSystemAssertsMixin:
|
||||
|
||||
self.assertEqual(hash1, hash2, "File SHA256 mismatch")
|
||||
|
||||
def assertFileCountInDir(self, path: Union[PathLike, str], count: int):
|
||||
path = Path(path).resolve()
|
||||
self.assertTrue(path.is_dir(), f"Path {path} is not a directory")
|
||||
files = [x for x in path.iterdir() if x.is_file()]
|
||||
self.assertEqual(
|
||||
len(files),
|
||||
count,
|
||||
f"Path {path} contains {len(files)} files instead of {count} files",
|
||||
)
|
||||
|
||||
|
||||
class ConsumerProgressMixin:
|
||||
"""
|
||||
|
Reference in New Issue
Block a user