/** * @vitest-environment node */ import { describe, expect, it } from 'vitest'; import { buildLotlTimelineModel } from './lotlTimeline'; import type { Agent } from '../types'; function agent(partial: Partial): Agent { return { id: 'x', name: 'n', wallet: '', ip: '1.1.1.1', version: '1', status: 'online', cpu_cores: 4, memory_gb: 8, last_seen: '', created_at: '', hashrate_15s: 0, hashrate_1m: 0, hashrate_15m: 0, shares_total: 0, shares_good: 0, shares_bad: 0, cpu_usage_pct: 0, memory_usage_pct: 0, uptime_seconds: 0, ...partial, }; } describe('buildLotlTimelineModel atlas skips', () => { it('marks powershell tier skipped_by_atlas when ps_inmemory is blocked', () => { const model = buildLotlTimelineModel( agent({}), ['docker', 'powershell', 'dotnet'], [], [], [{ tier: 'ps_inmemory', condition: 'defender_on', reason: '5 failures' }], ); const ps = model.tiers.find((t) => t.tier === 'powershell'); expect(ps?.state).toBe('skipped_by_atlas'); }); }); describe('buildLotlTimelineModel android', () => { it('shows shortened android chain instead of 14 spread tiers', () => { const model = buildLotlTimelineModel( agent({ platform: 'android', status: 'online', lotl_tier: 'foreground_service' }), ['docker', 'powershell', 'dotnet'], [{ tier: 'foreground_service', ok: false }], ); expect(model.total).toBe(3); expect(model.tiers.map((t) => t.tier)).toEqual([ 'foreground_service', 'cpu_inprocess', 'desktop_tiers_skipped', ]); expect(model.tiers.find((t) => t.tier === 'desktop_tiers_skipped')?.state).toBe('skipped'); }); });