196 lines
6.9 KiB
C#
196 lines
6.9 KiB
C#
using System.IO;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
using NeonSprawl.Server.Game.Items;
|
|
using NeonSprawl.Server.Tests;
|
|
using Xunit;
|
|
|
|
namespace NeonSprawl.Server.Tests.Game.Items;
|
|
|
|
public class ItemDefinitionRegistryTests
|
|
{
|
|
private static ItemDefinitionRegistry CreateRegistryFromRows(IReadOnlyDictionary<string, ItemDefRow> byId)
|
|
{
|
|
var catalog = new ItemDefinitionCatalog("/tmp/catalog", byId, catalogJsonFileCount: 1);
|
|
return new ItemDefinitionRegistry(catalog);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryGetDefinition_ShouldReturnTrueAndExpectedMetadata_WhenIdExists()
|
|
{
|
|
// Arrange
|
|
var rows = new Dictionary<string, ItemDefRow>(StringComparer.Ordinal)
|
|
{
|
|
["scrap_metal_bulk"] = new ItemDefRow(
|
|
"scrap_metal_bulk",
|
|
"Scrap Metal (Bulk)",
|
|
"material",
|
|
StackMax: 999,
|
|
InventorySlotKind: "bag",
|
|
Rarity: null,
|
|
BindPolicy: null,
|
|
DurabilityMax: null),
|
|
};
|
|
var registry = CreateRegistryFromRows(rows);
|
|
// Act
|
|
var found = registry.TryGetDefinition("scrap_metal_bulk", out var def);
|
|
// Assert
|
|
Assert.True(found);
|
|
Assert.NotNull(def);
|
|
Assert.Equal("material", def.PrototypeRole);
|
|
Assert.Equal("Scrap Metal (Bulk)", def.DisplayName);
|
|
Assert.Equal(999, def.StackMax);
|
|
Assert.Equal("bag", def.InventorySlotKind);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryGetDefinition_ShouldReturnFalse_WhenItemIdIsNull()
|
|
{
|
|
// Arrange
|
|
var rows = new Dictionary<string, ItemDefRow>(StringComparer.Ordinal)
|
|
{
|
|
["scrap_metal_bulk"] = new ItemDefRow(
|
|
"scrap_metal_bulk",
|
|
"Scrap Metal (Bulk)",
|
|
"material",
|
|
StackMax: 999,
|
|
InventorySlotKind: "bag",
|
|
Rarity: null,
|
|
BindPolicy: null,
|
|
DurabilityMax: null),
|
|
};
|
|
var registry = CreateRegistryFromRows(rows);
|
|
// Act
|
|
var found = registry.TryGetDefinition(null, out var def);
|
|
// Assert
|
|
Assert.False(found);
|
|
Assert.Null(def);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryGetDefinition_ShouldReturnFalse_WhenIdUnknown()
|
|
{
|
|
// Arrange
|
|
var rows = new Dictionary<string, ItemDefRow>(StringComparer.Ordinal)
|
|
{
|
|
["scrap_metal_bulk"] = new ItemDefRow(
|
|
"scrap_metal_bulk",
|
|
"Scrap Metal (Bulk)",
|
|
"material",
|
|
StackMax: 999,
|
|
InventorySlotKind: "bag",
|
|
Rarity: null,
|
|
BindPolicy: null,
|
|
DurabilityMax: null),
|
|
};
|
|
var registry = CreateRegistryFromRows(rows);
|
|
// Act
|
|
var found = registry.TryGetDefinition("not_a_real_item", out var def);
|
|
// Assert
|
|
Assert.False(found);
|
|
Assert.Null(def);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetDefinitionsInIdOrder_ShouldListAllRowsOrderedById_WhenMultipleItems()
|
|
{
|
|
// Arrange
|
|
var rows = new Dictionary<string, ItemDefRow>(StringComparer.Ordinal)
|
|
{
|
|
["survey_drone_kit"] = new ItemDefRow(
|
|
"survey_drone_kit",
|
|
"Survey Drone Kit",
|
|
"utility",
|
|
StackMax: 1,
|
|
InventorySlotKind: "bag",
|
|
Rarity: null,
|
|
BindPolicy: null,
|
|
DurabilityMax: null),
|
|
["scrap_metal_bulk"] = new ItemDefRow(
|
|
"scrap_metal_bulk",
|
|
"Scrap Metal (Bulk)",
|
|
"material",
|
|
StackMax: 999,
|
|
InventorySlotKind: "bag",
|
|
Rarity: null,
|
|
BindPolicy: null,
|
|
DurabilityMax: null),
|
|
["prototype_armor_shell"] = new ItemDefRow(
|
|
"prototype_armor_shell",
|
|
"Prototype Armor Shell",
|
|
"equip_stub",
|
|
StackMax: 1,
|
|
InventorySlotKind: "equipment",
|
|
Rarity: null,
|
|
BindPolicy: null,
|
|
DurabilityMax: null),
|
|
};
|
|
var registry = CreateRegistryFromRows(rows);
|
|
// Act
|
|
var list = registry.GetDefinitionsInIdOrder();
|
|
// Assert
|
|
Assert.Equal(3, list.Count);
|
|
Assert.Equal("prototype_armor_shell", list[0].Id);
|
|
Assert.Equal("scrap_metal_bulk", list[1].Id);
|
|
Assert.Equal("survey_drone_kit", list[2].Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryGetDefinition_ShouldMatchLoaderCatalog_WhenUsingPrototypeFixture()
|
|
{
|
|
// Arrange
|
|
var root = Directory.CreateTempSubdirectory("neon-sprawl-item-registry-loader-");
|
|
try
|
|
{
|
|
var itemsDir = Path.Combine(root.FullName, "content", "items");
|
|
var schemaDir = Path.Combine(root.FullName, "content", "schemas");
|
|
Directory.CreateDirectory(itemsDir);
|
|
Directory.CreateDirectory(schemaDir);
|
|
var schemaPath = Path.Combine(schemaDir, "item-def.schema.json");
|
|
File.Copy(ItemCatalogTestPaths.DiscoverRepoItemDefSchemaPath(), schemaPath, overwrite: true);
|
|
File.Copy(
|
|
Path.Combine(ItemCatalogTestPaths.DiscoverRepoItemsDirectory(), "prototype_items.json"),
|
|
Path.Combine(itemsDir, "prototype_items.json"),
|
|
overwrite: true);
|
|
var loaded = ItemDefinitionCatalogLoader.Load(itemsDir, schemaPath, NullLogger.Instance);
|
|
var registry = new ItemDefinitionRegistry(loaded);
|
|
// Act
|
|
var ok = registry.TryGetDefinition("prototype_armor_shell", out var equipStub);
|
|
// Assert
|
|
Assert.True(ok);
|
|
Assert.NotNull(equipStub);
|
|
Assert.Equal("equip_stub", equipStub.PrototypeRole);
|
|
Assert.Equal("equipment", equipStub.InventorySlotKind);
|
|
Assert.Equal(1, equipStub.StackMax);
|
|
}
|
|
finally
|
|
{
|
|
try
|
|
{
|
|
Directory.Delete(root.FullName, recursive: true);
|
|
}
|
|
catch (IOException)
|
|
{
|
|
// Best-effort: transient lock or race on some hosts; temp dir is unique per run.
|
|
}
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Host_ShouldResolveRegistryFromDi_WhenStartupSucceeds()
|
|
{
|
|
// Arrange
|
|
await using var factory = new InMemoryWebApplicationFactory();
|
|
using var client = factory.CreateClient();
|
|
_ = await client.GetAsync("/health");
|
|
// Act
|
|
var registry = factory.Services.GetRequiredService<IItemDefinitionRegistry>();
|
|
var found = registry.TryGetDefinition("scrap_metal_bulk", out var scrap);
|
|
// Assert
|
|
Assert.True(found);
|
|
Assert.NotNull(scrap);
|
|
Assert.Equal("material", scrap.PrototypeRole);
|
|
Assert.Equal(999, scrap.StackMax);
|
|
}
|
|
}
|