Merge branch 'main' into chore/format-chat-sdk-bridge
This commit is contained in:
55
setup/verify.test.ts
Normal file
55
setup/verify.test.ts
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
|
import { determineVerifyStatus } from './verify.js';
|
||||||
|
|
||||||
|
const healthyBase = {
|
||||||
|
service: 'running' as const,
|
||||||
|
credentials: 'configured',
|
||||||
|
anyChannelConfigured: false,
|
||||||
|
registeredGroups: 1,
|
||||||
|
agentPing: 'ok' as const,
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('determineVerifyStatus', () => {
|
||||||
|
it('accepts a working CLI-only install', () => {
|
||||||
|
expect(determineVerifyStatus(healthyBase)).toBe('success');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accepts a messaging-channel install when CLI ping is skipped', () => {
|
||||||
|
expect(
|
||||||
|
determineVerifyStatus({
|
||||||
|
...healthyBase,
|
||||||
|
anyChannelConfigured: true,
|
||||||
|
agentPing: 'skipped',
|
||||||
|
}),
|
||||||
|
).toBe('success');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails when neither CLI nor messaging channels are usable', () => {
|
||||||
|
expect(
|
||||||
|
determineVerifyStatus({
|
||||||
|
...healthyBase,
|
||||||
|
agentPing: 'skipped',
|
||||||
|
}),
|
||||||
|
).toBe('failed');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails when the CLI agent does not respond', () => {
|
||||||
|
expect(
|
||||||
|
determineVerifyStatus({
|
||||||
|
...healthyBase,
|
||||||
|
anyChannelConfigured: true,
|
||||||
|
agentPing: 'no_reply',
|
||||||
|
}),
|
||||||
|
).toBe('failed');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails when no agent groups are registered', () => {
|
||||||
|
expect(
|
||||||
|
determineVerifyStatus({
|
||||||
|
...healthyBase,
|
||||||
|
registeredGroups: 0,
|
||||||
|
}),
|
||||||
|
).toBe('failed');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -14,7 +14,7 @@ import Database from 'better-sqlite3';
|
|||||||
import { DATA_DIR } from '../src/config.js';
|
import { DATA_DIR } from '../src/config.js';
|
||||||
import { readEnvFile } from '../src/env.js';
|
import { readEnvFile } from '../src/env.js';
|
||||||
import { log } from '../src/log.js';
|
import { log } from '../src/log.js';
|
||||||
import { pingCliAgent } from './lib/agent-ping.js';
|
import { pingCliAgent, type PingResult } from './lib/agent-ping.js';
|
||||||
import { getLaunchdLabel, getSystemdUnit } from '../src/install-slug.js';
|
import { getLaunchdLabel, getSystemdUnit } from '../src/install-slug.js';
|
||||||
import {
|
import {
|
||||||
getPlatform,
|
getPlatform,
|
||||||
@@ -227,15 +227,15 @@ export async function run(_args: string[]): Promise<void> {
|
|||||||
log.info('Agent ping result', { agentPing });
|
log.info('Agent ping result', { agentPing });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine overall status
|
// Determine overall status. A CLI-only install is valid when the local
|
||||||
const status =
|
// agent round-trip succeeds; messaging app credentials are optional.
|
||||||
service === 'running' &&
|
const status = determineVerifyStatus({
|
||||||
credentials !== 'missing' &&
|
service,
|
||||||
anyChannelConfigured &&
|
credentials,
|
||||||
registeredGroups > 0 &&
|
anyChannelConfigured,
|
||||||
(agentPing === 'ok' || agentPing === 'skipped')
|
registeredGroups,
|
||||||
? 'success'
|
agentPing,
|
||||||
: 'failed';
|
});
|
||||||
|
|
||||||
log.info('Verification complete', { status, channelAuth });
|
log.info('Verification complete', { status, channelAuth });
|
||||||
|
|
||||||
@@ -255,6 +255,25 @@ export async function run(_args: string[]): Promise<void> {
|
|||||||
if (status === 'failed') process.exit(1);
|
if (status === 'failed') process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function determineVerifyStatus(input: {
|
||||||
|
service: 'not_found' | 'stopped' | 'running' | 'running_other_checkout';
|
||||||
|
credentials: string;
|
||||||
|
anyChannelConfigured: boolean;
|
||||||
|
registeredGroups: number;
|
||||||
|
agentPing: PingResult | 'skipped';
|
||||||
|
}): 'success' | 'failed' {
|
||||||
|
const cliAgentResponds = input.agentPing === 'ok';
|
||||||
|
const hasUsableChannel = input.anyChannelConfigured || cliAgentResponds;
|
||||||
|
|
||||||
|
return input.service === 'running' &&
|
||||||
|
input.credentials !== 'missing' &&
|
||||||
|
hasUsableChannel &&
|
||||||
|
input.registeredGroups > 0 &&
|
||||||
|
(cliAgentResponds || input.agentPing === 'skipped')
|
||||||
|
? 'success'
|
||||||
|
: 'failed';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a PID, resolve the script path the process is executing (i.e. the
|
* Given a PID, resolve the script path the process is executing (i.e. the
|
||||||
* first `.js` / `.ts` / `.mjs` arg after `node`). Returns null on any
|
* first `.js` / `.ts` / `.mjs` arg after `node`). Returns null on any
|
||||||
|
|||||||
Reference in New Issue
Block a user