mirror of
https://github.com/freedomofpress/dangerzone.git
synced 2025-04-28 18:02:38 +02:00

On Windows, if we somehow attempt to archive the same document twice (e.g, because it got archived once, and then we copy it back), we will get an error, because Windows does not overwrite the target path, if it already exists. Fix this issue by always removing the previously archived version, when performing the next archival action, and update our tests.
188 lines
5.6 KiB
Python
188 lines
5.6 KiB
Python
import os
|
|
import platform
|
|
import stat
|
|
import tempfile
|
|
from pathlib import Path
|
|
from unittest.mock import MagicMock
|
|
|
|
import pytest
|
|
|
|
from dangerzone import errors
|
|
from dangerzone.document import ARCHIVE_SUBDIR, SAFE_EXTENSION, Document
|
|
|
|
from . import sample_pdf, unreadable_pdf
|
|
|
|
|
|
def test_input_sample_init(sample_pdf: str) -> None:
|
|
Document(sample_pdf)
|
|
|
|
|
|
def test_input_sample_init_archive(sample_pdf: str) -> None:
|
|
Document(sample_pdf, archive=True)
|
|
|
|
|
|
def test_input_sample_after(sample_pdf: str) -> None:
|
|
d = Document()
|
|
d.input_filename = sample_pdf
|
|
|
|
|
|
def test_input_file_none() -> None:
|
|
"""
|
|
Attempts to read a document's filename when no doc has been set
|
|
"""
|
|
d = Document()
|
|
with pytest.raises(errors.NotSetInputFilenameException) as e:
|
|
d.input_filename
|
|
|
|
|
|
def test_input_file_non_existing() -> None:
|
|
with pytest.raises(errors.InputFileNotFoundException) as e:
|
|
Document("non-existing-file.pdf")
|
|
|
|
|
|
# XXX: This is not easy to test on Windows, as the file owner can always read it.
|
|
# See also:
|
|
# https://stackoverflow.com/questions/72528318/what-file-permissions-make-a-file-unreadable-by-owner-in-windows
|
|
@pytest.mark.skipif(platform.system() == "Windows", reason="Unix-specific")
|
|
def test_input_file_unreadable(unreadable_pdf: str) -> None:
|
|
with pytest.raises(errors.InputFileNotReadableException) as e:
|
|
Document(unreadable_pdf)
|
|
|
|
|
|
@pytest.mark.skipif(platform.system() == "Windows", reason="Unix-specific")
|
|
def test_output_file_unwriteable_dir(sample_pdf: str, tmp_path: Path) -> None:
|
|
# make parent dir unwriteable
|
|
sample_pdf_safe = str(tmp_path / "document-safe.pdf")
|
|
os.chmod(tmp_path, 0o400)
|
|
with pytest.raises(errors.UnwriteableOutputDirException) as e:
|
|
d = Document(sample_pdf, sample_pdf_safe)
|
|
|
|
|
|
def test_output(tmp_path: Path) -> None:
|
|
pdf_file = str(tmp_path.joinpath("document.pdf"))
|
|
d = Document()
|
|
d.output_filename = pdf_file
|
|
|
|
|
|
def test_output_file_none() -> None:
|
|
"""
|
|
Attempts to read a document's filename when no doc has been set
|
|
"""
|
|
d = Document()
|
|
with pytest.raises(errors.NotSetOutputFilenameException) as e:
|
|
d.output_filename
|
|
|
|
|
|
def test_output_file_not_pdf(tmp_path: Path) -> None:
|
|
docx_file = str(tmp_path / "document.docx")
|
|
d = Document()
|
|
|
|
with pytest.raises(errors.NonPDFOutputFileException) as e:
|
|
d.output_filename = docx_file
|
|
|
|
assert not os.path.exists(docx_file)
|
|
|
|
|
|
@pytest.mark.skipif(platform.system() == "Windows", reason="Unix-specific")
|
|
def test_archive_unwriteable_dir(tmp_path: Path) -> None:
|
|
doc = tmp_path / "doc.pdf"
|
|
Path.touch(doc)
|
|
d = Document(str(doc))
|
|
|
|
# make archive directory unreadable
|
|
os.chmod(tmp_path, 0o400)
|
|
|
|
with pytest.raises(errors.UnwriteableArchiveDirException) as e:
|
|
d.validate_default_archive_dir()
|
|
|
|
|
|
def test_archive(mocker: MagicMock, tmp_path: Path) -> None:
|
|
original_doc_path = str(tmp_path / "doc.pdf")
|
|
archived_doc_path = str(tmp_path / ARCHIVE_SUBDIR / "doc.pdf")
|
|
|
|
# Perform the archival operation two times: one with no archive dir, and one with an
|
|
# archive dir.
|
|
test_strings = ["original file 1", "original file 2"]
|
|
for test_string in test_strings:
|
|
# write some content for later verifying content integrity
|
|
with open(original_doc_path, "w") as f:
|
|
f.write(test_string)
|
|
|
|
# archive the document
|
|
d = Document(original_doc_path, archive=True)
|
|
d.archive()
|
|
|
|
# original document has been moved to unsafe/doc.pdf
|
|
assert not os.path.exists(original_doc_path)
|
|
assert os.path.exists(archived_doc_path)
|
|
|
|
# make sure it is the proper file by comparing its content
|
|
with open(archived_doc_path) as f:
|
|
assert f.read() == test_string
|
|
|
|
|
|
def test_set_output_dir(sample_pdf: str, tmp_path: Path) -> None:
|
|
d = Document(sample_pdf)
|
|
d.set_output_dir(str(tmp_path))
|
|
assert os.path.dirname(d.output_filename) == str(tmp_path)
|
|
|
|
|
|
def test_set_output_dir_non_existant(sample_pdf: str, tmp_path: Path) -> None:
|
|
non_existant_path = str(tmp_path / "fake-dir")
|
|
d = Document(sample_pdf)
|
|
with pytest.raises(errors.NonExistantOutputDirException):
|
|
d.set_output_dir(non_existant_path)
|
|
|
|
|
|
def test_set_output_dir_is_file(sample_pdf: str, tmp_path: Path) -> None:
|
|
# create a file
|
|
file_path = str(tmp_path / "file")
|
|
with open(file_path, "w"):
|
|
pass
|
|
|
|
d = Document(sample_pdf)
|
|
with pytest.raises(errors.OutputDirIsNotDirException):
|
|
d.set_output_dir(file_path)
|
|
|
|
|
|
def test_default_output_filename(sample_pdf: str) -> None:
|
|
d = Document(sample_pdf)
|
|
assert d.output_filename.endswith(SAFE_EXTENSION)
|
|
|
|
|
|
def test_set_output_filename_suffix(sample_pdf: str) -> None:
|
|
d = Document(sample_pdf)
|
|
safe_extension = "-trusted.pdf"
|
|
d.suffix = safe_extension
|
|
assert d.output_filename.endswith(safe_extension)
|
|
|
|
d.output_filename = "something_else.pdf"
|
|
with pytest.raises(errors.SuffixNotApplicableException) as e:
|
|
d.suffix = "-new-trusted.pdf"
|
|
|
|
|
|
def test_is_unconverted_by_default(sample_pdf: str) -> None:
|
|
d = Document(sample_pdf)
|
|
assert d.is_unconverted()
|
|
|
|
|
|
def test_mark_as_safe(sample_pdf: str) -> None:
|
|
d = Document(sample_pdf)
|
|
d.mark_as_safe()
|
|
assert d.is_safe()
|
|
assert not d.is_failed()
|
|
assert not d.is_unconverted()
|
|
|
|
|
|
def test_mark_as_converting(sample_pdf: str) -> None:
|
|
d = Document(sample_pdf)
|
|
d.mark_as_converting()
|
|
assert d.is_converting()
|
|
|
|
|
|
def test_mark_as_failed(sample_pdf: str) -> None:
|
|
d = Document(sample_pdf)
|
|
d.mark_as_failed()
|
|
assert d.is_failed()
|
|
assert not d.is_safe()
|
|
assert not d.is_unconverted()
|