multi_workspace_tests.rs

  1use super::*;
  2use feature_flags::FeatureFlagAppExt;
  3use fs::FakeFs;
  4use gpui::TestAppContext;
  5use project::DisableAiSettings;
  6use settings::SettingsStore;
  7
  8fn init_test(cx: &mut TestAppContext) {
  9    cx.update(|cx| {
 10        let settings_store = SettingsStore::test(cx);
 11        cx.set_global(settings_store);
 12        theme_settings::init(theme::LoadThemes::JustBase, cx);
 13        DisableAiSettings::register(cx);
 14        cx.update_flags(false, vec!["agent-v2".into()]);
 15    });
 16}
 17
 18#[gpui::test]
 19async fn test_sidebar_disabled_when_disable_ai_is_enabled(cx: &mut TestAppContext) {
 20    init_test(cx);
 21    let fs = FakeFs::new(cx.executor());
 22    let project = Project::test(fs, [], cx).await;
 23
 24    let (multi_workspace, cx) =
 25        cx.add_window_view(|window, cx| MultiWorkspace::test_new(project, window, cx));
 26
 27    multi_workspace.read_with(cx, |mw, cx| {
 28        assert!(mw.multi_workspace_enabled(cx));
 29    });
 30
 31    multi_workspace.update_in(cx, |mw, _window, cx| {
 32        mw.open_sidebar(cx);
 33        assert!(mw.sidebar_open());
 34    });
 35
 36    cx.update(|_window, cx| {
 37        DisableAiSettings::override_global(DisableAiSettings { disable_ai: true }, cx);
 38    });
 39    cx.run_until_parked();
 40
 41    multi_workspace.read_with(cx, |mw, cx| {
 42        assert!(
 43            !mw.sidebar_open(),
 44            "Sidebar should be closed when disable_ai is true"
 45        );
 46        assert!(
 47            !mw.multi_workspace_enabled(cx),
 48            "Multi-workspace should be disabled when disable_ai is true"
 49        );
 50    });
 51
 52    multi_workspace.update_in(cx, |mw, window, cx| {
 53        mw.toggle_sidebar(window, cx);
 54    });
 55    multi_workspace.read_with(cx, |mw, _cx| {
 56        assert!(
 57            !mw.sidebar_open(),
 58            "Sidebar should remain closed when toggled with disable_ai true"
 59        );
 60    });
 61
 62    cx.update(|_window, cx| {
 63        DisableAiSettings::override_global(DisableAiSettings { disable_ai: false }, cx);
 64    });
 65    cx.run_until_parked();
 66
 67    multi_workspace.read_with(cx, |mw, cx| {
 68        assert!(
 69            mw.multi_workspace_enabled(cx),
 70            "Multi-workspace should be enabled after re-enabling AI"
 71        );
 72        assert!(
 73            !mw.sidebar_open(),
 74            "Sidebar should still be closed after re-enabling AI (not auto-opened)"
 75        );
 76    });
 77
 78    multi_workspace.update_in(cx, |mw, window, cx| {
 79        mw.toggle_sidebar(window, cx);
 80    });
 81    multi_workspace.read_with(cx, |mw, _cx| {
 82        assert!(
 83            mw.sidebar_open(),
 84            "Sidebar should open when toggled after re-enabling AI"
 85        );
 86    });
 87}
 88
 89#[gpui::test]
 90async fn test_replace(cx: &mut TestAppContext) {
 91    init_test(cx);
 92    let fs = FakeFs::new(cx.executor());
 93    let project_a = Project::test(fs.clone(), [], cx).await;
 94    let project_b = Project::test(fs.clone(), [], cx).await;
 95    let project_c = Project::test(fs.clone(), [], cx).await;
 96    let project_d = Project::test(fs.clone(), [], cx).await;
 97
 98    let (multi_workspace, cx) =
 99        cx.add_window_view(|window, cx| MultiWorkspace::test_new(project_a.clone(), window, cx));
100
101    let workspace_a_id = multi_workspace.read_with(cx, |mw, _cx| mw.workspaces()[0].entity_id());
102
103    // Replace the only workspace (single-workspace case).
104    let workspace_b = multi_workspace.update_in(cx, |mw, window, cx| {
105        let workspace = cx.new(|cx| Workspace::test_new(project_b.clone(), window, cx));
106        mw.replace(workspace.clone(), &*window, cx);
107        workspace
108    });
109
110    multi_workspace.read_with(cx, |mw, _cx| {
111        assert_eq!(mw.workspaces().len(), 1);
112        assert_eq!(
113            mw.workspaces()[0].entity_id(),
114            workspace_b.entity_id(),
115            "slot should now be project_b"
116        );
117        assert_ne!(
118            mw.workspaces()[0].entity_id(),
119            workspace_a_id,
120            "project_a should be gone"
121        );
122    });
123
124    // Add project_c as a second workspace, then replace it with project_d.
125    let workspace_c = multi_workspace.update_in(cx, |mw, window, cx| {
126        mw.test_add_workspace(project_c.clone(), window, cx)
127    });
128
129    multi_workspace.read_with(cx, |mw, _cx| {
130        assert_eq!(mw.workspaces().len(), 2);
131        assert_eq!(mw.active_workspace_index(), 1);
132    });
133
134    let workspace_d = multi_workspace.update_in(cx, |mw, window, cx| {
135        let workspace = cx.new(|cx| Workspace::test_new(project_d.clone(), window, cx));
136        mw.replace(workspace.clone(), &*window, cx);
137        workspace
138    });
139
140    multi_workspace.read_with(cx, |mw, _cx| {
141        assert_eq!(mw.workspaces().len(), 2, "should still have 2 workspaces");
142        assert_eq!(mw.active_workspace_index(), 1);
143        assert_eq!(
144            mw.workspaces()[1].entity_id(),
145            workspace_d.entity_id(),
146            "active slot should now be project_d"
147        );
148        assert_ne!(
149            mw.workspaces()[1].entity_id(),
150            workspace_c.entity_id(),
151            "project_c should be gone"
152        );
153    });
154
155    // Replace with workspace_b which is already in the list — should just switch.
156    multi_workspace.update_in(cx, |mw, window, cx| {
157        mw.replace(workspace_b.clone(), &*window, cx);
158    });
159
160    multi_workspace.read_with(cx, |mw, _cx| {
161        assert_eq!(
162            mw.workspaces().len(),
163            2,
164            "no workspace should be added or removed"
165        );
166        assert_eq!(
167            mw.active_workspace_index(),
168            0,
169            "should have switched to workspace_b"
170        );
171    });
172}