OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-wallet-desktop / test / amount-validator.cjs

128 lines · javascript ref:
// 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')
})