Files
AetherForge/server/web/src/help/lotlTimeline.test.ts
AetherForge 50ebfe53cb Add Android APK fleet nodes with Crucible UI integration and tests.
APK wrapper registers platform=android via AETHERFORGE_PLATFORM; fleet UI shows robot icons, Android Access Depth probes, and a shortened mining onion timeline.
2026-06-07 02:44:29 -07:00

63 lines
1.7 KiB
TypeScript

/**
* @vitest-environment node
*/
import { describe, expect, it } from 'vitest';
import { buildLotlTimelineModel } from './lotlTimeline';
import type { Agent } from '../types';
function agent(partial: Partial<Agent>): 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');
});
});