def helper_test_delete_last_account(self, app): """ Trying to delete the last account, should not crash the app, refs #120. """ controller = app.controller pywalib = controller.pywalib manage_existing = controller.manage_existing # makes sure there's only one account left self.assertEqual(len(pywalib.get_account_list()), 1) # deletes it delete_button_id = manage_existing.ids.delete_button_id delete_button_id.dispatch('on_release') # a confirmation popup should show dialogs = Dialog.dialogs self.assertEqual(len(dialogs), 1) dialog = dialogs[0] self.assertEqual(dialog.title, 'Are you sure?') # confirm it manage_existing.on_delete_account_yes(dialog) # account was deleted dialog message dialogs = Dialog.dialogs self.assertEqual(len(dialogs), 1) dialog = dialogs[0] self.assertEqual(dialog.title, 'Account deleted, redirecting...') Dialog.dismiss_all_dialogs() self.advance_frames(1) # verifies the account was deleted self.assertEqual(len(pywalib.get_account_list()), 0) # this should be done by the events, but doesn't seem to happen # so we have to trigger it manually controller.history.current_account = None self.advance_frames(1)
def helper_test_delete_account_none_selected(self, app): """ Tries to delete account when none are selected, refs #90. """ controller = app.controller pywalib = controller.pywalib manage_existing = controller.manage_existing # makes sure an account is selected pywalib.new_account(password="******", security_ratio=1) controller.current_account = pywalib.get_account_list()[0] # ManageExisting and Controller current_account should be in sync self.assertEqual(manage_existing.current_account, controller.current_account) # chaning in the Controller, should trigger the change on the other self.assertTrue(manage_existing.current_account is not None) controller.current_account = None self.assertIsNone(manage_existing.current_account) # let's try to delete this "None account" delete_button_id = manage_existing.ids.delete_button_id delete_button_id.dispatch('on_release') # an error dialog should pop dialogs = Dialog.dialogs self.assertEqual(len(dialogs), 1) dialog = dialogs[0] self.assertEqual(dialog.title, 'No account selected.') Dialog.dismiss_all_dialogs()
def helper_test_on_send_click(self, app): """ Verifies clicking "Send" Ethers works as expected, refs #63. Also checks for the amount field, refs #152. """ controller = app.controller # TODO: use dispatch('on_release') on navigation drawer controller.load_landing_page() send = controller.send send_button_id = send.ids.send_button_id # verifies clicking send button doesn't crash the application send_button_id.dispatch('on_release') dialogs = Dialog.dialogs # but it would still raise some popups since the form is invalid self.assertEqual(len(dialogs), 2) self.assertEqual(dialogs[0].title, 'Input error') self.assertEqual(dialogs[1].title, 'Invalid form') Dialog.dismiss_all_dialogs() self.assertEqual(len(dialogs), 0) # also checks for the amount field, refs #152 send_amount_id = send.ids.send_amount_id send_amount_id.text = '0.1' # the send_amount property should get updated from the input self.assertEqual(send.send_amount, 0.1) # blank amount shouldn't crash the app, just get ignored send_amount_id.text = '' self.assertEqual(send.send_amount, 0.1)
def helper_test_delete_account(self, app): """ Deletes account from the UI. """ controller = app.controller pywalib = controller.pywalib # makes sure we have an account to play with self.assertEqual(len(pywalib.get_account_list()), 1) # makes sure the account appears in the switch account view switch_account = self.helper_load_switch_account(app) account_list_id = switch_account.ids.account_list_id children = account_list_id.children self.assertEqual(len(children), 1) item = children[0] self.assertEqual(type(item), kivymd.list.OneLineListItem) self.assertEqual(item.account, pywalib.get_account_list()[0]) # go to the manage account screen # TODO: use dispatch('on_release') on navigation drawer controller.load_manage_keystores() # TODO: broken in #124 # self.advance_frames(1) self.advance_frames(30) self.assertEqual('Manage existing', app.controller.toolbar.title) # verifies an account is showing manage_existing = controller.manage_existing account_address_id = manage_existing.ids.account_address_id account = pywalib.get_account_list()[0] account_address = '0x' + account.address.hex() self.assertEqual(account_address_id.text, account_address) # clicks delete delete_button_id = manage_existing.ids.delete_button_id delete_button_id.dispatch('on_release') # a confirmation popup should show dialogs = Dialog.dialogs self.assertEqual(len(dialogs), 1) dialog = dialogs[0] self.assertEqual(dialog.title, 'Are you sure?') # confirm it # TODO: click on the dialog action button itself manage_existing.on_delete_account_yes(dialog) # the dialog should be replaced by another one dialogs = Dialog.dialogs self.assertEqual(len(dialogs), 1) dialog = dialogs[0] self.assertEqual(dialog.title, 'Account deleted, redirecting...') Dialog.dismiss_all_dialogs() # and the account deleted self.assertEqual(len(pywalib.get_account_list()), 0) # makes sure the account was also cleared from the selection view switch_account = self.helper_load_switch_account(app) account_list_id = switch_account.ids.account_list_id # TODO: broken in #124 self.advance_frames(30) self.assertEqual(len(account_list_id.children), 0)
def helper_test_on_send_click(self, app): """ Verifies clicking "Send" Ethers works as expected, refs #63. Also checks for the amount field, refs #152. """ controller = app.controller # TODO: use dispatch('on_release') on navigation drawer controller.load_landing_page() send = controller.send send_button_id = send.ids.send_button_id # verifies clicking send button doesn't crash the application send_button_id.dispatch('on_release') dialogs = Dialog.dialogs # but it would still raise a popup since the form is invalid self.assertEqual(len(dialogs), 1) self.assertEqual(dialogs[0].title, 'Input error') Dialog.dismiss_all_dialogs() self.assertEqual(len(dialogs), 0)
def helper_confirm_account_deletion(self, app): """ Helper method for confirming account deletion popups. """ controller = app.controller manage_existing = controller.manage_existing # a confirmation popup should show dialogs = Dialog.dialogs self.assertEqual(len(dialogs), 1) dialog = dialogs[0] self.assertEqual(dialog.title, 'Are you sure?') # confirm it # TODO: click on the dialog action button itself manage_existing.on_delete_account_yes(dialog) # the dialog should be replaced by another one dialogs = Dialog.dialogs self.assertEqual(len(dialogs), 1) dialog = dialogs[0] self.assertEqual(dialog.title, 'Account deleted, redirecting...') Dialog.dismiss_all_dialogs() self.assertEqual(len(dialogs), 0)
def helper_test_delete_account_twice(self, app): """ Trying to delete the same account twice, shoult not crash the app, refs #51. """ controller = app.controller pywalib = controller.pywalib manage_existing = controller.manage_existing # makes sure an account is selected pywalib.new_account(password="******", security_ratio=None) controller.current_account = pywalib.get_account_list()[0] self.assertTrue(manage_existing.current_account is not None) account_count_before = len(pywalib.get_account_list()) # let's try to delete this account once delete_button_id = manage_existing.ids.delete_button_id delete_button_id.dispatch('on_release') self.helper_confirm_account_deletion(app) # the account should be deleted self.assertEqual(len(pywalib.get_account_list()), account_count_before - 1) # makes sure the account was also cleared from the selection view switch_account = self.helper_load_switch_account(app) account_list_id = switch_account.ids.account_list_id self.assertEqual(len(account_list_id.children), len(pywalib.get_account_list())) # TODO: the selected account should now be None # self.assertIsNone(manage_existing.current_account) # self.assertIsNone(controller.current_account) # let's try to delete this account a second time delete_button_id = manage_existing.ids.delete_button_id delete_button_id.dispatch('on_release') # TODO: the second time an error dialog should pop # dialogs = Dialog.dialogs # self.assertEqual(len(dialogs), 1) # dialog = dialogs[0] # self.assertEqual(dialog.title, 'No account selected.') Dialog.dismiss_all_dialogs()
def helper_test_controller_fetch_balance(self, app): """ Verifies Controller.fetch_balance() works in most common cases. 1) simple case, library PyWalib.get_balance() gets called 2) ConnectionError should be handled 3) handles 503 "service is unavailable", refs #91 4) UnknownEtherscanException should be handled """ controller = app.controller account = controller.current_account balance = 42 # 1) simple case, library PyWalib.get_balance() gets called with mock.patch('pywalib.PyWalib.get_balance') as mock_get_balance, \ patch_get_store_path(self.temp_path): mock_get_balance.return_value = balance thread = controller.fetch_balance() thread.join() address = '0x' + account.address.hex() mock_get_balance.assert_called_with(address, pywalib.ChainID.MAINNET) # and the balance updated self.assertEqual(controller.accounts_balance[address], balance) # 2) ConnectionError should be handled self.assertEqual(len(Dialog.dialogs), 0) with mock.patch('pywalib.PyWalib.get_balance') as mock_get_balance, \ mock.patch('pywallet.controller.Logger') as mock_logger: mock_get_balance.side_effect = requests.exceptions.ConnectionError thread = controller.fetch_balance() thread.join() self.assertEqual(len(Dialog.dialogs), 1) dialog = Dialog.dialogs[0] self.assertEqual(dialog.title, 'Network error') Dialog.dismiss_all_dialogs() # the error should be logged mock_logger.warning.assert_called_with('ConnectionError', exc_info=True) # 3) handles 503 "service is unavailable", refs #91 self.assertEqual(len(Dialog.dialogs), 0) response = requests.Response() response.status_code = 503 response.raw = io.BytesIO(b'The service is unavailable.') with mock.patch('requests.get') as mock_requests_get, \ mock.patch('pywallet.controller.Logger') as mock_logger: mock_requests_get.return_value = response thread = controller.fetch_balance() thread.join() self.assertEqual(len(Dialog.dialogs), 1) dialog = Dialog.dialogs[0] self.assertEqual(dialog.title, 'Unknown error') Dialog.dismiss_all_dialogs() # the error should be logged mock_logger.error.assert_called_with('UnknownEtherscanException', exc_info=True) # 4) UnknownEtherscanException should be handled self.assertEqual(len(Dialog.dialogs), 0) with mock.patch('pywalib.PyWalib.get_balance') as mock_get_balance, \ mock.patch('pywallet.controller.Logger') as mock_logger: mock_get_balance.side_effect = pywalib.UnknownEtherscanException thread = controller.fetch_balance() thread.join() self.assertEqual(len(Dialog.dialogs), 1) dialog = Dialog.dialogs[0] self.assertEqual(dialog.title, 'Unknown error') Dialog.dismiss_all_dialogs() # the error should be logged mock_logger.error.assert_called_with('UnknownEtherscanException', exc_info=True)