diff --git a/Content.IntegrationTests/Tests/Interaction/InteractionTest.Helpers.cs b/Content.IntegrationTests/Tests/Interaction/InteractionTest.Helpers.cs
index 3302b1bafc..8a5859fe06 100644
--- a/Content.IntegrationTests/Tests/Interaction/InteractionTest.Helpers.cs
+++ b/Content.IntegrationTests/Tests/Interaction/InteractionTest.Helpers.cs
@@ -264,9 +264,10 @@ public abstract partial class InteractionTest
/// The entity or stack prototype to spawn and place into the users hand
/// The number of entities to spawn. If the prototype is a stack, this sets the stack count.
/// Whether or not to wait for any do-afters to complete
- protected async Task InteractUsing(string id, int quantity = 1, bool awaitDoAfters = true)
+ /// 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);
}
///
@@ -274,7 +275,8 @@ public abstract partial class InteractionTest
///
/// The entity type & quantity to spawn and place into the users hand
/// Whether or not to wait for any do-afters to complete
- protected async Task InteractUsing(EntitySpecifier entity, bool awaitDoAfters = true)
+ /// 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);
}
///
/// Interact with an entity using the currently held entity.
///
/// Whether or not to wait for any do-afters to complete
- protected async Task Interact(bool awaitDoAfters = true)
+ /// 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();
}
- ///
- protected async Task Interact(NetEntity? target, NetCoordinates coordinates, bool awaitDoAfters = true)
+ ///
+ 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);
}
///
/// Interact with an entity using the currently held entity.
///
- 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
index 0000000000..c15de639de
--- /dev/null
+++ b/Content.IntegrationTests/Tests/Nutrition/WaterCoolerInteractionTest.cs
@@ -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
+{
+ ///
+ /// ProtoId of the water cooler entity.
+ ///
+ private static readonly EntProtoId WaterCooler = "WaterCooler";
+
+ ///
+ /// ProtoId of the paper cup entity dispensed by the water cooler.
+ ///
+ private static readonly EntProtoId PaperCup = "DrinkWaterCup";
+
+ ///
+ /// ProtoId of the water reagent that is stored in the water cooler.
+ ///
+ private static readonly ProtoId Water = "Water";
+
+ ///
+ /// 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.
+ ///
+ [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(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");
+ });
+ }
+
+ ///
+ /// 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.
+ ///
+ [Test]
+ public async Task FillCup()
+ {
+ var solutionSys = Server.System();
+
+ // 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");
+ }
+}