Tests and fixes for remaining Digital Bitbox commands

Adds tests for setup, wipe, backup, restore, displayaddress,
promptpin, and sendpin.
This commit is contained in:
Andrew Chow 2019-02-04 17:47:45 -05:00
parent 0085b8fd2c
commit 40abbc2927
2 changed files with 91 additions and 6 deletions

View File

@ -15,7 +15,7 @@ import sys
import time
from ..hwwclient import HardwareWalletClient
from ..errors import ActionCanceledError, BadArgumentError, DeviceFailureError, DeviceNotReadyError, NoPasswordError, UnavailableActionError, DeviceFailureError
from ..errors import ActionCanceledError, BadArgumentError, DeviceFailureError, DeviceAlreadyInitError, DeviceNotReadyError, NoPasswordError, UnavailableActionError, DeviceFailureError
from ..serializations import CTransaction, PSBT, hash256, hash160, ser_sig_der, ser_sig_compact, ser_compact_size
from ..base58 import get_xpub_fingerprint, decode, to_address, xpub_main_2_test, get_xpub_fingerprint_hex
@ -518,7 +518,7 @@ class DigitalbitboxClient(HardwareWalletClient):
# Need a wallet name and backup passphrase
if not label or not passphrase:
raise BadArgumentError('THe label and backup passphrase for a new Digital Bitbox wallet must be specified and cannot be empty')
raise BadArgumentError('The label and backup passphrase for a new Digital Bitbox wallet must be specified and cannot be empty')
# Set password
to_send = {'password': self.password}
@ -548,12 +548,16 @@ class DigitalbitboxClient(HardwareWalletClient):
# Begin backup process
@digitalbitbox_exception
def backup_device(self, label='', passphrase=''):
# Need a wallet name and backup passphrase
if not label or not passphrase:
raise BadArgumentError('The label and backup passphrase for a Digital Bitbox backup must be specified and cannot be empty')
key = stretch_backup_key(passphrase)
backup_filename = format_backup_filename(label)
to_send = {'backup': {'source': 'HWW', 'key': key, 'filename': backup_filename}}
to_send = {'backup': {'source': 'all', 'key': key, 'filename': backup_filename}}
reply = send_encrypt(json.dumps(to_send).encode(), self.password, self.device)
if 'error' in reply:
return {'success': False, 'error': reply['error']['message']}
raise DBBError(reply)
return {'success': True}
# Close the device
@ -562,10 +566,10 @@ class DigitalbitboxClient(HardwareWalletClient):
# Prompt pin
def prompt_pin(self):
raise UnavailableActionError('The Digtal Bitbox does not need a PIN sent from the host')
raise UnavailableActionError('The Digital Bitbox does not need a PIN sent from the host')
# Send pin
def send_pin(self):
def send_pin(self, pin):
raise UnavailableActionError('The Digital Bitbox does not need a PIN sent from the host')
def enumerate(password=''):

View File

@ -41,8 +41,89 @@ def digitalbitbox_test_suite(rpc, userpass, simulator):
fingerprint = 'a31b978a'
master_xpub = 'xpub6BsWJiRvbzQJg3J6tgUKmHWYbHJSj41EjAAje6LuDwnYLqLiNSWK4N7rCXwiUmNJTBrKL8AEH3LBzhJdgdxoy4T9aMPLCWAa6eWKGCFjQhq'
# DigitalBitbox specific management command tests
class TestDBBManCommands(DeviceTestCase):
def test_restore(self):
result = process_commands(self.dev_args + ['restore'])
self.assertIn('error', result)
self.assertIn('code', result)
self.assertEqual(result['error'], 'The Digital Bitbox does not support restoring via software')
self.assertEqual(result['code'], -9)
def test_pin(self):
result = process_commands(self.dev_args + ['promptpin'])
self.assertIn('error', result)
self.assertIn('code', result)
self.assertEqual(result['error'], 'The Digital Bitbox does not need a PIN sent from the host')
self.assertEqual(result['code'], -9)
result = process_commands(self.dev_args + ['sendpin', '1234'])
self.assertIn('error', result)
self.assertIn('code', result)
self.assertEqual(result['error'], 'The Digital Bitbox does not need a PIN sent from the host')
self.assertEqual(result['code'], -9)
def test_display(self):
result = process_commands(self.dev_args + ['displayaddress', 'm/0h'])
self.assertIn('error', result)
self.assertIn('code', result)
self.assertEqual(result['error'], 'The Digital Bitbox does not have a screen to display addresses on')
self.assertEqual(result['code'], -9)
def test_setup_wipe(self):
# Device is init, setup should fail
result = process_commands(self.dev_args + ['setup', '--label', 'setup_test', '--backup_passphrase', 'testpass'])
self.assertEquals(result['code'], -10)
self.assertEquals(result['error'], 'Device is already initialized. Use wipe first and try again')
# Wipe
result = process_commands(self.dev_args + ['wipe'])
self.assertTrue(result['success'])
# Check arguments
result = process_commands(self.dev_args + ['setup', '--label', 'setup_test'])
self.assertEquals(result['code'], -7)
self.assertEquals(result['error'], 'The label and backup passphrase for a new Digital Bitbox wallet must be specified and cannot be empty')
result = process_commands(self.dev_args + ['setup', '--backup_passphrase', 'testpass'])
self.assertEquals(result['code'], -7)
self.assertEquals(result['error'], 'The label and backup passphrase for a new Digital Bitbox wallet must be specified and cannot be empty')
# Setup
result = process_commands(self.dev_args + ['setup', '--label', 'setup_test', '--backup_passphrase', 'testpass'])
self.assertTrue(result['success'])
# Reset back to original
send_encrypt(json.dumps({"seed":{"source":"backup","filename":"test_backup.pdf","key":"key"}}), '0000', dev)
# Make sure device is init, setup should fail
result = process_commands(self.dev_args + ['setup', '--label', 'setup_test', '--backup_passphrase', 'testpass'])
self.assertEquals(result['code'], -10)
self.assertEquals(result['error'], 'Device is already initialized. Use wipe first and try again')
def test_backup(self):
# Check arguments
result = process_commands(self.dev_args + ['backup', '--label', 'backup_test'])
self.assertEquals(result['code'], -7)
self.assertEquals(result['error'], 'The label and backup passphrase for a Digital Bitbox backup must be specified and cannot be empty')
result = process_commands(self.dev_args + ['backup', '--backup_passphrase', 'key'])
self.assertEquals(result['code'], -7)
self.assertEquals(result['error'], 'The label and backup passphrase for a Digital Bitbox backup must be specified and cannot be empty')
# Wipe
result = process_commands(self.dev_args + ['wipe'])
self.assertTrue(result['success'])
# Setup
result = process_commands(self.dev_args + ['setup', '--label', 'backup_test', '--backup_passphrase', 'testpass'])
self.assertTrue(result['success'])
# make the backup
result = process_commands(self.dev_args + ['backup', '--label', 'backup_test_backup', '--backup_passphrase', 'testpass'])
self.assertTrue(result['success'])
# Generic Device tests
suite = unittest.TestSuite()
suite.addTest(DeviceTestCase.parameterize(TestDBBManCommands, rpc, userpass, type, path, fingerprint, master_xpub, '0000'))
suite.addTest(DeviceTestCase.parameterize(TestDeviceConnect, rpc, userpass, type, path, fingerprint, master_xpub, '0000'))
suite.addTest(DeviceTestCase.parameterize(TestGetKeypool, rpc, userpass, type, path, fingerprint, master_xpub, '0000'))
suite.addTest(DeviceTestCase.parameterize(TestSignTx, rpc, userpass, type, path, fingerprint, master_xpub, '0000'))