@@ -1279,6 +1279,54 @@ mod tests {
12791279 assert ! ( limited_producer. publish_only( & [ "other/path" . into( ) ] ) . is_none( ) ) ;
12801280 }
12811281
1282+ // Regression test for https://github.com/moq-dev/moq/issues/910
1283+ // with_root panics when String has trailing slash (AsPath for String skips normalization)
1284+ #[ tokio:: test]
1285+ async fn test_with_root_trailing_slash_consumer ( ) {
1286+ let origin = Origin :: produce ( ) ;
1287+
1288+ // Use an owned String so the trailing slash is NOT normalized away.
1289+ let prefix = "some_prefix/" . to_string ( ) ;
1290+ let mut consumer = origin. consume ( ) . with_root ( prefix) . unwrap ( ) ;
1291+
1292+ let b = origin. create_broadcast ( "some_prefix/test" ) . unwrap ( ) ;
1293+ consumer. assert_next ( "test" , & b. consume ( ) ) ;
1294+ }
1295+
1296+ // Same issue but for the producer side of with_root
1297+ #[ tokio:: test]
1298+ async fn test_with_root_trailing_slash_producer ( ) {
1299+ let origin = Origin :: produce ( ) ;
1300+
1301+ // Use an owned String so the trailing slash is NOT normalized away.
1302+ let prefix = "some_prefix/" . to_string ( ) ;
1303+ let rooted = origin. with_root ( prefix) . unwrap ( ) ;
1304+
1305+ let b = rooted. create_broadcast ( "test" ) . unwrap ( ) ;
1306+
1307+ let mut consumer = rooted. consume ( ) ;
1308+ consumer. assert_next ( "test" , & b. consume ( ) ) ;
1309+ }
1310+
1311+ // Verify unannounce also doesn't panic with trailing slash
1312+ #[ tokio:: test]
1313+ async fn test_with_root_trailing_slash_unannounce ( ) {
1314+ let origin = Origin :: produce ( ) ;
1315+
1316+ let prefix = "some_prefix/" . to_string ( ) ;
1317+ let mut consumer = origin. consume ( ) . with_root ( prefix) . unwrap ( ) ;
1318+
1319+ let b = origin. create_broadcast ( "some_prefix/test" ) . unwrap ( ) ;
1320+ consumer. assert_next ( "test" , & b. consume ( ) ) ;
1321+
1322+ // Drop the broadcast producer to trigger unannounce
1323+ drop ( b) ;
1324+ tokio:: time:: sleep ( tokio:: time:: Duration :: from_millis ( 1 ) ) . await ;
1325+
1326+ // unannounce also calls strip_prefix(&self.root).unwrap()
1327+ consumer. assert_next_none ( "test" ) ;
1328+ }
1329+
12821330 #[ tokio:: test]
12831331 async fn test_select_maintains_access_with_wider_prefix ( ) {
12841332 let origin = Origin :: produce ( ) ;
0 commit comments