Translate inventory parity tests
This commit is contained in:
302
tests/compat/tests/inventory_ais_semantics.rs
Normal file
302
tests/compat/tests/inventory_ais_semantics.rs
Normal file
@@ -0,0 +1,302 @@
|
||||
// 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"
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user