using NeonSprawl.Server.Game.Contracts; using NeonSprawl.Server.Game.Encounters; using NeonSprawl.Server.Game.Quests; namespace NeonSprawl.Server.Tests.Game.Contracts; public sealed class ContractEconomyValidationTests { [Fact] public void TryValidateTemplate_ShouldReturnTrue_WhenPrototypeFreezeRowAtCaps() { // Arrange var template = PrototypeE7M4ContractCatalogRules.ExpectedTemplateFreeze[ContractPrototypeTestFixtures.TemplateId]; var registries = ContractPrototypeTestFixtures.CreateCatalogRegistries(); // Act var ok = ContractEconomyValidation.TryValidateTemplate( template, registries.EncounterRegistry, registries.ItemRegistry, registries.SkillRegistry, registries.FactionRegistry, out var reasonCode); // Assert Assert.True(ok); Assert.Null(reasonCode); } [Fact] public void TryValidateTemplate_ShouldDenyEconomyCapExceeded_WhenItemQuantityOverBandCap() { // Arrange var prototype = PrototypeE7M4ContractCatalogRules.ExpectedTemplateFreeze[ContractPrototypeTestFixtures.TemplateId]; var overCapTemplate = prototype with { CompletionRewardBundle = new QuestRewardBundleRow( [new RewardGrantRow("scrap_metal_bulk", 11)], prototype.CompletionRewardBundle.SkillXpGrants, prototype.CompletionRewardBundle.ReputationGrants), }; var registries = ContractPrototypeTestFixtures.CreateCatalogRegistries(); // Act var ok = ContractEconomyValidation.TryValidateTemplate( overCapTemplate, registries.EncounterRegistry, registries.ItemRegistry, registries.SkillRegistry, registries.FactionRegistry, out var reasonCode); // Assert Assert.False(ok); Assert.Equal(ContractGeneratorReasonCodes.EconomyCapExceeded, reasonCode); } [Fact] public void TryValidateTemplate_ShouldDenyEconomyCapExceeded_WhenSkillXpOverBandCap() { // Arrange var prototype = PrototypeE7M4ContractCatalogRules.ExpectedTemplateFreeze[ContractPrototypeTestFixtures.TemplateId]; var overCapTemplate = prototype with { CompletionRewardBundle = new QuestRewardBundleRow( prototype.CompletionRewardBundle.ItemGrants, [new QuestSkillXpGrantRow("salvage", 26)], prototype.CompletionRewardBundle.ReputationGrants), }; var registries = ContractPrototypeTestFixtures.CreateCatalogRegistries(); // Act var ok = ContractEconomyValidation.TryValidateTemplate( overCapTemplate, registries.EncounterRegistry, registries.ItemRegistry, registries.SkillRegistry, registries.FactionRegistry, out var reasonCode); // Assert Assert.False(ok); Assert.Equal(ContractGeneratorReasonCodes.EconomyCapExceeded, reasonCode); } [Fact] public void TryValidateTemplate_ShouldDenyInvalidRewardBundle_WhenItemIdUnknown() { // Arrange var prototype = PrototypeE7M4ContractCatalogRules.ExpectedTemplateFreeze[ContractPrototypeTestFixtures.TemplateId]; var unknownItemTemplate = prototype with { CompletionRewardBundle = new QuestRewardBundleRow( [new RewardGrantRow("unknown_item_xyz", 1)], prototype.CompletionRewardBundle.SkillXpGrants, prototype.CompletionRewardBundle.ReputationGrants), }; var registries = ContractPrototypeTestFixtures.CreateCatalogRegistries(); // Act var ok = ContractEconomyValidation.TryValidateTemplate( unknownItemTemplate, registries.EncounterRegistry, registries.ItemRegistry, registries.SkillRegistry, registries.FactionRegistry, out var reasonCode); // Assert Assert.False(ok); Assert.Equal(ContractGeneratorReasonCodes.InvalidRewardBundle, reasonCode); } }