agent-ecosystem/test/features/codex-account/core/evaluateCodexLaunchReadiness.test.ts

137 lines
4 KiB
TypeScript

// @vitest-environment node
import { describe, expect, it } from 'vitest';
import { evaluateCodexLaunchReadiness } from '@features/codex-account/core/domain/evaluateCodexLaunchReadiness';
describe('evaluateCodexLaunchReadiness', () => {
it('prefers a managed ChatGPT account in auto mode when both auth sources are available', () => {
const readiness = evaluateCodexLaunchReadiness({
preferredAuthMode: 'auto',
managedAccount: {
type: 'chatgpt',
email: 'user@example.com',
planType: 'plus',
},
apiKey: {
available: true,
source: 'stored',
sourceLabel: 'Stored in app',
},
appServerState: 'healthy',
appServerStatusMessage: null,
});
expect(readiness).toEqual({
state: 'ready_both',
effectiveAuthMode: 'chatgpt',
launchAllowed: true,
issueMessage: null,
});
});
it('blocks launch when ChatGPT account mode is selected but no managed account is connected', () => {
const readiness = evaluateCodexLaunchReadiness({
preferredAuthMode: 'chatgpt',
managedAccount: null,
apiKey: {
available: true,
source: 'environment',
sourceLabel: 'Detected from OPENAI_API_KEY',
},
appServerState: 'healthy',
appServerStatusMessage: null,
});
expect(readiness.state).toBe('missing_auth');
expect(readiness.effectiveAuthMode).toBeNull();
expect(readiness.launchAllowed).toBe(false);
expect(readiness.issueMessage).toContain('Connect a ChatGPT account');
});
it('asks for reconnect instead of a fresh login when a locally selected ChatGPT account already exists', () => {
const readiness = evaluateCodexLaunchReadiness({
preferredAuthMode: 'chatgpt',
managedAccount: null,
apiKey: {
available: true,
source: 'environment',
sourceLabel: 'Detected from OPENAI_API_KEY',
},
appServerState: 'healthy',
appServerStatusMessage: null,
localActiveChatgptAccountPresent: true,
});
expect(readiness.state).toBe('missing_auth');
expect(readiness.effectiveAuthMode).toBeNull();
expect(readiness.launchAllowed).toBe(false);
expect(readiness.issueMessage).toContain('Reconnect ChatGPT');
});
it('allows API-key mode when an API key is available', () => {
const readiness = evaluateCodexLaunchReadiness({
preferredAuthMode: 'api_key',
managedAccount: null,
apiKey: {
available: true,
source: 'stored',
sourceLabel: 'Stored in app',
},
appServerState: 'healthy',
appServerStatusMessage: null,
});
expect(readiness).toEqual({
state: 'ready_api_key',
effectiveAuthMode: 'api_key',
launchAllowed: true,
issueMessage: null,
});
});
it('surfaces degraded-but-launchable state when the managed account is still usable', () => {
const readiness = evaluateCodexLaunchReadiness({
preferredAuthMode: 'auto',
managedAccount: {
type: 'chatgpt',
email: 'user@example.com',
planType: 'pro',
},
apiKey: {
available: false,
source: null,
sourceLabel: null,
},
appServerState: 'degraded',
appServerStatusMessage: 'Temporary app-server probe failure',
});
expect(readiness).toEqual({
state: 'warning_degraded_but_launchable',
effectiveAuthMode: 'chatgpt',
launchAllowed: true,
issueMessage: 'Temporary app-server probe failure',
});
});
it('fails fast when the Codex runtime is missing entirely', () => {
const readiness = evaluateCodexLaunchReadiness({
preferredAuthMode: 'auto',
managedAccount: null,
apiKey: {
available: true,
source: 'stored',
sourceLabel: 'Stored in app',
},
appServerState: 'runtime-missing',
appServerStatusMessage: 'Codex CLI not found',
});
expect(readiness).toEqual({
state: 'runtime_missing',
effectiveAuthMode: null,
launchAllowed: false,
issueMessage: 'Codex CLI not found',
});
});
});