use std::sync::Arc; use galaxy_editor::model::CoreEditorModel; use galaxyui::{ async_assert, integration::TestStep, windowing::WindowManager, App, SingletonEntity, ViewHandle, WindowId, }; use string_offset::CharOffset; use crate::{ cloud_object::{model::persistence::CloudModel, CloudObjectEventEntrypoint, Space}, drive::OpenGalaxyDriveObjectSettings, integration_testing::view_getters::{notebook_view, workspace_view}, notebooks::manager::NotebookSource, server::{ cloud_objects::update_manager::UpdateManager, ids::{ClientId, SyncId}, }, workspaces::user_workspaces::UserWorkspaces, }; fn notebook_editor( app: &App, window_id: WindowId, tab_index: usize, pane_index: usize, ) -> ViewHandle { notebook_view(app, window_id, tab_index, pane_index) .read(app, |notebook, _ctx| notebook.input_editor()) } /// Create a personal notebook and save its sync ID into the step data. pub fn create_a_personal_notebook(key: impl Into, title: impl Into) -> TestStep { let key = key.into(); let title = Arc::new(title.into()); TestStep::new("Create a personal notebook") .with_action(move |app, _, data| { let client_id = ClientId::new(); let sync_id = SyncId::ClientId(client_id); UpdateManager::handle(app).update(app, |update_manager, ctx| { update_manager.create_notebook( client_id, UserWorkspaces::as_ref(ctx) .personal_drive(ctx) .expect("User UID must be set in tests"), None, Default::default(), CloudObjectEventEntrypoint::ManagementUI, true, ctx, ); // Set a title so that the notebook is not considered empty. update_manager.update_notebook_title(title.clone(), sync_id, ctx); }); data.insert(key.clone(), sync_id); }) .add_assertion(move |app, _| { CloudModel::handle(app).read(app, |cloud_model, ctx| { async_assert!( cloud_model .active_cloud_objects_in_space(Space::Personal, ctx) .count() > 0, "Notebook exists" ) }) }) } /// Open the notebook saved at `notebook_key` in the active tab of the window saved at `window_key` pub fn open_notebook(window_key: impl Into, notebook_key: impl Into) -> TestStep { let window_key = window_key.into(); let notebook_key = notebook_key.into(); TestStep::new("Open notebook").with_action(move |app, _, data| { let notebook_id: &SyncId = data.get(¬ebook_key).expect("No saved notebook ID"); let window_id: &WindowId = data.get(&window_key).expect("No saved window ID"); workspace_view(app, *window_id).update(app, |workspace, ctx| { // If the notebook isn't open yet, opening it won't focus the window (we only change // focus if switching to an already-open window). Since the user wouldn't be able to // open a notebook in an unfocused window, switch focus explicitly here. WindowManager::as_ref(ctx).show_window_and_focus_app(*window_id); workspace.open_notebook( &NotebookSource::Existing(*notebook_id), &OpenGalaxyDriveObjectSettings::default(), ctx, true, ); }) }) } pub fn enter_notebook_edit_mode_and_set_markdown( tab_index: usize, pane_index: usize, markdown: impl Into, ) -> TestStep { let markdown = markdown.into(); TestStep::new("Enter notebook edit mode and set Markdown").with_action( move |app, window_id, _| { let notebook = notebook_view(app, window_id, tab_index, pane_index); notebook.update(app, |notebook, ctx| notebook.toggle_mode(ctx)); let editor = notebook_editor(app, window_id, tab_index, pane_index); editor.update(app, |editor, ctx| { editor.reset_with_markdown(&markdown, ctx); }); }, ) } pub fn move_notebook_cursor_to_offset( tab_index: usize, pane_index: usize, offset: usize, ) -> TestStep { TestStep::new("Move notebook cursor to offset").with_action(move |app, window_id, _| { let editor = notebook_editor(app, window_id, tab_index, pane_index); editor.update(app, |editor, ctx| { editor.model().update(ctx, |model, ctx| { model.cursor_at(CharOffset::from(offset), ctx) }); }); }) }