From 696f59992deedb843b30a14e4f25c3c7d038b538 Mon Sep 17 00:00:00 2001 From: kdmukai Date: Tue, 18 Apr 2023 07:20:22 -0500 Subject: [PATCH] Interim commit; refactoring View.run_screen patch --- src/seedsigner/views/seed_views.py | 23 ++++++++++++++--------- src/seedsigner/views/view.py | 21 ++++++++++----------- tests/base.py | 9 ++++++++- tests/test_flows.py | 12 ++---------- tests/test_flows_seed.py | 22 ++++++++++++++++++++++ 5 files changed, 56 insertions(+), 31 deletions(-) diff --git a/src/seedsigner/views/seed_views.py b/src/seedsigner/views/seed_views.py index 2b13a98c..efdcca81 100644 --- a/src/seedsigner/views/seed_views.py +++ b/src/seedsigner/views/seed_views.py @@ -31,6 +31,8 @@ from .view import NotYetImplementedView, View, Destination, BackStackView, MainM class SeedsMenuView(View): + LOAD = "Load a seed" + def __init__(self): super().__init__() self.seeds = [] @@ -50,11 +52,12 @@ class SeedsMenuView(View): button_data.append((seed["fingerprint"], SeedSignerCustomIconConstants.FINGERPRINT, "blue")) button_data.append("Load a seed") - selected_menu_num = ButtonListScreen( + selected_menu_num = self.run_screen( + ButtonListScreen, title="In-Memory Seeds", is_button_text_centered=False, button_data=button_data - ).display() + ) if len(self.seeds) > 0 and selected_menu_num < len(self.seeds): return Destination(SeedOptionsView, view_args={"seed_num": selected_menu_num}) @@ -291,6 +294,9 @@ class SeedReviewPassphraseView(View): class SeedDiscardView(View): + KEEP = "Keep Seed" + DISCARD = ("Discard", None, None, "red") + def __init__(self, seed_num: int = None): super().__init__() self.seed_num = seed_num @@ -301,27 +307,26 @@ class SeedDiscardView(View): def run(self): - KEEP = "Keep Seed" - DISCARD = ("Discard", None, None, "red") - button_data = [KEEP, DISCARD] + button_data = [self.KEEP, self.DISCARD] fingerprint = self.seed.get_fingerprint(self.settings.get_value(SettingsConstants.SETTING__NETWORK)) - selected_menu_num = WarningScreen( + selected_menu_num = self.run_screen( + WarningScreen, title="Discard Seed?", status_headline=None, text=f"Wipe seed {fingerprint} from the device?", show_back_button=False, button_data=button_data, - ).display() + ) - if button_data[selected_menu_num] == KEEP: + if button_data[selected_menu_num] == self.KEEP: # Use skip_current_view=True to prevent BACK from landing on this warning screen if self.seed_num is not None: return Destination(SeedOptionsView, view_args={"seed_num": self.seed_num}, skip_current_view=True) else: return Destination(SeedFinalizeView, skip_current_view=True) - elif button_data[selected_menu_num] == DISCARD: + elif button_data[selected_menu_num] == self.DISCARD: if self.seed_num is not None: self.controller.discard_seed(self.seed_num) else: diff --git a/src/seedsigner/views/view.py b/src/seedsigner/views/view.py index 6b699e23..f9a40f89 100644 --- a/src/seedsigner/views/view.py +++ b/src/seedsigner/views/view.py @@ -141,15 +141,14 @@ class MainMenuView(View): SEEDS = ("Seeds", FontAwesomeIconConstants.KEY) TOOLS = ("Tools", FontAwesomeIconConstants.SCREWDRIVER_WRENCH) SETTINGS = ("Settings", FontAwesomeIconConstants.GEAR) - button_data = [SCAN, SEEDS, TOOLS, SETTINGS] - def run(self): + button_data = [self.SCAN, self.SEEDS, self.TOOLS, self.SETTINGS] selected_menu_num = self.run_screen( LargeButtonScreen, title="Home", title_font_size=26, - button_data=self.button_data, + button_data=button_data, show_back_button=False, show_power_button=True, ) @@ -157,19 +156,19 @@ class MainMenuView(View): if selected_menu_num == RET_CODE__POWER_BUTTON: return Destination(PowerOptionsView) - if self.button_data[selected_menu_num] == self.SCAN: + if button_data[selected_menu_num] == self.SCAN: from .scan_views import ScanView return Destination(ScanView) - elif self.button_data[selected_menu_num] == self.SEEDS: + elif button_data[selected_menu_num] == self.SEEDS: from .seed_views import SeedsMenuView return Destination(SeedsMenuView) - elif self.button_data[selected_menu_num] == self.TOOLS: + elif button_data[selected_menu_num] == self.TOOLS: from .tools_views import ToolsMenuView return Destination(ToolsMenuView) - elif self.button_data[selected_menu_num] == self.SETTINGS: + elif button_data[selected_menu_num] == self.SETTINGS: from .settings_views import SettingsMenuView return Destination(SettingsMenuView) @@ -178,23 +177,23 @@ class MainMenuView(View): class PowerOptionsView(View): RESET = ("Restart", FontAwesomeIconConstants.ROTATE_RIGHT) POWER_OFF = ("Power Off", FontAwesomeIconConstants.POWER_OFF) - button_data = [RESET, POWER_OFF] def run(self): + button_data = [self.RESET, self.POWER_OFF] selected_menu_num = self.run_screen( LargeButtonScreen, title="Reset / Power", show_back_button=True, - button_data=self.button_data + button_data=button_data ) if selected_menu_num == RET_CODE__BACK_BUTTON: return Destination(BackStackView) - elif self.button_data[selected_menu_num] == PowerOptionsView.RESET: + elif button_data[selected_menu_num] == self.RESET: return Destination(RestartView) - elif self.button_data[selected_menu_num] == PowerOptionsView.POWER_OFF: + elif button_data[selected_menu_num] == self.POWER_OFF: return Destination(PowerOffView) diff --git a/tests/base.py b/tests/base.py index ebf520fe..27dd2d4e 100644 --- a/tests/base.py +++ b/tests/base.py @@ -138,8 +138,15 @@ class FlowTest(BaseTest): # Return the return value specified in the test sequence and # remove the completed test step from the sequence. flow_step = sequence.pop(0) + if flow_step.button_data_selection: - return view.button_data.index(flow_step.button_data_selection) + # We're mocking out the View.run_screen() method, so we'll get all of the + # input args that are normally passed into the Screen.run() method, + # including the button_data kwarg. + if "button_data" in kwargs: + return kwargs.get("button_data").index(flow_step.button_data_selection) + else: + raise Exception(f"Can't specify `FlowStep.button_data_selection` if `button_data` isn't a kwarg in {view.__class__.__name__}'s run_screen()") elif type(flow_step.screen_return_value) in [StopFlowBasedTest, Exception]: raise flow_step.screen_return_value diff --git a/tests/test_flows.py b/tests/test_flows.py index 3cc29e24..f900d1bc 100644 --- a/tests/test_flows.py +++ b/tests/test_flows.py @@ -43,16 +43,8 @@ class TestFlowTest(FlowTest): """ Ensure that the FlowTest can execute a function before running a View. """ - def break_button_data(view): - # Intentionally break the FlowTest's integration with the View's expected button_data - view.button_data = [] - - self.run_sequence([ - # Offering a button_data_selection that doesn't exist in the View's button_data - # will cause the FlowTest to raise an Exception. - FlowStep(MainMenuView, before_run=break_button_data, button_data_selection=MainMenuView.TOOLS), - FlowStep(UnhandledExceptionView), - ]) + # TODO + pass def test_back_button_flow(self): diff --git a/tests/test_flows_seed.py b/tests/test_flows_seed.py index a9692187..a8ea4e03 100644 --- a/tests/test_flows_seed.py +++ b/tests/test_flows_seed.py @@ -127,3 +127,25 @@ class TestSeedFlows(FlowTest): # TODO: Test is incomplete... ] ) + + + def test_discard_seed_flow(self): + """ + Selecting "Discard Seed" from the SeedOptionsView should enter the Discard Seed flow and + remove the in-memory seed from the Controller. + """ + # Load a finalized Seed into the Controller + mnemonic = "blush twice taste dawn feed second opinion lazy thumb play neglect impact".split() + self.controller.storage.set_pending_seed(Seed(mnemonic=mnemonic)) + self.controller.storage.finalize_pending_seed() + + self.run_sequence( + initial_destination_view_args=dict(seed_num=0), + sequence=[ + FlowStep(seed_views.SeedOptionsView, button_data_selection=seed_views.SeedOptionsView.DISCARD), + FlowStep(seed_views.SeedDiscardView, button_data_selection=seed_views.SeedDiscardView.DISCARD), + FlowStep(MainMenuView, button_data_selection=MainMenuView.SEEDS), + FlowStep(seed_views.SeedsMenuView, is_redirect=True), # When no seeds are loaded it auto-redirects to LoadSeedView + FlowStep(seed_views.LoadSeedView), + ] + )