mirror of
https://github.com/SeedSigner/seedsigner.git
synced 2026-10-05 15:08:25 +00:00
Improved integration w/View.button_data options
* Modifies Views to make button_data and its options available to external caller (FlowTests). * Adds button_data_selection for tighter integration with Views and better human-readability of FlowStep sequences. * Removes the unique recursive run() call in SettingsEntryUpdateSelectionView.
This commit is contained in:
@@ -71,41 +71,41 @@ class SeedsMenuView(View):
|
||||
Loading seeds, passphrases, etc
|
||||
****************************************************************************"""
|
||||
class LoadSeedView(View):
|
||||
def run(self):
|
||||
SEED_QR = (" Scan a SeedQR", FontAwesomeIconConstants.QRCODE)
|
||||
TYPE_12WORD = ("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_24WORD = ("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
CREATE = (" Create a seed", FontAwesomeIconConstants.PLUS)
|
||||
button_data=[
|
||||
SEED_QR,
|
||||
TYPE_12WORD,
|
||||
TYPE_24WORD,
|
||||
CREATE,
|
||||
]
|
||||
SEED_QR = (" Scan a SeedQR", FontAwesomeIconConstants.QRCODE)
|
||||
TYPE_12WORD = ("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_24WORD = ("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
CREATE = (" Create a seed", FontAwesomeIconConstants.PLUS)
|
||||
button_data=[
|
||||
SEED_QR,
|
||||
TYPE_12WORD,
|
||||
TYPE_24WORD,
|
||||
CREATE,
|
||||
]
|
||||
|
||||
def run(self):
|
||||
selected_menu_num = self.run_screen(
|
||||
ButtonListScreen,
|
||||
title="Load A Seed",
|
||||
is_button_text_centered=False,
|
||||
button_data=button_data
|
||||
button_data=self.button_data
|
||||
)
|
||||
|
||||
if selected_menu_num == RET_CODE__BACK_BUTTON:
|
||||
return Destination(BackStackView)
|
||||
|
||||
if button_data[selected_menu_num] == SEED_QR:
|
||||
if self.button_data[selected_menu_num] == self.SEED_QR:
|
||||
from .scan_views import ScanView
|
||||
return Destination(ScanView)
|
||||
|
||||
elif button_data[selected_menu_num] == TYPE_12WORD:
|
||||
elif self.button_data[selected_menu_num] == self.TYPE_12WORD:
|
||||
self.controller.storage.init_pending_mnemonic(num_words=12)
|
||||
return Destination(SeedMnemonicEntryView)
|
||||
|
||||
elif button_data[selected_menu_num] == TYPE_24WORD:
|
||||
elif self.button_data[selected_menu_num] == self.TYPE_24WORD:
|
||||
self.controller.storage.init_pending_mnemonic(num_words=24)
|
||||
return Destination(SeedMnemonicEntryView)
|
||||
|
||||
elif button_data[selected_menu_num] == CREATE:
|
||||
elif self.button_data[selected_menu_num] == self.CREATE:
|
||||
from .tools_views import ToolsMenuView
|
||||
return Destination(ToolsMenuView)
|
||||
|
||||
@@ -169,62 +169,60 @@ class SeedMnemonicEntryView(View):
|
||||
|
||||
|
||||
class SeedMnemonicInvalidView(View):
|
||||
EDIT = "Review & Edit"
|
||||
DISCARD = ("Discard", None, None, "red")
|
||||
button_data = [EDIT, DISCARD]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.mnemonic: List[str] = self.controller.storage.pending_mnemonic
|
||||
|
||||
|
||||
def run(self):
|
||||
EDIT = "Review & Edit"
|
||||
DISCARD = ("Discard", None, None, "red")
|
||||
button_data = [EDIT, DISCARD]
|
||||
|
||||
selected_menu_num = self.run_screen(
|
||||
WarningScreen,
|
||||
title="Invalid Mnemonic!",
|
||||
status_headline=None,
|
||||
text=f"Checksum failure; not a valid seed phrase.",
|
||||
show_back_button=False,
|
||||
button_data=button_data,
|
||||
button_data=self.button_data,
|
||||
)
|
||||
|
||||
if button_data[selected_menu_num] == EDIT:
|
||||
if self.button_data[selected_menu_num] == self.EDIT:
|
||||
return Destination(SeedMnemonicEntryView, view_args={"cur_word_index": 0})
|
||||
|
||||
elif button_data[selected_menu_num] == DISCARD:
|
||||
elif self.button_data[selected_menu_num] == self.DISCARD:
|
||||
self.controller.storage.discard_pending_mnemonic()
|
||||
return Destination(MainMenuView)
|
||||
|
||||
|
||||
|
||||
class SeedFinalizeView(View):
|
||||
FINALIZE = "Done"
|
||||
PASSPHRASE = "BIP-39 Passphrase"
|
||||
button_data = [FINALIZE]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.seed = self.controller.storage.get_pending_seed()
|
||||
self.fingerprint = self.seed.get_fingerprint(network=self.settings.get_value(SettingsConstants.SETTING__NETWORK))
|
||||
|
||||
if self.settings.get_value(SettingsConstants.SETTING__PASSPHRASE) != SettingsConstants.OPTION__DISABLED:
|
||||
self.button_data.append(self.PASSPHRASE)
|
||||
|
||||
|
||||
def run(self):
|
||||
FINALIZE = "Done"
|
||||
PASSPHRASE = "BIP-39 Passphrase"
|
||||
button_data = []
|
||||
|
||||
button_data.append(FINALIZE)
|
||||
|
||||
if self.settings.get_value(SettingsConstants.SETTING__PASSPHRASE) != SettingsConstants.OPTION__DISABLED:
|
||||
button_data.append(PASSPHRASE)
|
||||
|
||||
selected_menu_num = self.run_screen(
|
||||
seed_screens.SeedFinalizeScreen,
|
||||
fingerprint=self.fingerprint,
|
||||
button_data=button_data,
|
||||
button_data=self.button_data,
|
||||
)
|
||||
|
||||
if button_data[selected_menu_num] == FINALIZE:
|
||||
if self.button_data[selected_menu_num] == self.FINALIZE:
|
||||
seed_num = self.controller.storage.finalize_pending_seed()
|
||||
return Destination(SeedOptionsView, view_args={"seed_num": seed_num}, clear_history=True)
|
||||
|
||||
elif button_data[selected_menu_num] == PASSPHRASE:
|
||||
elif self.button_data[selected_menu_num] == self.PASSPHRASE:
|
||||
return Destination(SeedAddPassphraseView)
|
||||
|
||||
|
||||
@@ -254,16 +252,16 @@ class SeedReviewPassphraseView(View):
|
||||
"""
|
||||
Display the completed passphrase back to the user.
|
||||
"""
|
||||
EDIT = "Edit passphrase"
|
||||
DONE = "Done"
|
||||
button_data = [EDIT, DONE]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.seed = self.controller.storage.get_pending_seed()
|
||||
|
||||
|
||||
def run(self):
|
||||
EDIT = "Edit passphrase"
|
||||
DONE = "Done"
|
||||
button_data = [EDIT, DONE]
|
||||
|
||||
# Get the before/after fingerprints
|
||||
network = self.settings.get_value(SettingsConstants.SETTING__NETWORK)
|
||||
passphrase = self.seed.passphrase
|
||||
@@ -279,14 +277,14 @@ class SeedReviewPassphraseView(View):
|
||||
fingerprint_without=fingerprint_without,
|
||||
fingerprint_with=fingerprint_with,
|
||||
passphrase=self.seed.passphrase,
|
||||
button_data=button_data,
|
||||
button_data=self.button_data,
|
||||
show_back_button=False,
|
||||
)
|
||||
|
||||
if button_data[selected_menu_num] == EDIT:
|
||||
if self.button_data[selected_menu_num] == self.EDIT:
|
||||
return Destination(SeedAddPassphraseView)
|
||||
|
||||
elif button_data[selected_menu_num] == DONE:
|
||||
elif self.button_data[selected_menu_num] == self.DONE:
|
||||
seed_num = self.controller.storage.finalize_pending_seed()
|
||||
return Destination(SeedOptionsView, view_args={"seed_num": seed_num}, clear_history=True)
|
||||
|
||||
@@ -498,6 +496,10 @@ class SeedExportXpubScriptTypeView(View):
|
||||
self.seed_num = seed_num
|
||||
self.sig_type = sig_type
|
||||
|
||||
self.button_data = []
|
||||
for script_type in self.settings.get_multiselect_value_display_names(SettingsConstants.SETTING__SCRIPT_TYPES):
|
||||
self.button_data.append(script_type)
|
||||
|
||||
|
||||
def run(self):
|
||||
from .tools_views import ToolsAddressExplorerAddressTypeView
|
||||
@@ -511,10 +513,6 @@ class SeedExportXpubScriptTypeView(View):
|
||||
return Destination(ToolsAddressExplorerAddressTypeView, view_args=args, skip_current_view=True)
|
||||
else:
|
||||
return Destination(SeedExportXpubCoordinatorView, view_args=args, skip_current_view=True)
|
||||
|
||||
button_data = []
|
||||
for script_type in self.settings.get_multiselect_value_display_names(SettingsConstants.SETTING__SCRIPT_TYPES):
|
||||
button_data.append(script_type)
|
||||
|
||||
title = "Export Xpub"
|
||||
if self.controller.resume_main_flow == Controller.FLOW__ADDRESS_EXPLORER:
|
||||
@@ -524,7 +522,7 @@ class SeedExportXpubScriptTypeView(View):
|
||||
ButtonListScreen,
|
||||
title=title,
|
||||
is_button_text_centered=False,
|
||||
button_data=button_data,
|
||||
button_data=self.button_data,
|
||||
is_bottom_list=True,
|
||||
)
|
||||
|
||||
@@ -536,7 +534,7 @@ class SeedExportXpubScriptTypeView(View):
|
||||
|
||||
else:
|
||||
script_types_settings_entry = SettingsDefinition.get_settings_entry(SettingsConstants.SETTING__SCRIPT_TYPES)
|
||||
selected_display_name = button_data[selected_menu_num]
|
||||
selected_display_name = self.button_data[selected_menu_num]
|
||||
args["script_type"] = script_types_settings_entry.get_selection_option_value_by_display_name(selected_display_name)
|
||||
|
||||
if args["script_type"] == SettingsConstants.CUSTOM_DERIVATION:
|
||||
|
||||
@@ -8,6 +8,9 @@ from seedsigner.models.settings import SettingsConstants, SettingsDefinition
|
||||
|
||||
|
||||
class SettingsMenuView(View):
|
||||
IO_TEST = "I/O test"
|
||||
DONATE = "Donate"
|
||||
|
||||
def __init__(self, visibility: str = SettingsConstants.VISIBILITY__GENERAL, selected_attr: str = None, initial_scroll: int = 0):
|
||||
super().__init__()
|
||||
self.visibility = visibility
|
||||
@@ -16,51 +19,48 @@ class SettingsMenuView(View):
|
||||
# Used to preserve the rendering position in the list
|
||||
self.initial_scroll = initial_scroll
|
||||
|
||||
|
||||
def run(self):
|
||||
IO_TEST = "I/O test"
|
||||
DONATE = "Donate"
|
||||
|
||||
settings_entries = SettingsDefinition.get_settings_entries(
|
||||
self.settings_entries = SettingsDefinition.get_settings_entries(
|
||||
visibility=self.visibility
|
||||
)
|
||||
button_data=[e.display_name for e in settings_entries]
|
||||
self.button_data=[e.display_name for e in self.settings_entries]
|
||||
|
||||
selected_button = 0
|
||||
self.selected_button = 0
|
||||
if self.selected_attr:
|
||||
for i, entry in enumerate(settings_entries):
|
||||
for i, entry in enumerate(self.settings_entries):
|
||||
if entry.attr_name == self.selected_attr:
|
||||
selected_button = i
|
||||
self.selected_button = i
|
||||
break
|
||||
|
||||
if self.visibility == SettingsConstants.VISIBILITY__GENERAL:
|
||||
title = "Settings"
|
||||
self.title = "Settings"
|
||||
|
||||
# Set up the next nested level of menuing
|
||||
button_data.append(("Advanced", None, None, None, SeedSignerCustomIconConstants.SMALL_CHEVRON_RIGHT))
|
||||
next = Destination(SettingsMenuView, view_args={"visibility": SettingsConstants.VISIBILITY__ADVANCED})
|
||||
self.button_data.append(("Advanced", None, None, None, SeedSignerCustomIconConstants.SMALL_CHEVRON_RIGHT))
|
||||
self.next_destination = Destination(SettingsMenuView, view_args={"visibility": SettingsConstants.VISIBILITY__ADVANCED})
|
||||
|
||||
button_data.append(IO_TEST)
|
||||
button_data.append(DONATE)
|
||||
self.button_data.append(self.IO_TEST)
|
||||
self.button_data.append(self.DONATE)
|
||||
|
||||
elif self.visibility == SettingsConstants.VISIBILITY__ADVANCED:
|
||||
title = "Advanced"
|
||||
self.title = "Advanced"
|
||||
|
||||
# So far there are no real Developer options; disabling for now
|
||||
# button_data.append(("Developer Options", None, None, None, SeedSignerCustomIconConstants.SMALL_CHEVRON_RIGHT))
|
||||
# next = Destination(SettingsMenuView, view_args={"visibility": SettingsConstants.VISIBILITY__DEVELOPER})
|
||||
next = None
|
||||
# self.button_data.append(("Developer Options", None, None, None, SeedSignerCustomIconConstants.SMALL_CHEVRON_RIGHT))
|
||||
# self.next_destination = Destination(SettingsMenuView, view_args={"visibility": SettingsConstants.VISIBILITY__DEVELOPER})
|
||||
self.next_destination = None
|
||||
|
||||
elif self.visibility == SettingsConstants.VISIBILITY__DEVELOPER:
|
||||
title = "Dev Options"
|
||||
next = None
|
||||
self.title = "Dev Options"
|
||||
self.next_destination = None
|
||||
|
||||
|
||||
def run(self):
|
||||
selected_menu_num = self.run_screen(
|
||||
ButtonListScreen,
|
||||
title=title,
|
||||
title=self.title,
|
||||
is_button_text_centered=False,
|
||||
button_data=button_data,
|
||||
selected_button=selected_button,
|
||||
button_data=self.button_data,
|
||||
selected_button=self.selected_button,
|
||||
scroll_y_initial_offset=self.initial_scroll,
|
||||
)
|
||||
|
||||
@@ -75,17 +75,17 @@ class SettingsMenuView(View):
|
||||
else:
|
||||
return Destination(SettingsMenuView, view_args={"visibility": SettingsConstants.VISIBILITY__ADVANCED})
|
||||
|
||||
elif selected_menu_num == len(settings_entries):
|
||||
return next
|
||||
elif selected_menu_num == len(self.settings_entries):
|
||||
return self.next_destination
|
||||
|
||||
elif len(button_data) > selected_menu_num and button_data[selected_menu_num] == IO_TEST:
|
||||
elif len(self.button_data) > selected_menu_num and self.button_data[selected_menu_num] == self.IO_TEST:
|
||||
return Destination(IOTestView)
|
||||
|
||||
elif len(button_data) > selected_menu_num and button_data[selected_menu_num] == DONATE:
|
||||
elif len(self.button_data) > selected_menu_num and self.button_data[selected_menu_num] == self.DONATE:
|
||||
return Destination(DonateView)
|
||||
|
||||
else:
|
||||
return Destination(SettingsEntryUpdateSelectionView, view_args=dict(attr_name=settings_entries[selected_menu_num].attr_name, parent_initial_scroll=initial_scroll))
|
||||
return Destination(SettingsEntryUpdateSelectionView, view_args=dict(attr_name=self.settings_entries[selected_menu_num].attr_name, parent_initial_scroll=initial_scroll))
|
||||
|
||||
|
||||
|
||||
@@ -94,48 +94,44 @@ class SettingsEntryUpdateSelectionView(View):
|
||||
Handles changes to all selection-type settings (Multiselect, SELECT_1,
|
||||
Enabled/Disabled, etc).
|
||||
"""
|
||||
def __init__(self, attr_name: str, parent_initial_scroll: int = 0):
|
||||
def __init__(self, attr_name: str, parent_initial_scroll: int = 0, selected_button: int = None):
|
||||
super().__init__()
|
||||
self.settings_entry = SettingsDefinition.get_settings_entry(attr_name)
|
||||
self.selected_button = None
|
||||
self.selected_button = selected_button
|
||||
self.parent_initial_scroll = parent_initial_scroll
|
||||
|
||||
# hook for test suite to override recursion in run()
|
||||
self.is_test = False
|
||||
|
||||
|
||||
def run(self):
|
||||
initial_value = self.settings.get_value(self.settings_entry.attr_name)
|
||||
button_data = []
|
||||
checked_buttons = []
|
||||
self.button_data = []
|
||||
self.checked_buttons = []
|
||||
self.initial_value = self.settings.get_value(self.settings_entry.attr_name)
|
||||
for i, value in enumerate(self.settings_entry.selection_options):
|
||||
if type(value) == tuple:
|
||||
value, display_name = value
|
||||
else:
|
||||
display_name = value
|
||||
button_data.append(display_name)
|
||||
if (type(initial_value) == list and value in initial_value) or value == initial_value:
|
||||
checked_buttons.append(i)
|
||||
|
||||
self.button_data.append(display_name)
|
||||
|
||||
if (type(self.initial_value) == list and value in self.initial_value) or value == self.initial_value:
|
||||
self.checked_buttons.append(i)
|
||||
|
||||
if self.selected_button is None:
|
||||
# Highlight the selection (for multiselect highlight the first
|
||||
# selected option).
|
||||
self.selected_button = i
|
||||
|
||||
if not self.selected_button:
|
||||
if self.selected_button is None:
|
||||
self.selected_button = 0
|
||||
|
||||
screen_args = dict(
|
||||
display_name=self.settings_entry.display_name,
|
||||
help_text=self.settings_entry.help_text,
|
||||
button_data=button_data,
|
||||
selected_button=self.selected_button,
|
||||
checked_buttons=checked_buttons,
|
||||
settings_entry_type=self.settings_entry.type,
|
||||
)
|
||||
|
||||
def run(self):
|
||||
ret_value = self.run_screen(
|
||||
settings_screens.SettingsEntryUpdateSelectionScreen,
|
||||
**screen_args
|
||||
display_name=self.settings_entry.display_name,
|
||||
help_text=self.settings_entry.help_text,
|
||||
button_data=self.button_data,
|
||||
selected_button=self.selected_button,
|
||||
checked_buttons=self.checked_buttons,
|
||||
settings_entry_type=self.settings_entry.type,
|
||||
)
|
||||
|
||||
destination = None
|
||||
@@ -158,8 +154,8 @@ class SettingsEntryUpdateSelectionView(View):
|
||||
destination = settings_menu_view_destination
|
||||
|
||||
elif self.settings_entry.type == SettingsConstants.TYPE__MULTISELECT:
|
||||
updated_value = list(initial_value)
|
||||
if ret_value not in checked_buttons:
|
||||
updated_value = list(self.initial_value)
|
||||
if ret_value not in self.checked_buttons:
|
||||
# This is a new selection to add
|
||||
updated_value.append(value)
|
||||
else:
|
||||
@@ -168,7 +164,7 @@ class SettingsEntryUpdateSelectionView(View):
|
||||
|
||||
else:
|
||||
# All other types are single selects (e.g. Enabled/Disabled, SELECT_1)
|
||||
if value == initial_value:
|
||||
if value == self.initial_value:
|
||||
# No change, return to menu
|
||||
return settings_menu_view_destination
|
||||
else:
|
||||
@@ -185,12 +181,7 @@ class SettingsEntryUpdateSelectionView(View):
|
||||
# All selects stay in place; re-initialize where in the list we left off
|
||||
self.selected_button = ret_value
|
||||
|
||||
if self.is_test:
|
||||
# Test suite can't handle the recursive call. Fake it by returning us here
|
||||
# via a Destination back to this View.
|
||||
return Destination(self.__class__, view_args=dict(attr_name=self.settings_entry.attr_name, parent_initial_scroll=self.parent_initial_scroll))
|
||||
else:
|
||||
return self.run()
|
||||
return Destination(SettingsEntryUpdateSelectionView, view_args=dict(attr_name=self.settings_entry.attr_name, parent_initial_scroll=self.parent_initial_scroll, selected_button=self.selected_button), skip_current_view=True)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,33 +23,38 @@ from .view import View, Destination, BackStackView
|
||||
|
||||
|
||||
class ToolsMenuView(View):
|
||||
IMAGE = (" New seed", FontAwesomeIconConstants.CAMERA)
|
||||
DICE = ("New seed", FontAwesomeIconConstants.DICE)
|
||||
KEYBOARD = ("Calc 12th/24th word", FontAwesomeIconConstants.KEYBOARD)
|
||||
EXPLORER = "Address Explorer"
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.button_data = [self.IMAGE, self.DICE, self.KEYBOARD, self.EXPLORER]
|
||||
|
||||
|
||||
def run(self):
|
||||
IMAGE = (" New seed", FontAwesomeIconConstants.CAMERA)
|
||||
DICE = ("New seed", FontAwesomeIconConstants.DICE)
|
||||
KEYBOARD = ("Calc 12th/24th word", FontAwesomeIconConstants.KEYBOARD)
|
||||
EXPLORER = "Address Explorer"
|
||||
button_data = [IMAGE, DICE, KEYBOARD, EXPLORER]
|
||||
|
||||
selected_menu_num = self.run_screen(
|
||||
ButtonListScreen,
|
||||
title="Tools",
|
||||
is_button_text_centered=False,
|
||||
button_data=button_data
|
||||
button_data=self.button_data
|
||||
)
|
||||
|
||||
if selected_menu_num == RET_CODE__BACK_BUTTON:
|
||||
return Destination(BackStackView)
|
||||
|
||||
elif button_data[selected_menu_num] == IMAGE:
|
||||
elif self.button_data[selected_menu_num] == self.IMAGE:
|
||||
return Destination(ToolsImageEntropyLivePreviewView)
|
||||
|
||||
elif button_data[selected_menu_num] == DICE:
|
||||
elif self.button_data[selected_menu_num] == self.DICE:
|
||||
return Destination(ToolsDiceEntropyMnemonicLengthView)
|
||||
|
||||
elif button_data[selected_menu_num] == KEYBOARD:
|
||||
elif self.button_data[selected_menu_num] == self.KEYBOARD:
|
||||
return Destination(ToolsCalcFinalWordNumWordsView)
|
||||
|
||||
elif button_data[selected_menu_num] == EXPLORER:
|
||||
elif self.button_data[selected_menu_num] == self.EXPLORER:
|
||||
return Destination(ToolsAddressExplorerSelectSourceView)
|
||||
|
||||
|
||||
@@ -422,27 +427,27 @@ class ToolsCalcFinalWordDoneView(View):
|
||||
Address Explorer Views
|
||||
****************************************************************************"""
|
||||
class ToolsAddressExplorerSelectSourceView(View):
|
||||
def run(self):
|
||||
SCAN_SEED = ("Scan a seed", FontAwesomeIconConstants.QRCODE)
|
||||
SCAN_DESCRIPTOR = ("Scan wallet descriptor", FontAwesomeIconConstants.QRCODE)
|
||||
TYPE_12WORD = ("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_24WORD = ("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
button_data = []
|
||||
SCAN_SEED = ("Scan a seed", FontAwesomeIconConstants.QRCODE)
|
||||
SCAN_DESCRIPTOR = ("Scan wallet descriptor", FontAwesomeIconConstants.QRCODE)
|
||||
TYPE_12WORD = ("Enter 12-word seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
TYPE_24WORD = ("Enter 24-word seed", FontAwesomeIconConstants.KEYBOARD)
|
||||
button_data = [SCAN_SEED, SCAN_DESCRIPTOR, TYPE_12WORD, TYPE_24WORD]
|
||||
|
||||
seeds = self.controller.storage.seeds
|
||||
for seed in seeds:
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.seeds = self.controller.storage.seeds
|
||||
seed_buttons =[]
|
||||
for seed in self.seeds:
|
||||
button_str = seed.get_fingerprint(self.settings.get_value(SettingsConstants.SETTING__NETWORK))
|
||||
button_data.append((button_str, SeedSignerCustomIconConstants.FINGERPRINT, "blue"))
|
||||
seed_buttons.append((button_str, SeedSignerCustomIconConstants.FINGERPRINT, "blue"))
|
||||
self.button_data = seed_buttons + self.button_data
|
||||
|
||||
button_data.append(SCAN_SEED)
|
||||
button_data.append(SCAN_DESCRIPTOR)
|
||||
button_data.append(TYPE_12WORD)
|
||||
button_data.append(TYPE_24WORD)
|
||||
|
||||
def run(self):
|
||||
selected_menu_num = self.run_screen(
|
||||
ButtonListScreen,
|
||||
title="Address Explorer",
|
||||
button_data=button_data,
|
||||
button_data=self.button_data,
|
||||
is_button_text_centered=False,
|
||||
is_bottom_list=True,
|
||||
)
|
||||
@@ -455,7 +460,7 @@ class ToolsAddressExplorerSelectSourceView(View):
|
||||
# knows to re-route us once the side flow is complete.
|
||||
self.controller.resume_main_flow = Controller.FLOW__ADDRESS_EXPLORER
|
||||
|
||||
if len(seeds) > 0 and selected_menu_num < len(seeds):
|
||||
if len(self.seeds) > 0 and selected_menu_num < len(self.seeds):
|
||||
# User selected one of the n seeds
|
||||
return Destination(
|
||||
SeedExportXpubScriptTypeView,
|
||||
@@ -465,13 +470,13 @@ class ToolsAddressExplorerSelectSourceView(View):
|
||||
)
|
||||
)
|
||||
|
||||
elif button_data[selected_menu_num] in [SCAN_SEED, SCAN_DESCRIPTOR]:
|
||||
elif self.button_data[selected_menu_num] in [self.SCAN_SEED, self.SCAN_DESCRIPTOR]:
|
||||
from seedsigner.views.scan_views import ScanView
|
||||
return Destination(ScanView)
|
||||
|
||||
elif button_data[selected_menu_num] in [TYPE_12WORD, TYPE_24WORD]:
|
||||
elif self.button_data[selected_menu_num] in [self.TYPE_12WORD, self.TYPE_24WORD]:
|
||||
from seedsigner.views.seed_views import SeedMnemonicEntryView
|
||||
if button_data[selected_menu_num] == TYPE_12WORD:
|
||||
if self.button_data[selected_menu_num] == self.TYPE_12WORD:
|
||||
self.controller.storage.init_pending_mnemonic(num_words=12)
|
||||
else:
|
||||
self.controller.storage.init_pending_mnemonic(num_words=24)
|
||||
@@ -480,6 +485,11 @@ class ToolsAddressExplorerSelectSourceView(View):
|
||||
|
||||
|
||||
class ToolsAddressExplorerAddressTypeView(View):
|
||||
RECEIVE = "Receive Addresses"
|
||||
CHANGE = "Change Addresses"
|
||||
button_data = [RECEIVE, CHANGE]
|
||||
|
||||
|
||||
def __init__(self, seed_num: int = None, script_type: str = None, custom_derivation: str = None):
|
||||
"""
|
||||
If the explorer source is a seed, `seed_num` and `script_type` must be
|
||||
@@ -528,10 +538,6 @@ class ToolsAddressExplorerAddressTypeView(View):
|
||||
def run(self):
|
||||
data = self.controller.address_explorer_data
|
||||
|
||||
RECEIVE = "Receive Addresses"
|
||||
CHANGE = "Change Addresses"
|
||||
button_data = [RECEIVE, CHANGE]
|
||||
|
||||
wallet_descriptor_display_name = None
|
||||
if "wallet_descriptor" in data:
|
||||
wallet_descriptor_display_name = data["wallet_descriptor"].brief_policy.replace(" (sorted)", "")
|
||||
@@ -540,7 +546,7 @@ class ToolsAddressExplorerAddressTypeView(View):
|
||||
|
||||
selected_menu_num = self.run_screen(
|
||||
ToolsAddressExplorerAddressTypeScreen,
|
||||
button_data=button_data,
|
||||
button_data=self.button_data,
|
||||
fingerprint=self.seed.get_fingerprint() if self.seed_num is not None else None,
|
||||
wallet_descriptor_display_name=wallet_descriptor_display_name,
|
||||
script_type=script_type,
|
||||
@@ -550,8 +556,8 @@ class ToolsAddressExplorerAddressTypeView(View):
|
||||
if selected_menu_num == RET_CODE__BACK_BUTTON:
|
||||
return Destination(BackStackView)
|
||||
|
||||
elif button_data[selected_menu_num] in [RECEIVE, CHANGE]:
|
||||
return Destination(ToolsAddressExplorerAddressListView, view_args=dict(is_change=button_data[selected_menu_num] == CHANGE))
|
||||
elif self.button_data[selected_menu_num] in [self.RECEIVE, self.CHANGE]:
|
||||
return Destination(ToolsAddressExplorerAddressListView, view_args=dict(is_change=self.button_data[selected_menu_num] == self.CHANGE))
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@ class View:
|
||||
self.canvas_width = self.renderer.canvas_width
|
||||
self.canvas_height = self.renderer.canvas_height
|
||||
|
||||
self.buttons = self.controller.buttons
|
||||
self.screen = None
|
||||
|
||||
|
||||
@@ -100,20 +99,22 @@ class Destination:
|
||||
return out
|
||||
|
||||
|
||||
def run(self, run_before: Callable = None):
|
||||
def _instantiate_view(self):
|
||||
if not self.view_args:
|
||||
# Can't unpack (**) None so we replace with an empty dict
|
||||
self.view_args = {}
|
||||
|
||||
# Instantiate the `View_cls` with the `view_args` dict
|
||||
view = self.View_cls(**self.view_args)
|
||||
self.view = self.View_cls(**self.view_args)
|
||||
|
||||
|
||||
# Enable test suite modifications to the View before running it
|
||||
if run_before:
|
||||
run_before(view)
|
||||
def _run_view(self):
|
||||
return self.view.run()
|
||||
|
||||
# and run() it
|
||||
return view.run()
|
||||
|
||||
def run(self):
|
||||
self._instantiate_view()
|
||||
return self._run_view()
|
||||
|
||||
|
||||
def __eq__(self, obj):
|
||||
@@ -136,23 +137,22 @@ class Destination:
|
||||
#
|
||||
#########################################################################################
|
||||
class MainMenuView(View):
|
||||
def run(self):
|
||||
from .seed_views import SeedsMenuView
|
||||
from .settings_views import SettingsMenuView
|
||||
from .scan_views import ScanView
|
||||
from .tools_views import ToolsMenuView
|
||||
menu_items = [
|
||||
(("Scan", FontAwesomeIconConstants.QRCODE), ScanView),
|
||||
(("Seeds", FontAwesomeIconConstants.KEY), SeedsMenuView),
|
||||
(("Tools", FontAwesomeIconConstants.SCREWDRIVER_WRENCH), ToolsMenuView),
|
||||
(("Settings", FontAwesomeIconConstants.GEAR), SettingsMenuView),
|
||||
]
|
||||
SCAN = ("Scan", FontAwesomeIconConstants.QRCODE)
|
||||
SEEDS = ("Seeds", FontAwesomeIconConstants.KEY)
|
||||
TOOLS = ("Tools", FontAwesomeIconConstants.SCREWDRIVER_WRENCH)
|
||||
SETTINGS = ("Settings", FontAwesomeIconConstants.GEAR)
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.button_data = [self.SCAN, self.SEEDS, self.TOOLS, self.SETTINGS]
|
||||
|
||||
|
||||
def run(self):
|
||||
selected_menu_num = self.run_screen(
|
||||
LargeButtonScreen,
|
||||
title="Home",
|
||||
title_font_size=26,
|
||||
button_data=[entry[0] for entry in menu_items],
|
||||
button_data=self.button_data,
|
||||
show_back_button=False,
|
||||
show_power_button=True,
|
||||
)
|
||||
@@ -160,7 +160,21 @@ class MainMenuView(View):
|
||||
if selected_menu_num == RET_CODE__POWER_BUTTON:
|
||||
return Destination(PowerOptionsView)
|
||||
|
||||
return Destination(menu_items[selected_menu_num][1])
|
||||
if self.button_data[selected_menu_num] == self.SCAN:
|
||||
from .scan_views import ScanView
|
||||
return Destination(ScanView)
|
||||
|
||||
elif self.button_data[selected_menu_num] == self.SEEDS:
|
||||
from .seed_views import SeedsMenuView
|
||||
return Destination(SeedsMenuView)
|
||||
|
||||
elif self.button_data[selected_menu_num] == self.TOOLS:
|
||||
from .tools_views import ToolsMenuView
|
||||
return Destination(ToolsMenuView)
|
||||
|
||||
elif self.button_data[selected_menu_num] == self.SETTINGS:
|
||||
from .settings_views import SettingsMenuView
|
||||
return Destination(SettingsMenuView)
|
||||
|
||||
|
||||
|
||||
|
||||
+27
-5
@@ -1,7 +1,7 @@
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
from mock import MagicMock, patch
|
||||
from typing import Callable, List, Type, Union
|
||||
from typing import Callable, List, Tuple, Type, Union
|
||||
|
||||
# Prevent importing modules w/Raspi hardware dependencies.
|
||||
# These must precede any SeedSigner imports.
|
||||
@@ -37,6 +37,7 @@ class BaseTest:
|
||||
def reset_settings(cls):
|
||||
""" Wipe and re-initialize the Settings singleton """
|
||||
Settings._instance = None
|
||||
BaseTest.remove_settings()
|
||||
|
||||
|
||||
@classmethod
|
||||
@@ -71,10 +72,22 @@ class BaseTest:
|
||||
|
||||
@dataclass
|
||||
class FlowStep:
|
||||
""" Trivial helper class to express FlowTest sequences below """
|
||||
"""
|
||||
Trivial helper class to express FlowTest sequences below.
|
||||
|
||||
* expected_view: verify that the next step in the sequence ended up at the right View.
|
||||
* run_before: function that takes a View instance as an arg and modifies it before running the View.
|
||||
* screen_return_value: mocked Screen interaction result: raw return value as if from the Screen.
|
||||
* button_data_selection: mocked Screen interaction result: the View.button_data value of the desired option.
|
||||
"""
|
||||
expected_view: Type[View] = None
|
||||
run_before: Callable = None
|
||||
screen_return_value: Union[int, str] = None
|
||||
screen_return_value: Union[int,str] = None
|
||||
button_data_selection: Union[str,Tuple] = None
|
||||
|
||||
def __post_init__(self):
|
||||
if self.screen_return_value is not None and self.button_data_selection is not None:
|
||||
raise Exception("Should only specify screen_return_value or button_data_selection")
|
||||
|
||||
|
||||
|
||||
@@ -87,6 +100,7 @@ class FlowTest(BaseTest):
|
||||
* verifies that we landed on the expected_view (if provided).
|
||||
* mocks out the `View.run_screen()` to prevent the associated Screen class from instantiating.
|
||||
* patches in the FlowStep's screen_return_value (as if it came from user interaction).
|
||||
* OR retrieves the index number of the specified button_data_selection and provides that as the Screen return value.
|
||||
* optional `run_before` method modifies the View when necessary to be compatible w/test suite limitations.
|
||||
* Runs the View and receives the resulting next Destination.
|
||||
* then repeats the process on the next Destination until the sequence is complete.
|
||||
@@ -103,10 +117,18 @@ class FlowTest(BaseTest):
|
||||
# Patch the `View.run_screen()` so we don't actually instantiate the Screen
|
||||
qualname = ".".join([next_destination.View_cls.__module__, next_destination.View_cls.__name__])
|
||||
with patch(qualname + ".run_screen") as mock_run_screen:
|
||||
mock_run_screen.return_value = flow_step.screen_return_value
|
||||
next_destination._instantiate_view()
|
||||
|
||||
if flow_step.run_before:
|
||||
flow_step.run_before(next_destination.view)
|
||||
|
||||
if flow_step.button_data_selection:
|
||||
mock_run_screen.return_value = next_destination.view.button_data.index(flow_step.button_data_selection)
|
||||
else:
|
||||
mock_run_screen.return_value = flow_step.screen_return_value
|
||||
|
||||
# Now we can run the View and grab its resulting next Destination
|
||||
next_destination = next_destination.run(run_before=flow_step.run_before)
|
||||
next_destination = next_destination._run_view()
|
||||
except Exception as e:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
@@ -21,16 +21,16 @@ class TestSeedFlows(FlowTest):
|
||||
Destination(MainMenuView),
|
||||
sequence=[
|
||||
FlowStep(
|
||||
screen_return_value=0, # ret SCAN
|
||||
button_data_selection=MainMenuView.SCAN
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=scan_views.ScanView,
|
||||
run_before=load_seed_into_decoder, # simulate read SeedQR
|
||||
screen_return_value=None,
|
||||
# ret value is ignored
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=seed_views.SeedFinalizeView,
|
||||
screen_return_value=0, # ret DONE
|
||||
button_data_selection=seed_views.SeedFinalizeView.FINALIZE
|
||||
),
|
||||
]
|
||||
)
|
||||
@@ -45,7 +45,7 @@ class TestSeedFlows(FlowTest):
|
||||
def test_with_mnemonic(mnemonic):
|
||||
sequence = [
|
||||
FlowStep(
|
||||
screen_return_value=1, # ret SEEDS
|
||||
button_data_selection=MainMenuView.SEEDS
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=seed_views.SeedsMenuView,
|
||||
@@ -53,7 +53,7 @@ class TestSeedFlows(FlowTest):
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=seed_views.LoadSeedView,
|
||||
screen_return_value=1 if len(mnemonic) == 12 else 2, # ret TYPE_12WORD or TYPE_24WORD
|
||||
button_data_selection=seed_views.LoadSeedView.TYPE_12WORD if len(mnemonic) == 12 else seed_views.LoadSeedView.TYPE_24WORD,
|
||||
),
|
||||
]
|
||||
|
||||
@@ -70,7 +70,7 @@ class TestSeedFlows(FlowTest):
|
||||
sequence.append(
|
||||
FlowStep(
|
||||
expected_view=seed_views.SeedFinalizeView,
|
||||
screen_return_value=0, # ret DONE
|
||||
button_data_selection=seed_views.SeedFinalizeView.FINALIZE
|
||||
)
|
||||
)
|
||||
|
||||
@@ -94,7 +94,7 @@ class TestSeedFlows(FlowTest):
|
||||
mnemonic = "blush twice taste dawn feed second opinion lazy thumb play neglect impact".split()
|
||||
sequence = [
|
||||
FlowStep(
|
||||
screen_return_value=1 if len(mnemonic) == 12 else 2, # ret TYPE_12WORD or TYPE_24WORD
|
||||
button_data_selection=seed_views.LoadSeedView.TYPE_12WORD if len(mnemonic) == 12 else seed_views.LoadSeedView.TYPE_24WORD,
|
||||
),
|
||||
]
|
||||
for word in mnemonic[:-1]:
|
||||
@@ -112,7 +112,7 @@ class TestSeedFlows(FlowTest):
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=seed_views.SeedMnemonicInvalidView,
|
||||
screen_return_value=0 # ret EDIT
|
||||
button_data_selection=seed_views.SeedMnemonicInvalidView.EDIT
|
||||
),
|
||||
]
|
||||
|
||||
@@ -132,7 +132,7 @@ class TestSeedFlows(FlowTest):
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=seed_views.SeedMnemonicInvalidView,
|
||||
screen_return_value=1 # ret DISCARD; this time we give up
|
||||
button_data_selection=seed_views.SeedMnemonicInvalidView.DISCARD
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
@@ -17,30 +17,31 @@ class TestSettingsFlows(FlowTest):
|
||||
def test_persistent_settings(self):
|
||||
""" Basic flow from MainMenuView to enable/disable persistent settings """
|
||||
# Which option are we testing?
|
||||
settings_entries = SettingsDefinition.get_settings_entries()
|
||||
nth_entry = [s.attr_name for s in settings_entries].index(SettingsConstants.SETTING__PERSISTENT_SETTINGS)
|
||||
|
||||
settings_entry = SettingsDefinition.get_settings_entry(SettingsConstants.SETTING__PERSISTENT_SETTINGS)
|
||||
|
||||
def mock_settingsmenuview_screen(view: Type[View]):
|
||||
# SettingsMenuView reaches into its `self.screen` so we need to mock it out
|
||||
view.screen = MagicMock()
|
||||
|
||||
|
||||
destination = self.run_sequence(
|
||||
Destination(MainMenuView),
|
||||
sequence=[
|
||||
FlowStep(
|
||||
screen_return_value=3, # ret SETTINGS
|
||||
button_data_selection=MainMenuView.SETTINGS
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=settings_views.SettingsMenuView,
|
||||
run_before=mock_settingsmenuview_screen,
|
||||
screen_return_value=nth_entry, # ret persistent settings
|
||||
button_data_selection=settings_entry.display_name
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=settings_views.SettingsEntryUpdateSelectionView,
|
||||
screen_return_value=[s[0] for s in settings_entry.selection_options].index(SettingsConstants.OPTION__ENABLED),
|
||||
button_data_selection=settings_entry.get_selection_option_display_name_by_value(SettingsConstants.OPTION__ENABLED),
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=settings_views.SettingsEntryUpdateSelectionView,
|
||||
screen_return_value=RET_CODE__BACK_BUTTON
|
||||
)
|
||||
]
|
||||
)
|
||||
assert destination.View_cls == settings_views.SettingsMenuView
|
||||
@@ -50,41 +51,32 @@ class TestSettingsFlows(FlowTest):
|
||||
""" Multiselect Settings options should stay in-place; requires BACK to exit. """
|
||||
# Which option are we testing?
|
||||
settings_entry = SettingsDefinition.get_settings_entry(SettingsConstants.SETTING__COORDINATORS)
|
||||
nth_entry = SettingsDefinition.get_settings_entries().index(settings_entry)
|
||||
|
||||
def mock_settingsmenuview_screen(view: Type[View]):
|
||||
# SettingsMenuView reaches into its `self.screen` so we need to mock it out
|
||||
view.screen = MagicMock()
|
||||
|
||||
def disable_recursion(view: Type[View]):
|
||||
# The recursion in SettingsEntryUpdateSelectionView for multiselect settings
|
||||
# won't work with our FlowTest sequence structure.
|
||||
view.is_test = True
|
||||
|
||||
destination = self.run_sequence(
|
||||
Destination(MainMenuView),
|
||||
sequence=[
|
||||
FlowStep(
|
||||
screen_return_value=3, # ret SETTINGS
|
||||
button_data_selection=MainMenuView.SETTINGS
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=settings_views.SettingsMenuView,
|
||||
run_before=mock_settingsmenuview_screen,
|
||||
screen_return_value=nth_entry, # ret Coordinator software
|
||||
button_data_selection=settings_entry.display_name
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=settings_views.SettingsEntryUpdateSelectionView,
|
||||
run_before=disable_recursion,
|
||||
screen_return_value=0, # select/deselect first option
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=settings_views.SettingsEntryUpdateSelectionView,
|
||||
run_before=disable_recursion,
|
||||
screen_return_value=1, # select/deselect second option
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=settings_views.SettingsEntryUpdateSelectionView,
|
||||
run_before=disable_recursion,
|
||||
screen_return_value=1, # select/deselect second option
|
||||
),
|
||||
FlowStep(
|
||||
@@ -98,9 +90,6 @@ class TestSettingsFlows(FlowTest):
|
||||
|
||||
def test_io_test(self):
|
||||
""" Basic flow from MainMenuView to I/O Test View """
|
||||
# I/O Test will be the nth_entry after we include the submenu to "Advanced"
|
||||
nth_entry = len(SettingsDefinition.get_settings_entries()) + 1
|
||||
|
||||
def mock_settingsmenuview_screen(view: Type[View]):
|
||||
# SettingsMenuView reaches into its `self.screen` so we need to mock it out
|
||||
view.screen = MagicMock()
|
||||
@@ -109,16 +98,16 @@ class TestSettingsFlows(FlowTest):
|
||||
Destination(MainMenuView),
|
||||
sequence=[
|
||||
FlowStep(
|
||||
screen_return_value=3, # ret SETTINGS
|
||||
button_data_selection=MainMenuView.SETTINGS,
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=settings_views.SettingsMenuView,
|
||||
run_before=mock_settingsmenuview_screen,
|
||||
screen_return_value=nth_entry, # ret I/O Test
|
||||
button_data_selection=settings_views.SettingsMenuView.IO_TEST
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=settings_views.IOTestView,
|
||||
screen_return_value=None, # ret value is ignored
|
||||
# ret value is ignored
|
||||
),
|
||||
]
|
||||
)
|
||||
@@ -140,16 +129,16 @@ class TestSettingsFlows(FlowTest):
|
||||
Destination(MainMenuView),
|
||||
sequence=[
|
||||
FlowStep(
|
||||
screen_return_value=3, # ret SETTINGS
|
||||
button_data_selection=MainMenuView.SETTINGS,
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=settings_views.SettingsMenuView,
|
||||
run_before=mock_settingsmenuview_screen,
|
||||
screen_return_value=nth_entry, # ret Donate
|
||||
button_data_selection=settings_views.SettingsMenuView.DONATE
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=settings_views.DonateView,
|
||||
screen_return_value=None, # ret value is ignored
|
||||
# ret value is ignored
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
+12
-12
@@ -2,11 +2,12 @@
|
||||
# Must import this before the Controller
|
||||
from typing import Type
|
||||
|
||||
from mock import MagicMock
|
||||
from mock import MagicMock, Mock
|
||||
from base import FlowTest, FlowStep
|
||||
|
||||
from seedsigner.controller import Controller
|
||||
from seedsigner.models.seed import Seed
|
||||
from seedsigner.models.settings_definition import SettingsConstants, SettingsDefinition
|
||||
from seedsigner.views.view import Destination, MainMenuView, View
|
||||
from seedsigner.views import scan_views, seed_views, tools_views
|
||||
|
||||
@@ -31,11 +32,11 @@ class TestToolsFlows(FlowTest):
|
||||
Destination(MainMenuView),
|
||||
sequence=[
|
||||
FlowStep(
|
||||
screen_return_value=2 # ret TOOLS
|
||||
button_data_selection=MainMenuView.TOOLS
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=tools_views.ToolsMenuView,
|
||||
screen_return_value=3 # ret EXPLORER
|
||||
button_data_selection=tools_views.ToolsMenuView.EXPLORER
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=tools_views.ToolsAddressExplorerSelectSourceView,
|
||||
@@ -43,11 +44,11 @@ class TestToolsFlows(FlowTest):
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=seed_views.SeedExportXpubScriptTypeView,
|
||||
screen_return_value=0 # ret NATIVE_SEGWIT (1st script type option)
|
||||
button_data_selection=SettingsDefinition.get_settings_entry(SettingsConstants.SETTING__SCRIPT_TYPES).get_selection_option_display_name_by_value(SettingsConstants.NATIVE_SEGWIT)
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=tools_views.ToolsAddressExplorerAddressTypeView,
|
||||
screen_return_value=0 # ret RECEIVE addrs
|
||||
button_data_selection=tools_views.ToolsAddressExplorerAddressTypeView.RECEIVE
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=tools_views.ToolsAddressExplorerAddressListView,
|
||||
@@ -83,24 +84,23 @@ class TestToolsFlows(FlowTest):
|
||||
Destination(MainMenuView),
|
||||
sequence=[
|
||||
FlowStep(
|
||||
screen_return_value=2 # ret TOOLS
|
||||
button_data_selection=MainMenuView.TOOLS
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=tools_views.ToolsMenuView,
|
||||
screen_return_value=3 # ret EXPLORER
|
||||
button_data_selection=tools_views.ToolsMenuView.EXPLORER
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=tools_views.ToolsAddressExplorerSelectSourceView,
|
||||
screen_return_value=0 # ret SCAN SeedQR
|
||||
button_data_selection=tools_views.ToolsAddressExplorerSelectSourceView.SCAN_SEED
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=scan_views.ScanView,
|
||||
run_before=load_seed_into_decoder, # simulate read SeedQR
|
||||
screen_return_value=None,
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=seed_views.SeedFinalizeView,
|
||||
screen_return_value=0, # ret DONE
|
||||
button_data_selection=seed_views.SeedFinalizeView.FINALIZE
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=seed_views.SeedOptionsView,
|
||||
@@ -121,7 +121,7 @@ class TestToolsFlows(FlowTest):
|
||||
Destination(seed_views.SeedFinalizeView),
|
||||
sequence=[
|
||||
FlowStep(
|
||||
screen_return_value=1, # ret PASSPHRASE
|
||||
button_data_selection=seed_views.SeedFinalizeView.PASSPHRASE
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=seed_views.SeedAddPassphraseView,
|
||||
@@ -129,7 +129,7 @@ class TestToolsFlows(FlowTest):
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=seed_views.SeedReviewPassphraseView,
|
||||
screen_return_value=1, # ret DONE
|
||||
button_data_selection=seed_views.SeedReviewPassphraseView.DONE
|
||||
),
|
||||
FlowStep(
|
||||
expected_view=seed_views.SeedOptionsView,
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
from base import BaseTest
|
||||
from seedsigner.models.settings import Settings
|
||||
from seedsigner.models.settings_definition import SettingsConstants
|
||||
|
||||
|
||||
class TestSettings(BaseTest):
|
||||
|
||||
def test_reset_settings(self):
|
||||
""" BaseTest.reset_settings() should wipe out any previous Settings changes """
|
||||
settings = Settings.get_instance()
|
||||
settings.set_value(SettingsConstants.SETTING__PERSISTENT_SETTINGS, SettingsConstants.OPTION__ENABLED)
|
||||
assert settings.get_value(SettingsConstants.SETTING__PERSISTENT_SETTINGS) == SettingsConstants.OPTION__ENABLED
|
||||
|
||||
BaseTest.reset_settings()
|
||||
settings = Settings.get_instance()
|
||||
assert settings.get_value(SettingsConstants.SETTING__PERSISTENT_SETTINGS) == SettingsConstants.OPTION__DISABLED
|
||||
Reference in New Issue
Block a user