/** * Contract Test for AccountRegistry Interface * * Tests the core AccountRegistry functionality following TDD principles. * These tests MUST fail initially and pass after implementation. */ import { AccountRegistry } from '@/core/credential-manager/AccountRegistry' import { Platform, Account } from '@/types/credential' describe('AccountRegistry Contract Test', () => { let registry: AccountRegistry beforeEach(() => { registry = new AccountRegistry() }) describe('Account Loading', () => { test('should load accounts from configuration', async () => { const config = { accounts: [ { id: 'test-account-1', name: 'Test Account 1', platform: Platform.PACIFICA, enabled: true, credentials: { type: 'ed25519' as const, privateKey: 'f26670e2ca334117f8859f9f32e50251641953a30b54f6ffcf82db836cfdfea5' } } ] } await registry.loadAccounts(config) const accounts = registry.getAllAccounts() expect(accounts).toHaveLength(1) expect(accounts[0].id).toBe('test-account-1') expect(accounts[0].platform).toBe(Platform.PACIFICA) }) test('should handle empty configuration gracefully', async () => { const config = { accounts: [] } await registry.loadAccounts(config) const accounts = registry.getAllAccounts() expect(accounts).toHaveLength(0) }) test('should validate account configuration before loading', async () => { const invalidConfig = { accounts: [ { id: 'invalid-account', // Missing required fields platform: Platform.PACIFICA } ] } await expect(registry.loadAccounts(invalidConfig as any)) .rejects.toThrow('Invalid account configuration') }) }) describe('Account Retrieval', () => { beforeEach(async () => { const config = { accounts: [ { id: 'pacifica-account', name: 'Pacifica Test', platform: Platform.PACIFICA, enabled: true, credentials: { type: 'ed25519' as const, privateKey: 'f26670e2ca334117f8859f9f32e50251641953a30b54f6ffcf82db836cfdfea5' } }, { id: 'aster-account', name: 'Aster Test', platform: Platform.ASTER, enabled: true, credentials: { type: 'secp256k1' as const, privateKey: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' } } ] } await registry.loadAccounts(config) }) test('should get account by ID', () => { const account = registry.getAccount('pacifica-account') expect(account).toBeDefined() expect(account?.id).toBe('pacifica-account') expect(account?.platform).toBe(Platform.PACIFICA) }) test('should return undefined for non-existent account', () => { const account = registry.getAccount('non-existent') expect(account).toBeUndefined() }) test('should get accounts by platform', () => { const pacificaAccounts = registry.getAccountsByPlatform(Platform.PACIFICA) const asterAccounts = registry.getAccountsByPlatform(Platform.ASTER) const binanceAccounts = registry.getAccountsByPlatform(Platform.BINANCE) expect(pacificaAccounts).toHaveLength(1) expect(asterAccounts).toHaveLength(1) expect(binanceAccounts).toHaveLength(0) expect(pacificaAccounts[0].id).toBe('pacifica-account') expect(asterAccounts[0].id).toBe('aster-account') }) test('should get all accounts', () => { const allAccounts = registry.getAllAccounts() expect(allAccounts).toHaveLength(2) expect(allAccounts.map(a => a.id)).toContain('pacifica-account') expect(allAccounts.map(a => a.id)).toContain('aster-account') }) test('should get enabled accounts only', () => { const enabledAccounts = registry.getEnabledAccounts() expect(enabledAccounts).toHaveLength(2) expect(enabledAccounts.every(a => a.enabled)).toBe(true) }) }) describe('Account Management', () => { test('should add new account', () => { const newAccount: Account = { id: 'new-account', name: 'New Account', platform: Platform.BINANCE, enabled: true, credentials: { type: 'hmac' as const, apiKey: 'test-api-key', secretKey: 'test-secret-key' } } registry.addAccount(newAccount) const retrieved = registry.getAccount('new-account') expect(retrieved).toBeDefined() expect(retrieved?.platform).toBe(Platform.BINANCE) }) test('should prevent duplicate account IDs', () => { const account1: Account = { id: 'duplicate-id', name: 'Account 1', platform: Platform.PACIFICA, enabled: true, credentials: { type: 'ed25519' as const, privateKey: 'f26670e2ca334117f8859f9f32e50251641953a30b54f6ffcf82db836cfdfea5' } } const account2: Account = { id: 'duplicate-id', name: 'Account 2', platform: Platform.ASTER, enabled: true, credentials: { type: 'secp256k1' as const, privateKey: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' } } registry.addAccount(account1) expect(() => registry.addAccount(account2)) .toThrow('Account with ID duplicate-id already exists') }) test('should update existing account', () => { const originalAccount: Account = { id: 'update-test', name: 'Original Name', platform: Platform.PACIFICA, enabled: true, credentials: { type: 'ed25519' as const, privateKey: 'f26670e2ca334117f8859f9f32e50251641953a30b54f6ffcf82db836cfdfea5' } } registry.addAccount(originalAccount) const updatedAccount: Account = { ...originalAccount, name: 'Updated Name', enabled: false } registry.updateAccount('update-test', updatedAccount) const retrieved = registry.getAccount('update-test') expect(retrieved?.name).toBe('Updated Name') expect(retrieved?.enabled).toBe(false) }) test('should remove account', () => { const account: Account = { id: 'remove-test', name: 'Remove Test', platform: Platform.PACIFICA, enabled: true, credentials: { type: 'ed25519' as const, privateKey: 'f26670e2ca334117f8859f9f32e50251641953a30b54f6ffcf82db836cfdfea5' } } registry.addAccount(account) expect(registry.getAccount('remove-test')).toBeDefined() const removed = registry.removeAccount('remove-test') expect(removed).toBe(true) expect(registry.getAccount('remove-test')).toBeUndefined() }) test('should return false when removing non-existent account', () => { const removed = registry.removeAccount('non-existent') expect(removed).toBe(false) }) }) describe('Platform Support', () => { test('should return supported platforms', () => { const platforms = registry.getSupportedPlatforms() expect(platforms).toContain(Platform.PACIFICA) expect(platforms).toContain(Platform.ASTER) expect(platforms).toContain(Platform.BINANCE) }) test('should check if platform is supported', () => { expect(registry.isPlatformSupported(Platform.PACIFICA)).toBe(true) expect(registry.isPlatformSupported(Platform.ASTER)).toBe(true) expect(registry.isPlatformSupported(Platform.BINANCE)).toBe(true) }) }) describe('Performance Requirements', () => { test('should load accounts within performance limits', async () => { const config = { accounts: Array.from({ length: 100 }, (_, i) => ({ id: `account-${i}`, name: `Account ${i}`, platform: Platform.PACIFICA, enabled: true, credentials: { type: 'ed25519' as const, privateKey: 'f26670e2ca334117f8859f9f32e50251641953a30b54f6ffcf82db836cfdfea5' } })) } const startTime = Date.now() await registry.loadAccounts(config) const duration = Date.now() - startTime // Should load 100 accounts within 100ms expect(duration).toBeLessThan(100) expect(registry.getAllAccounts()).toHaveLength(100) }) test('should retrieve accounts efficiently', async () => { const config = { accounts: Array.from({ length: 50 }, (_, i) => ({ id: `account-${i}`, name: `Account ${i}`, platform: i % 2 === 0 ? Platform.PACIFICA : Platform.ASTER, enabled: true, credentials: { type: 'ed25519' as const, privateKey: 'f26670e2ca334117f8859f9f32e50251641953a30b54f6ffcf82db836cfdfea5' } })) } await registry.loadAccounts(config) const startTime = Date.now() for (let i = 0; i < 1000; i++) { registry.getAccount(`account-${i % 50}`) } const duration = Date.now() - startTime // Should handle 1000 lookups within 10ms expect(duration).toBeLessThan(10) }) }) describe('Error Handling', () => { test('should handle malformed configuration gracefully', async () => { const malformedConfig = { accounts: [ { id: 'malformed', platform: 'invalid-platform', credentials: 'not-an-object' } ] } await expect(registry.loadAccounts(malformedConfig as any)) .rejects.toThrow() }) test('should provide meaningful error messages', async () => { const invalidConfig = { accounts: [ { id: '', // Empty ID name: 'Test', platform: Platform.PACIFICA, enabled: true, credentials: { type: 'ed25519' as const, privateKey: 'invalid-key' } } ] } await expect(registry.loadAccounts(invalidConfig)) .rejects.toThrow('Account ID cannot be empty') }) }) })