mirror of
https://github.com/freedomofpress/dangerzone.git
synced 2025-04-28 09:52:37 +02:00
Add unit tests
This commit is contained in:
parent
e923c5a803
commit
36d96ccb5c
6 changed files with 187 additions and 2 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -133,7 +133,8 @@ dmypy.json
|
|||
deb_dist
|
||||
.DS_Store
|
||||
install/windows/Dangerzone.wxs
|
||||
test_docs/sample-safe.pdf
|
||||
**/*-safe.pdf
|
||||
test_docs/out/
|
||||
share/container.tar
|
||||
share/container.tar.gz
|
||||
share/image-id.txt
|
||||
|
|
0
dangerzone/tests/__init__.py
Normal file
0
dangerzone/tests/__init__.py
Normal file
125
dangerzone/tests/test_cli.py
Normal file
125
dangerzone/tests/test_cli.py
Normal file
|
@ -0,0 +1,125 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import os.path
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
|
||||
from click.testing import CliRunner, Result
|
||||
|
||||
from dangerzone.cli import cli_main
|
||||
|
||||
|
||||
# TODO --output-filename with spaces
|
||||
# TODO explore any symlink edge cases
|
||||
# TODO simulate ctrl-c, ctrl-d, SIGINT/SIGKILL/SIGTERM... (man 7 signal), etc?
|
||||
# TODO validate output PDFs https://github.com/pdfminer/pdfminer.six
|
||||
# TODO trigger "Invalid json returned from container"
|
||||
# TODO trigger "pdf-to-pixels failed"
|
||||
# TODO simulate container runtime missing
|
||||
# TODO simulate container connection error
|
||||
# TODO simulate container connection loss
|
||||
# FIXME "/" path separator is platform-dependent, use pathlib instead
|
||||
|
||||
|
||||
class CliTestCase(TestCase):
|
||||
SAMPLE_DIRECTORY = "test_docs"
|
||||
BASIC_SAMPLE = f"{SAMPLE_DIRECTORY}/sample.pdf"
|
||||
SAFE_SUFFIX = "-safe.pdf"
|
||||
|
||||
def setUp(self):
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
sys.dangerzone_dev = True
|
||||
self.runner = CliRunner()
|
||||
# TODO Use pathlib or similar for safer file handling here
|
||||
samples_dir = Path(self.SAMPLE_DIRECTORY)
|
||||
self.samples: list[Path | str] = [
|
||||
p
|
||||
for p in samples_dir.rglob("*")
|
||||
if p.is_file() and not p.name.endswith(self.SAFE_SUFFIX)
|
||||
]
|
||||
print(f"{self.BASIC_SAMPLE} --output-filename {self.SAMPLE_DIRECTORY}/out/my-output.pdf")
|
||||
if len(self.samples) < 10:
|
||||
raise RuntimeWarning(f"Only {len(self.samples)} samples found.")
|
||||
|
||||
def invoke_runner(self, *args, **kwargs) -> Result:
|
||||
return self.runner.invoke(cli_main, *args, **kwargs)
|
||||
|
||||
|
||||
class CliBasicTestCase(CliTestCase):
|
||||
def test_no_args(self):
|
||||
"""``$ dangerzone-cli``"""
|
||||
result = self.invoke_runner()
|
||||
self.assertNotEqual(result.exit_code, 0)
|
||||
|
||||
def test_help(self):
|
||||
"""``$ dangerzone-cli --help``"""
|
||||
result = self.invoke_runner("--help")
|
||||
self.assertEqual(result.exit_code, 0)
|
||||
|
||||
def test_version(self):
|
||||
"""``$ dangerzone-cli --version``"""
|
||||
# Note: fails for now, "--version" is not yet implemented.
|
||||
result = self.invoke_runner("--version")
|
||||
self.assertEqual(result.exit_code, 0)
|
||||
|
||||
|
||||
class CliConversionTestCase(CliTestCase):
|
||||
def test_invalid_lang(self):
|
||||
result = self.invoke_runner(f"{self.BASIC_SAMPLE} --ocr-lang piglatin")
|
||||
self.assertNotEqual(result.exit_code, 0)
|
||||
|
||||
def test_samples(self):
|
||||
for sample in self.samples:
|
||||
with self.subTest(f"Convert {sample}"):
|
||||
result = self.invoke_runner(f'"{sample}"')
|
||||
self.assertEqual(result.exit_code, 0)
|
||||
|
||||
def test_output_filename(self):
|
||||
result = self.invoke_runner(f"{self.BASIC_SAMPLE} --output-filename {self.SAMPLE_DIRECTORY}/out/my-output.pdf")
|
||||
self.assertEqual(result.exit_code, 0)
|
||||
|
||||
def test_output_filename_new_dir(self):
|
||||
result = self.invoke_runner(f"{self.BASIC_SAMPLE} --output-filename fake-directory/my-output.pdf")
|
||||
self.assertEqual(result.exit_code, 0)
|
||||
|
||||
def test_sample_not_found(self):
|
||||
result = self.invoke_runner("fake-directory/fake-file.pdf")
|
||||
self.assertEquals(result.exit_code, 1)
|
||||
|
||||
def test_lang_mismatch(self):
|
||||
"""Try to OCR sample.pdf (Lorem ipsum) as traditional Chinese characters."""
|
||||
# TODO how should we handle these cases?
|
||||
with self.assertWarns(RuntimeWarning):
|
||||
self.invoke_runner(f"{self.BASIC_SAMPLE} --ocr-lang chi_tra")
|
||||
|
||||
def test_lang_eng(self):
|
||||
# Rewrite this case if samples in other languages or scripts are added.
|
||||
result = self.invoke_runner(f'"{self.BASIC_SAMPLE}" --ocr-lang eng')
|
||||
self.assertEqual(result.exit_code, 0)
|
||||
|
||||
def test_bulk(self):
|
||||
"""
|
||||
Try to convert all sample documents in one run.
|
||||
Fails for now, since bulk conversion is not yet implemented.
|
||||
"""
|
||||
# FIXME Once bulk conversion is implemented, return here to expand and quote self.samples correctly.
|
||||
result = self.invoke_runner(self.samples)
|
||||
self.assertEqual(result.exit_code, 0)
|
||||
|
||||
def test_bulk_input_one_name(self):
|
||||
"""
|
||||
Try to convert all sample documents in one run and supplies --output-filename This should fail.
|
||||
"""
|
||||
# FIXME Once bulk conversion is implemented, return here to expand and quote self.samples correctly.
|
||||
result = self.invoke_runner(self.samples + ["--output-filename sample-safe.pdf"]) # more samples than names
|
||||
self.assertNotEqual(result.exit_code, 0)
|
||||
|
||||
def test_bulk_ocr_eng(self):
|
||||
"""
|
||||
Try to convert all sample documents in one run and with English OCR.
|
||||
Fails for now, since bulk conversion is not yet implemented.
|
||||
"""
|
||||
# FIXME Once bulk conversion is implemented, return here to expand and quote self.samples correctly.
|
||||
result = self.invoke_runner(self.samples + ["--ocr-lang eng"])
|
||||
self.assertEqual(result.exit_code, 0)
|
58
dangerzone/tests/test_global_common.py
Normal file
58
dangerzone/tests/test_global_common.py
Normal file
|
@ -0,0 +1,58 @@
|
|||
import io
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
from io import StringIO
|
||||
from pathlib import Path
|
||||
from unittest import TestCase, mock
|
||||
|
||||
from strip_ansi import strip_ansi # type: ignore
|
||||
|
||||
import dangerzone.global_common as global_common
|
||||
|
||||
|
||||
class TestGlobalCommon(TestCase):
|
||||
|
||||
VERSION_FILE_NAME = "version.txt"
|
||||
|
||||
def setUp(self):
|
||||
self.global_common = global_common.GlobalCommon()
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
sys.dangerzone_dev = True
|
||||
|
||||
def test_get_resource_path(self):
|
||||
share_dir = Path("share").resolve()
|
||||
resource_path = Path(
|
||||
self.global_common.get_resource_path(self.VERSION_FILE_NAME)
|
||||
).parent
|
||||
self.assertTrue(
|
||||
share_dir.samefile(resource_path),
|
||||
msg=f"{share_dir} is not the same file as {resource_path}",
|
||||
)
|
||||
|
||||
@unittest.skipUnless(platform.system() == "Windows", "STARTUPINFO is for Windows")
|
||||
def test_get_subprocess_startupinfo(self):
|
||||
startupinfo = self.global_common.get_subprocess_startupinfo()
|
||||
self.assertIsInstance(startupinfo, subprocess.STARTUPINFO)
|
||||
|
||||
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_display_banner(self, mock_stdout: StringIO):
|
||||
self.global_common.display_banner() # call the test subject
|
||||
banner = mock_stdout.getvalue()
|
||||
plain_lines = [strip_ansi(line) for line in banner.splitlines()]
|
||||
with self.subTest("banner top border"):
|
||||
self.assertEqual("╭──────────────────────────╮", plain_lines[0])
|
||||
with self.subTest("banner bottom border"):
|
||||
self.assertEqual("╰──────────────────────────╯", plain_lines[14])
|
||||
with self.subTest("banner consistent dimensions"):
|
||||
width = len(plain_lines[0])
|
||||
for line in plain_lines:
|
||||
self.assertEqual(len(line), width)
|
||||
|
||||
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_display_banner_dims(self, mock_stdout: StringIO):
|
||||
self.global_common.display_banner() # call the test subject
|
||||
banner = mock_stdout.getvalue()
|
||||
banner_lines = banner.splitlines()
|
2
poetry.lock
generated
2
poetry.lock
generated
|
@ -367,7 +367,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-
|
|||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = ">=3.7,<3.10"
|
||||
content-hash = "786373e6750c907d6353d3c96c2d8aebffb1b0271035a793469055e2d6502bac"
|
||||
content-hash = "06c3321d6ee6b4e8dc1512f6dbc9ef8d911347aac642f1a709a55d8eec1cc09a"
|
||||
|
||||
[metadata.files]
|
||||
altgraph = [
|
||||
|
|
|
@ -23,6 +23,7 @@ black = "*"
|
|||
isort = "*"
|
||||
mypy = "*"
|
||||
PySide2-stubs = "*"
|
||||
strip-ansi = "*"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
dangerzone = 'dangerzone:main'
|
||||
|
|
Loading…
Reference in a new issue