]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Add water cooler interaction test (#39612)
authorTayrtahn <tayrtahn@gmail.com>
Fri, 5 Sep 2025 17:05:49 +0000 (13:05 -0400)
committerGitHub <noreply@github.com>
Fri, 5 Sep 2025 17:05:49 +0000 (19:05 +0200)
* Add altInteract option to interaction test helper methods

* Add water cooler interaction test

* Oops, that's not a NetEntity

* Is.Not.Empty

* SPlayer

* Assert.Multiple

* Document parameters

Content.IntegrationTests/Tests/Interaction/InteractionTest.Helpers.cs
Content.IntegrationTests/Tests/Nutrition/WaterCoolerInteractionTest.cs [new file with mode: 0644]

index 3302b1bafc53bd3d231b9fb24ac11908c6da782d..8a5859fe060831dcf652a2445615340508994d13 100644 (file)
@@ -264,9 +264,10 @@ public abstract partial class InteractionTest
     /// <param name="id">The entity or stack prototype to spawn and place into the users hand</param>
     /// <param name="quantity">The number of entities to spawn. If the prototype is a stack, this sets the stack count.</param>
     /// <param name="awaitDoAfters">Whether or not to wait for any do-afters to complete</param>
-    protected async Task InteractUsing(string id, int quantity = 1, bool awaitDoAfters = true)
+    /// <param name="altInteract">If true, perform an alternate interaction instead of a standard one.
+    protected async Task InteractUsing(string id, int quantity = 1, bool awaitDoAfters = true, bool altInteract = false)
     {
-        await InteractUsing((id, quantity), awaitDoAfters);
+        await InteractUsing((id, quantity), awaitDoAfters, altInteract);
     }
 
     /// <summary>
@@ -274,7 +275,8 @@ public abstract partial class InteractionTest
     /// </summary>
     /// <param name="entity">The entity type & quantity to spawn and place into the users hand</param>
     /// <param name="awaitDoAfters">Whether or not to wait for any do-afters to complete</param>
-    protected async Task InteractUsing(EntitySpecifier entity, bool awaitDoAfters = true)
+    /// <param name="altInteract">If true, perform an alternate interaction instead of a standard one.
+    protected async Task InteractUsing(EntitySpecifier entity, bool awaitDoAfters = true, bool altInteract = false)
     {
         // For every interaction, we will also examine the entity, just in case this breaks something, somehow.
         // (e.g., servers attempt to assemble construction examine hints).
@@ -284,18 +286,19 @@ public abstract partial class InteractionTest
         }
 
         await PlaceInHands(entity);
-        await Interact(awaitDoAfters);
+        await Interact(awaitDoAfters, altInteract);
     }
 
     /// <summary>
     /// Interact with an entity using the currently held entity.
     /// </summary>
     /// <param name="awaitDoAfters">Whether or not to wait for any do-afters to complete</param>
-    protected async Task Interact(bool awaitDoAfters = true)
+    /// <param name="altInteract">If true, performs an alternate interaction instead of a standard one.
+    protected async Task Interact(bool awaitDoAfters = true, bool altInteract = false)
     {
         if (Target == null || !Target.Value.IsClientSide())
         {
-            await Interact(Target, TargetCoords, awaitDoAfters);
+            await Interact(Target, TargetCoords, awaitDoAfters, altInteract);
             return;
         }
 
@@ -311,23 +314,23 @@ public abstract partial class InteractionTest
         await CheckTargetChange();
     }
 
-    /// <inheritdoc cref="Interact(EntityUid?,EntityCoordinates,bool)"/>
-    protected async Task Interact(NetEntity? target, NetCoordinates coordinates, bool awaitDoAfters = true)
+    /// <inheritdoc cref="Interact(EntityUid?,EntityCoordinates,bool,bool)"/>
+    protected async Task Interact(NetEntity? target, NetCoordinates coordinates, bool awaitDoAfters = true, bool altInteract = false)
     {
         Assert.That(SEntMan.TryGetEntity(target, out var sTarget) || target == null);
         var coords = SEntMan.GetCoordinates(coordinates);
         Assert.That(coords.IsValid(SEntMan));
-        await Interact(sTarget, coords, awaitDoAfters);
+        await Interact(sTarget, coords, awaitDoAfters, altInteract);
     }
 
     /// <summary>
     /// Interact with an entity using the currently held entity.
     /// </summary>
-    protected async Task Interact(EntityUid? target, EntityCoordinates coordinates, bool awaitDoAfters = true)
+    protected async Task Interact(EntityUid? target, EntityCoordinates coordinates, bool awaitDoAfters = true, bool altInteract = false)
     {
         Assert.That(SEntMan.TryGetEntity(Player, out var player));
 
-        await Server.WaitPost(() => InteractSys.UserInteraction(player!.Value, coordinates, target));
+        await Server.WaitPost(() => InteractSys.UserInteraction(player!.Value, coordinates, target, altInteract: altInteract));
         await RunTicks(1);
 
         if (awaitDoAfters)
diff --git a/Content.IntegrationTests/Tests/Nutrition/WaterCoolerInteractionTest.cs b/Content.IntegrationTests/Tests/Nutrition/WaterCoolerInteractionTest.cs
new file mode 100644 (file)
index 0000000..c15de63
--- /dev/null
@@ -0,0 +1,99 @@
+using Content.IntegrationTests.Tests.Interaction;
+using Content.Shared.Chemistry.EntitySystems;
+using Content.Shared.Chemistry.Reagent;
+using Content.Shared.FixedPoint;
+using Content.Shared.Storage.Components;
+using Robust.Shared.Prototypes;
+
+namespace Content.IntegrationTests.Tests.Nutrition;
+
+public sealed class WaterCoolerInteractionTest : InteractionTest
+{
+    /// <summary>
+    /// ProtoId of the water cooler entity.
+    /// </summary>
+    private static readonly EntProtoId WaterCooler = "WaterCooler";
+
+    /// <summary>
+    /// ProtoId of the paper cup entity dispensed by the water cooler.
+    /// </summary>
+    private static readonly EntProtoId PaperCup = "DrinkWaterCup";
+
+    /// <summary>
+    /// ProtoId of the water reagent that is stored in the water cooler.
+    /// </summary>
+    private static readonly ProtoId<ReagentPrototype> Water = "Water";
+
+    /// <summary>
+    /// Spawns a water cooler and tests that the player can retrieve a paper cup
+    /// by interacting with it, and can return the paper cup by alt-interacting with it.
+    /// </summary>
+    [Test]
+    public async Task GetAndReturnCup()
+    {
+        // Spawn the water cooler
+        var cooler = await SpawnTarget(WaterCooler);
+
+        // Record how many paper cups are in the cooler
+        var binComp = Comp<BinComponent>(cooler);
+        var initialCount = binComp.Items.Count;
+        Assert.That(binComp.Items, Is.Not.Empty, "Water cooler didn't start with any cups");
+
+        // Interact with the water cooler using an empty hand to grab a paper cup
+        await Interact();
+
+        var cup = HandSys.GetActiveItem((SPlayer, Hands));
+
+        Assert.Multiple(() =>
+        {
+            // Make sure the player is now holding a cup
+            Assert.That(cup, Is.Not.Null, "Player's hand is empty");
+            AssertPrototype(PaperCup, SEntMan.GetNetEntity(cup));
+
+            // Make sure the number of cups in the cooler has decreased by one
+            Assert.That(binComp.Items, Has.Count.EqualTo(initialCount - 1), "Number of cups in cooler bin did not decrease by one");
+
+            // Make sure the cup isn't somehow still in the cooler too
+            Assert.That(binComp.Items, Does.Not.Contain(cup));
+        });
+
+        // Alt-interact with the water cooler while holding the cup to put it back
+        await Interact(altInteract: true);
+
+        Assert.Multiple(() =>
+        {
+            // Make sure the player's hand is empty
+            Assert.That(HandSys.ActiveHandIsEmpty((SPlayer, Hands)), "Player's hand is not empty");
+
+            // Make sure the count has gone back up by one
+            Assert.That(binComp.Items, Has.Count.EqualTo(initialCount), "Number of cups in cooler bin did not return to initial count");
+
+            // Make sure the cup is in the cooler
+            Assert.That(binComp.Items, Contains.Item(cup), "Cup was not returned to cooler");
+        });
+    }
+
+    /// <summary>
+    /// Spawns a water cooler and gives the player an empty paper cup.
+    /// Tests that the player can put water into the cup by interacting
+    /// with the water cooler while holding the cup.
+    /// </summary>
+    [Test]
+    public async Task FillCup()
+    {
+        var solutionSys = Server.System<SharedSolutionContainerSystem>();
+
+        // Spawn the water cooler
+        await SpawnTarget(WaterCooler);
+
+        // Give the player a cup
+        var cup = await PlaceInHands(PaperCup);
+
+        // Make the player interact with the water cooler using the held cup
+        await Interact();
+
+        // Make sure the cup now contains water
+        Assert.That(solutionSys.GetTotalPrototypeQuantity(ToServer(cup), Water), Is.GreaterThan(FixedPoint2.Zero),
+            "Cup does not contain any water");
+    }
+}