mirror of
https://github.com/JogmansonReal/Radicade.git
synced 2026-10-25 23:18:56 -07:00
98 lines
4.7 KiB
C#
98 lines
4.7 KiB
C#
using RadicadeServer.RecNet.Avatar;
|
|
using Xunit;
|
|
|
|
namespace RadicadeServer.Tests;
|
|
|
|
/// <summary>
|
|
/// The catalog descriptions we hand the client must match the shape its own
|
|
/// AvatarItemWardrobeRuntimeConfig uses. Live RecNet records only ever carry
|
|
/// "guid," (no combination) or "guid,mat1,mat2," (materialised), never empty slots.
|
|
/// An empty slot makes the client log "Browsable avatar item not found" and drop the
|
|
/// item from the avatar, so these tests pin both the rewrite and its no-op cases.
|
|
/// </summary>
|
|
public class AvatarItemDescriptionTests
|
|
{
|
|
[Theory]
|
|
// The legacy "no combination" form loses its empty slots.
|
|
[InlineData("8aa79563-ace1-4ba7-ad0c-f3210a78142f,,,", "8aa79563-ace1-4ba7-ad0c-f3210a78142f,")]
|
|
[InlineData("_OWVy3z6iU-M3-zbQgSLig,,,", "_OWVy3z6iU-M3-zbQgSLig,")]
|
|
// An empty slot in the middle of a material list is dropped, order is preserved.
|
|
[InlineData("d0a9262f-5504-46a7-bb10-7507503db58e,95e4cc30-cb68-473d-a395-feadf5b51512,,0440f08f-ef1d-49d8-942b-523056e8bb45,",
|
|
"d0a9262f-5504-46a7-bb10-7507503db58e,95e4cc30-cb68-473d-a395-feadf5b51512,0440f08f-ef1d-49d8-942b-523056e8bb45,")]
|
|
// Surrounding whitespace is not part of the identifier.
|
|
[InlineData(" 8aa79563-ace1-4ba7-ad0c-f3210a78142f,, ", "8aa79563-ace1-4ba7-ad0c-f3210a78142f,")]
|
|
// Well-formed descriptions are returned byte-for-byte, including the shapes live
|
|
// RecNet writes and the trailing comma the client's own serializer omits.
|
|
[InlineData("8aa79563-ace1-4ba7-ad0c-f3210a78142f,", "8aa79563-ace1-4ba7-ad0c-f3210a78142f,")]
|
|
[InlineData("8aa79563-ace1-4ba7-ad0c-f3210a78142f,95e4cc30-cb68-473d-a395-feadf5b51512,05f0ee6e-c824-470e-9178-5ed576c6fe0c,",
|
|
"8aa79563-ace1-4ba7-ad0c-f3210a78142f,95e4cc30-cb68-473d-a395-feadf5b51512,05f0ee6e-c824-470e-9178-5ed576c6fe0c,")]
|
|
[InlineData("d84993dd-4e15-4481-9450-f88a34cdbc82,FnhttSsCoUCSAW8j-stC5A",
|
|
"d84993dd-4e15-4481-9450-f88a34cdbc82,FnhttSsCoUCSAW8j-stC5A")]
|
|
[InlineData("8aa79563-ace1-4ba7-ad0c-f3210a78142f,95e4cc30-cb68-473d-a395-feadf5b51512,05f0ee6e-c824-470e-9178-5ed576c6fe0c",
|
|
"8aa79563-ace1-4ba7-ad0c-f3210a78142f,95e4cc30-cb68-473d-a395-feadf5b51512,05f0ee6e-c824-470e-9178-5ed576c6fe0c")]
|
|
public void Normalize_ProducesClientShapedDescriptions(string input, string expected)
|
|
{
|
|
Assert.Equal(expected, AvatarItemDescription.Normalize(input));
|
|
}
|
|
|
|
[Fact]
|
|
public void Normalize_IsIdempotent()
|
|
{
|
|
var once = AvatarItemDescription.Normalize("8aa79563-ace1-4ba7-ad0c-f3210a78142f,,,");
|
|
Assert.Equal(once, AvatarItemDescription.Normalize(once));
|
|
}
|
|
|
|
[Fact]
|
|
public void Normalize_LeavesMissingDescriptionsAlone()
|
|
{
|
|
Assert.Equal("", AvatarItemDescription.Normalize(""));
|
|
Assert.Equal("", AvatarItemDescription.Normalize(null));
|
|
Assert.Equal("", AvatarItemDescription.Normalize(" "));
|
|
// A description with no item GUID at all is not something this can repair.
|
|
Assert.Equal(",,,", AvatarItemDescription.Normalize(",,,"));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("8aa79563-ace1-4ba7-ad0c-f3210a78142f,,,", true)]
|
|
[InlineData("8aa79563-ace1-4ba7-ad0c-f3210a78142f,", false)]
|
|
[InlineData("8aa79563-ace1-4ba7-ad0c-f3210a78142f,95e4cc30-cb68-473d-a395-feadf5b51512,", false)]
|
|
[InlineData("", false)]
|
|
[InlineData(null, false)]
|
|
public void HasEmptyMaterialSlot_DetectsOnlyLegacyRows(string? input, bool expected)
|
|
{
|
|
Assert.Equal(expected, AvatarItemDescription.HasEmptyMaterialSlot(input));
|
|
}
|
|
|
|
[Fact]
|
|
public void CatalogParsingRepairsLegacyRows()
|
|
{
|
|
var items = AvatarUnlockCatalog.ParseCatalog("""
|
|
[{"AvatarItemDesc":"8aa79563-ace1-4ba7-ad0c-f3210a78142f,,,","UnlockedLevel":0,"PlatformMask":-1,
|
|
"FriendlyName":"Rec Room Shirt (V-Neck, White)","Rarity":0}]
|
|
""");
|
|
|
|
var item = Assert.Single(items);
|
|
Assert.Equal("8aa79563-ace1-4ba7-ad0c-f3210a78142f,", item.AvatarItemDesc);
|
|
Assert.Equal("Rec Room Shirt (V-Neck, White)", item.FriendlyName);
|
|
}
|
|
|
|
[Fact]
|
|
public void KeepSupportedItemsRepairsLegacyRows()
|
|
{
|
|
var copy = Assert.Single(AvatarUnlockCatalog.KeepSupportedItems(
|
|
[new AvatarItem { AvatarItemDesc = "_qXaNbm4yEeyalo372QbvA,,,", FriendlyName = "Biker Goggles" }]));
|
|
|
|
Assert.Equal("_qXaNbm4yEeyalo372QbvA,", copy.AvatarItemDesc);
|
|
}
|
|
|
|
[Fact]
|
|
public void ShippedCatalogNeverServesEmptyMaterialSlots()
|
|
{
|
|
var catalogJson = File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "Fixtures", "avatar.json"));
|
|
var items = AvatarUnlockCatalog.ParseCatalog(catalogJson);
|
|
|
|
Assert.NotEmpty(items);
|
|
Assert.DoesNotContain(items, item => AvatarItemDescription.HasEmptyMaterialSlot(item.AvatarItemDesc));
|
|
}
|
|
}
|