import { expect, tap } from '@git.zone/tstest/tapbundle'; import * as smartsecret from '../ts/index.js'; import * as path from 'path'; import * as fs from 'fs'; import * as os from 'os'; let testDir: string; let instance: smartsecret.SmartSecret; tap.test('setup - create temp directory', async () => { testDir = path.join(os.tmpdir(), `smartsecret-test-${Date.now()}`); fs.mkdirSync(testDir, { recursive: true }); instance = new smartsecret.SmartSecret({ service: 'smartsecret-test', vaultPath: path.join(testDir, 'vault.json'), }); }); tap.test('should report file-encrypted backend type', async () => { const backendType = await instance.getBackendType(); // On CI/test environments without keychain, should fall back to file expect(backendType).toEqual('file-encrypted'); }); tap.test('should set and get a secret', async () => { await instance.setSecret('test-account', 'my-secret-value'); const result = await instance.getSecret('test-account'); expect(result).toEqual('my-secret-value'); }); tap.test('should return null for non-existent secret', async () => { const result = await instance.getSecret('nonexistent'); expect(result).toBeNull(); }); tap.test('should overwrite an existing secret', async () => { await instance.setSecret('test-account', 'updated-secret'); const result = await instance.getSecret('test-account'); expect(result).toEqual('updated-secret'); }); tap.test('should handle special characters in secrets', async () => { const specialSecret = '!@#$%^&*()_+-=[]{}|;:\'",.<>?/\\`~\n\ttabs and newlines'; await instance.setSecret('special-chars', specialSecret); const result = await instance.getSecret('special-chars'); expect(result).toEqual(specialSecret); }); tap.test('should handle empty string secrets', async () => { await instance.setSecret('empty-secret', ''); const result = await instance.getSecret('empty-secret'); expect(result).toEqual(''); }); tap.test('should list accounts', async () => { const accounts = await instance.listAccounts(); expect(accounts).toContain('test-account'); expect(accounts).toContain('special-chars'); expect(accounts).toContain('empty-secret'); }); tap.test('should delete a secret', async () => { const deleted = await instance.deleteSecret('test-account'); expect(deleted).toBeTrue(); const result = await instance.getSecret('test-account'); expect(result).toBeNull(); }); tap.test('should return false when deleting non-existent secret', async () => { const deleted = await instance.deleteSecret('nonexistent'); expect(deleted).toBeFalse(); }); tap.test('should isolate secrets by service', async () => { const otherInstance = new smartsecret.SmartSecret({ service: 'other-service', vaultPath: path.join(testDir, 'vault.json'), }); await otherInstance.setSecret('shared-name', 'other-value'); await instance.setSecret('shared-name', 'original-value'); const otherResult = await otherInstance.getSecret('shared-name'); const originalResult = await instance.getSecret('shared-name'); expect(otherResult).toEqual('other-value'); expect(originalResult).toEqual('original-value'); }); tap.test('cleanup - remove temp directory', async () => { fs.rmSync(testDir, { recursive: true, force: true }); }); export default tap.start();