import json import os import shutil import threading import time from pathlib import Path import pytest from werkzeug.serving import make_server FIXTURES_DIR = Path(__file__).parent / "fixtures" TINY_PNG = bytes.fromhex( "89504e470d0a1a0a0000000d4948445200000001000000010806" "0000001f15c4890000000a4944415478016360000000020001e2" "21bc330000000049454e44ae426082" ) MOCK_ALBUMS = [ { "id": "album-1", "albumName": "Central Asia 2023", "assetCount": 3, "albumThumbnailAssetId": "asset-1", } ] MOCK_ALBUM_DETAIL = { "id": "album-1", "albumName": "Central Asia 2023", "assets": [ {"id": "asset-1", "originalFileName": "IMG_001.jpg", "localDateTime": "2023-09-05T09:03:00"}, {"id": "asset-2", "originalFileName": "IMG_002.jpg", "localDateTime": "2023-09-05T14:30:00"}, {"id": "asset-3", "originalFileName": "IMG_003.jpg", "localDateTime": "2023-09-06T10:00:00"}, ], } @pytest.fixture(scope="session") def httpserver_listen_address(): return ("127.0.0.1", 8099) @pytest.fixture(scope="session") def mock_immich(make_httpserver): server = make_httpserver server.expect_request("/api/albums").respond_with_json(MOCK_ALBUMS) server.expect_request("/api/albums/album-1").respond_with_json(MOCK_ALBUM_DETAIL) for asset_id in ["asset-1", "asset-2", "asset-3"]: server.expect_request( f"/api/assets/{asset_id}/thumbnail" ).respond_with_data(TINY_PNG, content_type="image/png") server.expect_request( f"/api/assets/{asset_id}/original" ).respond_with_data(TINY_PNG, content_type="image/jpeg") return server @pytest.fixture(scope="session") def state_dir(tmp_path_factory): return tmp_path_factory.mktemp("state") @pytest.fixture(scope="session") def pages_dir(tmp_path_factory): return tmp_path_factory.mktemp("pages") @pytest.fixture(scope="session") def flask_app(state_dir, pages_dir, mock_immich): os.environ["IMMICH_URL"] = f"http://127.0.0.1:8099" os.environ["IMMICH_API_KEY"] = "test-key" from app import create_app return create_app(state_dir=str(state_dir), pages_dir=str(pages_dir)) @pytest.fixture(scope="session") def base_url(flask_app): server = make_server("127.0.0.1", 8083, flask_app) t = threading.Thread(target=server.serve_forever) t.daemon = True t.start() time.sleep(0.2) yield "http://127.0.0.1:8083" server.shutdown() @pytest.fixture() def seed_state(state_dir): """Copy a fixture JSON into the state dir; return the album_id.""" def _seed(fixture_name: str) -> str: src = FIXTURES_DIR / f"{fixture_name}.json" with open(src) as f: data = json.load(f) dst = Path(state_dir) / f"{data['album_id']}.json" shutil.copy(src, dst) return data["album_id"] return _seed