Files
bitbucket-mcp/tests/unit/config.test.ts
2026-05-19 16:45:59 +02:00

142 lines
4.3 KiB
TypeScript

/**
* Unit tests for TokenConfigLoader
*/
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { TokenConfigLoader, TokenConfig, DefaultConfigLoader, DefaultConfig } from '../../src/config.js';
describe('TokenConfigLoader', () => {
const originalEnv = { ...process.env };
beforeEach(() => {
process.env = { ...originalEnv };
delete process.env.BITBUCKET_MCP_TOKEN;
delete process.env.DEFAULT_WORKSPACE;
delete process.env.DEFAULT_REPO;
});
afterEach(() => {
process.env = originalEnv;
vi.restoreAllMocks();
});
describe('token validation', () => {
it('should accept valid tokens (alphanumeric with special chars)', () => {
const validPattern = /^[A-Za-z0-9=._-]+$/;
expect(validPattern.test('abc123def45678901234567')).toBe(true);
expect(validPattern.test('ATBB1234567890abcdefgh')).toBe(true);
expect(validPattern.test('Bearer_token.with=chars12')).toBe(true);
expect(validPattern.test('a'.repeat(20))).toBe(true);
});
it('should reject tokens that are too short', () => {
const shortToken = 'abc123';
expect(shortToken.length).toBeLessThan(20);
});
it('should reject tokens with invalid characters', () => {
const invalidToken = 'token with spaces!@#$%';
const validPattern = /^[A-Za-z0-9=._-]+$/;
expect(validPattern.test(invalidToken)).toBe(false);
});
});
describe('environment variable loading', () => {
it('should load token from BITBUCKET_MCP_TOKEN env var', async () => {
process.env.BITBUCKET_MCP_EMAIL = 'test@example.com';
process.env.BITBUCKET_MCP_TOKEN = 'valid_test_token_12345678901234567';
const config = await TokenConfigLoader.load();
expect(config.token).toBe('valid_test_token_12345678901234567');
expect(config.source).toBe('env');
});
});
describe('TokenConfig interface', () => {
it('should return correct config structure for env source', async () => {
process.env.BITBUCKET_MCP_TOKEN = 'test_token_12345678901234567';
const config = await TokenConfigLoader.load();
expect(config).toHaveProperty('token');
expect(config).toHaveProperty('source');
expect(['env', 'dotenv', 'prompt']).toContain(config.source);
});
});
});
describe('DefaultConfigLoader', () => {
const originalEnv = { ...process.env };
beforeEach(() => {
process.env = { ...originalEnv };
delete process.env.DEFAULT_WORKSPACE;
delete process.env.DEFAULT_REPO;
});
afterEach(() => {
process.env = originalEnv;
});
describe('load', () => {
it('should return null values when env vars are not set', () => {
const config = DefaultConfigLoader.load();
expect(config.workspace).toBeNull();
expect(config.repo).toBeNull();
});
it('should return workspace and repo from env vars when set', () => {
process.env.DEFAULT_WORKSPACE = 'my-workspace';
process.env.DEFAULT_REPO = 'my-repo';
const config = DefaultConfigLoader.load();
expect(config.workspace).toBe('my-workspace');
expect(config.repo).toBe('my-repo');
});
it('should return partial config when only workspace is set', () => {
process.env.DEFAULT_WORKSPACE = 'only-workspace';
const config = DefaultConfigLoader.load();
expect(config.workspace).toBe('only-workspace');
expect(config.repo).toBeNull();
});
it('should return partial config when only repo is set', () => {
process.env.DEFAULT_REPO = 'only-repo';
const config = DefaultConfigLoader.load();
expect(config.workspace).toBeNull();
expect(config.repo).toBe('only-repo');
});
});
describe('getWorkspace', () => {
it('should return null when DEFAULT_WORKSPACE is not set', () => {
expect(DefaultConfigLoader.getWorkspace()).toBeNull();
});
it('should return workspace value when set', () => {
process.env.DEFAULT_WORKSPACE = 'test-workspace';
expect(DefaultConfigLoader.getWorkspace()).toBe('test-workspace');
});
});
describe('getRepo', () => {
it('should return null when DEFAULT_REPO is not set', () => {
expect(DefaultConfigLoader.getRepo()).toBeNull();
});
it('should return repo value when set', () => {
process.env.DEFAULT_REPO = 'test-repo';
expect(DefaultConfigLoader.getRepo()).toBe('test-repo');
});
});
});