Files
eth_hedge_sim/backend/tests/test_delete_trade_group.py
dekun 42e56d940c Add delete for closed trade records.
Only closed groups can be removed from local history; equity is unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 16:06:36 +08:00

93 lines
3.2 KiB
Python

"""删除单条已平仓交易记录。"""
from __future__ import annotations
import asyncio
import pytest
from fastapi import HTTPException
from app.api.trades import delete_group
from app.models.db import Database
def _seed_closed(db: Database, gid: str = "G-DEL-1") -> None:
with db._lock:
db._conn.execute(
"""INSERT INTO groups(group_id, status, open_at_ms, close_at_ms, realized_pnl)
VALUES (?, 'closed', 1, 2, 1.5)""",
(gid,),
)
db._conn.execute(
"""INSERT INTO fills(group_id, leg, action, side, inst_id, qty_eth,
fill_px, fee, slip, notional, ts_ms)
VALUES (?, 'option', 'open', 'buy', 'ETH-C', 1, 10, 0.1, 0, 10, 1)""",
(gid,),
)
db._conn.execute(
"""INSERT INTO residual_options(
group_id, option_inst_id, option_side, option_qty_eth,
option_entry_px, status, created_at_ms
) VALUES (?, 'ETH-C', 'call', 1, 10, 'pending', 1)""",
(gid,),
)
db._conn.execute(
"""INSERT INTO ledger_entries(group_id, kind, amount, balance_after, note, ts_ms)
VALUES (?, 'pnl', 1.5, 10001.5, 't', 2)""",
(gid,),
)
db._conn.commit()
def test_delete_closed_group(tmp_path, monkeypatch) -> None:
monkeypatch.setenv("MODE", "SIM")
db = Database(tmp_path / "del.db")
monkeypatch.setattr("app.api.trades.get_db", lambda: db)
_seed_closed(db)
out = asyncio.run(delete_group("G-DEL-1", _user="t"))
assert out["ok"] is True
assert db.fetchone("SELECT COUNT(*) AS c FROM groups")["c"] == 0
assert db.fetchone("SELECT COUNT(*) AS c FROM fills")["c"] == 0
assert db.fetchone("SELECT COUNT(*) AS c FROM residual_options")["c"] == 0
assert db.fetchone("SELECT COUNT(*) AS c FROM ledger_entries")["c"] == 0
db.close()
def test_delete_open_group_refused(tmp_path, monkeypatch) -> None:
monkeypatch.setenv("MODE", "SIM")
db = Database(tmp_path / "del_open.db")
monkeypatch.setattr("app.api.trades.get_db", lambda: db)
with db._lock:
db._conn.execute(
"""INSERT INTO groups(group_id, status, open_at_ms)
VALUES ('G-OPEN', 'open', 1)"""
)
db._conn.commit()
with pytest.raises(HTTPException) as ei:
asyncio.run(delete_group("G-OPEN", _user="t"))
assert ei.value.status_code == 409
assert db.fetchone("SELECT COUNT(*) AS c FROM groups")["c"] == 1
db.close()
def test_delete_active_position_refused(tmp_path, monkeypatch) -> None:
monkeypatch.setenv("MODE", "SIM")
db = Database(tmp_path / "del_pos.db")
monkeypatch.setattr("app.api.trades.get_db", lambda: db)
_seed_closed(db, "G-POS")
with db._lock:
# status closed but still referenced (edge)
db._conn.execute(
"UPDATE positions SET group_id=?, status='open' WHERE id=1",
("G-POS",),
)
db._conn.commit()
with pytest.raises(HTTPException) as ei:
asyncio.run(delete_group("G-POS", _user="t"))
assert ei.value.status_code == 409
assert db.fetchone("SELECT COUNT(*) AS c FROM groups")["c"] == 1
db.close()