Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Test Coverage for packages/web3-wallet/src #464

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 87 additions & 6 deletions packages/web3-wallet/src/password-crypto.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,93 @@ You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { decrypt } from './password-crypto'
import { encrypt, decrypt } from './password-crypto'

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(500_000) // 0.5 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)
})
})
})
70 changes: 67 additions & 3 deletions packages/web3-wallet/src/privatekey-wallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,79 @@ You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { web3 } from '@alephium/web3'
import { verifySignature, web3 } from '@alephium/web3'
import { PrivateKeyWallet } from './privatekey-wallet'

describe('privatekey wallet', () => {
it('test the length of private key', () => {
describe('PrivateKeyWallet', () => {
beforeAll(() => {
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<string>()
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).toBe(45)
expect(wallet.publicKey.length).toBe(66)
})

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')
expect(verifySignature(hexString, wallet.publicKey, signature)).toBe(true)
})

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)
})
})