alt/packages/domain/trading/account_test.go
toki c0db4b24c1 feat(live-trading): 계좌 동기화와 감사 추적을 추가한다
Live Trading Boundary의 남은 account-sync/audit-trail 작업을 완료해 운영자 headless workflow와 roadmap 완료 후보 상태를 함께 반영한다.
2026-06-08 11:18:41 +09:00

97 lines
2.6 KiB
Go

package trading
import (
"testing"
"time"
"git.toki-labs.com/toki/alt/packages/domain/market"
)
func sampleAccountSnapshot() AccountSnapshot {
return AccountSnapshot{
Broker: BrokerKIS,
AccountID: "op-alias-001",
Cash: []CashBalance{
{Currency: market.CurrencyUSD, Amount: market.Decimal{Value: "1000"}},
{Currency: market.CurrencyKRW, Amount: market.Decimal{Value: "5000000"}},
},
Positions: []PositionSnapshot{
{
InstrumentID: "KRX:005930",
Side: OrderSideBuy,
Quantity: market.Quantity{Amount: market.Decimal{Value: "10"}},
},
},
SyncedAt: time.Date(2026, 6, 8, 0, 0, 0, 0, time.UTC),
Stale: false,
}
}
func TestSortCashBalancesIsStable(t *testing.T) {
snap := sampleAccountSnapshot()
// USD comes before KRW alphabetically; after sort KRW should be first.
SortCashBalances(snap.Cash)
if len(snap.Cash) != 2 {
t.Fatalf("expected 2 cash balances, got %d", len(snap.Cash))
}
if snap.Cash[0].Currency != market.CurrencyKRW {
t.Errorf("expected KRW first after sort, got %q", snap.Cash[0].Currency)
}
if snap.Cash[1].Currency != market.CurrencyUSD {
t.Errorf("expected USD second after sort, got %q", snap.Cash[1].Currency)
}
}
func TestSortCashBalancesEmptyIsNoop(t *testing.T) {
SortCashBalances(nil)
SortCashBalances([]CashBalance{})
}
func TestSortPositionSnapshotsIsStable(t *testing.T) {
positions := []PositionSnapshot{
{InstrumentID: "US:MSFT"},
{InstrumentID: "KRX:005930"},
}
SortPositionSnapshots(positions)
if positions[0].InstrumentID != "KRX:005930" {
t.Errorf("expected KRX:005930 first, got %q", positions[0].InstrumentID)
}
if positions[1].InstrumentID != "US:MSFT" {
t.Errorf("expected US:MSFT second, got %q", positions[1].InstrumentID)
}
}
func TestAccountSnapshotHasNoRawAccountNumber(t *testing.T) {
snap := sampleAccountSnapshot()
if HasRawAccountNumber(snap) {
t.Error("AccountSnapshot must not carry a raw account number")
}
}
func TestAccountSnapshotMultiCurrencyCashPreserved(t *testing.T) {
snap := sampleAccountSnapshot()
if len(snap.Cash) != 2 {
t.Errorf("expected 2 cash entries, got %d", len(snap.Cash))
}
foundKRW := false
foundUSD := false
for _, c := range snap.Cash {
if c.Currency == market.CurrencyKRW {
foundKRW = true
}
if c.Currency == market.CurrencyUSD {
foundUSD = true
}
}
if !foundKRW || !foundUSD {
t.Error("expected KRW and USD cash balances to be preserved")
}
}
func TestStaleSnapshotFlagIsPreserved(t *testing.T) {
snap := sampleAccountSnapshot()
snap.Stale = true
if !snap.Stale {
t.Error("expected Stale=true to be preserved")
}
}