Files
chatgpt-mcp/test/config/env.test.js
T

145 lines
4.2 KiB
JavaScript

import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { loadConfig } from '../../src/config/env.js';
const originalEnv = { ...process.env };
function setEnv(partial) {
for (const key of Object.keys(process.env)) {
if (key.startsWith('OPENAI_') || key.startsWith('CHATGPT_MCP_')) {
delete process.env[key];
}
}
Object.assign(process.env, partial);
}
beforeEach(() => {
setEnv({ OPENAI_API_KEY: 'test-key' });
});
afterEach(() => {
for (const key of Object.keys(process.env)) {
if (key.startsWith('OPENAI_') || key.startsWith('CHATGPT_MCP_')) {
delete process.env[key];
}
}
Object.assign(process.env, originalEnv);
});
describe('loadConfig', () => {
it('throws when OPENAI_API_KEY is missing', () => {
delete process.env.OPENAI_API_KEY;
expect(() => loadConfig()).toThrow(
'Configuration error: OPENAI_API_KEY is missing.'
);
});
it('returns defaults when no optional vars are set', () => {
const cfg = loadConfig();
expect(cfg.openaiApiKey).toBe('test-key');
expect(cfg.openaiModel).toBe('gpt-5.1');
expect(cfg.temperature).toBe(0.2);
expect(cfg.maxOutputTokens).toBe(2000);
expect(cfg.logLevel).toBe('info');
expect(cfg.enableFileContext).toBe(false);
expect(cfg.contextDir).toBe('./context');
expect(cfg.maxInputChars).toBe(30000);
expect(cfg.maxFileChars).toBe(12000);
expect(cfg.maxFiles).toBe(5);
expect(cfg.maxLogChars).toBe(10000);
expect(cfg.redactSecrets).toBe(true);
});
it('applies custom string values', () => {
setEnv({
OPENAI_API_KEY: 'test-key',
OPENAI_MODEL: 'gpt-4',
CHATGPT_MCP_LOG_LEVEL: 'debug',
CHATGPT_MCP_CONTEXT_DIR: './custom',
});
const cfg = loadConfig();
expect(cfg.openaiModel).toBe('gpt-4');
expect(cfg.logLevel).toBe('debug');
expect(cfg.contextDir).toBe('./custom');
});
it('applies custom numeric values', () => {
setEnv({
OPENAI_API_KEY: 'test-key',
OPENAI_TEMPERATURE: '0.5',
OPENAI_MAX_OUTPUT_TOKENS: '4096',
CHATGPT_MCP_MAX_INPUT_CHARS: '15000',
CHATGPT_MCP_MAX_FILE_CHARS: '8000',
CHATGPT_MCP_MAX_FILES: '3',
CHATGPT_MCP_MAX_LOG_CHARS: '5000',
});
const cfg = loadConfig();
expect(cfg.temperature).toBe(0.5);
expect(cfg.maxOutputTokens).toBe(4096);
expect(cfg.maxInputChars).toBe(15000);
expect(cfg.maxFileChars).toBe(8000);
expect(cfg.maxFiles).toBe(3);
expect(cfg.maxLogChars).toBe(5000);
});
it('applies custom boolean values', () => {
setEnv({
OPENAI_API_KEY: 'test-key',
CHATGPT_MCP_ENABLE_FILE_CONTEXT: 'true',
CHATGPT_MCP_REDACT_SECRETS: 'false',
});
const cfg = loadConfig();
expect(cfg.enableFileContext).toBe(true);
expect(cfg.redactSecrets).toBe(false);
});
it('throws on invalid numeric values', () => {
setEnv({
OPENAI_API_KEY: 'test-key',
CHATGPT_MCP_MAX_INPUT_CHARS: 'abc',
});
expect(() => loadConfig()).toThrow(
'Configuration error: CHATGPT_MCP_MAX_INPUT_CHARS must be a positive number, got "abc".'
);
});
it('throws on invalid boolean values', () => {
setEnv({
OPENAI_API_KEY: 'test-key',
CHATGPT_MCP_ENABLE_FILE_CONTEXT: 'yes',
});
expect(() => loadConfig()).toThrow(
'Configuration error: CHATGPT_MCP_ENABLE_FILE_CONTEXT must be true or false, got "yes".'
);
});
it('throws on negative numeric values', () => {
setEnv({
OPENAI_API_KEY: 'test-key',
CHATGPT_MCP_MAX_FILES: '-1',
});
expect(() => loadConfig()).toThrow(
'Configuration error: CHATGPT_MCP_MAX_FILES must be a positive number, got "-1".'
);
});
it('throws on NaN numeric values', () => {
setEnv({
OPENAI_API_KEY: 'test-key',
CHATGPT_MCP_MAX_FILES: 'NaN',
});
expect(() => loadConfig()).toThrow(
'Configuration error: CHATGPT_MCP_MAX_FILES must be a positive number, got "NaN".'
);
});
it('throws on Infinity numeric values', () => {
setEnv({
OPENAI_API_KEY: 'test-key',
CHATGPT_MCP_MAX_FILES: 'Infinity',
});
expect(() => loadConfig()).toThrow(
'Configuration error: CHATGPT_MCP_MAX_FILES must be a positive number, got "Infinity".'
);
});
});