from __future__ import annotations import json from pathlib import Path from syncgames.hashutil import tree_hash from syncgames.store import FilesystemStore, empty_meta def test_tree_hash_stable(): a = {"b.bin": "sha256:aa", "a.bin": "sha256:bb"} b = {"a.bin": "sha256:bb", "b.bin": "sha256:aa"} assert tree_hash(a) == tree_hash(b) def test_filesystem_roundtrip(tmp_path: Path): store = FilesystemStore(tmp_path / "ssot") game = "test-game" meta = empty_meta(game, 3) store.put_meta(game, meta) assert store.get_meta(game) is not None local = tmp_path / "wip" local.mkdir() (local / "save.dat").write_bytes(b"hello-save") checksums = store.upload_prefix(game, "live", "", local) assert "save.dat" in checksums dest = tmp_path / "down" got = store.download_live(game, dest) assert got["save.dat"].startswith("sha256:") assert (dest / "save.dat").read_bytes() == b"hello-save" store.upload_prefix(game, "history", "phone/20260101T000000Z", local) hist = store.list_history(game) assert any(h.startswith("phone/") for h in hist) probe = store.probe() assert probe.startswith("sha256:") def test_meta_json_roundtrip(tmp_path: Path): store = FilesystemStore(tmp_path) m = empty_meta("g1") m.raw["lease"] = { "holder": "pc", "expires_at": "2099-01-01T00:00:00Z", "session_id": "x", } store.put_meta("g1", m) again = store.get_meta("g1") assert again is not None assert again.lease["holder"] == "pc" # ensure valid json file text = (tmp_path / "games" / "g1" / "meta.json").read_text() json.loads(text)