import { describe, it, expect, beforeEach } from 'vitest'; import { Encrypter } from '~/src/utils/encrypter'; import { binToUtf8, utf8ToBin } from '@bitauth/libauth'; describe('Encrypter', () => { let encryption: Encrypter; const testKey = 'test-secret-key-123'; beforeEach(async () => { encryption = await Encrypter.fromPassphrase(testKey); }); describe('constructor', () => { it('should create instance with string key', async () => { const enc = await Encrypter.fromPassphrase('test-key'); expect(enc).toBeInstanceOf(Encrypter); }); it('should create instance with Uint8Array key', async () => { const enc = await Encrypter.fromBytes(utf8ToBin('test-key')); expect(enc).toBeInstanceOf(Encrypter); }); }); describe('encrypt', () => { it('should encrypt string data', async () => { const data = 'Hello, World!'; const encrypted = await encryption.encrypt(data); expect(encrypted).toBeInstanceOf(Uint8Array); expect(encrypted.length).toBeGreaterThan(0); }); it('should encrypt Uint8Array data', async () => { const data = utf8ToBin('Hello, World!'); const encrypted = await encryption.encrypt(data); expect(encrypted).toBeInstanceOf(Uint8Array); expect(encrypted.length).toBeGreaterThan(0); }); it('should produce different ciphertext for same input due to random IV', async () => { const data = 'Hello, World!'; const encrypted1 = await encryption.encrypt(data); const encrypted2 = await encryption.encrypt(data); expect(Buffer.from(encrypted1).toString('hex')).not.toBe( Buffer.from(encrypted2).toString('hex'), ); }); }); describe('decrypt', () => { it('should decrypt encrypted string data correctly', async () => { const originalData = 'Hello, World!'; const encrypted = await encryption.encrypt(originalData); const decrypted = await encryption.decrypt(encrypted); expect(binToUtf8(decrypted)).toBe(originalData); }); it('should decrypt encrypted Uint8Array data correctly', async () => { const originalData = utf8ToBin('Hello, World!'); const encrypted = await encryption.encrypt(originalData); const decrypted = await encryption.decrypt(encrypted); expect(decrypted).toEqual(originalData); }); it('should throw error when trying to decrypt string input', async () => { await expect(encryption.decrypt('invalid-input' as any)).rejects.toThrow( 'Encrypted payload must be Uint8Array', ); }); it('should throw error when trying to decrypt invalid data', async () => { const invalidData = new Uint8Array([1, 2, 3, 4]); await expect(encryption.decrypt(invalidData)).rejects.toThrow(); }); }); describe('cross-instance encryption', () => { it('should decrypt data encrypted with different instance using same key', async () => { const enc1 = await Encrypter.fromPassphrase(testKey); const enc2 = await Encrypter.fromPassphrase(testKey); const originalData = 'Hello, World!'; const encrypted = await enc1.encrypt(originalData); const decrypted = await enc2.decrypt(encrypted); expect(binToUtf8(decrypted)).toBe(originalData); }); }); describe('large data handling', () => { it('should handle large data correctly', async () => { const largeData = 'x'.repeat(1000000); // 1MB of data const encrypted = await encryption.encrypt(largeData); const decrypted = await encryption.decrypt(encrypted); expect(binToUtf8(decrypted)).toBe(largeData); }); }); }); //