Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve 547 #580

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions src/seedsigner/views/seed_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

class SeedsMenuView(View):
LOAD = "Load a seed"
CREATE = "Create a seed"

def __init__(self):
super().__init__()
Expand All @@ -49,7 +50,7 @@ def run(self):
button_data = []
for seed in self.seeds:
button_data.append((seed["fingerprint"], SeedSignerIconConstants.FINGERPRINT))
button_data.append("Load a seed")
button_data.extend([self.LOAD, self.CREATE])

selected_menu_num = self.run_screen(
ButtonListScreen,
Expand All @@ -61,9 +62,14 @@ def run(self):
if len(self.seeds) > 0 and selected_menu_num < len(self.seeds):
return Destination(SeedOptionsView, view_args={"seed_num": selected_menu_num})

# accessed relative to len(self.seeds) which may have changed
elif selected_menu_num == len(self.seeds):
return Destination(LoadSeedView)

elif selected_menu_num == len(self.seeds) + 1:
from .tools_views import ToolsMenuView
return Destination(ToolsMenuView, view_args={"new_seeds_only": True})

elif selected_menu_num == RET_CODE__BACK_BUTTON:
return Destination(BackStackView)

Expand Down Expand Up @@ -184,7 +190,8 @@ def run(self):
if self.settings.get_value(SettingsConstants.SETTING__ELECTRUM_SEEDS) == SettingsConstants.OPTION__ENABLED:
button_data.append(self.TYPE_ELECTRUM)

button_data.append(self.CREATE)
if len(self.controller.storage.seeds) == 0:
button_data.append(self.CREATE)

selected_menu_num = self.run_screen(
ButtonListScreen,
Expand Down Expand Up @@ -213,8 +220,7 @@ def run(self):

elif button_data[selected_menu_num] == self.CREATE:
from .tools_views import ToolsMenuView
return Destination(ToolsMenuView)

return Destination(ToolsMenuView, view_args={"new_seeds_only": True})


class SeedMnemonicEntryView(View):
Expand Down
19 changes: 13 additions & 6 deletions src/seedsigner/views/tools_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,18 @@ class ToolsMenuView(View):
ADDRESS_EXPLORER = "Address Explorer"
VERIFY_ADDRESS = "Verify address"

def __init__(self, new_seeds_only: bool = False):
super().__init__()
self.new_seeds_only = new_seeds_only

def run(self):
button_data = [self.IMAGE, self.DICE, self.KEYBOARD, self.ADDRESS_EXPLORER, self.VERIFY_ADDRESS]
button_data = [self.IMAGE, self.DICE, self.KEYBOARD]
if not self.new_seeds_only:
button_data.extend([self.ADDRESS_EXPLORER, self.VERIFY_ADDRESS])

selected_menu_num = self.run_screen(
ButtonListScreen,
title="Tools",
title="Tools" if not self.new_seeds_only else "Create A Seed",
is_button_text_centered=False,
button_data=button_data
)
Expand All @@ -54,10 +60,10 @@ def run(self):
elif button_data[selected_menu_num] == self.KEYBOARD:
return Destination(ToolsCalcFinalWordNumWordsView)

elif button_data[selected_menu_num] == self.ADDRESS_EXPLORER:
elif not self.new_seeds_only and button_data[selected_menu_num] == self.ADDRESS_EXPLORER:
return Destination(ToolsAddressExplorerSelectSourceView)

elif button_data[selected_menu_num] == self.VERIFY_ADDRESS:
elif not self.new_seeds_only and button_data[selected_menu_num] == self.VERIFY_ADDRESS:
from seedsigner.views.scan_views import ScanAddressView
return Destination(ScanAddressView)

Expand Down Expand Up @@ -193,12 +199,13 @@ def run(self):
TWENTY_FOUR = f"24 words ({mnemonic_generation.DICE__NUM_ROLLS__24WORD} rolls)"

button_data = [TWELVE, TWENTY_FOUR]
selected_menu_num = ButtonListScreen(
selected_menu_num = self.run_screen(
ButtonListScreen,
title="Mnemonic Length",
is_bottom_list=True,
is_button_text_centered=True,
button_data=button_data,
).display()
)

if selected_menu_num == RET_CODE__BACK_BUTTON:
return Destination(BackStackView)
Expand Down
1 change: 1 addition & 0 deletions tests/screenshot_generator/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ def add_op_return_to_psbt(psbt: PSBT, raw_payload_data: bytes):
"Seed Views": [
seed_views.SeedsMenuView,
seed_views.LoadSeedView,
(tools_views.ToolsMenuView, dict(new_seeds_only=True), "ToolsViaCreateASeed"),
seed_views.SeedMnemonicEntryView,
seed_views.SeedMnemonicInvalidView,
seed_views.SeedFinalizeView,
Expand Down
80 changes: 79 additions & 1 deletion tests/test_flows_seed.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from seedsigner.models.settings import Settings, SettingsConstants
from seedsigner.models.seed import ElectrumSeed, Seed
from seedsigner.views.view import ErrorView, MainMenuView, OptionDisabledView, View, NetworkMismatchErrorView
from seedsigner.views import seed_views, scan_views, settings_views
from seedsigner.views import seed_views, scan_views, settings_views, tools_views


def load_seed_into_decoder(view: scan_views.ScanView):
Expand Down Expand Up @@ -408,6 +408,83 @@ def test_discard_seed_flow(self):
)


def test_create_first_seed_via_seeds(self):
# From SeedMenu into "Create a Seed", then foreach valid option: in-out-next
self.run_sequence([
FlowStep(MainMenuView, button_data_selection=MainMenuView.SEEDS),
FlowStep(seed_views.SeedsMenuView, is_redirect=True),
FlowStep(seed_views.LoadSeedView, button_data_selection=seed_views.LoadSeedView.CREATE),
FlowStep(tools_views.ToolsMenuView, button_data_selection=tools_views.ToolsMenuView.IMAGE),
FlowStep(tools_views.ToolsImageEntropyLivePreviewView, screen_return_value=RET_CODE__BACK_BUTTON, is_redirect=True),
FlowStep(tools_views.ToolsMenuView, button_data_selection=tools_views.ToolsMenuView.DICE),
FlowStep(tools_views.ToolsDiceEntropyMnemonicLengthView, screen_return_value=RET_CODE__BACK_BUTTON),
FlowStep(tools_views.ToolsMenuView, button_data_selection=tools_views.ToolsMenuView.KEYBOARD),
FlowStep(tools_views.ToolsCalcFinalWordNumWordsView, screen_return_value=RET_CODE__BACK_BUTTON),
FlowStep(tools_views.ToolsMenuView)
])

# From SeedMenu into "Create a Seed", Address Explorer not available
with pytest.raises(FlowTestInvalidButtonDataSelectionException) as e:
self.run_sequence([
FlowStep(MainMenuView, button_data_selection=MainMenuView.SEEDS),
FlowStep(seed_views.SeedsMenuView, is_redirect=True),
FlowStep(seed_views.LoadSeedView, button_data_selection=seed_views.LoadSeedView.CREATE),
FlowStep(tools_views.ToolsMenuView, button_data_selection=tools_views.ToolsMenuView.ADDRESS_EXPLORER),
])

# From SeedMenu into "Create a Seed", Verify Address not available
with pytest.raises(FlowTestInvalidButtonDataSelectionException) as e:
self.run_sequence([
FlowStep(MainMenuView, button_data_selection=MainMenuView.SEEDS),
FlowStep(seed_views.SeedsMenuView, is_redirect=True),
FlowStep(seed_views.LoadSeedView, button_data_selection=seed_views.LoadSeedView.CREATE),
FlowStep(tools_views.ToolsMenuView, button_data_selection=tools_views.ToolsMenuView.VERIFY_ADDRESS),
])


def test_create_additional_seed_via_seeds(self):
# 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()

# From SeedMenu into "Create a Seed", then foreach valid option: in-out-next
self.run_sequence([
FlowStep(MainMenuView, button_data_selection=MainMenuView.SEEDS),
FlowStep(seed_views.SeedsMenuView, button_data_selection=seed_views.SeedsMenuView.CREATE),
FlowStep(tools_views.ToolsMenuView, button_data_selection=tools_views.ToolsMenuView.IMAGE),
FlowStep(tools_views.ToolsImageEntropyLivePreviewView, screen_return_value=RET_CODE__BACK_BUTTON, is_redirect=True),
FlowStep(tools_views.ToolsMenuView, button_data_selection=tools_views.ToolsMenuView.DICE),
FlowStep(tools_views.ToolsDiceEntropyMnemonicLengthView, screen_return_value=RET_CODE__BACK_BUTTON),
FlowStep(tools_views.ToolsMenuView, button_data_selection=tools_views.ToolsMenuView.KEYBOARD),
FlowStep(tools_views.ToolsCalcFinalWordNumWordsView, screen_return_value=RET_CODE__BACK_BUTTON),
FlowStep(tools_views.ToolsMenuView)
])

# From SeedMenu into "Load a Seed", Create a seed not available
with pytest.raises(FlowTestInvalidButtonDataSelectionException) as e:
self.run_sequence([
FlowStep(MainMenuView, button_data_selection=MainMenuView.SEEDS),
FlowStep(seed_views.SeedsMenuView, button_data_selection=seed_views.SeedsMenuView.LOAD),
FlowStep(seed_views.LoadSeedView, button_data_selection=seed_views.LoadSeedView.CREATE),
])

# From SeedMenu into "Create a Seed", Address Explorer not available
with pytest.raises(FlowTestInvalidButtonDataSelectionException) as e:
self.run_sequence([
FlowStep(MainMenuView, button_data_selection=MainMenuView.SEEDS),
FlowStep(seed_views.SeedsMenuView, button_data_selection=seed_views.SeedsMenuView.CREATE),
FlowStep(tools_views.ToolsMenuView, button_data_selection=tools_views.ToolsMenuView.ADDRESS_EXPLORER),
])

# From SeedMenu into "Create a Seed", Verify Address not available
with pytest.raises(FlowTestInvalidButtonDataSelectionException) as e:
self.run_sequence([
FlowStep(MainMenuView, button_data_selection=MainMenuView.SEEDS),
FlowStep(seed_views.SeedsMenuView, button_data_selection=seed_views.SeedsMenuView.CREATE),
FlowStep(tools_views.ToolsMenuView, button_data_selection=tools_views.ToolsMenuView.VERIFY_ADDRESS),
])


class TestMessageSigningFlows(FlowTest):
MAINNET_DERIVATION_PATH = "m/84h/0h/0h/0/0"
Expand Down Expand Up @@ -664,3 +741,4 @@ def expect_unsupported_derivation(load_message: Callable):
self.settings.set_value(SettingsConstants.SETTING__NETWORK, SettingsConstants.MAINNET)
expect_unsupported_derivation(self.load_custom_derivation_into_decoder)


12 changes: 12 additions & 0 deletions tests/test_flows_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,3 +245,15 @@ def load_descriptor_into_decoder(view: scan_views.ScanView):
FlowStep(seed_views.AddressVerificationSuccessView),
])


def test_create_seed_via_tools_has_other_tools(self):
"""
When Navigating to ToolsMenuView (also used for "Create a seed") from MainMenu,
other tools exist; Into AddressExplorer, then back, then into VerifyAddress
"""
self.run_sequence([
FlowStep(MainMenuView, button_data_selection=MainMenuView.TOOLS),
FlowStep(tools_views.ToolsMenuView, button_data_selection=tools_views.ToolsMenuView.ADDRESS_EXPLORER),
FlowStep(tools_views.ToolsAddressExplorerSelectSourceView, screen_return_value=RET_CODE__BACK_BUTTON),
FlowStep(tools_views.ToolsMenuView, button_data_selection=tools_views.ToolsMenuView.VERIFY_ADDRESS),
])
Loading