import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { mkdtempSync, rmSync, statSync, existsSync } from 'node:fs'; import { join } from 'node:path'; import { tmpdir } from 'node:os'; import { saveCredentials, loadCredentials, deleteCredentials } from '../../src/auth/index.js'; let tempDir: string; beforeEach(() => { tempDir = mkdtempSync(join(tmpdir(), 'mcpctl-auth-test-')); }); afterEach(() => { rmSync(tempDir, { recursive: true, force: true }); }); describe('saveCredentials', () => { it('saves credentials file', () => { saveCredentials({ token: 'tok123', mcpdUrl: 'http://x:3100', user: 'alice@test.com' }, { configDir: tempDir }); expect(existsSync(join(tempDir, 'credentials'))).toBe(true); }); it('sets 0600 permissions', () => { saveCredentials({ token: 'tok123', mcpdUrl: 'http://x:3100', user: 'alice@test.com' }, { configDir: tempDir }); const stat = statSync(join(tempDir, 'credentials')); expect(stat.mode & 0o777).toBe(0o600); }); it('creates config dir if missing', () => { const nested = join(tempDir, 'sub', 'dir'); saveCredentials({ token: 'tok', mcpdUrl: 'http://x:3100', user: 'bob' }, { configDir: nested }); expect(existsSync(join(nested, 'credentials'))).toBe(true); }); }); describe('loadCredentials', () => { it('returns null when no credentials file', () => { expect(loadCredentials({ configDir: tempDir })).toBeNull(); }); it('round-trips credentials', () => { const creds = { token: 'tok456', mcpdUrl: 'http://remote:3100', user: 'charlie@test.com', expiresAt: '2099-01-01' }; saveCredentials(creds, { configDir: tempDir }); const loaded = loadCredentials({ configDir: tempDir }); expect(loaded).toEqual(creds); }); }); describe('deleteCredentials', () => { it('returns false when no credentials file', () => { expect(deleteCredentials({ configDir: tempDir })).toBe(false); }); it('deletes credentials file', () => { saveCredentials({ token: 'tok', mcpdUrl: 'http://x:3100', user: 'u' }, { configDir: tempDir }); expect(deleteCredentials({ configDir: tempDir })).toBe(true); expect(existsSync(join(tempDir, 'credentials'))).toBe(false); }); });