143 lines
4.8 KiB
Python
143 lines
4.8 KiB
Python
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}]
|
|
)
|