import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
import {requireEnv, loadOAuthCredentials} from './config.js';
import {readFileSync} from 'fs';
vi.mock('fs', () => ({
readFileSync: vi.fn(),
}));
describe('config', () => {
describe('requireEnv', () => {
const originalEnv = process.env;
beforeEach(() => {
process.env = {...originalEnv};
});
afterEach(() => {
process.env = originalEnv;
});
it('returns value when env var is set', () => {
process.env.TEST_VAR = 'test-value';
expect(requireEnv('TEST_VAR')).toBe('test-value');
});
it('throws error when env var is missing', () => {
delete process.env.MISSING_VAR;
expect(() => requireEnv('MISSING_VAR'))
.toThrow('Missing required environment variable: MISSING_VAR');
});
it('throws error when env var is empty string', () => {
process.env.EMPTY_VAR = '';
expect(() => requireEnv('EMPTY_VAR'))
.toThrow('Missing required environment variable: EMPTY_VAR');
});
});
describe('loadOAuthCredentials', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('parses valid credentials file', () => {
const mockCredentials = {
web: {
client_id: 'test-client-id',
client_secret: 'test-secret',
redirect_uris: ['http://localhost:3000/callback'],
},
};
vi.mocked(readFileSync).mockReturnValue(JSON.stringify(mockCredentials));
const result = loadOAuthCredentials('/path/to/creds.json');
expect(result).toEqual({
client_id: 'test-client-id',
client_secret: 'test-secret',
redirect_uri: 'http://localhost:3000/callback',
});
});
it('uses first redirect_uri from array', () => {
const mockCredentials = {
web: {
client_id: 'id',
client_secret: 'secret',
redirect_uris: ['first-uri', 'second-uri'],
},
};
vi.mocked(readFileSync).mockReturnValue(JSON.stringify(mockCredentials));
const result = loadOAuthCredentials('/path/to/creds.json');
expect(result.redirect_uri).toBe('first-uri');
});
it('throws on invalid JSON', () => {
vi.mocked(readFileSync).mockReturnValue('not valid json');
expect(() => loadOAuthCredentials('/path/to/creds.json'))
.toThrow();
});
it('throws on missing file', () => {
vi.mocked(readFileSync).mockImplementation(() => {
throw new Error('ENOENT: no such file or directory');
});
expect(() => loadOAuthCredentials('/nonexistent.json'))
.toThrow('ENOENT: no such file or directory');
});
it('throws on missing web property', () => {
vi.mocked(readFileSync).mockReturnValue(JSON.stringify({}));
expect(() => loadOAuthCredentials('/path/to/creds.json'))
.toThrow();
});
});
});