Skip to content

Commit a8d119b

Browse files
committed
feat(dashboard/test): Added tests for dashboard endpoints
1 parent 564f405 commit a8d119b

2 files changed

Lines changed: 82 additions & 0 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import axios from 'axios'
2+
import { createDashboardService } from '../../../src/dashboard-service/app'
3+
import { expect } from 'chai'
4+
import WebSocket from 'ws'
5+
6+
describe('dashboard-service app', () => {
7+
it('serves health, snapshot, and websocket endpoints', async () => {
8+
const service = createDashboardService({
9+
host: '127.0.0.1',
10+
port: 0,
11+
wsPath: '/api/v1/kpis/stream',
12+
pollIntervalMs: 1000,
13+
})
14+
15+
await service.start()
16+
17+
const port = service.getHttpPort()
18+
19+
const healthResponse = await axios.get(`http://127.0.0.1:${port}/healthz`)
20+
expect(healthResponse.status).to.equal(200)
21+
22+
const snapshotResponse = await axios.get(`http://127.0.0.1:${port}/api/v1/kpis/snapshot`)
23+
expect(snapshotResponse.status).to.equal(200)
24+
25+
const snapshotJson = snapshotResponse.data as any
26+
expect(snapshotJson.data).to.have.property('sequence')
27+
28+
const ws = new WebSocket(`ws://127.0.0.1:${port}/api/v1/kpis/stream`)
29+
30+
const connectedEvent = await new Promise<any>((resolve, reject) => {
31+
const timeout = setTimeout(() => reject(new Error('timeout waiting for ws message')), 2000)
32+
ws.once('message', (raw) => {
33+
clearTimeout(timeout)
34+
resolve(JSON.parse(raw.toString()))
35+
})
36+
})
37+
38+
expect(connectedEvent).to.have.property('type', 'dashboard.connected')
39+
40+
ws.close()
41+
await service.stop()
42+
})
43+
})
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { expect } from 'chai'
2+
import Sinon from 'sinon'
3+
4+
import { PollingScheduler } from '../../../src/dashboard-service/polling/polling-scheduler'
5+
6+
describe('PollingScheduler', () => {
7+
let clock: Sinon.SinonFakeTimers
8+
9+
beforeEach(() => {
10+
clock = Sinon.useFakeTimers()
11+
})
12+
13+
afterEach(() => {
14+
clock.restore()
15+
})
16+
17+
it('runs tick callback on interval while running', async () => {
18+
const tick = Sinon.stub().resolves(undefined)
19+
const scheduler = new PollingScheduler(1000, tick)
20+
21+
scheduler.start()
22+
await clock.tickAsync(3000)
23+
24+
expect(tick.callCount).to.equal(3)
25+
scheduler.stop()
26+
})
27+
28+
it('stops running when stop is called', async () => {
29+
const tick = Sinon.stub().resolves(undefined)
30+
const scheduler = new PollingScheduler(500, tick)
31+
32+
scheduler.start()
33+
await clock.tickAsync(1000)
34+
scheduler.stop()
35+
await clock.tickAsync(1000)
36+
37+
expect(tick.callCount).to.equal(2)
38+
})
39+
})

0 commit comments

Comments
 (0)