Implement test stubs

Mikayla Maki created

Change summary

crates/live_kit_client/examples/test_app.rs   | 19 +++-
crates/live_kit_client/src/live_kit_client.rs |  2 
crates/live_kit_client/src/prod.rs            | 38 ++--------
crates/live_kit_client/src/test.rs            | 78 +++++++++++++++++---
4 files changed, 86 insertions(+), 51 deletions(-)

Detailed changes

crates/live_kit_client/examples/test_app.rs 🔗

@@ -1,9 +1,10 @@
-
 use std::time::Duration;
 
 use futures::StreamExt;
 use gpui::{actions, keymap_matcher::Binding, Menu, MenuItem};
-use live_kit_client::{LocalVideoTrack, RemoteVideoTrackUpdate, Room, LocalAudioTrack, RemoteAudioTrackUpdate};
+use live_kit_client::{
+    LocalAudioTrack, LocalVideoTrack, RemoteAudioTrackUpdate, RemoteVideoTrackUpdate, Room,
+};
 use live_kit_server::token::{self, VideoGrant};
 use log::LevelFilter;
 use simplelog::SimpleLogger;
@@ -14,7 +15,6 @@ fn main() {
     SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
 
     gpui::App::new(()).unwrap().run(|cx| {
-
         #[cfg(any(test, feature = "test-support"))]
         println!("USING TEST LIVEKIT");
 
@@ -63,7 +63,9 @@ fn main() {
             let audio_track = LocalAudioTrack::create();
             let audio_track_publication = room_a.publish_audio_track(&audio_track).await.unwrap();
 
-            if let RemoteAudioTrackUpdate::Subscribed(track) = audio_track_updates.next().await.unwrap() {
+            if let RemoteAudioTrackUpdate::Subscribed(track) =
+                audio_track_updates.next().await.unwrap()
+            {
                 let remote_tracks = room_b.remote_audio_tracks("test-participant-1");
                 assert_eq!(remote_tracks.len(), 1);
                 assert_eq!(remote_tracks[0].publisher_id(), "test-participant-1");
@@ -98,9 +100,14 @@ fn main() {
             let display = displays.into_iter().next().unwrap();
 
             let local_video_track = LocalVideoTrack::screen_share_for_display(&display);
-            let local_video_track_publication = room_a.publish_video_track(&local_video_track).await.unwrap();
+            let local_video_track_publication = room_a
+                .publish_video_track(&local_video_track)
+                .await
+                .unwrap();
 
-            if let RemoteVideoTrackUpdate::Subscribed(track) = video_track_updates.next().await.unwrap() {
+            if let RemoteVideoTrackUpdate::Subscribed(track) =
+                video_track_updates.next().await.unwrap()
+            {
                 let remote_video_tracks = room_b.remote_video_tracks("test-participant-1");
                 assert_eq!(remote_video_tracks.len(), 1);
                 assert_eq!(remote_video_tracks[0].publisher_id(), "test-participant-1");

crates/live_kit_client/src/prod.rs 🔗

@@ -84,17 +84,13 @@ extern "C" {
     ) -> *const c_void;
 
     fn LKRemoteAudioTrackGetSid(track: *const c_void) -> CFStringRef;
-    fn LKRemoteAudioTrackStart(
-        track: *const c_void,
-        callback: extern "C" fn(*mut c_void, bool),
-        callback_data: *mut c_void
-    );
+    // fn LKRemoteAudioTrackStart(
+    //     track: *const c_void,
+    //     callback: extern "C" fn(*mut c_void, bool),
+    //     callback_data: *mut c_void
+    // );
 
-    fn LKVideoTrackAddRenderer(
-        track: *const c_void,
-        renderer: *const c_void
-       ,
-    );
+    fn LKVideoTrackAddRenderer(track: *const c_void, renderer: *const c_void);
     fn LKRemoteVideoTrackGetSid(track: *const c_void) -> CFStringRef;
 
     fn LKDisplaySources(
@@ -537,7 +533,7 @@ impl Drop for LocalTrackPublication {
 
 #[derive(Debug)]
 pub struct RemoteAudioTrack {
-    native_track: *const c_void,
+    _native_track: *const c_void,
     sid: Sid,
     publisher_id: String,
 }
@@ -548,7 +544,7 @@ impl RemoteAudioTrack {
             CFRetain(native_track);
         }
         Self {
-            native_track,
+            _native_track: native_track,
             sid,
             publisher_id,
         }
@@ -561,24 +557,6 @@ impl RemoteAudioTrack {
     pub fn publisher_id(&self) -> &str {
         &self.publisher_id
     }
-
-    pub fn start(&self) -> futures::channel::oneshot::Receiver<bool> {
-        let (tx, rx) = futures::channel::oneshot::channel();
-
-        extern "C" fn on_start(callback_data: *mut c_void, success: bool) {
-            unsafe {
-                let tx =
-                    Box::from_raw(callback_data as *mut futures::channel::oneshot::Sender<bool>);
-                tx.send(success).ok();
-            }
-        }
-
-        unsafe {
-            LKRemoteAudioTrackStart(self.native_track, on_start, Box::into_raw(Box::new(tx)) as *mut c_void)
-        }
-
-        rx
-    }
 }
 
 #[derive(Debug)]

crates/live_kit_client/src/test.rs 🔗

@@ -67,7 +67,7 @@ impl TestServer {
         }
     }
 
-    async fn create_room(&self, room: String) -> Result<()> {
+    pub async fn create_room(&self, room: String) -> Result<()> {
         self.background.simulate_random_delay().await;
         let mut server_rooms = self.rooms.lock();
         if server_rooms.contains_key(&room) {
@@ -104,7 +104,7 @@ impl TestServer {
                 room_name
             ))
         } else {
-            for track in &room.tracks {
+            for track in &room.video_tracks {
                 client_room
                     .0
                     .lock()
@@ -182,7 +182,7 @@ impl TestServer {
             frames_rx: local_track.frames_rx.clone(),
         });
 
-        room.tracks.push(track.clone());
+        room.video_tracks.push(track.clone());
 
         for (id, client_room) in &room.client_rooms {
             if *id != identity {
@@ -199,6 +199,43 @@ impl TestServer {
         Ok(())
     }
 
+    async fn publish_audio_track(
+        &self,
+        token: String,
+        _local_track: &LocalAudioTrack,
+    ) -> Result<()> {
+        self.background.simulate_random_delay().await;
+        let claims = live_kit_server::token::validate(&token, &self.secret_key)?;
+        let identity = claims.sub.unwrap().to_string();
+        let room_name = claims.video.room.unwrap();
+
+        let mut server_rooms = self.rooms.lock();
+        let room = server_rooms
+            .get_mut(&*room_name)
+            .ok_or_else(|| anyhow!("room {} does not exist", room_name))?;
+
+        let track = Arc::new(RemoteAudioTrack {
+            sid: nanoid::nanoid!(17),
+            publisher_id: identity.clone(),
+        });
+
+        room.audio_tracks.push(track.clone());
+
+        for (id, client_room) in &room.client_rooms {
+            if *id != identity {
+                let _ = client_room
+                    .0
+                    .lock()
+                    .audio_track_updates
+                    .0
+                    .try_broadcast(RemoteAudioTrackUpdate::Subscribed(track.clone()))
+                    .unwrap();
+            }
+        }
+
+        Ok(())
+    }
+
     fn video_tracks(&self, token: String) -> Result<Vec<Arc<RemoteVideoTrack>>> {
         let claims = live_kit_server::token::validate(&token, &self.secret_key)?;
         let room_name = claims.video.room.unwrap();
@@ -207,18 +244,26 @@ impl TestServer {
         let room = server_rooms
             .get_mut(&*room_name)
             .ok_or_else(|| anyhow!("room {} does not exist", room_name))?;
-        Ok(room.tracks.clone())
+        Ok(room.video_tracks.clone())
     }
 
-    async fn publish_audio_track(&self, _token: String, _local_track: &LocalAudioTrack) -> Result<()> {
-        todo!()
+    fn audio_tracks(&self, token: String) -> Result<Vec<Arc<RemoteAudioTrack>>> {
+        let claims = live_kit_server::token::validate(&token, &self.secret_key)?;
+        let room_name = claims.video.room.unwrap();
+
+        let mut server_rooms = self.rooms.lock();
+        let room = server_rooms
+            .get_mut(&*room_name)
+            .ok_or_else(|| anyhow!("room {} does not exist", room_name))?;
+        Ok(room.audio_tracks.clone())
     }
 }
 
 #[derive(Default)]
 struct TestServerRoom {
     client_rooms: HashMap<Sid, Arc<Room>>,
-    tracks: Vec<Arc<RemoteVideoTrack>>,
+    video_tracks: Vec<Arc<RemoteVideoTrack>>,
+    audio_tracks: Vec<Arc<RemoteAudioTrack>>,
 }
 
 impl TestServerRoom {}
@@ -350,10 +395,19 @@ impl Room {
         }
     }
 
-    pub fn unpublish_track(&self, _: LocalTrackPublication) {}
+    pub fn unpublish_track(&self, _publication: LocalTrackPublication) {}
 
-    pub fn remote_audio_tracks(&self, _publisher_id: &str) -> Vec<Arc<RemoteAudioTrack>> {
-       todo!()
+    pub fn remote_audio_tracks(&self, publisher_id: &str) -> Vec<Arc<RemoteAudioTrack>> {
+        if !self.is_connected() {
+            return Vec::new();
+        }
+
+        self.test_server()
+            .audio_tracks(self.token())
+            .unwrap()
+            .into_iter()
+            .filter(|track| track.publisher_id() == publisher_id)
+            .collect()
     }
 
     pub fn remote_video_tracks(&self, publisher_id: &str) -> Vec<Arc<RemoteVideoTrack>> {
@@ -476,10 +530,6 @@ impl RemoteAudioTrack {
     pub fn publisher_id(&self) -> &str {
         &self.publisher_id
     }
-
-    pub fn start(&self)  -> futures::channel::oneshot::Receiver<bool> {
-        todo!();
-    }
 }
 
 #[derive(Clone)]