1 use wasm_bindgen::{prelude::*, JsCast};
2 use wasm_bindgen_futures::JsFuture;
3 use wasm_bindgen_test::*;
4 
5 use web_sys::{
6     RtcPeerConnection, RtcRtpTransceiver, RtcRtpTransceiverDirection, RtcRtpTransceiverInit,
7     RtcSessionDescriptionInit,
8 };
9 
10 #[wasm_bindgen(
11     inline_js = "export function is_unified_avail() { return Object.keys(RTCRtpTransceiver.prototype).indexOf('currentDirection')>-1; }"
12 )]
13 extern "C" {
14     /// Available in FF since forever, in Chrome since 72, in Safari since 12.1
is_unified_avail() -> bool15     fn is_unified_avail() -> bool;
16 }
17 
18 #[wasm_bindgen_test]
rtc_rtp_transceiver_direction()19 async fn rtc_rtp_transceiver_direction() {
20     if !is_unified_avail() {
21         return;
22     }
23 
24     let mut tr_init: RtcRtpTransceiverInit = RtcRtpTransceiverInit::new();
25 
26     let pc1: RtcPeerConnection = RtcPeerConnection::new().unwrap();
27 
28     let tr1: RtcRtpTransceiver = pc1.add_transceiver_with_str_and_init(
29         "audio",
30         tr_init.direction(RtcRtpTransceiverDirection::Sendonly),
31     );
32     assert_eq!(tr1.direction(), RtcRtpTransceiverDirection::Sendonly);
33     assert_eq!(tr1.current_direction(), None);
34 
35     let pc2: RtcPeerConnection = RtcPeerConnection::new().unwrap();
36 
37     let (_, p2) = exchange_sdps(pc1, pc2).await;
38     assert_eq!(tr1.direction(), RtcRtpTransceiverDirection::Sendonly);
39     assert_eq!(
40         tr1.current_direction(),
41         Some(RtcRtpTransceiverDirection::Sendonly)
42     );
43 
44     let tr2: RtcRtpTransceiver = js_sys::try_iter(&p2.get_transceivers())
45         .unwrap()
46         .unwrap()
47         .next()
48         .unwrap()
49         .unwrap()
50         .unchecked_into();
51 
52     assert_eq!(tr2.direction(), RtcRtpTransceiverDirection::Recvonly);
53     assert_eq!(
54         tr2.current_direction(),
55         Some(RtcRtpTransceiverDirection::Recvonly)
56     );
57 }
58 
exchange_sdps( p1: RtcPeerConnection, p2: RtcPeerConnection, ) -> (RtcPeerConnection, RtcPeerConnection)59 async fn exchange_sdps(
60     p1: RtcPeerConnection,
61     p2: RtcPeerConnection,
62 ) -> (RtcPeerConnection, RtcPeerConnection) {
63     let offer = JsFuture::from(p1.create_offer()).await.unwrap();
64     let offer = offer.unchecked_into::<RtcSessionDescriptionInit>();
65     JsFuture::from(p1.set_local_description(&offer))
66         .await
67         .unwrap();
68     JsFuture::from(p2.set_remote_description(&offer))
69         .await
70         .unwrap();
71     let answer = JsFuture::from(p2.create_answer()).await.unwrap();
72     let answer = answer.unchecked_into::<RtcSessionDescriptionInit>();
73     JsFuture::from(p2.set_local_description(&answer))
74         .await
75         .unwrap();
76     JsFuture::from(p1.set_remote_description(&answer))
77         .await
78         .unwrap();
79     (p1, p2)
80 }
81