From c4ef1934c71e900bc177ed5283481dc7731913d6 Mon Sep 17 00:00:00 2001 From: Guillaume George Date: Sun, 2 Dec 2018 20:22:15 +0900 Subject: [PATCH 1/2] Add missing tests for wallet create, verbose and create_addr Signed-off-by: Guillaume George --- .../Commands/tests/test_wallet_commands.py | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/neo/Prompt/Commands/tests/test_wallet_commands.py b/neo/Prompt/Commands/tests/test_wallet_commands.py index 10068ec79..fb99c94f5 100644 --- a/neo/Prompt/Commands/tests/test_wallet_commands.py +++ b/neo/Prompt/Commands/tests/test_wallet_commands.py @@ -5,6 +5,8 @@ from neocore.UInt160 import UInt160 from neocore.Fixed8 import Fixed8 from neo.Prompt.Commands.Wallet import CommandWallet, CreateAddress, DeleteAddress, ImportToken, ImportWatchAddr, ShowUnspentCoins, SplitUnspentCoin +from neo.Prompt.PromptData import PromptData +import os import shutil from mock import patch @@ -34,8 +36,73 @@ def GetWallet1(cls, recreate=False): to_aes_key(UserWalletTestCase.wallet_1_pass())) return cls._wallet1 + @classmethod + def OpenWallet(cls): + PromptData.Wallet = cls.GetWallet1(recreate=True) + + @classmethod + def tearDown(cls): + PromptData.Wallet = None + # Beginning with refactored tests + def test_wallet_create(self): + def remove_new_wallet(): + path = UserWalletTestCase.new_wallet_dest() + try: + if os.path.exists(path): + os.remove(path) + except Exception as e: + print("couldn't remove wallets %s " % e) + + with patch('neo.Prompt.PromptData.PromptData.Prompt'): + with patch('neo.Prompt.Commands.Wallet.prompt', side_effect=["testpassword", "testpassword"]): + # test wallet create successful + path = UserWalletTestCase.new_wallet_dest() + args = ['create', path] + self.assertFalse(os.path.isfile(path)) + res = CommandWallet().execute(args) + self.assertEqual(str(type(res)), "") + self.assertTrue(os.path.isfile(path)) + remove_new_wallet() + + # test wallet create with no path + args = ['create'] + res = CommandWallet().execute(args) + self.assertFalse(res) + + # test wallet open with already existing path + with patch('neo.Prompt.Commands.Wallet.prompt', side_effect=["testpassword", "testpassword"]): + path = UserWalletTestCase.new_wallet_dest() + args = ['create', path] + self.assertFalse(os.path.isfile(path)) + res = CommandWallet().execute(args) + self.assertEqual(str(type(res)), "") + self.assertTrue(os.path.isfile(path)) + + res = CommandWallet().execute(args) + self.assertFalse(res) + self.assertTrue(os.path.isfile(path)) + remove_new_wallet() + + # test wallet with different passwords + with patch('neo.Prompt.Commands.Wallet.prompt', side_effect=["testpassword", "bad"]): + path = UserWalletTestCase.new_wallet_dest() + args = ['create', path] + self.assertFalse(os.path.isfile(path)) + res = CommandWallet().execute(args) + self.assertFalse(res) + self.assertFalse(os.path.isfile(path)) + + # test wallet create unsuccessful + with patch('neo.Prompt.Commands.Wallet.prompt', side_effect=["testpassword", "testpassword"]): + with patch('neo.Implementations.Wallets.peewee.UserWallet.UserWallet.Create', side_effect=[Exception('test exception')]): + path = UserWalletTestCase.new_wallet_dest() + args = ['create', path] + res = CommandWallet().execute(args) + self.assertFalse(res) + self.assertFalse(os.path.isfile(path)) + def test_wallet_open(self): with patch('neo.Prompt.PromptData.PromptData.Prompt'): with patch('neo.Prompt.Commands.Wallet.prompt', side_effect=["testpassword"]): @@ -93,6 +160,54 @@ def test_wallet_close(self): self.assertTrue(res) + def test_wallet_verbose(self): + with patch('neo.Prompt.PromptData.PromptData.Prompt'): + # test wallet verbose with no wallet + args = ['verbose'] + res = CommandWallet().execute(args) + self.assertFalse(res) + + # test wallet close with open wallet + self.OpenWallet() + args = ['verbose'] + res = CommandWallet().execute(args) + self.assertTrue(res) + + def test_wallet_migrate(self): + pass + + def test_wallet_create_address(self): + with patch('neo.Prompt.PromptData.PromptData.Prompt'): + # test wallet create address with no wallet open + args = ['create_addr', 1] + res = CommandWallet().execute(args) + self.assertFalse(res) + + self.OpenWallet() + + # test wallet create address with no argument + args = ['create_addr'] + res = CommandWallet().execute(args) + self.assertFalse(res) + + # test wallet create address with negative number + args = ['create_addr', -1] + res = CommandWallet().execute(args) + self.assertFalse(res) + + # test wallet create successful + args = ['create_addr', 1] + res = CommandWallet().execute(args) + self.assertTrue(res) + self.assertEqual(str(type(res)), "") + self.assertEqual(len(res.Addresses), 2) # Has one address when created. + + args = ['create_addr', 7] + res = CommandWallet().execute(args) + self.assertTrue(res) + self.assertEqual(str(type(res)), "") + self.assertEqual(len(res.Addresses), 9) + ########################################################## ########################################################## def test_1_import_addr(self): From 57cba0c9aea1b7b3f1730d601e3a752fa0fe5a7f Mon Sep 17 00:00:00 2001 From: Guillaume George Date: Mon, 3 Dec 2018 19:04:15 +0900 Subject: [PATCH 2/2] fix reviews Signed-off-by: Guillaume George --- neo/Prompt/Commands/Wallet.py | 121 +++++++++--------- .../Commands/tests/test_wallet_commands.py | 108 ++++++++++------ 2 files changed, 129 insertions(+), 100 deletions(-) diff --git a/neo/Prompt/Commands/Wallet.py b/neo/Prompt/Commands/Wallet.py index 55639490b..ebb8e109e 100644 --- a/neo/Prompt/Commands/Wallet.py +++ b/neo/Prompt/Commands/Wallet.py @@ -56,7 +56,7 @@ def execute(self, arguments): if not item: print("Wallet %s " % json.dumps(wallet.ToJson(), indent=4)) - return + return wallet try: return self.execute_sub_command(item, arguments[1:]) @@ -75,45 +75,43 @@ def execute(self, arguments): PromptData.close_wallet() path = get_arg(arguments, 0) - if path: - if os.path.exists(path): - print("File already exists") - return - - passwd1 = prompt("[password]> ", is_password=True) - passwd2 = prompt("[password again]> ", is_password=True) - - if passwd1 != passwd2 or len(passwd1) < 10: - print("Please provide matching passwords that are at least 10 characters long") - return - - password_key = to_aes_key(passwd1) - - try: - PromptData.Wallet = UserWallet.Create(path=path, password=password_key) - contract = PromptData.Wallet.GetDefaultContract() - key = PromptData.Wallet.GetKey(contract.PublicKeyHash) - print("Wallet %s" % json.dumps(PromptData.Wallet.ToJson(), indent=4)) - print("Pubkey %s" % key.PublicKey.encode_point(True)) - return PromptData.Wallet - except Exception as e: - print("Exception creating wallet: %s" % e) - PromptData.Wallet = None - if os.path.isfile(path): - try: - os.remove(path) - except Exception as e: - print("Could not remove {}: {}".format(path, e)) - return - - if PromptData.Wallet: - PromptData.Prompt.start_wallet_loop() - return - - else: + if not path: print("Please specify a path") return + if os.path.exists(path): + print("File already exists") + return + + passwd1 = prompt("[password]> ", is_password=True) + passwd2 = prompt("[password again]> ", is_password=True) + + if passwd1 != passwd2 or len(passwd1) < 10: + print("Please provide matching passwords that are at least 10 characters long") + return + + password_key = to_aes_key(passwd1) + + try: + PromptData.Wallet = UserWallet.Create(path=path, password=password_key) + contract = PromptData.Wallet.GetDefaultContract() + key = PromptData.Wallet.GetKey(contract.PublicKeyHash) + print("Wallet %s" % json.dumps(PromptData.Wallet.ToJson(), indent=4)) + print("Pubkey %s" % key.PublicKey.encode_point(True)) + except Exception as e: + print("Exception creating wallet: %s" % e) + PromptData.Wallet = None + if os.path.isfile(path): + try: + os.remove(path) + except Exception as e: + print("Could not remove {}: {}".format(path, e)) + return + + if PromptData.Wallet: + PromptData.Prompt.start_wallet_loop() + return PromptData.Wallet + def command_desc(self): p1 = ParameterDesc('path', 'path to store the wallet file') return CommandDesc('create', 'create a new NEO wallet (with 1 address)', [p1]) @@ -130,28 +128,25 @@ def execute(self, arguments): path = get_arg(arguments, 0) - if path: - - if not os.path.exists(path): - print("Wallet file not found") - return + if not path: + print("Please specify a path") + return - passwd = prompt("[password]> ", is_password=True) - password_key = to_aes_key(passwd) + if not os.path.exists(path): + print("Wallet file not found") + return - try: - PromptData.Wallet = UserWallet.Open(path, password_key) + passwd = prompt("[password]> ", is_password=True) + password_key = to_aes_key(passwd) - PromptData.Prompt.start_wallet_loop() - print("Opened wallet at %s" % path) - return PromptData.Wallet - except Exception as e: - print("Could not open wallet: %s" % e) - return + try: + PromptData.Wallet = UserWallet.Open(path, password_key) - else: - print("Please specify a path") - return + PromptData.Prompt.start_wallet_loop() + print("Opened wallet at %s" % path) + return PromptData.Wallet + except Exception as e: + print("Could not open wallet: %s" % e) def command_desc(self): p1 = ParameterDesc('path', 'path to open the wallet file') @@ -175,7 +170,7 @@ class CommandWalletVerbose(CommandBase): def __init__(self): super().__init__() - def execute(self, arguments): + def execute(self, arguments=None): print("Wallet %s " % json.dumps(PromptData.Wallet.ToJson(verbose=True), indent=4)) return True @@ -188,12 +183,9 @@ class CommandWalletMigrate(CommandBase): def __init__(self): super().__init__() - def execute(self, arguments): - if PromptData.Wallet is not None: - PromptData.Wallet.Migrate() - print("Migrated wallet") - return True - return False + def execute(self, arguments=None): + PromptData.Wallet.Migrate() + return True def command_desc(self): return CommandDesc('migrate', 'migrate an old wallet to the new format') @@ -206,6 +198,11 @@ def __init__(self): def execute(self, arguments): addresses_to_create = get_arg(arguments, 0) + + if not addresses_to_create: + print("Please specify a number of addresses to create.") + return + return CreateAddress(PromptData.Wallet, addresses_to_create) def command_desc(self): diff --git a/neo/Prompt/Commands/tests/test_wallet_commands.py b/neo/Prompt/Commands/tests/test_wallet_commands.py index fb99c94f5..54e209697 100644 --- a/neo/Prompt/Commands/tests/test_wallet_commands.py +++ b/neo/Prompt/Commands/tests/test_wallet_commands.py @@ -4,7 +4,8 @@ from neo.Core.Blockchain import Blockchain from neocore.UInt160 import UInt160 from neocore.Fixed8 import Fixed8 -from neo.Prompt.Commands.Wallet import CommandWallet, CreateAddress, DeleteAddress, ImportToken, ImportWatchAddr, ShowUnspentCoins, SplitUnspentCoin +from neo.Prompt.Commands.Wallet import CommandWallet +from neo.Prompt.Commands.Wallet import CreateAddress, DeleteAddress, ImportToken, ImportWatchAddr, ShowUnspentCoins, SplitUnspentCoin from neo.Prompt.PromptData import PromptData import os import shutil @@ -46,6 +47,22 @@ def tearDown(cls): # Beginning with refactored tests + def test_wallet(self): + # without wallet opened + res = CommandWallet().execute(None) + self.assertFalse(res) + + # with wallet opened + self.OpenWallet() + res = CommandWallet().execute(None) + self.assertEqual(type(res), UserWallet) + + def test_wallet_wrong_command(self): + self.OpenWallet() + args = ['badcommand'] + res = CommandWallet().execute(args) + self.assertFalse(res) + def test_wallet_create(self): def remove_new_wallet(): path = UserWalletTestCase.new_wallet_dest() @@ -62,7 +79,7 @@ def remove_new_wallet(): args = ['create', path] self.assertFalse(os.path.isfile(path)) res = CommandWallet().execute(args) - self.assertEqual(str(type(res)), "") + self.assertEqual(type(res), UserWallet) self.assertTrue(os.path.isfile(path)) remove_new_wallet() @@ -77,7 +94,7 @@ def remove_new_wallet(): args = ['create', path] self.assertFalse(os.path.isfile(path)) res = CommandWallet().execute(args) - self.assertEqual(str(type(res)), "") + self.assertEqual(type(res), UserWallet) self.assertTrue(os.path.isfile(path)) res = CommandWallet().execute(args) @@ -103,6 +120,26 @@ def remove_new_wallet(): self.assertFalse(res) self.assertFalse(os.path.isfile(path)) + # test wallet create exception after creation + with patch('neo.Prompt.Commands.Wallet.prompt', side_effect=["testpassword", "testpassword"]): + with patch('neo.Wallets.Wallet.Wallet.GetKey', side_effect=[Exception('test exception')]): + path = UserWalletTestCase.new_wallet_dest() + args = ['create', path] + res = CommandWallet().execute(args) + self.assertFalse(res) + self.assertFalse(os.path.isfile(path)) + + # test wallet create exception after creation with file deletion failure + with patch('neo.Prompt.Commands.Wallet.prompt', side_effect=["testpassword", "testpassword"]): + with patch('neo.Wallets.Wallet.Wallet.GetKey', side_effect=[Exception('test exception')]): + with patch('os.remove', side_effect=[Exception('test exception')]): + path = UserWalletTestCase.new_wallet_dest() + args = ['create', path] + res = CommandWallet().execute(args) + self.assertFalse(res) + self.assertTrue(os.path.isfile(path)) + remove_new_wallet() + def test_wallet_open(self): with patch('neo.Prompt.PromptData.PromptData.Prompt'): with patch('neo.Prompt.Commands.Wallet.prompt', side_effect=["testpassword"]): @@ -111,7 +148,7 @@ def test_wallet_open(self): res = CommandWallet().execute(args) - self.assertEqual(str(type(res)), "") + self.assertEqual(type(res), UserWallet) # test wallet open with no path; this will also close the open wallet args = ['open'] @@ -151,7 +188,7 @@ def test_wallet_close(self): res = CommandWallet().execute(args) - self.assertEqual(str(type(res)), "") + self.assertEqual(type(res), UserWallet) # now close the open wallet manually args = ['close'] @@ -161,11 +198,10 @@ def test_wallet_close(self): self.assertTrue(res) def test_wallet_verbose(self): - with patch('neo.Prompt.PromptData.PromptData.Prompt'): - # test wallet verbose with no wallet - args = ['verbose'] - res = CommandWallet().execute(args) - self.assertFalse(res) + # test wallet verbose with no wallet opened + args = ['verbose'] + res = CommandWallet().execute(args) + self.assertFalse(res) # test wallet close with open wallet self.OpenWallet() @@ -173,40 +209,36 @@ def test_wallet_verbose(self): res = CommandWallet().execute(args) self.assertTrue(res) - def test_wallet_migrate(self): - pass - def test_wallet_create_address(self): - with patch('neo.Prompt.PromptData.PromptData.Prompt'): - # test wallet create address with no wallet open - args = ['create_addr', 1] - res = CommandWallet().execute(args) - self.assertFalse(res) + # test wallet create address with no wallet open + args = ['create_addr', 1] + res = CommandWallet().execute(args) + self.assertFalse(res) - self.OpenWallet() + self.OpenWallet() - # test wallet create address with no argument - args = ['create_addr'] - res = CommandWallet().execute(args) - self.assertFalse(res) + # test wallet create address with no argument + args = ['create_addr'] + res = CommandWallet().execute(args) + self.assertFalse(res) - # test wallet create address with negative number - args = ['create_addr', -1] - res = CommandWallet().execute(args) - self.assertFalse(res) + # test wallet create address with negative number + args = ['create_addr', -1] + res = CommandWallet().execute(args) + self.assertFalse(res) - # test wallet create successful - args = ['create_addr', 1] - res = CommandWallet().execute(args) - self.assertTrue(res) - self.assertEqual(str(type(res)), "") - self.assertEqual(len(res.Addresses), 2) # Has one address when created. + # test wallet create successful + args = ['create_addr', 1] + res = CommandWallet().execute(args) + self.assertTrue(res) + self.assertEqual(type(res), UserWallet) + self.assertEqual(len(res.Addresses), 2) # Has one address when created. - args = ['create_addr', 7] - res = CommandWallet().execute(args) - self.assertTrue(res) - self.assertEqual(str(type(res)), "") - self.assertEqual(len(res.Addresses), 9) + args = ['create_addr', 7] + res = CommandWallet().execute(args) + self.assertTrue(res) + self.assertEqual(type(res), UserWallet) + self.assertEqual(len(res.Addresses), 9) ########################################################## ##########################################################