@@ -2235,3 +2235,88 @@ async fn test_webxdc_info_app_sender() -> Result<()> {
22352235
22362236 Ok ( ( ) )
22372237}
2238+
2239+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
2240+ async fn test_webxdc_broadcast_channel_updates ( ) -> Result < ( ) > {
2241+ let mut tcm = TestContextManager :: new ( ) ;
2242+ let alice = & tcm. alice ( ) . await ;
2243+ let bob = & tcm. bob ( ) . await ;
2244+ let claire = & tcm. charlie ( ) . await ;
2245+
2246+ // Alice creates a broadcast channel
2247+ let alice_broadcast_id = create_broadcast ( alice, "Channel" . to_string ( ) ) . await ?;
2248+
2249+ // Bob and Claire join via securejoin QR
2250+ let qr = get_securejoin_qr ( alice, Some ( alice_broadcast_id) ) . await ?;
2251+ tcm. exec_securejoin_qr ( bob, alice, & qr) . await ;
2252+ let qr = get_securejoin_qr ( alice, Some ( alice_broadcast_id) ) . await ?;
2253+ tcm. exec_securejoin_qr ( claire, alice, & qr) . await ;
2254+
2255+ // Alice sends a webxdc app to the channel
2256+ let alice_instance = send_webxdc_instance ( alice, alice_broadcast_id) . await ?;
2257+ let sent_instance = alice. pop_sent_msg ( ) . await ;
2258+
2259+ // Bob and Claire receive the webxdc app
2260+ let bob_instance = bob. recv_msg ( & sent_instance) . await ;
2261+ let claire_instance = claire. recv_msg ( & sent_instance) . await ;
2262+ assert_eq ! ( bob_instance. viewtype, Viewtype :: Webxdc ) ;
2263+ assert_eq ! ( claire_instance. viewtype, Viewtype :: Webxdc ) ;
2264+
2265+ // Verify broadcast context flags
2266+ assert ! ( alice_instance. get_webxdc_info( alice) . await ?. is_app_sender) ;
2267+ assert ! ( alice_instance. get_webxdc_info( alice) . await ?. is_broadcast) ;
2268+ assert ! ( !bob_instance. get_webxdc_info( bob) . await ?. is_app_sender) ;
2269+ assert ! ( bob_instance. get_webxdc_info( bob) . await ?. is_broadcast) ;
2270+ assert ! ( !claire_instance. get_webxdc_info( claire) . await ?. is_app_sender) ;
2271+ assert ! ( claire_instance. get_webxdc_info( claire) . await ?. is_broadcast) ;
2272+
2273+ // Alice sends a webxdc update, Bob and Claire both receive it
2274+ alice
2275+ . send_webxdc_status_update ( alice_instance. id , r#"{"payload": "hello from alice"}"# )
2276+ . await ?;
2277+ alice. flush_status_updates ( ) . await ?;
2278+ let sent_alice_update = alice. pop_sent_msg ( ) . await ;
2279+
2280+ bob. recv_msg_trash ( & sent_alice_update) . await ;
2281+ claire. recv_msg_trash ( & sent_alice_update) . await ;
2282+
2283+ assert_eq ! (
2284+ bob. get_webxdc_status_updates( bob_instance. id, StatusUpdateSerial ( 0 ) )
2285+ . await ?,
2286+ r#"[{"payload":"hello from alice","serial":1,"max_serial":1}]"#
2287+ ) ;
2288+ assert_eq ! (
2289+ claire
2290+ . get_webxdc_status_updates( claire_instance. id, StatusUpdateSerial ( 0 ) )
2291+ . await ?,
2292+ r#"[{"payload":"hello from alice","serial":1,"max_serial":1}]"#
2293+ ) ;
2294+
2295+ // Bob sends a webxdc update — Alice should receive it, but Claire should NOT
2296+ bob. send_webxdc_status_update ( bob_instance. id , r#"{"payload": "hello from bob"}"# )
2297+ . await ?;
2298+ bob. flush_status_updates ( ) . await ?;
2299+
2300+ let sent_bob_update = bob. pop_sent_msg ( ) . await ;
2301+
2302+ // Alice receives Bob's update
2303+ alice. recv_msg_trash ( & sent_bob_update) . await ;
2304+ assert_eq ! (
2305+ alice
2306+ . get_webxdc_status_updates( alice_instance. id, StatusUpdateSerial ( 0 ) )
2307+ . await ?,
2308+ r#"[{"payload":"hello from alice","serial":1,"max_serial":2},
2309+ {"payload":"hello from bob","serial":2,"max_serial":2}]"#
2310+ ) ;
2311+
2312+ // Claire does NOT receive Bob's update;
2313+ // in a broadcast channel, subscriber updates are sent back to the owner only
2314+ assert_eq ! (
2315+ claire
2316+ . get_webxdc_status_updates( claire_instance. id, StatusUpdateSerial ( 0 ) )
2317+ . await ?,
2318+ r#"[{"payload":"hello from alice","serial":1,"max_serial":1}]"#
2319+ ) ;
2320+
2321+ Ok ( ( ) )
2322+ }
0 commit comments