#!/usr/bin/env python3 from __future__ import annotations import importlib.util import sys import tempfile import unittest from pathlib import Path from unittest.mock import patch RECEIVER_PATH = Path(__file__).with_name("receiver.py") SPEC = importlib.util.spec_from_file_location("iphone_photo_receiver", RECEIVER_PATH) receiver = importlib.util.module_from_spec(SPEC) assert SPEC.loader is not None sys.modules[SPEC.name] = receiver SPEC.loader.exec_module(receiver) class ReceiverTests(unittest.TestCase): def tearDown(self) -> None: batch = getattr(self, "batch", None) if batch is not None and batch.timer is not None: batch.timer.cancel() def test_load_env_file_does_not_override_existing_environment(self) -> None: with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8") as env_file, \ patch.dict(receiver.os.environ, {"PHOTO_INBOX_TOKEN": "existing"}, clear=False): env_file.write("PHOTO_INBOX_TOKEN=from-file\n") env_file.write('PHOTO_INBOX_DEBOUNCE_SECONDS="5"\n') env_file.flush() receiver.load_env_file(Path(env_file.name)) self.assertEqual(receiver.os.environ["PHOTO_INBOX_TOKEN"], "existing") self.assertEqual(receiver.os.environ["PHOTO_INBOX_DEBOUNCE_SECONDS"], "5") def test_batch_add_accumulates_paths(self) -> None: config = receiver.Config(Path("/tmp"), clipboard=True, notify=False, reveal=False) manager = receiver.BatchManager(debounce_seconds=60, config=config) count1, paths1 = manager.add(Path("/tmp/one.jpg")) count2, paths2 = manager.add(Path("/tmp/two.jpg")) self.batch = manager.batch self.assertEqual(count1, 1) self.assertEqual(paths1, [Path("/tmp/one.jpg")]) self.assertEqual(count2, 2) self.assertEqual(paths2, [Path("/tmp/one.jpg"), Path("/tmp/two.jpg")]) def test_files_clipboard_passes_all_paths_to_native_helper(self) -> None: paths = [Path("/tmp/one.jpg"), Path("/tmp/two.jpg")] with tempfile.NamedTemporaryFile() as helper: helper_path = Path(helper.name) with patch.object(receiver, "COPY_FILES_HELPER_BIN", Path("/tmp/missing-helper-bin")), \ patch.object(receiver, "COPY_FILES_HELPER", helper_path), \ patch.object(receiver, "run_macos_action", return_value=True) as run_action: self.assertTrue(receiver.copy_files_to_clipboard(paths)) run_action.assert_called_once_with([ str(helper_path), "/tmp/one.jpg", "/tmp/two.jpg", ]) def test_build_config_uses_boolean_clipboard(self) -> None: args = type("Args", (), { "output_dir": Path("/tmp/photos"), "clipboard": False, "notify": True, "reveal": False, })() config = receiver.build_config(args) self.assertEqual(config.output_dir, Path("/tmp/photos").resolve()) self.assertFalse(config.clipboard) self.assertTrue(config.notify) self.assertFalse(config.reveal) if __name__ == "__main__": unittest.main()