Files
wehub-resource-sync 0d3cb498a3
Deploy local.promptfoo.app / Deploy to Cloudflare Pages (push) Waiting to run
Test and Publish Multi-arch Docker Image / test (push) Waiting to run
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-amd64 platform:linux/amd64 runner:ubuntu-latest]) (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-arm64 platform:linux/arm64 runner:ubuntu-24.04-arm]) (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / merge-docker-digests (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / Attest Multi-arch Image (push) Blocked by required conditions
Validate Renovate Config / Validate Renovate Configuration (push) Waiting to run
CI / Shell Format Check (push) Has been cancelled
CI / Check Ruby (3.4) (push) Has been cancelled
CI / CI Config (push) Has been cancelled
CI / Test on Node ${{ matrix.node }} and ${{ matrix.os }}${{ matrix.shard && format(' (shard {0}/3)', matrix.shard) || '' }} (push) Has been cancelled
CI / Build on Node ${{ matrix.node }} (push) Has been cancelled
CI / Style Check (push) Has been cancelled
CI / Generate Assets (push) Has been cancelled
CI / Check Python (3.14) (push) Has been cancelled
CI / Check Python (3.9) (push) Has been cancelled
CI / Build Docs (push) Has been cancelled
CI / Code Scan Action (push) Has been cancelled
CI / Site tests (push) Has been cancelled
CI / webui tests (push) Has been cancelled
CI / Run Integration Tests (push) Has been cancelled
CI / Run Smoke Tests (push) Has been cancelled
CI / Go Tests (push) Has been cancelled
CI / Share Test (push) Has been cancelled
CI / Redteam (Production API) (push) Has been cancelled
CI / Redteam (Staging API) (push) Has been cancelled
CI / GitHub Actions Lint (push) Has been cancelled
CI / Check Ruby (3.0) (push) Has been cancelled
release-please / release-please (push) Has been cancelled
release-please / build (push) Has been cancelled
release-please / publish-npm (push) Has been cancelled
release-please / publish-npm-backfill (push) Has been cancelled
release-please / docker (push) Has been cancelled
release-please / publish-code-scan-action (push) Has been cancelled
release-please / attest-code-scan-action (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:24:08 +08:00

213 lines
7.1 KiB
TypeScript

import { Command } from 'commander';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { viewCommand } from '../../src/commands/view';
import { getDefaultPort } from '../../src/constants';
import { startServer } from '../../src/server/server';
import { setConfigDirectoryPath } from '../../src/util/config/manage';
import { setupEnv } from '../../src/util/index';
import { BrowserBehavior } from '../../src/util/server';
vi.mock('../../src/util/config/manage', () => ({
getConfigDirectoryPath: vi.fn().mockReturnValue('/tmp/test-config'),
setConfigDirectoryPath: vi.fn(),
maybeReadConfig: vi.fn(),
readConfigs: vi.fn(),
}));
vi.mock('../../src/server/server');
vi.mock('../../src/util');
describe('viewCommand', () => {
let program: Command;
beforeEach(() => {
program = new Command();
vi.clearAllMocks();
});
it('should register view command with correct options', () => {
viewCommand(program);
const viewCmd = program.commands[0];
expect(viewCmd.name()).toBe('view');
expect(viewCmd.description()).toBe('Start browser UI');
const options = viewCmd.opts();
expect(options).toEqual({
port: getDefaultPort(),
});
});
it('should call startServer with correct parameters when executed', async () => {
viewCommand(program);
const viewCmd = program.commands[0];
await viewCmd.parseAsync(['node', 'test', '--port', '3001']);
expect(startServer).toHaveBeenCalledWith(3001, BrowserBehavior.ASK);
});
it('should handle directory parameter and set config directory', async () => {
viewCommand(program);
const viewCmd = program.commands[0];
await viewCmd.parseAsync(['node', 'test', 'testdir', '--port', '3001']);
expect(setConfigDirectoryPath).toHaveBeenCalledWith('testdir');
});
it('should handle browser behavior options correctly', async () => {
viewCommand(program);
let viewCmd = program.commands[0];
await viewCmd.parseAsync(['node', 'test', '--yes']);
expect(startServer).toHaveBeenCalledWith(getDefaultPort(), BrowserBehavior.OPEN);
vi.clearAllMocks();
// Reset program and viewCommand for the second test
program = new Command();
viewCommand(program);
viewCmd = program.commands[0];
// Use a unique port to avoid confusion with default port
await viewCmd.parseAsync(['node', 'test', '--no', '--port', '15500']);
// --no sets BrowserBehavior.SKIP
expect(startServer).toHaveBeenCalledWith(15500, BrowserBehavior.SKIP);
});
it('should ignore filter description option', async () => {
viewCommand(program);
const viewCmd = program.commands[0];
await viewCmd.parseAsync(['node', 'test', '--filter-description', 'test-pattern']);
expect(startServer).toHaveBeenCalledWith(getDefaultPort(), BrowserBehavior.ASK);
});
it('should setup environment from env file path', async () => {
viewCommand(program);
const viewCmd = program.commands[0];
await viewCmd.parseAsync(['node', 'test', '--env-path', '.env.test']);
expect(setupEnv).toHaveBeenCalledWith('.env.test');
});
it('should handle both --yes and --no options with --yes taking precedence', async () => {
viewCommand(program);
const viewCmd = program.commands[0];
await viewCmd.parseAsync(['node', 'test', '--yes', '--no']);
expect(startServer).toHaveBeenCalledWith(getDefaultPort(), BrowserBehavior.OPEN);
});
it('should call startServer with default port if no port is specified', async () => {
viewCommand(program);
const viewCmd = program.commands[0];
await viewCmd.parseAsync(['node', 'test']);
expect(startServer).toHaveBeenCalledWith(getDefaultPort(), BrowserBehavior.ASK);
});
it('should support all options together', async () => {
viewCommand(program);
const viewCmd = program.commands[0];
await viewCmd.parseAsync([
'node',
'test',
'mydir',
'--port',
'9876',
'--yes',
'--filter-description',
'desc',
'--env-path',
'.env.foo',
]);
expect(setConfigDirectoryPath).toHaveBeenCalledWith('mydir');
expect(setupEnv).toHaveBeenCalledWith('.env.foo');
expect(startServer).toHaveBeenCalledWith(9876, BrowserBehavior.OPEN);
});
it('should pass undefined directory if not provided', async () => {
viewCommand(program);
const viewCmd = program.commands[0];
await viewCmd.parseAsync(['node', 'test', '--port', '3002']);
expect(setConfigDirectoryPath).not.toHaveBeenCalled();
});
it('should prefer --yes over --no if both are supplied', async () => {
viewCommand(program);
const viewCmd = program.commands[0];
await viewCmd.parseAsync(['node', 'test', '--yes', '--no', '--port', '4444']);
expect(startServer).toHaveBeenCalledWith(4444, BrowserBehavior.OPEN);
});
it('should parse port as string if passed as number', async () => {
viewCommand(program);
const viewCmd = program.commands[0];
// Simulate user passing a numeric port
await viewCmd.parseAsync(['node', 'test', '--port', '7777']);
expect(startServer).toHaveBeenCalledWith(7777, BrowserBehavior.ASK);
});
it('should call startServer with undefined filterDescription if not provided', async () => {
viewCommand(program);
const viewCmd = program.commands[0];
await viewCmd.parseAsync(['node', 'test', '--yes', '--port', '2222']);
expect(startServer).toHaveBeenCalledWith(2222, BrowserBehavior.OPEN);
});
it('should handle --filter-description with empty string', async () => {
viewCommand(program);
const viewCmd = program.commands[0];
await viewCmd.parseAsync(['node', 'test', '--filter-description', '']);
expect(startServer).toHaveBeenCalledWith(getDefaultPort(), BrowserBehavior.ASK);
});
it('should call setupEnv with undefined if --env-path not provided', async () => {
viewCommand(program);
const viewCmd = program.commands[0];
await viewCmd.parseAsync(['node', 'test']);
expect(setupEnv).toHaveBeenCalledWith(undefined);
});
it('should call startServer with correct port and browserBehavior when only --no is supplied and --yes is not present', async () => {
viewCommand(program);
const viewCmd = program.commands[0];
vi.clearAllMocks();
// Only --no, no --yes
await viewCmd.parseAsync(['node', 'test', '--no', '--port', '15501']);
// Commander sets --no to true, --yes to undefined, so browserBehavior should be SKIP
expect(startServer).toHaveBeenCalledWith(15501, BrowserBehavior.SKIP);
});
it('should call startServer with correct port and browserBehavior when only --yes is supplied', async () => {
viewCommand(program);
const viewCmd = program.commands[0];
vi.clearAllMocks();
await viewCmd.parseAsync(['node', 'test', '--yes', '--port', '16600']);
expect(startServer).toHaveBeenCalledWith(16600, BrowserBehavior.OPEN);
});
it('should call startServer with ASK when neither --yes nor --no is supplied', async () => {
viewCommand(program);
const viewCmd = program.commands[0];
vi.clearAllMocks();
await viewCmd.parseAsync(['node', 'test', '--port', '17700']);
expect(startServer).toHaveBeenCalledWith(17700, BrowserBehavior.ASK);
});
});