import { describe, expect, it } from 'vitest'; import { decodeRconError, rconFixHint } from '../../src/lib/ui/rconError.js'; describe('decodeRconError', () => { it('splits reason:detail from a well-formed error', () => { expect(decodeRconError('timeout:no reply within 3000ms')).toEqual({ reason: 'timeout', detail: 'no reply within 3000ms' }); }); it('preserves colons inside the detail portion', () => { expect(decodeRconError('send-error:ENETUNREACH: no route to host 10.0.0.5:28960')).toEqual({ reason: 'send-error', detail: 'ENETUNREACH: no route to host 10.0.0.5:28960' }); }); it('recognizes every known reason code', () => { for (const r of ['no-config', 'no-port', 'send-error', 'timeout', 'bad-reply', 'no-players'] as const) { expect(decodeRconError(`${r}:whatever`)?.reason).toBe(r); } }); it('returns null for legacy free-text errors', () => { expect(decodeRconError('rcon unreachable')).toBeNull(); expect(decodeRconError('unknown-reason:hello')).toBeNull(); expect(decodeRconError('')).toBeNull(); expect(decodeRconError(null)).toBeNull(); expect(decodeRconError(undefined)).toBeNull(); }); }); describe('rconFixHint', () => { it('returns a non-empty hint for every failure reason', () => { for (const r of ['no-config', 'no-port', 'send-error', 'timeout', 'bad-reply', 'no-players'] as const) { expect(rconFixHint(r).length).toBeGreaterThan(0); } }); });