"""Tests du stockage local de licence (vrais fichiers, aucun mock). Couvre : résolution du chemin par plateforme, round-trip save/load, création du répertoire parent, suppression, robustesse au JSON corrompu. """ from __future__ import annotations import json from pathlib import Path import pytest from gui_v6.license_store import LicenseStore, default_license_path def test_default_path_windows(monkeypatch): monkeypatch.setattr("sys.platform", "win32") monkeypatch.setenv("LOCALAPPDATA", r"C:\Users\dom\AppData\Local") path = default_license_path() parts = path.as_posix() assert parts.endswith("Aivanov/Anonymisation/license.json") def test_default_path_linux(monkeypatch): monkeypatch.setattr("sys.platform", "linux") monkeypatch.delenv("XDG_DATA_HOME", raising=False) monkeypatch.setattr(Path, "home", classmethod(lambda cls: Path("/home/tester"))) path = default_license_path() assert path == Path("/home/tester/.local/share/aivanov/anonymisation/license.json") def test_default_path_linux_respects_xdg(monkeypatch): monkeypatch.setattr("sys.platform", "linux") monkeypatch.setenv("XDG_DATA_HOME", "/custom/data") path = default_license_path() assert path == Path("/custom/data/aivanov/anonymisation/license.json") def test_save_creates_parent_dir_and_roundtrips(tmp_path): target = tmp_path / "nested" / "dir" / "license.json" store = LicenseStore(target) assert not store.exists() payload = {"status": "active", "license_ref": "LIC-123", "expires_at": "2027-01-01"} store.save(payload) assert target.is_file() assert store.exists() assert store.load() == payload # Vérifie aussi le contenu sur disque (vrai fichier JSON). on_disk = json.loads(target.read_text(encoding="utf-8")) assert on_disk["license_ref"] == "LIC-123" def test_load_absent_returns_none(tmp_path): store = LicenseStore(tmp_path / "absent.json") assert store.load() is None def test_load_corrupted_returns_none(tmp_path): target = tmp_path / "license.json" target.write_text("{ this is not valid json", encoding="utf-8") store = LicenseStore(target) assert store.load() is None def test_load_non_object_returns_none(tmp_path): target = tmp_path / "license.json" target.write_text("[1, 2, 3]", encoding="utf-8") store = LicenseStore(target) assert store.load() is None def test_delete(tmp_path): target = tmp_path / "license.json" store = LicenseStore(target) store.save({"status": "active"}) assert store.delete() is True assert not target.exists() # Suppression idempotente : un second delete ne lève pas. assert store.delete() is False def test_save_overwrites(tmp_path): store = LicenseStore(tmp_path / "license.json") store.save({"status": "active", "v": 1}) store.save({"status": "grace", "v": 2}) loaded = store.load() assert loaded["status"] == "grace" assert loaded["v"] == 2