Buttplug sex toy control library
at dev 351 lines 14 kB view raw
1// Buttplug Rust Source Code File - See https://buttplug.io for more info. 2// 3// Copyright 2016-2024 Nonpolynomial Labs LLC. All rights reserved. 4// 5// Licensed under the BSD 3-Clause license. See LICENSE file in the project root 6// for full license information. 7 8mod util; 9use std::time::Duration; 10 11use buttplug_server_device_config::Endpoint; 12pub use util::test_device_manager::check_test_recv_value; 13 14use buttplug_core::message::{ 15 StartScanningV0, 16 serializer::{ButtplugMessageSerializer, ButtplugSerializedMessage}, 17}; 18use buttplug_server::{ 19 ButtplugServerBuilder, 20 device::hardware::{HardwareCommand, HardwareWriteCmd}, 21 message::{ButtplugClientMessageVariant, serializer::ButtplugServerJSONSerializer}, 22}; 23use futures::{StreamExt, pin_mut}; 24use util::test_server_with_device; 25use uuid::Uuid; 26 27#[tokio::test] 28async fn test_version0_connection() { 29 let server = ButtplugServerBuilder::default().finish().unwrap(); 30 let serializer = ButtplugServerJSONSerializer::default(); 31 let rsi = r#"[{"RequestServerInfo":{"Id": 1, "ClientName": "Test Client"}}]"#; 32 let output = serializer 33 .deserialize(&rsi.to_owned().into()) 34 .expect("Test, assuming infallible."); 35 let incoming = server 36 .parse_message(output[0].clone()) 37 .await 38 .expect("Test, assuming infallible."); 39 let incoming_json = serializer.serialize(&vec![incoming]); 40 assert_eq!( 41 incoming_json, 42 r#"[{"ServerInfo":{"Id":1,"MajorVersion":0,"MinorVersion":0,"BuildVersion":0,"MessageVersion":0,"MaxPingTime":0,"ServerName":"Buttplug Server"}}]"#.to_owned().into(), 43 ); 44} 45 46#[tokio::test] 47async fn test_version2_connection() { 48 let server = ButtplugServerBuilder::default().finish().unwrap(); 49 let serializer = ButtplugServerJSONSerializer::default(); 50 let rsi = 51 r#"[{"RequestServerInfo":{"Id": 1, "ClientName": "Test Client", "MessageVersion": 2}}]"#; 52 let output = serializer 53 .deserialize(&rsi.to_owned().into()) 54 .expect("Test, assuming infallible."); 55 let incoming = server 56 .parse_message(output[0].clone()) 57 .await 58 .expect("Test, assuming infallible."); 59 let incoming_json = serializer.serialize(&vec![incoming]); 60 assert_eq!( 61 incoming_json, 62 r#"[{"ServerInfo":{"Id":1,"MessageVersion":2,"MaxPingTime":0,"ServerName":"Buttplug Server"}}]"#.to_owned().into(), 63 ); 64} 65 66#[tokio::test] 67async fn test_version0_device_added_device_list() { 68 let (server, _) = test_server_with_device("Massage Demo"); 69 let recv = server.event_stream(); 70 pin_mut!(recv); 71 let serializer = ButtplugServerJSONSerializer::default(); 72 let rsi = r#"[{"RequestServerInfo":{"Id": 1, "ClientName": "Test Client"}}]"#; 73 let mut output = server 74 .parse_message( 75 serializer 76 .deserialize(&rsi.to_owned().into()) 77 .expect("Test, assuming infallible.")[0] 78 .clone(), 79 ) 80 .await 81 .expect("Test, assuming infallible."); 82 assert_eq!( 83 serializer.serialize(&vec!(output)), 84 r#"[{"ServerInfo":{"Id":1,"MajorVersion":0,"MinorVersion":0,"BuildVersion":0,"MessageVersion":0,"MaxPingTime":0,"ServerName":"Buttplug Server"}}]"#.to_owned().into(), 85 ); 86 // Skip JSON parsing here, we aren't converting versions. 87 let reply = server 88 .parse_message(ButtplugClientMessageVariant::V0( 89 StartScanningV0::default().into(), 90 )) 91 .await; 92 assert!(reply.is_ok(), "Should get back ok: {:?}", reply); 93 // Check that we got an event back about scanning finishing. 94 let mut msg = recv.next().await.expect("Test, assuming infallible."); 95 // We should receive ScanningFinished and DeviceAdded, but the order may change. 96 let possible_messages: Vec<ButtplugSerializedMessage> = vec![r#"[{"ScanningFinished":{"Id":0}}]"#.to_owned().into(), r#"[{"DeviceAdded":{"Id":0,"DeviceIndex":0,"DeviceName":"Aneros Vivi","DeviceMessages":["SingleMotorVibrateCmd","StopDeviceCmd"]}}]"#.to_owned().into()]; 97 assert!(possible_messages.contains(&serializer.serialize(&vec!(msg)))); 98 msg = recv.next().await.expect("Test, assuming infallible."); 99 // We should get back an aneros with only SingleMotorVibrateCmd 100 assert!(possible_messages.contains(&serializer.serialize(&vec!(msg)))); 101 let rdl = serializer 102 .deserialize(&ButtplugSerializedMessage::Text( 103 r#"[{"RequestDeviceList": { "Id": 1}}]"#.to_owned(), 104 )) 105 .expect("Test, assuming infallible."); 106 output = server 107 .parse_message(rdl[0].clone()) 108 .await 109 .expect("Test, assuming infallible."); 110 assert_eq!( 111 serializer.serialize(&vec!(output)), 112 r#"[{"DeviceList":{"Id":1,"Devices":[{"DeviceIndex":0,"DeviceName":"Aneros Vivi","DeviceMessages":["SingleMotorVibrateCmd","StopDeviceCmd"]}]}}]"#.to_owned().into() 113 ); 114} 115 116#[tokio::test] 117async fn test_version0_singlemotorvibratecmd() { 118 tracing_subscriber::fmt::init(); 119 let (server, mut device) = test_server_with_device("Massage Demo"); 120 let recv = server.event_stream(); 121 pin_mut!(recv); 122 let serializer = ButtplugServerJSONSerializer::default(); 123 let rsi = r#"[{"RequestServerInfo":{"Id": 1, "ClientName": "Test Client"}}]"#; 124 let output = server 125 .parse_message( 126 serializer 127 .deserialize(&rsi.to_owned().into()) 128 .expect("Test, assuming infallible.")[0] 129 .clone(), 130 ) 131 .await 132 .expect("Test, assuming infallible."); 133 assert_eq!( 134 serializer.serialize(&vec!(output)), 135 r#"[{"ServerInfo":{"Id":1,"MajorVersion":0,"MinorVersion":0,"BuildVersion":0,"MessageVersion":0,"MaxPingTime":0,"ServerName":"Buttplug Server"}}]"#.to_owned().into(), 136 ); 137 // Skip JSON parsing here, we aren't converting versions. 138 let reply = server 139 .parse_message(ButtplugClientMessageVariant::V0( 140 StartScanningV0::default().into(), 141 )) 142 .await; 143 assert!(reply.is_ok(), "Should get back ok: {:?}", reply); 144 // Check that we got an event back about scanning finishing. 145 let mut msg = recv.next().await.expect("Test, assuming infallible."); 146 // We should receive ScanningFinished and DeviceAdded, but the order may change. 147 let possible_messages: Vec<ButtplugSerializedMessage> = vec![r#"[{"ScanningFinished":{"Id":0}}]"#.to_owned().into(), r#"[{"DeviceAdded":{"Id":0,"DeviceIndex":0,"DeviceName":"Aneros Vivi","DeviceMessages":["SingleMotorVibrateCmd","StopDeviceCmd"]}}]"#.to_owned().into()]; 148 assert!(possible_messages.contains(&serializer.serialize(&vec!(msg)))); 149 msg = recv.next().await.expect("Test, assuming infallible."); 150 // We should get back an aneros with only SingleMotorVibrateCmd 151 assert!(possible_messages.contains(&serializer.serialize(&vec!(msg)))); 152 let output2 = server 153 .parse_message( 154 serializer 155 .deserialize( 156 &r#"[{"SingleMotorVibrateCmd": { "Id": 2, "DeviceIndex": 0, "Speed": 0.5}}]"# 157 .to_owned() 158 .into(), 159 ) 160 .expect("Test, assuming infallible.")[0] 161 .clone(), 162 ) 163 .await 164 .expect("Test, assuming infallible."); 165 assert_eq!( 166 serializer.serialize(&vec!(output2)), 167 r#"[{"Ok":{"Id":2}}]"#.to_owned().into() 168 ); 169 check_test_recv_value( 170 &Duration::from_millis(150), 171 &mut device, 172 HardwareCommand::Write(HardwareWriteCmd::new( 173 &[Uuid::nil()], 174 Endpoint::Tx, 175 vec![0xF1, 64], 176 false, 177 )), 178 ) 179 .await; 180} 181 182#[tokio::test] 183async fn test_version1_singlemotorvibratecmd() { 184 let (server, mut device) = test_server_with_device("Massage Demo"); 185 let recv = server.event_stream(); 186 pin_mut!(recv); 187 let serializer = ButtplugServerJSONSerializer::default(); 188 let rsi = 189 r#"[{"RequestServerInfo":{"Id": 1, "ClientName": "Test Client", "MessageVersion": 1}}]"#; 190 let output = server 191 .parse_message( 192 serializer 193 .deserialize(&rsi.to_owned().into()) 194 .expect("Test, assuming infallible.")[0] 195 .clone(), 196 ) 197 .await 198 .expect("Test, assuming infallible."); 199 assert_eq!( 200 serializer.serialize(&vec!(output)), 201 r#"[{"ServerInfo":{"Id":1,"MajorVersion":0,"MinorVersion":0,"BuildVersion":0,"MessageVersion":1,"MaxPingTime":0,"ServerName":"Buttplug Server"}}]"#.to_owned().into(), 202 ); 203 // Skip JSON parsing here, we aren't converting versions. 204 let reply = server 205 .parse_message(ButtplugClientMessageVariant::V1( 206 StartScanningV0::default().into(), 207 )) 208 .await; 209 assert!(reply.is_ok(), "Should get back ok: {:?}", reply); 210 // Check that we got an event back about scanning finishing. 211 let mut msg = recv.next().await.expect("Test, assuming infallible."); 212 let mut smsg = serializer.serialize(&vec![msg]); 213 // We should receive ScanningFinished and DeviceAdded, but the order may change. 214 let possible_messages: Vec<ButtplugSerializedMessage> = vec![r#"[{"ScanningFinished":{"Id":0}}]"#.to_owned().into(), r#"[{"DeviceAdded":{"Id":0,"DeviceIndex":0,"DeviceName":"Aneros Vivi","DeviceMessages":{"VibrateCmd":{"FeatureCount":2},"stop_device_cmd":{},"single_motor_vibrate_cmd":{}}}}]"#.to_owned().into()]; 215 assert!( 216 possible_messages.contains(&smsg), 217 "We should receive ScanningFinished and DeviceAdded, but the order may change. Got {:?}", 218 smsg 219 ); 220 msg = recv.next().await.expect("Test, assuming infallible."); 221 smsg = serializer.serialize(&vec![msg]); 222 // We should get back an aneros with only SingleMotorVibrateCmd 223 assert!( 224 possible_messages.contains(&smsg), 225 "We should receive ScanningFinished and DeviceAdded, but the order may change. Got {:?}", 226 smsg 227 ); 228 let output2 = server 229 .parse_message( 230 serializer 231 .deserialize( 232 &r#"[{"VibrateCmd": { "Id": 2, "DeviceIndex": 0, "Speeds": [{ "Index": 0, "Speed": 0.5 }]}}]"# 233 .to_owned() 234 .into(), 235 ) 236 .expect("Test, assuming infallible.")[0] 237 .clone(), 238 ) 239 .await 240 .expect("Test, assuming infallible."); 241 assert_eq!( 242 serializer.serialize(&vec!(output2)), 243 r#"[{"Ok":{"Id":2}}]"#.to_owned().into() 244 ); 245 check_test_recv_value( 246 &Duration::from_millis(150), 247 &mut device, 248 HardwareCommand::Write(HardwareWriteCmd::new( 249 &[Uuid::nil()], 250 Endpoint::Tx, 251 vec![0xF1, 64], 252 false, 253 )), 254 ) 255 .await; 256} 257 258#[tokio::test] 259async fn test_version0_oscillatoronly() { 260 let (server, mut _device) = test_server_with_device("Xone"); 261 let recv = server.event_stream(); 262 pin_mut!(recv); 263 let serializer = ButtplugServerJSONSerializer::default(); 264 let rsi = r#"[{"RequestServerInfo":{"Id": 1, "ClientName": "Test Client"}}]"#; 265 let output = server 266 .parse_message( 267 serializer 268 .deserialize(&rsi.to_owned().into()) 269 .expect("Test, assuming infallible.")[0] 270 .clone(), 271 ) 272 .await 273 .expect("Test, assuming infallible."); 274 assert_eq!( 275 serializer.serialize(&vec!(output)), 276 r#"[{"ServerInfo":{"Id":1,"MajorVersion":0,"MinorVersion":0,"BuildVersion":0,"MessageVersion":0,"MaxPingTime":0,"ServerName":"Buttplug Server"}}]"#.to_owned().into(), 277 ); 278 // Skip JSON parsing here, we aren't converting versions. 279 let reply = server 280 .parse_message(ButtplugClientMessageVariant::V0( 281 StartScanningV0::default().into(), 282 )) 283 .await; 284 assert!(reply.is_ok(), "Should get back ok: {:?}", reply); 285 // Check that we got an event back about scanning finishing. 286 let mut msg = recv.next().await.expect("Test, assuming infallible."); 287 let mut smsg = serializer.serialize(&vec![msg]); 288 // We should receive ScanningFinished and DeviceAdded, but the order may change. 289 let possible_messages: Vec<ButtplugSerializedMessage> = vec![r#"[{"ScanningFinished":{"Id":0}}]"#.to_owned().into(), r#"[{"DeviceAdded":{"Id":0,"DeviceIndex":0,"DeviceName":"MagicMotion Xone","DeviceMessages":["StopDeviceCmd"]}}]"#.to_owned().into()]; 290 assert!( 291 possible_messages.contains(&smsg), 292 "We should receive ScanningFinished and DeviceAdded, but the order may change. Got {:?}", 293 smsg 294 ); 295 msg = recv.next().await.expect("Test, assuming infallible."); 296 smsg = serializer.serialize(&vec![msg]); 297 // We should get back an MagicMotion Xone with no actuators 298 assert!( 299 possible_messages.contains(&smsg), 300 "We should receive ScanningFinished and DeviceAdded, but the order may change. Got {:?}", 301 smsg 302 ); 303} 304 305#[tokio::test] 306async fn test_version1_oscilatoronly() { 307 let (server, mut _device) = test_server_with_device("Xone"); 308 let recv = server.event_stream(); 309 pin_mut!(recv); 310 let serializer = ButtplugServerJSONSerializer::default(); 311 let rsi = 312 r#"[{"RequestServerInfo":{"Id": 1, "ClientName": "Test Client", "MessageVersion": 1}}]"#; 313 let output = server 314 .parse_message( 315 serializer 316 .deserialize(&rsi.to_owned().into()) 317 .expect("Test, assuming infallible.")[0] 318 .clone(), 319 ) 320 .await 321 .expect("Test, assuming infallible."); 322 assert_eq!( 323 serializer.serialize(&vec!(output)), 324 r#"[{"ServerInfo":{"Id":1,"MajorVersion":0,"MinorVersion":0,"BuildVersion":0,"MessageVersion":1,"MaxPingTime":0,"ServerName":"Buttplug Server"}}]"#.to_owned().into(), 325 ); 326 // Skip JSON parsing here, we aren't converting versions. 327 let reply = server 328 .parse_message(ButtplugClientMessageVariant::V1( 329 StartScanningV0::default().into(), 330 )) 331 .await; 332 assert!(reply.is_ok(), "Should get back ok: {:?}", reply); 333 // Check that we got an event back about scanning finishing. 334 let mut msg = recv.next().await.expect("Test, assuming infallible."); 335 let mut smsg = serializer.serialize(&vec![msg]); 336 // We should receive ScanningFinished and DeviceAdded, but the order may change. 337 let possible_messages: Vec<ButtplugSerializedMessage> = vec![r#"[{"ScanningFinished":{"Id":0}}]"#.to_owned().into(), r#"[{"DeviceAdded":{"Id":0,"DeviceIndex":0,"DeviceName":"MagicMotion Xone","DeviceMessages":{"stop_device_cmd":{}}}}]"#.to_owned().into()]; 338 assert!( 339 possible_messages.contains(&smsg), 340 "We should receive ScanningFinished and DeviceAdded, but the order may change. Got {:?}", 341 smsg 342 ); 343 msg = recv.next().await.expect("Test, assuming infallible."); 344 smsg = serializer.serialize(&vec![msg]); 345 // We should get back an MagicMotion Xone with no actuators 346 assert!( 347 possible_messages.contains(&smsg), 348 "We should receive ScanningFinished and DeviceAdded, but the order may change. Got {:?}", 349 smsg 350 ); 351}