aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-node/tests')
-rw-r--r--packages/meshbay-node/tests/test_photo_folder_videos.py80
1 files changed, 80 insertions, 0 deletions
diff --git a/packages/meshbay-node/tests/test_photo_folder_videos.py b/packages/meshbay-node/tests/test_photo_folder_videos.py
new file mode 100644
index 0000000..79953a1
--- /dev/null
+++ b/packages/meshbay-node/tests/test_photo_folder_videos.py
@@ -0,0 +1,80 @@
+"""
+A video in a photo folder (a phone's clips, backed up beside its photos,
+docs/MESHBAY_DESIGN.md §9.12) is probed and thumbnailed by the video enricher,
+so the Photos app can show it in its album; one outside every photo folder
+and every video folder is left alone, as before.
+"""
+
+import asyncio
+
+import pytest
+from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
+from meshbay_common.crypto import generate_gek
+from meshbay_node.config import Config, GroupConfig, HubConfig, KeystoreConfig, NodeConfig
+from meshbay_node.daemon import NodeDaemon
+from meshbay_node.indexer import DirectoryIndexer
+from meshbay_node.indexer.enrich import Enricher
+from meshbay_node.indexer.enrich_photo import PhotoEnricher
+from meshbay_node.media_cache import MediaCache
+from meshbay_node.roster import Roster
+
+from conftest import one_root
+
+pytestmark = pytest.mark.asyncio
+
+
+def _free_port() -> int:
+ import socket
+ with socket.socket() as s:
+ s.bind(("127.0.0.1", 0))
+ return s.getsockname()[1]
+
+
+async def _make_daemon(tmp_path, shared, group_id):
+ config = Config(
+ hub=HubConfig(url="http://localhost:9999", username="testuser"),
+ node=NodeConfig(quic_port=_free_port(), ui_port=_free_port()),
+ groups=[GroupConfig(
+ id=group_id, name="test-group", shared_dir=str(shared),
+ visibility="private", quic_port=29015,
+ )],
+ keystore=KeystoreConfig(path=tmp_path / "keystore.enc"),
+ data_dir=tmp_path / "data",
+ )
+ daemon = NodeDaemon(config)
+ daemon._broadcast_coalesce_secs = 0.01
+ daemon._media_cache = MediaCache(db_path=tmp_path / "media_cache.db")
+ await daemon._media_cache.open()
+ daemon._enricher = Enricher(daemon._media_cache)
+ daemon._photo_enricher = PhotoEnricher(daemon._media_cache)
+ daemon._roster = Roster(db_path=tmp_path / "roster.db")
+ await daemon._roster.open()
+ return daemon
+
+
+async def test_a_video_in_a_photo_folder_goes_to_the_video_enricher(tmp_path):
+ group_id = "b" * 32
+ shared = tmp_path / "shared"
+ (shared / "Photos" / "bob-photos").mkdir(parents=True)
+ (shared / "Photos" / "bob-photos" / "clip.mp4").write_bytes(b"a clip")
+ (shared / "Photos" / "bob-photos" / "shot.jpg").write_bytes(b"a photo")
+ (shared / "elsewhere.mp4").write_bytes(b"not in any app folder")
+
+ daemon = await _make_daemon(tmp_path, shared, group_id)
+ video_spawned, photo_spawned = [], []
+ daemon._enricher.spawn = lambda entry, path, on_done: video_spawned.append(entry.name)
+ daemon._photo_enricher.spawn = lambda entry, path, on_done: photo_spawned.append(entry.name)
+ try:
+ await daemon._roster.set_app_directories(group_id, "photo", ["shared/Photos"], set_by="op")
+ indexer = DirectoryIndexer(
+ roots=one_root(shared), group_id=group_id,
+ sk_node=Ed25519PrivateKey.generate(), gek=generate_gek())
+ await indexer.initial_scan()
+ await daemon._on_index_change(indexer)
+ await asyncio.sleep(0.05)
+
+ assert video_spawned == ["clip.mp4"]
+ assert photo_spawned == ["shot.jpg"]
+ finally:
+ await daemon._media_cache.close()
+ await daemon._roster.close()