72 lines
2.8 KiB
Python
72 lines
2.8 KiB
Python
from __future__ import annotations
|
|
|
|
import subprocess
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
from tools.exiftool import run_exiftool_command, run_exiftool_write
|
|
from tools.media_metadata import parse_exif_datetime
|
|
from tools.metadata_copy import copy_meaningful_metadata
|
|
|
|
|
|
class ExiftoolInvocationTests(unittest.TestCase):
|
|
def test_windows_uses_utf8_argument_file_for_unicode_paths(self) -> None:
|
|
captured: dict[str, object] = {}
|
|
|
|
def fake_run(command, **kwargs):
|
|
captured["command"] = command
|
|
argument_file = Path(kwargs["cwd"]) / command[-1]
|
|
captured["contents"] = argument_file.read_text(encoding="utf-8")
|
|
return subprocess.CompletedProcess(command, 0)
|
|
|
|
with (
|
|
patch("tools.exiftool._use_windows_argument_file", return_value=True),
|
|
patch("tools.exiftool.subprocess.run", side_effect=fake_run),
|
|
):
|
|
run_exiftool_command(
|
|
"exiftool.exe",
|
|
["-j", "C:\\Photos\\M\u00e4rchen.jpg"],
|
|
check=True,
|
|
)
|
|
|
|
self.assertEqual(
|
|
captured["command"],
|
|
["exiftool.exe", "-charset", "filename=UTF8", "-@", "arguments.txt"],
|
|
)
|
|
self.assertEqual(captured["contents"], "-j\nC:\\Photos\\M\u00e4rchen.jpg\n")
|
|
|
|
def test_write_captures_success_output(self) -> None:
|
|
with patch(
|
|
"tools.exiftool.subprocess.run",
|
|
return_value=subprocess.CompletedProcess([], 0, "1 image files updated\n", ""),
|
|
) as run:
|
|
run_exiftool_write("exiftool", Path("photo.jpg"), ["-Artist=Test"])
|
|
|
|
self.assertTrue(run.call_args.kwargs["capture_output"])
|
|
self.assertTrue(run.call_args.kwargs["text"])
|
|
|
|
def test_write_includes_exiftool_failure_output(self) -> None:
|
|
with patch(
|
|
"tools.exiftool.subprocess.run",
|
|
return_value=subprocess.CompletedProcess([], 1, "", "Error renaming temporary file"),
|
|
):
|
|
with self.assertRaisesRegex(RuntimeError, "Error renaming temporary file"):
|
|
run_exiftool_write("exiftool", Path("photo.jpg"), ["-Artist=Test"])
|
|
|
|
def test_metadata_copy_uses_exiftool_for_photos(self) -> None:
|
|
with patch("tools.metadata_copy.run_exiftool_command") as run:
|
|
copy_meaningful_metadata("exiftool", Path("source.jpg"), Path("target.jpg"))
|
|
|
|
args = run.call_args.args[1]
|
|
self.assertEqual(args[:4], ["-overwrite_original", "-TagsFromFile", "source.jpg", "-all:all"])
|
|
self.assertEqual(args[-1], "target.jpg")
|
|
|
|
def test_metadata_datetime_can_assume_utc(self) -> None:
|
|
parsed = parse_exif_datetime("2026:07:04 14:13:36", assume_utc=True)
|
|
self.assertEqual(str(parsed.tzinfo), "UTC")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|