diff --git a/Content.IntegrationTests/Tests/DeviceLinking/DeviceLinkingTest.cs b/Content.IntegrationTests/Tests/DeviceLinking/DeviceLinkingTest.cs new file mode 100644 index 0000000000..96836d378a --- /dev/null +++ b/Content.IntegrationTests/Tests/DeviceLinking/DeviceLinkingTest.cs @@ -0,0 +1,94 @@ +using System.Collections.Generic; +using System.Linq; +using Content.Server.DeviceLinking.Systems; +using Content.Shared.DeviceLinking; +using Content.Shared.Prototypes; +using Robust.Shared.GameObjects; +using Robust.Shared.Map; +using Robust.Shared.Maths; +using Robust.Shared.Prototypes; + +namespace Content.IntegrationTests.Tests.DeviceLinking; + +public sealed class DeviceLinkingTest +{ + private const string PortTesterProtoId = "DeviceLinkingSinkPortTester"; + + [TestPrototypes] + private const string Prototypes = $@" +- type: entity + id: {PortTesterProtoId} + components: + - type: DeviceLinkSource + ports: + - Output +"; + + /// + /// Spawns every entity that has a + /// and sends a signal to every port to make sure nothing causes an error. + /// + [Test] + public async Task AllDeviceLinkSinksWorkTest() + { + await using var pair = await PoolManager.GetServerClient(); + var server = pair.Server; + var compFact = server.ResolveDependency(); + var mapMan = server.ResolveDependency(); + var mapSys = server.System(); + var deviceLinkSys = server.System(); + + var prototypes = server.ProtoMan.EnumeratePrototypes(); + + await server.WaitAssertion(() => + { + Assert.Multiple(() => + { + foreach (var proto in prototypes) + { + if (proto.Abstract || pair.IsTestPrototype(proto)) + continue; + + if (!proto.TryGetComponent(out var protoSinkComp, compFact)) + continue; + + foreach (var port in protoSinkComp.Ports) + { + // Create a map for each entity/port combo so they can't interfere + mapSys.CreateMap(out var mapId); + var grid = mapMan.CreateGridEntity(mapId); + mapSys.SetTile(grid.Owner, grid.Comp, Vector2i.Zero, new Tile(1)); + var coord = new EntityCoordinates(grid.Owner, 0, 0); + + // Spawn the sink entity + var sinkEnt = server.EntMan.SpawnEntity(proto.ID, coord); + // Get the actual sink component, since the one we got from the prototype doesn't have its owner set up + Assert.That(server.EntMan.TryGetComponent(sinkEnt, out var sinkComp), + $"Tester prototype does not have a DeviceLinkSourceComponent!"); + + // Spawn the tester + var sourceEnt = server.EntMan.SpawnEntity(PortTesterProtoId, coord); + Assert.That(server.EntMan.TryGetComponent(sourceEnt, out var sourceComp), + $"Tester prototype does not have a DeviceLinkSourceComponent!"); + + // Create a link from the tester's output to the target port on the sink + deviceLinkSys.SaveLinks(null, + sourceEnt, + sinkEnt, + [("Output", port.Id)], + sourceComp, + sinkComp); + + // Send a signal to the port + Assert.DoesNotThrow(() => { deviceLinkSys.InvokePort(sourceEnt, "Output", null, sourceComp); }, + $"Exception thrown while triggering port {port.Id} of sink device {proto.ID}"); + + mapSys.DeleteMap(mapId); + } + } + }); + }); + + await pair.CleanReturnAsync(); + } +}