test_app.rs

  1use std::{sync::Arc, time::Duration};
  2
  3use futures::StreamExt;
  4use gpui::{actions, KeyBinding};
  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!(live_kit_client, [Quit]);
 13
 14fn main() {
 15    SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
 16
 17    gpui::App::production(Arc::new(())).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.activate(true);
 25
 26        cx.on_action(quit);
 27        cx.bind_keys([KeyBinding::new("cmd-q", Quit, None)]);
 28
 29        // todo!()
 30        // cx.set_menus(vec![Menu {
 31        //     name: "Zed",
 32        //     items: vec![MenuItem::Action {
 33        //         name: "Quit",
 34        //         action: Box::new(Quit),
 35        //         os_action: None,
 36        //     }],
 37        // }]);
 38
 39        let live_kit_url = std::env::var("LIVE_KIT_URL").unwrap_or("http://localhost:7880".into());
 40        let live_kit_key = std::env::var("LIVE_KIT_KEY").unwrap_or("devkey".into());
 41        let live_kit_secret = std::env::var("LIVE_KIT_SECRET").unwrap_or("secret".into());
 42
 43        cx.spawn(|cx| async move {
 44            let user_a_token = token::create(
 45                &live_kit_key,
 46                &live_kit_secret,
 47                Some("test-participant-1"),
 48                VideoGrant::to_join("test-room"),
 49            )
 50            .unwrap();
 51            let room_a = Room::new();
 52            room_a.connect(&live_kit_url, &user_a_token).await.unwrap();
 53
 54            let user2_token = token::create(
 55                &live_kit_key,
 56                &live_kit_secret,
 57                Some("test-participant-2"),
 58                VideoGrant::to_join("test-room"),
 59            )
 60            .unwrap();
 61            let room_b = Room::new();
 62            room_b.connect(&live_kit_url, &user2_token).await.unwrap();
 63
 64            let mut audio_track_updates = room_b.remote_audio_track_updates();
 65            let audio_track = LocalAudioTrack::create();
 66            let audio_track_publication = room_a.publish_audio_track(audio_track).await.unwrap();
 67
 68            if let RemoteAudioTrackUpdate::Subscribed(track, _) =
 69                audio_track_updates.next().await.unwrap()
 70            {
 71                let remote_tracks = room_b.remote_audio_tracks("test-participant-1");
 72                assert_eq!(remote_tracks.len(), 1);
 73                assert_eq!(remote_tracks[0].publisher_id(), "test-participant-1");
 74                assert_eq!(track.publisher_id(), "test-participant-1");
 75            } else {
 76                panic!("unexpected message");
 77            }
 78
 79            audio_track_publication.set_mute(true).await.unwrap();
 80
 81            println!("waiting for mute changed!");
 82            if let RemoteAudioTrackUpdate::MuteChanged { track_id, muted } =
 83                audio_track_updates.next().await.unwrap()
 84            {
 85                let remote_tracks = room_b.remote_audio_tracks("test-participant-1");
 86                assert_eq!(remote_tracks[0].sid(), track_id);
 87                assert_eq!(muted, true);
 88            } else {
 89                panic!("unexpected message");
 90            }
 91
 92            audio_track_publication.set_mute(false).await.unwrap();
 93
 94            if let RemoteAudioTrackUpdate::MuteChanged { track_id, muted } =
 95                audio_track_updates.next().await.unwrap()
 96            {
 97                let remote_tracks = room_b.remote_audio_tracks("test-participant-1");
 98                assert_eq!(remote_tracks[0].sid(), track_id);
 99                assert_eq!(muted, false);
100            } else {
101                panic!("unexpected message");
102            }
103
104            println!("Pausing for 5 seconds to test audio, make some noise!");
105            let timer = cx.background_executor().timer(Duration::from_secs(5));
106            timer.await;
107            let remote_audio_track = room_b
108                .remote_audio_tracks("test-participant-1")
109                .pop()
110                .unwrap();
111            room_a.unpublish_track(audio_track_publication);
112
113            // Clear out any active speakers changed messages
114            let mut next = audio_track_updates.next().await.unwrap();
115            while let RemoteAudioTrackUpdate::ActiveSpeakersChanged { speakers } = next {
116                println!("Speakers changed: {:?}", speakers);
117                next = audio_track_updates.next().await.unwrap();
118            }
119
120            if let RemoteAudioTrackUpdate::Unsubscribed {
121                publisher_id,
122                track_id,
123            } = next
124            {
125                assert_eq!(publisher_id, "test-participant-1");
126                assert_eq!(remote_audio_track.sid(), track_id);
127                assert_eq!(room_b.remote_audio_tracks("test-participant-1").len(), 0);
128            } else {
129                panic!("unexpected message");
130            }
131
132            let mut video_track_updates = room_b.remote_video_track_updates();
133            let displays = room_a.display_sources().await.unwrap();
134            let display = displays.into_iter().next().unwrap();
135
136            let local_video_track = LocalVideoTrack::screen_share_for_display(&display);
137            let local_video_track_publication =
138                room_a.publish_video_track(local_video_track).await.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.update(|cx| cx.shutdown()).ok();
169        })
170        .detach();
171    });
172}
173
174fn quit(_: &Quit, cx: &mut gpui::AppContext) {
175    cx.quit();
176}