from __future__ import annotations from pathlib import Path from gyxx_flow.adapters.browser import BrowserCookieStore from gyxx_flow.adapters.erp_state import ( has_erp_session_cookie, persist_erp_runtime_state, restore_erp_runtime_state, ) class _FakeContext: def __init__(self) -> None: self._cookies: list[dict[str, object]] = [] self._storage_state: dict[str, object] = {"cookies": [], "origins": []} def set_storage_state(self, state: dict[str, object]) -> None: self._storage_state = state def add_cookies(self, cookies: list[dict[str, object]]) -> None: self._cookies.extend(cookies) def cookies(self) -> list[dict[str, object]]: return list(self._cookies) def storage_state(self) -> dict[str, object]: return dict(self._storage_state) def _set_state_environment(monkeypatch, root: Path) -> tuple[Path, Path, Path, Path]: account_cookie = root / "account" / "cookies.json" account_storage = root / "account" / "storage_state.json" binding_cookie = root / "binding" / "cookies.json" binding_storage = root / "binding" / "storage_state.json" monkeypatch.setenv("GYXX_ACCOUNT_ID", "erp-jushuitan") monkeypatch.setenv("GYXX_ACCOUNT_COOKIE_FILE", str(account_cookie)) monkeypatch.setenv("GYXX_ACCOUNT_STORAGE_STATE_FILE", str(account_storage)) monkeypatch.setenv("GYXX_BROWSER_COOKIE_FILE", str(binding_cookie)) monkeypatch.setenv("GYXX_BROWSER_STORAGE_STATE_FILE", str(binding_storage)) return account_cookie, account_storage, binding_cookie, binding_storage def test_account_vault_is_restored_first_and_verified_state_is_persisted( tmp_path: Path, monkeypatch ) -> None: account_cookie, account_storage, binding_cookie, binding_storage = ( _set_state_environment(monkeypatch, tmp_path) ) account_state = [ { "name": "ASP.NET_SessionId", "value": "vault-session", "domain": ".erp321.com", "path": "/", } ] BrowserCookieStore(account_cookie, account_storage).save_cookies(account_state) BrowserCookieStore(account_cookie, account_storage).save_storage_state( {"cookies": account_state, "origins": []} ) binding_state = [ { "name": "ASP.NET_SessionId", "value": "old-binding-session", "domain": ".erp321.com", "path": "/", } ] BrowserCookieStore(binding_cookie, binding_storage).save_cookies(binding_state) BrowserCookieStore(binding_cookie, binding_storage).save_storage_state( {"cookies": binding_state, "origins": []} ) context = _FakeContext() assert restore_erp_runtime_state(context) == "account vault" assert context.cookies()[0]["value"] == "vault-session" context._cookies = [ { "name": "ASP.NET_SessionId", "value": "fresh-session", "domain": ".erp321.com", "path": "/", } ] context._storage_state = {"cookies": context.cookies(), "origins": []} assert persist_erp_runtime_state(context) == 1 assert BrowserCookieStore(account_cookie, account_storage).load_cookies()[0][ "value" ] == "fresh-session" assert BrowserCookieStore(binding_cookie, binding_storage).load_cookies()[0][ "value" ] == "fresh-session" def test_erp_restore_uses_cookies_without_replaying_indexeddb_origins( tmp_path: Path, monkeypatch ) -> None: account_cookie, account_storage, _, _ = _set_state_environment(monkeypatch, tmp_path) cookies = [ { "name": "ASP.NET_SessionId", "value": "vault-session", "domain": ".erp321.com", "path": "/", } ] store = BrowserCookieStore(account_cookie, account_storage) store.save_cookies(cookies) store.save_storage_state( { "cookies": cookies, "origins": [ { "origin": "https://www.erp321.com", "localStorage": [{"name": "session", "value": "state"}], "indexedDB": [{"name": "erp", "version": 1}], } ], } ) context = _FakeContext() assert restore_erp_runtime_state(context) == "account vault" assert context._storage_state == {"cookies": cookies} assert context.cookies()[0]["value"] == "vault-session" def test_erp_session_cookie_detection_accepts_jushuitan_identity_cookie() -> None: assert has_erp_session_cookie( [{"name": "u_id", "value": "22469720", "domain": ".erp321.com"}] ) assert not has_erp_session_cookie( [{"name": "u_id", "value": "", "domain": ".erp321.com"}] ) def test_erp_session_cookie_detection_rejects_expired_identity_cookie() -> None: assert not has_erp_session_cookie( [{"name": "u_id", "value": "expired", "expires": 1}] )