// test/amount-validator.cjs - Tests for lib/amount-validator.cjs
const test = require('brittle')
const {
validateAmount,
validateSufficientBalance,
formatAmount,
parseAmount
} = require('../lib/amount-validator.cjs')
// Bitcoin Tests
test('validateAmount accepts valid satoshi amounts', function (t) {
const validAmounts = ['1000', '100000000', '2100000000000000']
for (const amount of validAmounts) {
const result = validateAmount(amount, 'bitcoin')
t.ok(result.valid, `valid satoshi: ${amount}`)
}
})
test('validateAmount rejects scientific notation', function (t) {
const result = validateAmount('1e8', 'bitcoin')
t.absent(result.valid, 'rejects scientific notation')
t.ok(result.reason.includes('scientific'), 'reason mentions scientific notation')
})
test('validateAmount rejects decimals', function (t) {
const result = validateAmount('0.5', 'bitcoin')
t.absent(result.valid, 'rejects decimal')
})
test('validateAmount rejects negative amounts', function (t) {
const result = validateAmount('-1000', 'bitcoin')
t.absent(result.valid, 'rejects negative')
})
test('validateAmount rejects amounts over Bitcoin max', function (t) {
const tooMuch = '9999999999999999999' // Way over 21M BTC
const result = validateAmount(tooMuch, 'bitcoin')
t.absent(result.valid, 'rejects over max')
})
// Ethereum Tests
test('validateAmount accepts valid wei amounts', function (t) {
const validAmounts = ['1000000000000000000', '500000000000000000']
for (const amount of validAmounts) {
const result = validateAmount(amount, 'ethereum')
t.ok(result.valid, `valid wei: ${amount}`)
}
})
test('validateAmount rejects amounts over Ethereum max', function (t) {
const tooMuch = '999999999999999999999999999999' // Way over 1B ETH
const result = validateAmount(tooMuch, 'ethereum')
t.absent(result.valid, 'rejects over max')
})
// Balance Validation
test('validateSufficientBalance accepts sufficient funds', function (t) {
const amount = BigInt(1000000)
const balance = BigInt(2000000)
const fee = BigInt(500000)
const result = validateSufficientBalance(amount, balance, fee, 'bitcoin')
t.ok(result.valid, 'sufficient balance')
})
test('validateSufficientBalance rejects insufficient balance', function (t) {
const amount = BigInt(2000000)
const balance = BigInt(1000000)
const fee = BigInt(500000)
const result = validateSufficientBalance(amount, balance, fee, 'bitcoin')
t.absent(result.valid, 'insufficient balance')
t.ok(result.reason.includes('Insufficient'), 'reason mentions insufficient')
})
// Formatting Tests
test('formatAmount converts satoshi to BTC', function (t) {
const formatted = formatAmount(BigInt(100000000), 'bitcoin')
t.is(formatted, '1.00000000 BTC', 'formats 1 BTC correctly')
const formatted2 = formatAmount(BigInt(50000000), 'bitcoin')
t.is(formatted2, '0.50000000 BTC', 'formats 0.5 BTC correctly')
})
test('formatAmount converts wei to ETH', function (t) {
const formatted = formatAmount(BigInt('1000000000000000000'), 'ethereum')
t.is(formatted, '1.000000000000000000 ETH', 'formats 1 ETH correctly')
const formatted2 = formatAmount(BigInt('500000000000000000'), 'ethereum')
t.is(formatted2, '0.500000000000000000 ETH', 'formats 0.5 ETH correctly')
})
// Parsing Tests
test('parseAmount converts BTC to satoshi', function (t) {
const parsed = parseAmount('1', 'bitcoin')
t.is(parsed, BigInt(100000000), 'parses 1 BTC correctly')
const parsed2 = parseAmount('0.5', 'bitcoin')
t.is(parsed2, BigInt(50000000), 'parses 0.5 BTC correctly')
})
test('parseAmount converts ETH to wei', function (t) {
const parsed = parseAmount('1', 'ethereum')
t.is(parsed, BigInt('1000000000000000000'), 'parses 1 ETH correctly')
const parsed2 = parseAmount('0.5', 'ethereum')
t.is(parsed2, BigInt('500000000000000000'), 'parses 0.5 ETH correctly')
})
// Edge Cases
test('validateAmount handles zero', function (t) {
const result = validateAmount('0', 'bitcoin')
t.ok(result.valid, 'zero is valid')
})
test('validateAmount rejects empty string', function (t) {
const result = validateAmount('', 'bitcoin')
t.absent(result.valid, 'rejects empty')
})
test('validateAmount rejects non-numeric', function (t) {
const result = validateAmount('not-a-number', 'bitcoin')
t.absent(result.valid, 'rejects non-numeric')
})