Skip to content
Merged
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
25 changes: 15 additions & 10 deletions datashuttle/tui/tabs/transfer.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ def compose(self) -> ComposeResult:
),
# These are almost identical to create tab
Label("Datatype(s)", id="transfer_datatype_label"),
]
self.refreshed_transfer_custom_widgets = [
self.create_datatype_checkboxes_widget(),
self.get_displayed_datatypes_button(),
]
Expand All @@ -161,6 +163,7 @@ def compose(self) -> ComposeResult:
*self.transfer_all_widgets,
*self.transfer_toplevel_widgets,
*self.transfer_custom_widgets,
*self.refreshed_transfer_custom_widgets,
id="transfer_params_container",
)
yield Horizontal(
Expand Down Expand Up @@ -279,7 +282,10 @@ def switch_transfer_widgets_display(self) -> None:
"#transfer_toplevel_radiobutton"
).value

for widget in self.transfer_custom_widgets:
for widget in (
self.transfer_custom_widgets
+ self.refreshed_transfer_custom_widgets
):
widget.display = self.query_one(
"#transfer_custom_radiobutton"
).value
Expand Down Expand Up @@ -326,7 +332,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None:
self.refresh_after_datatype_changed,
)

async def refresh_after_datatype_changed(self, ignore):
async def refresh_after_datatype_changed(self, ignore) -> None:
"""Refresh Checkboxes after the shown datatypes have changed.

The widget must be completely removed and reinitialised.
Expand All @@ -341,14 +347,13 @@ async def refresh_after_datatype_changed(self, ignore):
"#transfer_tab_displayed_datatypes_button"
).remove()

(
Button(
"Displayed Datatypes",
id="transfer_tab_displayed_datatypes_button",
),
)
await container.mount(self.create_datatype_checkboxes_widget())
await container.mount(self.get_displayed_datatypes_button())
self.refreshed_transfer_custom_widgets = [
self.create_datatype_checkboxes_widget(),
self.get_displayed_datatypes_button(),
]

for widget in self.refreshed_transfer_custom_widgets:
await container.mount(widget)

def on_custom_directory_tree_directory_tree_special_key_press(
self, event: CustomDirectoryTree.DirectoryTreeSpecialKeyPress
Expand Down
98 changes: 98 additions & 0 deletions tests/tests_tui/test_tui_datatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,101 @@ async def test_select_displayed_datatypes_transfer(
assert kwargs["datatype"] == ["ecephys", "fusi"]
assert kwargs["overwrite_existing_files"] == "never"
assert kwargs["dry_run"] is False

@pytest.mark.asyncio
async def test_transfer_displayed_datatypes_widgets_hide_after_mode_switch(
self, setup_project_paths
):
"""Check refreshed transfer widgets hide correctly and still drive transfer.

Covers the bug where the deleted custom widgets persisted after
switching transfer type, then verifies a newly displayed narrow
datatype can still be selected and transferred correctly.
"""
_, _, project_name = setup_project_paths.values()
subs, sessions = test_utils.get_default_sub_sessions_to_test()
sub_to_transfer, ses_to_transfer = "sub-002", "ses-003"

refreshed_widgets = [
"#transfer_custom_datatype_checkboxes",
"#transfer_tab_displayed_datatypes_button",
]

def assert_refreshed_widgets_display(pilot, expected):
for id in refreshed_widgets:
assert pilot.app.screen.query_one(id).display is expected

app = TuiApp()
async with app.run_test(size=self.tui_size()) as pilot:
await self.check_and_click_onto_existing_project(
pilot, project_name
)
await self.switch_tab(pilot, "transfer")
await self.scroll_to_click_pause(
pilot, "#transfer_custom_radiobutton"
)

# Set up a project containing only the (narrow) "conf" datatype.
project = pilot.app.screen.interface.project
folders_used = test_utils.get_all_broad_folders_used(value=False)
folders_used["conf"] = True

test_utils.make_and_check_local_project_folders(
project,
"rawdata",
subs,
sessions,
["conf"],
datatypes_used=folders_used,
)
_, base_path_to_check = test_utils.handle_upload_or_download(
project, "upload", transfer_method=None
)

# Display the narrow datatypes, refreshing the custom widgets.
await self.scroll_to_click_pause(
pilot, "#transfer_tab_displayed_datatypes_button"
)
pilot.app.screen.query_one(
"#displayed_datatypes_selection_list"
).toggle_all()
await self.scroll_to_click_pause(
pilot, "#displayed_datatypes_save_button"
)

# The refreshed widgets must hide / show with the transfer mode.
await self.scroll_to_click_pause(
pilot, "#transfer_toplevel_radiobutton"
)
assert_refreshed_widgets_display(pilot, False)

await self.scroll_to_click_pause(
pilot, "#transfer_custom_radiobutton"
)
assert_refreshed_widgets_display(pilot, True)

# Select the newly displayed "conf" datatype and transfer.
await self.fill_input(
pilot, "#transfer_subject_input", sub_to_transfer
)
await self.fill_input(
pilot, "#transfer_session_input", ses_to_transfer
)
await self.change_checkbox(pilot, "#transfer_conf_checkbox")

assert (
pilot.app.screen.query_one(
"#transfer_custom_datatype_checkboxes"
).datatype_config["conf"]["on"]
is True
)

await self.click_and_await_transfer(pilot)

test_utils.check_working_top_level_folder_only_exists(
"rawdata",
base_path_to_check / "rawdata",
[sub_to_transfer],
[ses_to_transfer],
folders_used,
)
Loading