Files
brain/tools/keychain-read.test.mjs
T

56 lines
2.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// tools/keychain-read.test.mjs
// Синхронное чтение OS-keychain через async-only keytar (у keytar НЕТ getPasswordSync).
// Обёртка запускает короткий node-subprocess (execFileSync блокирует), который await'ит
// keytar.getPassword и печатает значение → resolveReceiptKey/resolveJudgeKey остаются синхронными.
import { describe, it, expect } from 'vitest';
import { buildKeychainReadScript, parseKeychainStdout, readKeychainSync } from './keychain-read.mjs';
describe('buildKeychainReadScript (pure)', () => {
it('строит node-скрипт с async getPassword по абсолютному пути keytar', () => {
const s = buildKeychainReadScript('/abs/keytar', 'svc', 'acct');
expect(s).toContain('getPassword');
expect(s).toContain(JSON.stringify('/abs/keytar'));
expect(s).toContain(JSON.stringify('svc'));
expect(s).toContain(JSON.stringify('acct'));
expect(s).not.toContain('getPasswordSync');
});
it('JSON-экранирует аргументы (кавычки безопасны)', () => {
const s = buildKeychainReadScript('/k', 'a"b', 'c');
expect(s).toContain(JSON.stringify('a"b'));
});
});
describe('parseKeychainStdout (pure)', () => {
it('непустой stdout → значение', () => {
expect(parseKeychainStdout('secret123')).toBe('secret123');
});
it('пустой stdout → null', () => {
expect(parseKeychainStdout('')).toBe(null);
});
it('null/undefined → null', () => {
expect(parseKeychainStdout(null)).toBe(null);
expect(parseKeychainStdout(undefined)).toBe(null);
});
});
describe('readKeychainSync (sync-обёртка над async keytar)', () => {
const fakeRequire = { resolve: () => '/abs/keytar' };
it('exec вернул значение → оно же', () => {
const r = readKeychainSync('svc', 'acct', { requireImpl: fakeRequire, exec: () => 'the-key' });
expect(r).toBe('the-key');
});
it('exec вернул пусто → null', () => {
const r = readKeychainSync('svc', 'acct', { requireImpl: fakeRequire, exec: () => '' });
expect(r).toBe(null);
});
it('exec бросил → null (fail-closed, не кидает)', () => {
const r = readKeychainSync('svc', 'acct', { requireImpl: fakeRequire, exec: () => { throw new Error('spawn fail'); } });
expect(r).toBe(null);
});
it('require.resolve бросил (keytar не найден) → null', () => {
const req = { resolve: () => { throw new Error('MODULE_NOT_FOUND'); } };
const r = readKeychainSync('svc', 'acct', { requireImpl: req, exec: () => 'x' });
expect(r).toBe(null);
});
});