agent-ecosystem/test/renderer/components/team/provisioningSteps.test.ts
infiniti 9758fafd10
feat(team): support sent message revisions
* fix(opencode): recover empty bridge output sends

* fix(opencode): handle empty readiness bridge output

* fix(opencode): retry read-only bridge no-output

* fix(opencode): recover empty bridge output sends

---------

Co-authored-by: iliya <iliyazelenkog@gmail.com>

* fix(runtime-provider): clarify opencode model routes ux

* fix(team): show create dialog loading fallback

* feat(team): support revising sent messages

* test(team): cover sent message revision flow

* fix(opencode): harden local runtime bridge support

* fix(member-work-sync): recover stale nudge payload conflicts

* fix(runtime): gate codex install prompt on runtime status

* fix(team): persist incomplete launch state before cleanup

* fix(team): keep launch pending for dead runtime entries

* feat(logs): compact team log source controls

* fix(build): verify radix presence patch before build

* fix(renderer): recover failed dynamic imports

* fix(team): preserve task labels and change presence

* fix(logs): restore member process log source

* fix(team): require revision notice before editing

---------

Co-authored-by: iliya <iliyazelenkog@gmail.com>
Co-authored-by: 777genius <quantjumppro@gmail.com>
2026-05-25 21:11:59 +03:00

246 lines
7.5 KiB
TypeScript

import { getLaunchJoinMilestonesFromMembers } from '@renderer/components/team/provisioningSteps';
import { describe, expect, it } from 'vitest';
const members = [{ name: 'alice' }, { name: 'bob' }, { name: 'tom' }, { name: 'jane' }];
describe('getLaunchJoinMilestonesFromMembers', () => {
it('does not count shell-only liveness as process alive', () => {
const milestones = getLaunchJoinMilestonesFromMembers({
members,
memberSpawnStatuses: {
alice: {
status: 'online',
launchState: 'runtime_pending_bootstrap',
runtimeAlive: true,
livenessSource: 'process',
livenessKind: 'shell_only',
updatedAt: '2026-04-24T12:00:00.000Z',
},
bob: {
status: 'online',
launchState: 'runtime_pending_bootstrap',
runtimeAlive: true,
livenessSource: 'process',
livenessKind: 'runtime_process',
updatedAt: '2026-04-24T12:00:00.000Z',
},
tom: {
status: 'online',
launchState: 'runtime_pending_bootstrap',
runtimeAlive: true,
livenessSource: 'process',
livenessKind: 'runtime_process_candidate',
updatedAt: '2026-04-24T12:00:00.000Z',
},
jane: {
status: 'online',
launchState: 'runtime_pending_bootstrap',
runtimeAlive: true,
livenessSource: 'process',
updatedAt: '2026-04-24T12:00:00.000Z',
},
},
});
expect(milestones.processOnlyAliveCount).toBe(1);
expect(milestones.pendingSpawnCount).toBe(3);
});
it('does not count missing liveness kind as process alive', () => {
const milestones = getLaunchJoinMilestonesFromMembers({
members,
memberSpawnStatuses: {
alice: {
status: 'online',
launchState: 'runtime_pending_bootstrap',
runtimeAlive: true,
livenessSource: 'process',
updatedAt: '2026-04-24T12:00:00.000Z',
},
},
});
expect(milestones.processOnlyAliveCount).toBe(0);
expect(milestones.pendingSpawnCount).toBe(4);
});
it('keeps bootstrap-stalled runtime processes out of process-alive progress', () => {
const milestones = getLaunchJoinMilestonesFromMembers({
members,
memberSpawnStatuses: {
alice: {
status: 'waiting',
launchState: 'runtime_pending_bootstrap',
runtimeAlive: true,
livenessKind: 'runtime_process',
bootstrapStalled: true,
updatedAt: '2026-04-24T12:05:00.000Z',
},
},
});
expect(milestones.processOnlyAliveCount).toBe(0);
expect(milestones.pendingSpawnCount).toBe(4);
});
it('uses runtimeProcessPendingCount instead of legacy runtimeAlivePendingCount for snapshot pending math', () => {
const milestones = getLaunchJoinMilestonesFromMembers({
members,
memberSpawnSnapshot: {
expectedMembers: ['alice', 'bob', 'tom', 'jane'],
summary: {
confirmedCount: 0,
pendingCount: 4,
failedCount: 0,
runtimeAlivePendingCount: 3,
runtimeProcessPendingCount: 1,
shellOnlyPendingCount: 1,
runtimeCandidatePendingCount: 1,
permissionPendingCount: 1,
},
},
});
expect(milestones.processOnlyAliveCount).toBe(1);
expect(milestones.pendingSpawnCount).toBe(3);
});
it('does not trust legacy runtimeAlivePendingCount without runtime process count', () => {
const milestones = getLaunchJoinMilestonesFromMembers({
members,
memberSpawnSnapshot: {
expectedMembers: ['alice', 'bob', 'tom', 'jane'],
summary: {
confirmedCount: 0,
pendingCount: 4,
failedCount: 0,
runtimeAlivePendingCount: 3,
},
},
});
expect(milestones.processOnlyAliveCount).toBe(0);
expect(milestones.pendingSpawnCount).toBe(4);
});
it('counts skipped teammates separately from pending and failed launch members', () => {
const milestones = getLaunchJoinMilestonesFromMembers({
members,
memberSpawnStatuses: {
alice: {
status: 'skipped',
launchState: 'skipped_for_launch',
skippedForLaunch: true,
runtimeAlive: false,
bootstrapConfirmed: false,
hardFailure: false,
updatedAt: '2026-04-24T12:00:00.000Z',
},
},
});
expect(milestones.skippedSpawnCount).toBe(1);
expect(milestones.failedSpawnCount).toBe(0);
expect(milestones.pendingSpawnCount).toBe(3);
});
it('does not let a stale clean snapshot hide live registered-only members', () => {
const milestones = getLaunchJoinMilestonesFromMembers({
members,
memberSpawnStatuses: {
alice: {
status: 'online',
launchState: 'confirmed_alive',
runtimeAlive: true,
bootstrapConfirmed: true,
updatedAt: '2026-04-24T12:00:00.000Z',
},
bob: {
status: 'waiting',
launchState: 'runtime_pending_bootstrap',
runtimeAlive: false,
bootstrapConfirmed: false,
livenessKind: 'registered_only',
updatedAt: '2026-04-24T12:00:01.000Z',
},
tom: {
status: 'online',
launchState: 'confirmed_alive',
runtimeAlive: true,
bootstrapConfirmed: true,
updatedAt: '2026-04-24T12:00:00.000Z',
},
jane: {
status: 'online',
launchState: 'confirmed_alive',
runtimeAlive: true,
bootstrapConfirmed: true,
updatedAt: '2026-04-24T12:00:00.000Z',
},
},
memberSpawnSnapshot: {
expectedMembers: ['alice', 'bob', 'tom', 'jane'],
summary: {
confirmedCount: 4,
pendingCount: 0,
failedCount: 0,
runtimeAlivePendingCount: 0,
},
},
});
expect(milestones.heartbeatConfirmedCount).toBe(3);
expect(milestones.pendingSpawnCount).toBe(1);
expect(milestones.expectedTeammateCount).toBe(4);
});
it('does not count confirmed spawn as joined when runtime snapshot is unavailable', () => {
const milestones = getLaunchJoinMilestonesFromMembers({
members,
memberSpawnStatuses: {
alice: {
status: 'online',
launchState: 'confirmed_alive',
runtimeAlive: true,
bootstrapConfirmed: true,
updatedAt: '2026-04-24T12:00:00.000Z',
},
bob: {
status: 'online',
launchState: 'confirmed_alive',
runtimeAlive: true,
bootstrapConfirmed: true,
updatedAt: '2026-04-24T12:00:01.000Z',
},
tom: {
status: 'online',
launchState: 'confirmed_alive',
runtimeAlive: true,
bootstrapConfirmed: true,
updatedAt: '2026-04-24T12:00:00.000Z',
},
jane: {
status: 'online',
launchState: 'confirmed_alive',
runtimeAlive: true,
bootstrapConfirmed: true,
updatedAt: '2026-04-24T12:00:00.000Z',
},
},
memberRuntimeEntries: {
bob: {
memberName: 'bob',
alive: false,
restartable: true,
livenessKind: 'registered_only',
runtimeDiagnostic: 'registered runtime metadata without live process',
updatedAt: '2026-04-24T12:00:02.000Z',
},
},
});
expect(milestones.heartbeatConfirmedCount).toBe(3);
expect(milestones.pendingSpawnCount).toBe(1);
expect(milestones.expectedTeammateCount).toBe(4);
});
});