import { describe, expect, it } from 'vitest'; import { mockAgent } from '../test/fixtures'; import type { FleetGroup } from './fleetGroups'; import { groupClusterCenter, hashrateSpiked, hashPosition, layoutAgentPoints, layoutComradePoints, } from './fleetHeatMap'; describe('fleetHeatMap', () => { it('hashPosition is stable for the same seed', () => { const a = hashPosition('node-alpha'); const b = hashPosition('node-alpha'); expect(a).toEqual(b); expect(a.x).toBeGreaterThanOrEqual(12); expect(a.y).toBeLessThanOrEqual(88); }); it('groupClusterCenter spreads clusters around the map', () => { const c0 = groupClusterCenter(0, 4); const c1 = groupClusterCenter(2, 4); expect(Math.hypot(c0.x - c1.x, c0.y - c1.y)).toBeGreaterThan(10); }); it('layoutAgentPoints clusters grouped agents and hashes ungrouped hosts', () => { const groups: FleetGroup[] = [ { id: 'g1', name: 'Alpha', color: '#00e8f5', agentIds: ['a1', 'a2'], createdAt: '2026-01-01T00:00:00Z', }, ]; const agents = [ mockAgent({ id: 'a1', name: 'one', hostname: 'host-one' }), mockAgent({ id: 'a2', name: 'two', hostname: 'host-two' }), mockAgent({ id: 'a3', name: 'solo', hostname: 'solo-host' }), ]; const points = layoutAgentPoints(agents, groups); expect(points).toHaveLength(3); const grouped = points.filter((p) => p.id === 'a1' || p.id === 'a2'); const solo = points.find((p) => p.id === 'a3'); const dist = Math.hypot(grouped[0].x - grouped[1].x, grouped[0].y - grouped[1].y); expect(dist).toBeLessThan(20); expect(solo?.color).toBeUndefined(); const soloAgain = layoutAgentPoints([agents[2]], groups).find((p) => p.id === 'a3'); expect(solo).toEqual(soloAgain); }); it('layoutComradePoints uses distinct comrade kind', () => { const pts = layoutComradePoints(['india', 'ally']); expect(pts.every((p) => p.kind === 'comrade')).toBe(true); expect(pts[0].id).toBe('comrade:india'); }); it('hashrateSpiked detects ratio and minimum delta', () => { expect(hashrateSpiked(undefined, 0)).toBe(false); expect(hashrateSpiked(undefined, 80)).toBe(true); expect(hashrateSpiked(100, 110)).toBe(false); expect(hashrateSpiked(100, 160)).toBe(true); }); });