test_app.rs

  1use std::time::Duration;
  2
  3use futures::StreamExt;
  4use gpui::{actions, keymap_matcher::Binding, Menu, MenuItem};
  5use live_kit_client::{
  6    LocalAudioTrack, LocalVideoTrack, RemoteAudioTrackUpdate, RemoteVideoTrackUpdate, Room,
  7};
  8use live_kit_server::token::{self, VideoGrant};
  9use log::LevelFilter;
 10use simplelog::SimpleLogger;
 11
 12actions!(capture, [Quit]);
 13
 14fn main() {
 15    SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
 16
 17    gpui::App::new(()).unwrap().run(|cx| {
 18        #[cfg(any(test, feature = "test-support"))]
 19        println!("USING TEST LIVEKIT");
 20
 21        #[cfg(not(any(test, feature = "test-support")))]
 22        println!("USING REAL LIVEKIT");
 23
 24        cx.platform().activate(true);
 25        cx.add_global_action(quit);
 26
 27        cx.add_bindings([Binding::new("cmd-q", Quit, None)]);
 28        cx.set_menus(vec![Menu {
 29            name: "Zed",
 30            items: vec![MenuItem::Action {
 31                name: "Quit",
 32                action: Box::new(Quit),
 33                os_action: None,
 34            }],
 35        }]);
 36
 37        let live_kit_url = std::env::var("LIVE_KIT_URL").unwrap_or("http://localhost:7880".into());
 38        let live_kit_key = std::env::var("LIVE_KIT_KEY").unwrap_or("devkey".into());
 39        let live_kit_secret = std::env::var("LIVE_KIT_SECRET").unwrap_or("secret".into());
 40
 41        cx.spawn(|cx| async move {
 42            let user_a_token = token::create(
 43                &live_kit_key,
 44                &live_kit_secret,
 45                Some("test-participant-1"),
 46                VideoGrant::to_join("test-room"),
 47            )
 48            .unwrap();
 49            let room_a = Room::new();
 50            room_a.connect(&live_kit_url, &user_a_token).await.unwrap();
 51
 52            let user2_token = token::create(
 53                &live_kit_key,
 54                &live_kit_secret,
 55                Some("test-participant-2"),
 56                VideoGrant::to_join("test-room"),
 57            )
 58            .unwrap();
 59            let room_b = Room::new();
 60            room_b.connect(&live_kit_url, &user2_token).await.unwrap();
 61
 62            let mut audio_track_updates = room_b.remote_audio_track_updates();
 63            let audio_track = LocalAudioTrack::create();
 64            let audio_track_publication = room_a.publish_audio_track(&audio_track).await.unwrap();
 65
 66            if let RemoteAudioTrackUpdate::Subscribed(track, _) =
 67                audio_track_updates.next().await.unwrap()
 68            {
 69                let remote_tracks = room_b.remote_audio_tracks("test-participant-1");
 70                assert_eq!(remote_tracks.len(), 1);
 71                assert_eq!(remote_tracks[0].publisher_id(), "test-participant-1");
 72                assert_eq!(track.publisher_id(), "test-participant-1");
 73            } else {
 74                panic!("unexpected message");
 75            }
 76
 77            audio_track_publication.set_mute(true).await.unwrap();
 78
 79            println!("waiting for mute changed!");
 80            if let RemoteAudioTrackUpdate::MuteChanged { track_id, muted } =
 81                audio_track_updates.next().await.unwrap()
 82            {
 83                let remote_tracks = room_b.remote_audio_tracks("test-participant-1");
 84                assert_eq!(remote_tracks[0].sid(), track_id);
 85                assert_eq!(muted, true);
 86            } else {
 87                panic!("unexpected message");
 88            }
 89
 90            audio_track_publication.set_mute(false).await.unwrap();
 91
 92            if let RemoteAudioTrackUpdate::MuteChanged { track_id, muted } =
 93                audio_track_updates.next().await.unwrap()
 94            {
 95                let remote_tracks = room_b.remote_audio_tracks("test-participant-1");
 96                assert_eq!(remote_tracks[0].sid(), track_id);
 97                assert_eq!(muted, false);
 98            } else {
 99                panic!("unexpected message");
100            }
101
102            println!("Pausing for 5 seconds to test audio, make some noise!");
103            let timer = cx.background().timer(Duration::from_secs(5));
104            timer.await;
105            let remote_audio_track = room_b
106                .remote_audio_tracks("test-participant-1")
107                .pop()
108                .unwrap();
109            room_a.unpublish_track(audio_track_publication);
110
111            // Clear out any active speakers changed messages
112            let mut next = audio_track_updates.next().await.unwrap();
113            while let RemoteAudioTrackUpdate::ActiveSpeakersChanged { speakers } = next {
114                println!("Speakers changed: {:?}", speakers);
115                next = audio_track_updates.next().await.unwrap();
116            }
117
118            if let RemoteAudioTrackUpdate::Unsubscribed {
119                publisher_id,
120                track_id,
121            } = next
122            {
123                assert_eq!(publisher_id, "test-participant-1");
124                assert_eq!(remote_audio_track.sid(), track_id);
125                assert_eq!(room_b.remote_audio_tracks("test-participant-1").len(), 0);
126            } else {
127                panic!("unexpected message");
128            }
129
130            let mut video_track_updates = room_b.remote_video_track_updates();
131            let displays = room_a.display_sources().await.unwrap();
132            let display = displays.into_iter().next().unwrap();
133
134            let local_video_track = LocalVideoTrack::screen_share_for_display(&display);
135            let local_video_track_publication = room_a
136                .publish_video_track(&local_video_track)
137                .await
138                .unwrap();
139
140            if let RemoteVideoTrackUpdate::Subscribed(track) =
141                video_track_updates.next().await.unwrap()
142            {
143                let remote_video_tracks = room_b.remote_video_tracks("test-participant-1");
144                assert_eq!(remote_video_tracks.len(), 1);
145                assert_eq!(remote_video_tracks[0].publisher_id(), "test-participant-1");
146                assert_eq!(track.publisher_id(), "test-participant-1");
147            } else {
148                panic!("unexpected message");
149            }
150
151            let remote_video_track = room_b
152                .remote_video_tracks("test-participant-1")
153                .pop()
154                .unwrap();
155            room_a.unpublish_track(local_video_track_publication);
156            if let RemoteVideoTrackUpdate::Unsubscribed {
157                publisher_id,
158                track_id,
159            } = video_track_updates.next().await.unwrap()
160            {
161                assert_eq!(publisher_id, "test-participant-1");
162                assert_eq!(remote_video_track.sid(), track_id);
163                assert_eq!(room_b.remote_video_tracks("test-participant-1").len(), 0);
164            } else {
165                panic!("unexpected message");
166            }
167
168            cx.platform().quit();
169        })
170        .detach();
171    });
172}
173
174fn quit(_: &Quit, cx: &mut gpui::AppContext) {
175    cx.platform().quit();
176}