1use std::{
2 path::{Path, PathBuf},
3 sync::Arc,
4};
5
6use call::ActiveCall;
7use git::status::{FileStatus, StatusCode, TrackedStatus};
8use git_ui::project_diff::ProjectDiff;
9use gpui::{TestAppContext, VisualTestContext};
10use project::ProjectPath;
11use serde_json::json;
12use workspace::Workspace;
13
14//
15use crate::tests::TestServer;
16
17#[gpui::test]
18async fn test_project_diff(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
19 let mut server = TestServer::start(cx_a.background_executor.clone()).await;
20 let client_a = server.create_client(cx_a, "user_a").await;
21 let client_b = server.create_client(cx_b, "user_b").await;
22 cx_a.set_name("cx_a");
23 cx_b.set_name("cx_b");
24
25 server
26 .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
27 .await;
28
29 client_a
30 .fs()
31 .insert_tree(
32 "/a",
33 json!({
34 ".git": {},
35 "changed.txt": "after\n",
36 "unchanged.txt": "unchanged\n",
37 "created.txt": "created\n",
38 "secret.pem": "secret-changed\n",
39 }),
40 )
41 .await;
42
43 client_a.fs().set_git_content_for_repo(
44 Path::new("/a/.git"),
45 &[
46 ("changed.txt".into(), "before\n".to_string(), None),
47 ("unchanged.txt".into(), "unchanged\n".to_string(), None),
48 ("deleted.txt".into(), "deleted\n".to_string(), None),
49 ("secret.pem".into(), "shh\n".to_string(), None),
50 ],
51 );
52 let (project_a, worktree_id) = client_a.build_local_project("/a", cx_a).await;
53 let active_call_a = cx_a.read(ActiveCall::global);
54 let project_id = active_call_a
55 .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
56 .await
57 .unwrap();
58
59 cx_b.update(editor::init);
60 cx_b.update(git_ui::init);
61 let project_b = client_b.join_remote_project(project_id, cx_b).await;
62 let workspace_b = cx_b.add_window(|window, cx| {
63 Workspace::new(
64 None,
65 project_b.clone(),
66 client_b.app_state.clone(),
67 window,
68 cx,
69 )
70 });
71 let cx_b = &mut VisualTestContext::from_window(*workspace_b, cx_b);
72 let workspace_b = workspace_b.root(cx_b).unwrap();
73
74 cx_b.update(|window, cx| {
75 window
76 .focused(cx)
77 .unwrap()
78 .dispatch_action(&git_ui::project_diff::Diff, window, cx)
79 });
80 let diff = workspace_b.update(cx_b, |workspace, cx| {
81 workspace.active_item(cx).unwrap().act_as::<ProjectDiff>(cx)
82 });
83 let diff = diff.unwrap();
84 cx_b.run_until_parked();
85
86 diff.update(cx_b, |diff, cx| {
87 assert_eq!(
88 diff.excerpt_paths(cx),
89 vec!["changed.txt", "deleted.txt", "created.txt"]
90 );
91 });
92
93 client_a
94 .fs()
95 .insert_tree(
96 "/a",
97 json!({
98 ".git": {},
99 "changed.txt": "before\n",
100 "unchanged.txt": "changed\n",
101 "created.txt": "created\n",
102 "secret.pem": "secret-changed\n",
103 }),
104 )
105 .await;
106 cx_b.run_until_parked();
107
108 project_b.update(cx_b, |project, cx| {
109 let project_path = ProjectPath {
110 worktree_id,
111 path: Arc::from(PathBuf::from("unchanged.txt")),
112 };
113 let status = project.project_path_git_status(&project_path, cx);
114 assert_eq!(
115 status.unwrap(),
116 FileStatus::Tracked(TrackedStatus {
117 worktree_status: StatusCode::Modified,
118 index_status: StatusCode::Unmodified,
119 })
120 );
121 });
122
123 diff.update(cx_b, |diff, cx| {
124 assert_eq!(
125 diff.excerpt_paths(cx),
126 vec!["deleted.txt", "unchanged.txt", "created.txt"]
127 );
128 });
129}