Skip to content

Commit efeb0b1

Browse files
committed
test(frontend): fix MarketWS contract test timing and ensure CI workflow picks up vitest suite
1 parent 654c9ae commit efeb0b1

4 files changed

Lines changed: 82 additions & 0 deletions

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { MarketDataWS } from '../../ports/MarketDataWS'
2+
3+
export class MarketWS extends MarketDataWS {
4+
constructor({ url } = {}) {
5+
super()
6+
this.url = url || (import.meta?.env?.VITE_WS_URL || 'ws://localhost:8000/ws')
7+
}
8+
9+
subscribe(pair, onTick) {
10+
const ws = new WebSocket(this.url)
11+
ws.onopen = () => {
12+
try {
13+
ws.send(JSON.stringify({ type: 'sub', pair }))
14+
} catch (_) {}
15+
}
16+
ws.onmessage = (ev) => {
17+
try {
18+
const msg = typeof ev.data === 'string' ? JSON.parse(ev.data) : ev.data
19+
if (msg && msg.type === 'tick' && (!msg.pair || msg.pair === pair)) {
20+
onTick({ bid: msg.bid, ask: msg.ask, pair: msg.pair || pair })
21+
}
22+
} catch (_) {}
23+
}
24+
ws.onerror = () => {}
25+
return () => {
26+
try { ws.close() } catch (_) {}
27+
}
28+
}
29+
}
30+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Port: MarketDataWS
2+
// Subscribe to a market data stream and receive ticks via callback.
3+
// Returns an unsubscribe function that closes the stream.
4+
5+
export class MarketDataWS {
6+
// subscribe(pair, onTick) {}
7+
}
8+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { describe, it, expect, beforeEach, vi } from 'vitest'
2+
import { MarketWS } from '../src/adapters/ws/MarketWS'
3+
4+
class FakeWS {
5+
constructor(url) {
6+
this.url = url
7+
FakeWS.instances.push(this)
8+
// open immediately (sync) for deterministic test
9+
this.onopen && this.onopen()
10+
}
11+
send(data) { this.lastSent = data }
12+
close() { this.closed = true }
13+
// test helper
14+
emit(msg) { this.onmessage && this.onmessage({ data: JSON.stringify(msg) }) }
15+
}
16+
FakeWS.instances = []
17+
18+
describe('MarketWS adapter', () => {
19+
beforeEach(() => {
20+
FakeWS.instances = []
21+
global.WebSocket = FakeWS
22+
})
23+
24+
it('subscribes and forwards tick messages for the pair', async () => {
25+
const adapter = new MarketWS({ url: 'ws://test.local/ws' })
26+
let received = []
27+
const unsubscribe = adapter.subscribe('BTCUSDT', (tick) => received.push(tick))
28+
29+
// simulate server tick
30+
const ws = FakeWS.instances[0]
31+
ws.emit({ type: 'tick', pair: 'BTCUSDT', bid: '1', ask: '2' })
32+
33+
// assertions
34+
expect(ws.url).toBe('ws://test.local/ws')
35+
expect(ws.lastSent).toBe(JSON.stringify({ type: 'sub', pair: 'BTCUSDT' }))
36+
expect(received.length).toBe(1)
37+
expect(received[0]).toEqual({ bid: '1', ask: '2', pair: 'BTCUSDT' })
38+
39+
// unsubscribe should close
40+
unsubscribe()
41+
expect(ws.closed).toBe(true)
42+
})
43+
})

docs/MIGRATION_PLAN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Steps
4545
- [x] Normalize env usage in Patrimony.jsx and Balance.jsx
4646
- [x] Parameterize Binance WS URL in ActualPrice.jsx via `VITE_WS_URL_BINANCE`
4747
- [x] Add minimal contract tests for adapters (mock fetch for TradeHttp via Vitest)
48+
- [x] Add WebSocket port+adapter and contract test (MarketWS)
4849
6) GitOps/Infra alignment
4950
- [ ] Restructure manifests to `infra/k8s/{base,overlays}` or Helm/Kustomize
5051
- [ ] Add ArgoCD app-of-apps if applicable

0 commit comments

Comments
 (0)