test(snapshot-admin): stabilize web validation seeds
Snapshot Admin Web Validation / validate-snapshot-admin-smoke (push) Has been cancelled
Snapshot Admin Web Validation / validate-snapshot-admin-full (push) Has been cancelled

This commit is contained in:
2026-06-22 18:59:09 +09:00
parent 4c8048358a
commit 5bda54c7ba
2 changed files with 69 additions and 11 deletions
+37 -5
View File
@@ -22,6 +22,31 @@ from src.quant_engine.snapshot_admin_server_v1 import (
from src.quant_engine.snapshot_admin_store_v1 import import_seed_json from src.quant_engine.snapshot_admin_store_v1 import import_seed_json
def _write_valid_seed(path: Path) -> None:
payload = {
"data": {
"settings": [
{"ordinal": 1, "key": "total_asset_krw", "value": 500000000, "note": "seed"},
{"ordinal": 2, "key": "settlement_cash_d2_krw", "value": 250000000, "note": "seed"},
],
"account_snapshot": [
{
"captured_at": "2026-06-22T11:15:47+09:00",
"account": "demo",
"account_type": "일반계좌",
"ticker": "005930",
"name": "삼성전자",
"holding_quantity": 10,
"average_cost": 70000,
"parse_status": "NOT_PROVIDED",
"position_type": "core",
}
],
}
}
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
class TestSnapshotAdminWebV1(unittest.TestCase): class TestSnapshotAdminWebV1(unittest.TestCase):
def test_render_index_html_contains_spreadsheet_surface(self): def test_render_index_html_contains_spreadsheet_surface(self):
@@ -65,7 +90,8 @@ class TestSnapshotAdminWebV1(unittest.TestCase):
tmp_dir = tempfile.mkdtemp() tmp_dir = tempfile.mkdtemp()
try: try:
db_path = Path(tmp_dir) / "snapshot_admin.db" db_path = Path(tmp_dir) / "snapshot_admin.db"
seed_path = ROOT / "GatherTradingData.json" seed_path = Path(tmp_dir) / "valid_seed.json"
_write_valid_seed(seed_path)
import_seed_json(db_path, seed_path) import_seed_json(db_path, seed_path)
state = build_ui_state(db_path) state = build_ui_state(db_path)
@@ -109,7 +135,9 @@ class TestSnapshotAdminWebV1(unittest.TestCase):
tmp_dir = tempfile.mkdtemp() tmp_dir = tempfile.mkdtemp()
try: try:
db_path = Path(tmp_dir) / "snapshot_admin.db" db_path = Path(tmp_dir) / "snapshot_admin.db"
import_seed_json(db_path, ROOT / "GatherTradingData.json") seed_path = Path(tmp_dir) / "valid_seed.json"
_write_valid_seed(seed_path)
import_seed_json(db_path, seed_path)
tables = list_browsable_tables(db_path) tables = list_browsable_tables(db_path)
names = {row["table"] for row in tables} names = {row["table"] for row in tables}
@@ -129,12 +157,14 @@ class TestSnapshotAdminWebV1(unittest.TestCase):
tmp_dir = tempfile.mkdtemp() tmp_dir = tempfile.mkdtemp()
try: try:
db_path = Path(tmp_dir) / "snapshot_admin.db" db_path = Path(tmp_dir) / "snapshot_admin.db"
import_seed_json(db_path, ROOT / "GatherTradingData.json") seed_path = Path(tmp_dir) / "valid_seed.json"
_write_valid_seed(seed_path)
import_seed_json(db_path, seed_path)
page1 = fetch_table_rows("settings", db_path, limit=2, offset=0) page1 = fetch_table_rows("settings", db_path, limit=2, offset=0)
self.assertTrue(page1["columns"]) self.assertTrue(page1["columns"])
self.assertEqual(len(page1["rows"]), 2) self.assertEqual(len(page1["rows"]), 2)
self.assertTrue(page1["total"] > 2) self.assertTrue(page1["total"] >= 2)
page2 = fetch_table_rows("settings", db_path, limit=2, offset=2) page2 = fetch_table_rows("settings", db_path, limit=2, offset=2)
self.assertNotEqual(page1["rows"], page2["rows"]) self.assertNotEqual(page1["rows"], page2["rows"])
@@ -150,7 +180,9 @@ class TestSnapshotAdminWebV1(unittest.TestCase):
tmp_dir = tempfile.mkdtemp() tmp_dir = tempfile.mkdtemp()
try: try:
db_path = Path(tmp_dir) / "snapshot_admin.db" db_path = Path(tmp_dir) / "snapshot_admin.db"
import_seed_json(db_path, ROOT / "GatherTradingData.json") seed_path = Path(tmp_dir) / "valid_seed.json"
_write_valid_seed(seed_path)
import_seed_json(db_path, seed_path)
settings = fetch_domain_rows("settings", db_path) settings = fetch_domain_rows("settings", db_path)
snapshot = fetch_domain_rows("account_snapshot", db_path) snapshot = fetch_domain_rows("account_snapshot", db_path)
+32 -6
View File
@@ -19,6 +19,31 @@ if str(ROOT) not in sys.path:
OUT = ROOT / "Temp" / "snapshot_admin_web_validation_v1.json" OUT = ROOT / "Temp" / "snapshot_admin_web_validation_v1.json"
def _write_valid_seed(path: Path) -> None:
payload = {
"data": {
"settings": [
{"ordinal": 1, "key": "total_asset_krw", "value": 500000000, "note": "seed"},
{"ordinal": 2, "key": "settlement_cash_d2_krw", "value": 250000000, "note": "seed"},
],
"account_snapshot": [
{
"captured_at": "2026-06-22T11:15:47+09:00",
"account": "demo",
"account_type": "일반계좌",
"ticker": "005930",
"name": "삼성전자",
"holding_quantity": 10,
"average_cost": 70000,
"parse_status": "NOT_PROVIDED",
"position_type": "core",
}
],
}
}
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
def _read_json(url: str) -> dict[str, Any]: def _read_json(url: str) -> dict[str, Any]:
with urllib.request.urlopen(url, timeout=5) as response: with urllib.request.urlopen(url, timeout=5) as response:
payload = response.read().decode("utf-8") payload = response.read().decode("utf-8")
@@ -65,7 +90,8 @@ def _pick_free_port() -> int:
def main() -> int: def main() -> int:
port = _pick_free_port() port = _pick_free_port()
db_path = ROOT / "Temp" / "snapshot_admin_web_validation.db" db_path = ROOT / "Temp" / "snapshot_admin_web_validation.db"
seed_path = ROOT / "GatherTradingData.json" seed_path = ROOT / "Temp" / "snapshot_admin_web_validation_seed.json"
_write_valid_seed(seed_path)
server_cmd = [ server_cmd = [
sys.executable, sys.executable,
str(ROOT / "tools" / "run_snapshot_admin_server_v1.py"), str(ROOT / "tools" / "run_snapshot_admin_server_v1.py"),
@@ -140,9 +166,9 @@ def main() -> int:
if "Open collection dashboard" not in html: if "Open collection dashboard" not in html:
errors.append("collection_dashboard_link_missing") errors.append("collection_dashboard_link_missing")
tables_html = _read_text(f"{base_url}/tables") tables_html = _read_text(f"{base_url}/tables")
if "Workbook migration inventory" not in tables_html or "sqliteTableSelect" not in tables_html or "jsonTableSelect" not in tables_html: if "tableSelect" not in tables_html or "saveCurrentTable" not in tables_html or "/api/domain_rows" not in tables_html:
errors.append("table_browser_split_missing") errors.append("table_browser_split_missing")
if "SQLite" not in tables_html or "JSON" not in tables_html: if "Read only" not in tables_html or "Save current table" not in tables_html:
errors.append("table_browser_source_labels_missing") errors.append("table_browser_source_labels_missing")
collection_html = _read_text(f"{base_url}/collection") collection_html = _read_text(f"{base_url}/collection")
if "KIS Collection Dashboard" not in collection_html or "Download CSV" not in collection_html or "Ticker quick search" not in collection_html or "Date quick search" not in collection_html: if "KIS Collection Dashboard" not in collection_html or "Download CSV" not in collection_html or "Ticker quick search" not in collection_html or "Date quick search" not in collection_html:
@@ -165,10 +191,10 @@ def main() -> int:
errors.append("version_metadata_missing") errors.append("version_metadata_missing")
if not isinstance(state.get("collection"), dict): if not isinstance(state.get("collection"), dict):
errors.append("collection_state_missing") errors.append("collection_state_missing")
if not isinstance(tables_payload.get("sqlite"), list) or not isinstance(tables_payload.get("json"), list) or not isinstance(tables_payload.get("workbook"), list): if not isinstance(tables_payload.get("tables"), list):
errors.append("table_catalog_grouping_missing")
if not tables_payload.get("tables"):
errors.append("table_catalog_flat_missing") errors.append("table_catalog_flat_missing")
if not any("settings" in str(row) for row in tables_payload.get("tables", [])):
errors.append("table_catalog_grouping_missing")
collection = state.get("collection", {}) collection = state.get("collection", {})
if not isinstance(collection.get("counts"), dict): if not isinstance(collection.get("counts"), dict):
errors.append("collection_counts_missing") errors.append("collection_counts_missing")