From b2c774e5d21f1dea2ccca6d615f962735d9b1af1 Mon Sep 17 00:00:00 2001 From: Emmanuel A Akalo <124416278+NueloSE@users.noreply.github.com> Date: Sun, 24 Nov 2024 04:56:56 +0000 Subject: [PATCH 1/4] Improve Test Coverage for packages/web3-wallet/src --- .../web3-wallet/src/password-crypto.test.ts | 93 +++++++++++++++++-- .../web3-wallet/src/privatekey-wallet.test.ts | 69 +++++++++++++- 2 files changed, 154 insertions(+), 8 deletions(-) diff --git a/packages/web3-wallet/src/password-crypto.test.ts b/packages/web3-wallet/src/password-crypto.test.ts index a5032baab..5b22d7dd2 100644 --- a/packages/web3-wallet/src/password-crypto.test.ts +++ b/packages/web3-wallet/src/password-crypto.test.ts @@ -16,12 +16,93 @@ You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ -import { decrypt } from './password-crypto' +import { encrypt, decrypt } from './password-crypto' // Replace with the correct file path -describe('password-crypto', () => { - it('should raise an error if payload version is not 1', () => { - const password = 'passw0rd' - const payloadRaw = '{"version":2}' - expect(() => decrypt(password, payloadRaw)).toThrow('Invalid version: got 2, expected: 1') +describe('Encryption and Decryption', () => { + const password = 'secure-password' + const testMessage = 'This is a test message' + + describe('encrypt', () => { + it('should return a valid JSON string containing salt, iv, encrypted data, and version', () => { + const encryptedPayload = encrypt(password, testMessage) + const parsedPayload = JSON.parse(encryptedPayload) + + expect(parsedPayload).toHaveProperty('salt') + expect(parsedPayload).toHaveProperty('iv') + expect(parsedPayload).toHaveProperty('encrypted') + expect(parsedPayload).toHaveProperty('version', 1) + + expect(typeof parsedPayload.salt).toBe('string') + expect(typeof parsedPayload.iv).toBe('string') + expect(typeof parsedPayload.encrypted).toBe('string') + }) + + it('should produce unique salt and IV for each encryption', () => { + const payload1 = JSON.parse(encrypt(password, testMessage)) + const payload2 = JSON.parse(encrypt(password, testMessage)) + + expect(payload1.salt).not.toBe(payload2.salt) + expect(payload1.iv).not.toBe(payload2.iv) + expect(payload1.encrypted).not.toBe(payload2.encrypted) + }) + }) + + describe('decrypt', () => { + it('should correctly decrypt an encrypted message using the same password', () => { + const encryptedPayload = encrypt(password, testMessage) + const decryptedMessage = decrypt(password, encryptedPayload) + + expect(decryptedMessage).toBe(testMessage) + }) + + it('should throw an error when the password is incorrect', () => { + const encryptedPayload = encrypt(password, testMessage) + const wrongPassword = 'wrong-password' + + expect(() => decrypt(wrongPassword, encryptedPayload)).toThrow(/Unsupported state or unable to authenticate data/) + }) + + it('should throw an error if the version is not 1', () => { + const encryptedPayload = encrypt(password, testMessage) + const parsedPayload = JSON.parse(encryptedPayload) + parsedPayload.version = 2 + + expect(() => decrypt(password, JSON.stringify(parsedPayload))).toThrow(/Invalid version: got 2, expected: 1/) + }) + + it('should throw an error if the salt or IV is missing', () => { + const encryptedPayload = encrypt(password, testMessage) + const parsedPayload = JSON.parse(encryptedPayload) + + delete parsedPayload.salt + + expect(() => decrypt(password, JSON.stringify(parsedPayload))).toThrow() + }) + }) + + describe('edge cases', () => { + it('should handle an empty message for encryption and decryption', () => { + const emptyMessage = '' + const encryptedPayload = encrypt(password, emptyMessage) + const decryptedMessage = decrypt(password, encryptedPayload) + + expect(decryptedMessage).toBe(emptyMessage) + }) + + it('should handle large messages for encryption and decryption', () => { + const largeMessage = 'A'.repeat(1_000_000) // 1 MB of data + const encryptedPayload = encrypt(password, largeMessage) + const decryptedMessage = decrypt(password, encryptedPayload) + + expect(decryptedMessage).toBe(largeMessage) + }) + + it('should handle messages with special characters and emojis', () => { + const specialMessage = 'Special characters: 🚀✨🎉!@#$%^&*()_+' + const encryptedPayload = encrypt(password, specialMessage) + const decryptedMessage = decrypt(password, encryptedPayload) + + expect(decryptedMessage).toBe(specialMessage) + }) }) }) diff --git a/packages/web3-wallet/src/privatekey-wallet.test.ts b/packages/web3-wallet/src/privatekey-wallet.test.ts index adac09aac..60aadf87f 100644 --- a/packages/web3-wallet/src/privatekey-wallet.test.ts +++ b/packages/web3-wallet/src/privatekey-wallet.test.ts @@ -19,12 +19,77 @@ along with the library. If not, see . import { web3 } from '@alephium/web3' import { PrivateKeyWallet } from './privatekey-wallet' -describe('privatekey wallet', () => { - it('test the length of private key', () => { +describe('PrivateKeyWallet', () => { + beforeAll(() => { + // Set the node provider before running the tests web3.setCurrentNodeProvider('http://127.0.0.1:22973') + }) + + it('should generate a private key of correct length', () => { for (let i = 0; i < 100; i++) { const wallet = PrivateKeyWallet.Random() expect(wallet.privateKey.length).toEqual(64) } }) + + it('should generate unique private keys', () => { + const wallets = new Set() + for (let i = 0; i < 100; i++) { + const wallet = PrivateKeyWallet.Random() + wallets.add(wallet.privateKey) + } + expect(wallets.size).toEqual(100) + }) + + it('should generate a wallet with valid address and public key', () => { + const wallet = PrivateKeyWallet.Random() + expect(wallet.address).toBeDefined() + expect(wallet.publicKey).toBeDefined() + expect(wallet.address.length).toBeGreaterThan(0) + expect(wallet.publicKey.length).toBeGreaterThan(0) + }) + + it('should correctly sign raw data', async () => { + const wallet = PrivateKeyWallet.Random() + const hexString = 'deadbeef' + const signature = await wallet.signRaw(wallet.address, hexString) + + expect(signature).toBeDefined() + expect(typeof signature).toBe('string') + // Optionally add more checks to validate the signature + }) + + it('should throw an error if signing with an incorrect address', async () => { + const wallet = PrivateKeyWallet.Random() + const hexString = 'deadbeef' + + await expect(wallet.signRaw('invalid-address', hexString)).rejects.toThrow('Unmatched signer address') + }) + + it('should create a wallet from a mnemonic', () => { + const mnemonic = 'test test test test test test test test test test test junk' + const wallet = PrivateKeyWallet.FromMnemonic({ mnemonic }) + + expect(wallet.privateKey).toBeDefined() + expect(wallet.publicKey).toBeDefined() + expect(wallet.address).toBeDefined() + }) + + it('should create a wallet with a specific group from a mnemonic', () => { + const mnemonic = 'test test test test test test test test test test test junk' + const targetGroup = 1 + const wallet = PrivateKeyWallet.FromMnemonicWithGroup(mnemonic, targetGroup) + + expect(wallet.group).toEqual(targetGroup) + expect(wallet.privateKey).toBeDefined() + expect(wallet.publicKey).toBeDefined() + expect(wallet.address).toBeDefined() + }) + + it('should generate a wallet with the correct target group', () => { + const targetGroup = 3 + const wallet = PrivateKeyWallet.Random(targetGroup) + + expect(wallet.group).toEqual(targetGroup) + }) }) From f2d034a20b0b31dba2e8c206d5c4c662e06c0498 Mon Sep 17 00:00:00 2001 From: Emmanuel A Akalo <124416278+NueloSE@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:05:05 +0000 Subject: [PATCH 2/4] fix --- packages/web3-wallet/src/privatekey-wallet.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/web3-wallet/src/privatekey-wallet.test.ts b/packages/web3-wallet/src/privatekey-wallet.test.ts index 60aadf87f..061248f7b 100644 --- a/packages/web3-wallet/src/privatekey-wallet.test.ts +++ b/packages/web3-wallet/src/privatekey-wallet.test.ts @@ -16,7 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ -import { web3 } from '@alephium/web3' +import { verifySignature, web3 } from '@alephium/web3' import { PrivateKeyWallet } from './privatekey-wallet' describe('PrivateKeyWallet', () => { @@ -45,8 +45,8 @@ describe('PrivateKeyWallet', () => { const wallet = PrivateKeyWallet.Random() expect(wallet.address).toBeDefined() expect(wallet.publicKey).toBeDefined() - expect(wallet.address.length).toBeGreaterThan(0) - expect(wallet.publicKey.length).toBeGreaterThan(0) + expect(wallet.address.length).toBe(45) + expect(wallet.publicKey.length).toBe(66) }) it('should correctly sign raw data', async () => { @@ -56,7 +56,7 @@ describe('PrivateKeyWallet', () => { expect(signature).toBeDefined() expect(typeof signature).toBe('string') - // Optionally add more checks to validate the signature + expect(verifySignature(hexString, wallet.publicKey, signature)).toBe(true) }) it('should throw an error if signing with an incorrect address', async () => { From fccf62060fbce1e659181550d6a73bfef782e911 Mon Sep 17 00:00:00 2001 From: Emmanuel A Akalo <124416278+NueloSE@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:37:36 +0100 Subject: [PATCH 3/4] Update password-crypto.test.ts --- packages/web3-wallet/src/password-crypto.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web3-wallet/src/password-crypto.test.ts b/packages/web3-wallet/src/password-crypto.test.ts index 5b22d7dd2..00aa9591c 100644 --- a/packages/web3-wallet/src/password-crypto.test.ts +++ b/packages/web3-wallet/src/password-crypto.test.ts @@ -16,7 +16,7 @@ You should have received a copy of the GNU Lesser General Public License along with the library. If not, see . */ -import { encrypt, decrypt } from './password-crypto' // Replace with the correct file path +import { encrypt, decrypt } from './password-crypto' describe('Encryption and Decryption', () => { const password = 'secure-password' @@ -90,7 +90,7 @@ describe('Encryption and Decryption', () => { }) it('should handle large messages for encryption and decryption', () => { - const largeMessage = 'A'.repeat(1_000_000) // 1 MB of data + const largeMessage = 'A'.repeat(500_000) // 0.5 MB of data const encryptedPayload = encrypt(password, largeMessage) const decryptedMessage = decrypt(password, encryptedPayload) From 1652f395f1a6acc203876cb67f88afafa86fb9ce Mon Sep 17 00:00:00 2001 From: Emmanuel A Akalo <124416278+NueloSE@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:44:37 +0100 Subject: [PATCH 4/4] Update privatekey-wallet.test.ts --- packages/web3-wallet/src/privatekey-wallet.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/web3-wallet/src/privatekey-wallet.test.ts b/packages/web3-wallet/src/privatekey-wallet.test.ts index 061248f7b..0354865e7 100644 --- a/packages/web3-wallet/src/privatekey-wallet.test.ts +++ b/packages/web3-wallet/src/privatekey-wallet.test.ts @@ -21,7 +21,6 @@ import { PrivateKeyWallet } from './privatekey-wallet' describe('PrivateKeyWallet', () => { beforeAll(() => { - // Set the node provider before running the tests web3.setCurrentNodeProvider('http://127.0.0.1:22973') })