Files
Delta-v/Content.IntegrationTests/Tests/StoreTests.cs
Moony 6656adc083 Gametest Part 2: Preliminary refactor every test to use GameTest as the framework. (#43207)
* Pass 1.

* i'm FREE

* Prevent hangups.

* okay fine here's an attribute for settings, will polish later and prolly remove the overridable thing.

* sigh.

* fix singular trigger bug so LatheTest doesn't flake.

* Remove SystemAttribute usage.

* Poke

* I used the shotgun. You know why? Cause the shot gun doesn’t miss, and unlike the shitty hybrid taser it stops a criminal in their tracks in two hits. Bang, bang, and they’re fucking done. I use four shots just to make damn sure. Because, once again, I’m not there to coddle a buncha criminal scum sucking f------, I’m there to 1) Survive the fucking round. 2) Guard the armory. So you can absolutely get fucked. If I get unbanned, which I won’t, you can guarantee I will continue to use the shotgun to apprehend criminals. Because it’s quick, clean and effective as fuck. Why in the seven hells would I fuck around with the disabler shots, which take half a clip just to bring someone down, or with the tazer bolts which are slow as balls, impossible to aim and do about next to jack shit, fuck all. The shotgun is the superior law enforcement weapon. Because it stops crime. And it stops crime by reducing the number of criminals roaming the fucking halls.

* Change the faulty store test into two tests, one of which is ignored for failing.
2026-06-29 12:44:18 +02:00

175 lines
7.9 KiB
C#

using System.Linq;
using Content.IntegrationTests.Fixtures;
using Content.IntegrationTests.Fixtures.Attributes;
using Content.Server.Traitor.Uplink;
using Content.Shared.FixedPoint;
using Content.Shared.Inventory;
using Content.Shared.Mind;
using Content.Shared.Store;
using Content.Shared.Store.Components;
using Content.Shared.StoreDiscount.Components;
using Robust.Shared.GameObjects;
using Robust.Shared.Random;
namespace Content.IntegrationTests.Tests;
[TestFixture]
public sealed class StoreTests : GameTest
{
[TestPrototypes]
private const string Prototypes = @"
- type: entity
name: InventoryPdaDummy
id: InventoryPdaDummy
parent: BasePDA
components:
- type: Clothing
QuickEquip: false
slots:
- idcard
- type: Pda
";
[Test]
[Ignore("""
This currently causes the client to crash, failing the test.
When this is fixed, this test should be removed and StoreDiscountAndRefund
should just use the default pair config.
""")]
public async Task StoreDiscountAndRefundWithClient()
{
await StoreDiscountAndRefund();
}
[Test]
[PairConfig(nameof(PsDisconnected))]
public async Task StoreDiscountAndRefund()
{
var pair = Pair;
var server = pair.Server;
var testMap = await pair.CreateTestMap();
await server.WaitIdleAsync();
var serverRandom = server.ResolveDependency<IRobustRandom>();
serverRandom.SetSeed(534);
var entManager = server.ResolveDependency<IEntityManager>();
var mapSystem = server.System<SharedMapSystem>();
var prototypeManager = server.ProtoMan;
Assert.That(mapSystem.IsInitialized(testMap.MapId));
EntityUid human = default;
EntityUid uniform = default;
EntityUid pda = default;
var uplinkSystem = entManager.System<UplinkSystem>();
var listingPrototypes = prototypeManager.EnumeratePrototypes<ListingPrototype>()
.ToArray();
var coordinates = testMap.GridCoords;
await server.WaitAssertion(() =>
{
var invSystem = entManager.System<InventorySystem>();
var mindSystem = entManager.System<SharedMindSystem>();
human = entManager.SpawnEntity("HumanUniformDummy", coordinates);
uniform = entManager.SpawnEntity("UniformDummy", coordinates);
pda = entManager.SpawnEntity("InventoryPdaDummy", coordinates);
Assert.That(invSystem.TryEquip(human, uniform, "jumpsuit"));
Assert.That(invSystem.TryEquip(human, pda, "id"));
var mind = mindSystem.CreateMind(null);
mindSystem.TransferTo(mind, human, mind: mind);
FixedPoint2 originalBalance = 20;
uplinkSystem.AddUplink(human, originalBalance, null, true);
var storeComponent = entManager.GetComponent<StoreComponent>(pda);
var discountComponent = entManager.GetComponent<StoreDiscountComponent>(pda);
Assert.That(
discountComponent.Discounts,
Has.Exactly(6).Items,
$"After applying discount total discounted items count was expected to be '6' "
+ $"but was actually {discountComponent.Discounts.Count}- this can be due to discount "
+ $"categories settings (maxItems, weight) not being realistically set, or default "
+ $"discounted count being changed from '6' in StoreDiscountSystem.InitializeDiscounts."
);
var discountedListingItems = storeComponent.FullListingsCatalog
.Where(x => x.IsCostModified)
.OrderBy(x => x.ID)
.ToArray();
Assert.That(discountComponent.Discounts
.Select(x => x.ListingId.Id),
Is.EquivalentTo(discountedListingItems.Select(x => x.ID)),
$"{nameof(StoreComponent)}.{nameof(StoreComponent.FullListingsCatalog)} does not contain all "
+ $"items that are marked as discounted, or they don't have flag '{nameof(ListingDataWithCostModifiers.IsCostModified)}'"
+ $"flag as 'true'. This marks the fact that cost modifier of discount is not applied properly!"
);
// Refund action requests re-generation of listing items so we will be re-acquiring items from component a lot of times.
var itemIds = discountedListingItems.Select(x => x.ID);
foreach (var itemId in itemIds)
{
Assert.Multiple(() =>
{
storeComponent.RefundAllowed = true;
var discountedListingItem = storeComponent.FullListingsCatalog.First(x => x.ID == itemId);
var plainDiscountedCost = discountedListingItem.Cost[UplinkSystem.TelecrystalCurrencyPrototype];
var prototype = listingPrototypes.First(x => x.ID == discountedListingItem.ID);
var prototypeCost = prototype.Cost[UplinkSystem.TelecrystalCurrencyPrototype];
var discountDownTo = prototype.DiscountDownTo[UplinkSystem.TelecrystalCurrencyPrototype];
Assert.That(plainDiscountedCost.Value, Is.GreaterThanOrEqualTo(discountDownTo.Value), "Expected discounted cost to be greater then DiscountDownTo value.");
Assert.That(plainDiscountedCost.Value, Is.LessThan(prototypeCost.Value), "Expected discounted cost to be lower then prototype cost.");
var buyMsg = new StoreBuyListingMessage(discountedListingItem.ID){Actor = human};
server.EntMan.EventBus.RaiseLocalEvent(pda, buyMsg);
var newBalance = storeComponent.Balance[UplinkSystem.TelecrystalCurrencyPrototype];
Assert.That(newBalance.Value, Is.EqualTo((originalBalance - plainDiscountedCost).Value), "Expected to have balance reduced by discounted cost");
Assert.That(
discountedListingItem.IsCostModified,
Is.False,
$"Expected item cost to not be modified after Buying discounted item."
);
var costAfterBuy = discountedListingItem.Cost[UplinkSystem.TelecrystalCurrencyPrototype];
Assert.That(costAfterBuy.Value, Is.EqualTo(prototypeCost.Value), "Expected cost after discount refund to be equal to prototype cost.");
var refundMsg = new StoreRequestRefundMessage { Actor = human };
server.EntMan.EventBus.RaiseLocalEvent(pda, refundMsg);
// get refreshed item after refund re-generated items
discountedListingItem = storeComponent.FullListingsCatalog.First(x => x.ID == itemId);
var afterRefundBalance = storeComponent.Balance[UplinkSystem.TelecrystalCurrencyPrototype];
Assert.That(afterRefundBalance.Value, Is.EqualTo(originalBalance.Value), "Expected refund to return all discounted cost value.");
Assert.That(
discountComponent.Discounts.First(x => x.ListingId == discountedListingItem.ID).Count,
Is.EqualTo(0),
"Discounted count should still be zero even after refund."
);
Assert.That(
discountedListingItem.IsCostModified,
Is.False,
$"Expected item cost to not be modified after Buying discounted item (even after refund was done)."
);
var costAfterRefund = discountedListingItem.Cost[UplinkSystem.TelecrystalCurrencyPrototype];
Assert.That(costAfterRefund.Value, Is.EqualTo(prototypeCost.Value), "Expected cost after discount refund to be equal to prototype cost.");
});
}
});
}
}