Files
MetaCrate/tests/compat/tests/social_message_semantics.rs

160 lines
6.8 KiB
Rust

// Exact Rust translations of LibreMetaverse.Tests/OfflineMessagesTests.cs and
// LibreMetaverse.Tests/ProductInfoRequestMessageTests.cs.
// Source SHA-256: ad649e9efb2b60b8a323d3d457be568fda9cc5ecb80b8999f6066d0b7f5a6527
// Source SHA-256: fabdc141e6f616b88d998ceca16f1884d4c3aa6efc5152060e8840a4ef0d6db7
use libremetaverse::messages::linden::{
ProductInfoRequestMessage, ProductInfoRequestMessageProductInfo,
};
use libremetaverse::{GridClient, HttpCapsClient, Simulator};
use libremetaverse_compat_tests::block_on;
use libremetaverse_structured_data::{OSD, OSDMap};
use libremetaverse_types::compat::{HttpMessageHandler, HttpResponse, Uri};
use std::collections::{BTreeMap, HashMap};
use std::sync::{Arc, Mutex};
const CAP: &str = "http://test.invalid/read-offline-msgs";
const SEED: &str = "http://test.invalid/seed";
fn response(body: &str) -> HttpResponse {
HttpResponse {
status_code: 200,
headers: BTreeMap::new(),
content_type: Some("application/json".into()),
body: body.as_bytes().to_vec(),
}
}
fn offline_client(body: &str) -> GridClient {
let body = body.to_owned();
let handler = HttpMessageHandler::new(move |request, _| {
let reply = if request.uri.0 == SEED {
HttpResponse {
status_code: 200,
headers: BTreeMap::new(),
content_type: Some("application/llsd+xml".into()),
body: format!(
"<llsd><map><key>ReadOfflineMsgs</key><uri>{CAP}</uri><key>AcceptFriendship</key><uri>http://test.invalid/accept-friendship</uri><key>AcceptGroupInvite</key><uri>http://test.invalid/accept-group-invite</uri></map></llsd>"
)
.into_bytes(),
}
} else {
response(&body)
};
async move { reply }
});
let mut client = GridClient::new().expect("GridClient constructor");
client.set_http_caps_client(HttpCapsClient::new(handler.clone()).unwrap());
let mut simulator_client = GridClient::new().expect("simulator GridClient constructor");
simulator_client.set_http_caps_client(HttpCapsClient::new(handler).unwrap());
let simulator = Simulator::new(
simulator_client,
"127.0.0.1:13".parse().unwrap(),
0,
None,
None,
)
.expect("Simulator constructor");
simulator
.set_seed_caps(Some(Uri(SEED.into())), Some(true))
.unwrap();
let mut network = client.network();
network.set_current_sim(Some(simulator));
client.set_network(network);
client
}
fn message_json(from_name: &str, text: &str) -> String {
format!(
"{{\"from_agent_id\":\"11111111-1111-1111-1111-111111111111\",\"from_agent_name\":\"{from_name}\",\"to_agent_id\":\"22222222-2222-2222-2222-222222222222\",\"region_id\":\"33333333-3333-3333-3333-333333333333\",\"dialog\":0,\"transaction-id\":\"44444444-4444-4444-4444-444444444444\",\"timestamp\":0,\"message\":\"{text}\",\"local_x\":1.0,\"local_y\":2.0,\"local_z\":3.0}}"
)
}
fn retrieve(body: &str) -> Vec<(String, String)> {
let mut client = offline_client(body);
let received = Arc::new(Mutex::new(Vec::new()));
let captured = Arc::clone(&received);
let agent = client.self_();
let _subscription = agent.subscribe_im(Arc::new(move |args| {
let message = args.im();
captured
.lock()
.unwrap()
.push((message.message, message.from_agent_name));
}));
block_on(agent.retrieve_instant_messages(None)).unwrap();
received.lock().unwrap().clone()
}
fn map(entries: impl IntoIterator<Item = (&'static str, OSD)>) -> OSDMap {
OSDMap::new_with_dictionary(
entries
.into_iter()
.map(|(key, value)| (key.into(), value))
.collect(),
)
.expect("OSDMap dictionary constructor")
}
// parity-case: LibreMetaverse.Tests/OfflineMessagesTests.cs::OfflineMessagesTests.RetrieveInstantMessagesAsync_BareArrayOfArraysResponse_RaisesInstantMessage::test d51f69e0fa1e1e59a5cedec7d60315d1f590848672a9f4f0c5e21d2abff5c372 translated
#[test]
fn retrieve_offline_messages_bare_array_raises_instant_message() {
let received = retrieve(&format!("[[{}]]", message_json("Jim", "hello")));
assert_eq!(received.len(), 1);
assert_eq!(received[0].0, "hello");
assert_eq!(received[0].1, "Jim");
}
// parity-case: LibreMetaverse.Tests/OfflineMessagesTests.cs::OfflineMessagesTests.RetrieveInstantMessagesAsync_MessagesMapResponse_RaisesInstantMessage::test dbce6320d57d12ca5557cfba65257e15be314cde947b20dd21bc386819fcb3ce translated
#[test]
fn retrieve_offline_messages_map_raises_instant_message() {
let received = retrieve(&format!(
"{{\"messages\":[{}]}}",
message_json("Jim", "hello via map")
));
assert_eq!(received.len(), 1);
assert_eq!(received[0].0, "hello via map");
}
// parity-case: LibreMetaverse.Tests/ProductInfoRequestMessageTests.cs::ProductInfoRequestMessageTests.Deserialize_BareArray_ReadsSkuNameDescription::test 5d51fdbb1bec1ff74df59778d214413e78fb650679d36e7c44be92d1b2e3205f translated
#[test]
fn product_info_deserialize_bare_array_reads_fields() {
let product = OSD::Map(HashMap::from([
("sku".into(), OSD::String("023".into())),
("name".into(), OSD::String("Homestead".into())),
(
"description".into(),
OSD::String("A Homestead region".into()),
),
]));
let mut message =
ProductInfoRequestMessage::new().expect("ProductInfoRequestMessage constructor");
message
.deserialize(map([("products", OSD::Array(vec![product]))]))
.unwrap();
assert_eq!(message.products.len(), 1);
assert_eq!(message.products[0].sku, "023");
assert_eq!(message.products[0].name, "Homestead");
assert_eq!(message.products[0].description, "A Homestead region");
}
// parity-case: LibreMetaverse.Tests/ProductInfoRequestMessageTests.cs::ProductInfoRequestMessageTests.SerializeDeserialize_RoundTrips::test 5cb54bed4150cf13f815b223d6b7e35e7427004a12e98c7328c7674b6fe6309b translated
#[test]
fn product_info_serialize_deserialize_round_trips() {
let mut product = ProductInfoRequestMessageProductInfo::new().expect("ProductInfo constructor");
product.sku = "001".into();
product.name = "Full Region".into();
product.description = "A full region".into();
let mut message =
ProductInfoRequestMessage::new().expect("ProductInfoRequestMessage constructor");
message.products.push(product);
let encoded = message.serialize().unwrap();
let mut decoded =
ProductInfoRequestMessage::new().expect("ProductInfoRequestMessage constructor");
decoded.deserialize(encoded).unwrap();
assert_eq!(decoded.products.len(), 1);
assert_eq!(decoded.products[0].sku, "001");
assert_eq!(decoded.products[0].name, "Full Region");
assert_eq!(decoded.products[0].description, "A full region");
}