from __future__ import annotations import json from gibby.models import AccountRecord, StateFile, UsageSnapshot, UsageWindow from gibby.store import JsonStateStore def test_store_writes_canonical_usage_snapshot_shape(tmp_path) -> None: store = JsonStateStore(tmp_path / "accounts.json") snapshot = UsageSnapshot( checked_at=1000, used_percent=75, remaining_percent=25, exhausted=False, primary_window=UsageWindow(75, 18000, 300, 1300), secondary_window=UsageWindow(10, 604800, 3600, 4600), limit_reached=False, allowed=True, ) store.save( StateFile( accounts=[ AccountRecord( id="acc@example.com", email="acc@example.com", access_token="tok", refresh_token="ref", expires_at=2000, last_known_usage=snapshot, ) ] ) ) payload = json.loads((tmp_path / "accounts.json").read_text()) saved_snapshot = payload["accounts"][0]["last_known_usage"] assert set(saved_snapshot) == { "checked_at", "primary_window", "secondary_window", "limit_reached", "allowed", } def test_store_load_reconstructs_derived_usage_fields(tmp_path) -> None: path = tmp_path / "accounts.json" path.write_text( json.dumps( { "version": 1, "active_account_id": "acc@example.com", "accounts": [ { "id": "acc@example.com", "email": "acc@example.com", "account_id": "acc-1", "access_token": "tok", "refresh_token": "ref", "expires_at": 2000, "cooldown_until": None, "last_known_usage": { "checked_at": 1000, "primary_window": { "used_percent": 80, "limit_window_seconds": 18000, "reset_after_seconds": 300, "reset_at": 1300, }, "secondary_window": { "used_percent": 100, "limit_window_seconds": 604800, "reset_after_seconds": 3600, "reset_at": 4600, }, "limit_reached": False, "allowed": True, }, "last_error": None, } ], } ) ) state = JsonStateStore(path).load() snapshot = state.accounts[0].last_known_usage assert snapshot is not None assert snapshot.used_percent == 100 assert snapshot.remaining_percent == 0 assert snapshot.exhausted is True assert snapshot.limit_reached is False assert snapshot.allowed is True