303 lines
11 KiB
Rust
303 lines
11 KiB
Rust
// Exact Rust translations of LibreMetaverse.Tests/ConstructorNullArgumentTests.cs and
|
|
// LibreMetaverse.Tests/InventoryAISClientTests.cs inventory-owned cases.
|
|
// Source SHA-256: 28deea0bf4d9353a2424842c6184abab8fe82746ceb12e093912728a247f21bc
|
|
// Source SHA-256: 6de18630ff0da2612721a9d4e28b5fdee5845c8d9477d322a8d608508762e1ff
|
|
|
|
use libremetaverse::{Error, GridClient, InventoryAISClient};
|
|
use libremetaverse_compat_tests::block_on;
|
|
use libremetaverse_structured_data::OSD;
|
|
use libremetaverse_types::{AssetType, InventoryType, SaleType, UUID};
|
|
use std::collections::HashMap;
|
|
use std::future::Future;
|
|
use std::sync::Arc;
|
|
use std::task::{Context, Poll, Waker};
|
|
use std::time::{SystemTime, UNIX_EPOCH};
|
|
|
|
fn uuid() -> UUID {
|
|
UUID::random().expect("UUID Random")
|
|
}
|
|
|
|
fn now_seconds() -> i32 {
|
|
i32::try_from(
|
|
SystemTime::now()
|
|
.duration_since(UNIX_EPOCH)
|
|
.expect("clock before Unix epoch")
|
|
.as_secs(),
|
|
)
|
|
.expect("current Unix time fits the C# Int32 fixture")
|
|
}
|
|
|
|
fn map(entries: impl IntoIterator<Item = (&'static str, OSD)>) -> OSD {
|
|
OSD::Map(
|
|
entries
|
|
.into_iter()
|
|
.map(|(key, value)| (key.to_owned(), value))
|
|
.collect(),
|
|
)
|
|
}
|
|
|
|
fn permissions(creator: UUID, last_owner: UUID, owner: Option<UUID>) -> OSD {
|
|
map([
|
|
("creator_id", OSD::UUID(creator)),
|
|
("last_owner_id", OSD::UUID(last_owner)),
|
|
("owner_id", OSD::UUID(owner.unwrap_or(last_owner))),
|
|
("base_mask", OSD::Integer(0)),
|
|
("everyone_mask", OSD::Integer(0)),
|
|
("group_mask", OSD::Integer(0)),
|
|
("next_owner_mask", OSD::Integer(0)),
|
|
("owner_mask", OSD::Integer(0)),
|
|
("is_owner_group", OSD::Boolean(false)),
|
|
("group_id", OSD::UUID(UUID::zero())),
|
|
])
|
|
}
|
|
|
|
fn sale_info() -> OSD {
|
|
map([
|
|
("sale_price", OSD::Integer(0)),
|
|
("sale_type", OSD::Integer(SaleType::Not as i32)),
|
|
])
|
|
}
|
|
|
|
fn concrete_item(item_id: UUID, parent_id: UUID, agent_id: UUID, name: &str) -> OSD {
|
|
map([
|
|
("item_id", OSD::UUID(item_id)),
|
|
("parent_id", OSD::UUID(parent_id)),
|
|
("name", OSD::String(name.into())),
|
|
("desc", OSD::String("desc".into())),
|
|
("agent_id", OSD::UUID(agent_id)),
|
|
("inv_type", OSD::Integer(i32::from(InventoryType::OBJECT.0))),
|
|
("type", OSD::Integer(AssetType::Object as i32)),
|
|
("created_at", OSD::Integer(now_seconds())),
|
|
("permissions", permissions(uuid(), uuid(), Some(agent_id))),
|
|
("sale_info", sale_info()),
|
|
])
|
|
}
|
|
|
|
fn link_item(
|
|
item_id: UUID,
|
|
parent_id: UUID,
|
|
agent_id: UUID,
|
|
linked_id: UUID,
|
|
name: &str,
|
|
asset_type: AssetType,
|
|
) -> OSD {
|
|
map([
|
|
("item_id", OSD::UUID(item_id)),
|
|
("parent_id", OSD::UUID(parent_id)),
|
|
("name", OSD::String(name.into())),
|
|
("desc", OSD::String("desc".into())),
|
|
("agent_id", OSD::UUID(agent_id)),
|
|
("linked_id", OSD::UUID(linked_id)),
|
|
(
|
|
"inv_type",
|
|
OSD::Integer(i32::from(InventoryType::TEXTURE.0)),
|
|
),
|
|
("type", OSD::Integer(asset_type as i32)),
|
|
("created_at", OSD::Integer(now_seconds())),
|
|
("permissions", permissions(uuid(), uuid(), None)),
|
|
("sale_info", sale_info()),
|
|
])
|
|
}
|
|
|
|
fn section(name: &'static str, value: OSD, embedded: bool) -> OSD {
|
|
let content = map([(name, value)]);
|
|
if embedded {
|
|
map([("_embedded", content)])
|
|
} else {
|
|
content
|
|
}
|
|
}
|
|
|
|
fn numbered(value: OSD) -> OSD {
|
|
OSD::Map(HashMap::from([("0".into(), value)]))
|
|
}
|
|
|
|
fn client() -> InventoryAISClient {
|
|
let grid = GridClient::new().expect("GridClient constructor");
|
|
InventoryAISClient::new(Some(Arc::new(grid))).expect("InventoryAISClient constructor")
|
|
}
|
|
|
|
// parity-case: LibreMetaverse.Tests/ConstructorNullArgumentTests.cs::ConstructorNullArgumentTests.InventoryAISClient_Null_Throws::test ac92e375efc45c50b37e6c82aea372d605fceb470ce053a025e05ff47a5c7121 translated
|
|
#[test]
|
|
fn inventory_ais_client_null_throws() {
|
|
match InventoryAISClient::new(None) {
|
|
Err(error) => assert_eq!(error, Error::ArgumentNull),
|
|
Ok(_) => panic!("expected ArgumentNull for client"),
|
|
}
|
|
}
|
|
|
|
// parity-case: LibreMetaverse.Tests/InventoryAISClientTests.cs::InventoryAISClientTests.ParseLinksFromEmbedded_ObjectAsset_ResultsInAttachmentInventoryTypeAndParsesFields::test 3ae365ed34f12d036dcd44c94f8568d163cfeec2a58b4975975b77b418770131 translated
|
|
#[test]
|
|
fn parse_links_object_asset_results_in_attachment_type_and_parses_fields() {
|
|
let item_id = uuid();
|
|
let parent_id = uuid();
|
|
let agent_id = uuid();
|
|
let linked_id = uuid();
|
|
let response = section(
|
|
"links",
|
|
numbered(link_item(
|
|
item_id,
|
|
parent_id,
|
|
agent_id,
|
|
linked_id,
|
|
"TestObject",
|
|
AssetType::Object,
|
|
)),
|
|
true,
|
|
);
|
|
let result = client()
|
|
.parse_links_from_embedded(Some(response))
|
|
.expect("ParseLinksFromEmbedded");
|
|
assert_eq!(result.len(), 1);
|
|
let parsed = &result[0];
|
|
assert_eq!(parsed.base.name(), "TestObject");
|
|
assert_eq!(parsed.base.parent_uuid(), parent_id);
|
|
assert_eq!(parsed.asset_uuid(), linked_id);
|
|
assert_eq!(parsed.base.owner_id(), agent_id);
|
|
assert_ne!(parsed.creation_date(), UNIX_EPOCH);
|
|
}
|
|
|
|
// parity-case: LibreMetaverse.Tests/InventoryAISClientTests.cs::InventoryAISClientTests.ParseItemsFromEmbedded_ItemsKey_ParsesConcreteItems::test d9e7c64106639071e1ec6ada7346bfa050a31183becaac79efefcd4755fe2855 translated
|
|
#[test]
|
|
fn parse_items_items_key_parses_concrete_items() {
|
|
let item_id = uuid();
|
|
let parent_id = uuid();
|
|
let agent_id = uuid();
|
|
let response = section(
|
|
"items",
|
|
numbered(concrete_item(item_id, parent_id, agent_id, "ConcreteItem")),
|
|
true,
|
|
);
|
|
let result = client()
|
|
.parse_items_from_embedded(Some(response))
|
|
.expect("ParseItemsFromEmbedded");
|
|
assert_eq!(result.len(), 1);
|
|
let parsed = &result[0];
|
|
assert_eq!(parsed.base.name(), "ConcreteItem");
|
|
assert_eq!(parsed.base.parent_uuid(), parent_id);
|
|
assert_eq!(parsed.base.owner_id(), agent_id);
|
|
assert_ne!(parsed.creation_date(), UNIX_EPOCH);
|
|
}
|
|
|
|
// parity-case: LibreMetaverse.Tests/InventoryAISClientTests.cs::InventoryAISClientTests.ParseLinksFromEmbedded_MeshAsset_TreatedAsAttachment::test f807110d577c654128dd8d42e618c610c260c4f3367cf2795776564409f876a2 translated
|
|
#[test]
|
|
fn parse_links_mesh_asset_treated_as_attachment() {
|
|
let item_id = uuid();
|
|
let parent_id = uuid();
|
|
let agent_id = uuid();
|
|
let linked_id = uuid();
|
|
let response = section(
|
|
"links",
|
|
numbered(link_item(
|
|
item_id,
|
|
parent_id,
|
|
agent_id,
|
|
linked_id,
|
|
"MeshLink",
|
|
AssetType::Mesh,
|
|
)),
|
|
false,
|
|
);
|
|
let result = client()
|
|
.parse_links_from_embedded(Some(response))
|
|
.expect("ParseLinksFromEmbedded");
|
|
assert_eq!(result.len(), 1);
|
|
let parsed = &result[0];
|
|
assert_eq!(parsed.base.name(), "MeshLink");
|
|
assert_eq!(parsed.base.parent_uuid(), parent_id);
|
|
assert_eq!(parsed.asset_uuid(), linked_id);
|
|
}
|
|
|
|
// parity-case: LibreMetaverse.Tests/InventoryAISClientTests.cs::InventoryAISClientTests.ParseItemsFromEmbedded_TopLevelItemsKey_WorksWithoutEmbedded::test 9c8f2090d59ff5e75e75381a7283c501cadd56e591991cdead23c504738a0a6d translated
|
|
#[test]
|
|
fn parse_items_top_level_items_key_works_without_embedded() {
|
|
let response = section(
|
|
"items",
|
|
numbered(concrete_item(uuid(), uuid(), uuid(), "TopLevelItem")),
|
|
false,
|
|
);
|
|
let result = client()
|
|
.parse_items_from_embedded(Some(response))
|
|
.expect("ParseItemsFromEmbedded");
|
|
assert_eq!(result.len(), 1);
|
|
assert_eq!(result[0].base.name(), "TopLevelItem");
|
|
}
|
|
|
|
// parity-case: LibreMetaverse.Tests/InventoryAISClientTests.cs::InventoryAISClientTests.ParseLinksFromEmbedded_TopLevelLinksKey_WorksWithoutEmbedded::test 29afd2bd6a554959d6cfa99b632672d56bbb5bcad2ccbaf8caf4773a514f5d79 translated
|
|
#[test]
|
|
fn parse_links_top_level_links_key_works_without_embedded() {
|
|
let response = section(
|
|
"links",
|
|
numbered(link_item(
|
|
uuid(),
|
|
uuid(),
|
|
uuid(),
|
|
uuid(),
|
|
"TopLevelLink",
|
|
AssetType::Object,
|
|
)),
|
|
false,
|
|
);
|
|
let result = client()
|
|
.parse_links_from_embedded(Some(response))
|
|
.expect("ParseLinksFromEmbedded");
|
|
assert_eq!(result.len(), 1);
|
|
assert_eq!(result[0].base.name(), "TopLevelLink");
|
|
}
|
|
|
|
// parity-case: LibreMetaverse.Tests/InventoryAISClientTests.cs::InventoryAISClientTests.ParseItemsFromEmbedded_NullOrEmpty_ReturnsEmptyList::test 198fb619bbf396a4b1a7b4b85b7fba8808ae127e2575b2b84d21f01a2bdbc445 translated
|
|
#[test]
|
|
fn parse_items_null_or_empty_returns_empty_list() {
|
|
let ais = client();
|
|
assert!(
|
|
ais.parse_items_from_embedded(None)
|
|
.expect("ParseItemsFromEmbedded null")
|
|
.is_empty()
|
|
);
|
|
assert!(
|
|
ais.parse_items_from_embedded(Some(OSD::Map(HashMap::new())))
|
|
.expect("ParseItemsFromEmbedded empty")
|
|
.is_empty()
|
|
);
|
|
}
|
|
|
|
// parity-case: LibreMetaverse.Tests/InventoryAISClientTests.cs::InventoryAISClientTests.ParseEmbedded_CombinesItemsAndLinks::test f2ebf4638c9aef3c846dc182d97d80c95118799428cf8c2bba86163e33196846 translated
|
|
#[test]
|
|
fn parse_embedded_combines_items_and_links() {
|
|
let item = concrete_item(uuid(), uuid(), uuid(), "I");
|
|
let link = link_item(uuid(), uuid(), uuid(), uuid(), "L", AssetType::Object);
|
|
let response = map([(
|
|
"_embedded",
|
|
map([("items", numbered(item)), ("links", numbered(link))]),
|
|
)]);
|
|
let mut folders = None;
|
|
let mut items = None;
|
|
let mut links = None;
|
|
client()
|
|
.parse_embedded(response, &mut folders, &mut items, &mut links)
|
|
.expect("ParseEmbedded");
|
|
assert_eq!(items.expect("items output").len(), 1);
|
|
assert_eq!(links.expect("links output").len(), 1);
|
|
assert!(folders.is_some(), "folders output must not be null");
|
|
}
|
|
|
|
// parity-case: LibreMetaverse.Tests/InventoryAISClientTests.cs::InventoryAISClientTests.MoveCategoryLinksAsync_AlwaysReturnsFalse::test bebad05897efc0da2f959b4f567faa3ffee950520d13265ecbab1dee978f4886 translated
|
|
#[test]
|
|
fn move_category_links_always_returns_false() {
|
|
let result = block_on(client().move_category_links("outfit".into(), uuid(), None))
|
|
.expect("MoveCategoryLinksAsync");
|
|
assert!(!result, "AIS v3 has no MoveCategoryLinks equivalent");
|
|
}
|
|
|
|
// parity-case: LibreMetaverse.Tests/InventoryAISClientTests.cs::InventoryAISClientTests.MoveCategoryLinksAsync_ReturnsCompletedTask::test f9830b11e6a75c90f8394a5ade56bbd542c140be4c050ba7db6c9ee4d2b7a699 translated
|
|
#[test]
|
|
fn move_category_links_returns_completed_future() {
|
|
let ais = client();
|
|
let mut future = std::pin::pin!(ais.move_category_links("outfit".into(), uuid(), None));
|
|
let mut context = Context::from_waker(Waker::noop());
|
|
assert!(
|
|
matches!(future.as_mut().poll(&mut context), Poll::Ready(Ok(false))),
|
|
"MoveCategoryLinksAsync should be immediately ready with false"
|
|
);
|
|
}
|