From 85e91a7551f3ca246489347b17930c1f77533c12 Mon Sep 17 00:00:00 2001 From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Sat, 1 Nov 2025 05:00:17 +0100 Subject: [PATCH] Allow InteractionTests to load other maps (#41226) * load maps and marker * cleanup * sneaky doc * sneaky doc2 --------- Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com> --- .../Pair/TestPair.Helpers.cs | 47 +++++++++++++++++-- .../Tests/Interaction/InteractionTest.cs | 18 ++++++- .../Tests/Interaction/InteractionTestTests.cs | 31 ++++++++++++ Content.Shared/Tests/TestMarkerComponent.cs | 16 +++++++ Resources/Maps/Test/empty.yml | 2 +- .../Entities/Markers/integration_test.yml | 8 ++++ 6 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 Content.IntegrationTests/Tests/Interaction/InteractionTestTests.cs create mode 100644 Content.Shared/Tests/TestMarkerComponent.cs create mode 100644 Resources/Prototypes/Entities/Markers/integration_test.yml diff --git a/Content.IntegrationTests/Pair/TestPair.Helpers.cs b/Content.IntegrationTests/Pair/TestPair.Helpers.cs index 1a3b38e829..4d02b560c9 100644 --- a/Content.IntegrationTests/Pair/TestPair.Helpers.cs +++ b/Content.IntegrationTests/Pair/TestPair.Helpers.cs @@ -4,8 +4,13 @@ using System.Linq; using Content.Server.Preferences.Managers; using Content.Shared.Preferences; using Content.Shared.Roles; +using Robust.Shared.EntitySerialization; +using Robust.Shared.EntitySerialization.Systems; +using Robust.Shared.GameObjects; +using Robust.Shared.Map; using Robust.Shared.Network; using Robust.Shared.Prototypes; +using Robust.Shared.Utility; namespace Content.IntegrationTests.Pair; @@ -15,13 +20,49 @@ public sealed partial class TestPair public Task CreateTestMap(bool initialized = true) => CreateTestMap(initialized, "Plating"); + /// + /// Loads a test map and returns a representing it. + /// + /// The to the test map to load. + /// Whether to initialize the map on load. + /// A representing the loaded map. + public async Task LoadTestMap(ResPath testMapPath, bool initialized = true) + { + TestMapData mapData = new(); + var deserializationOptions = DeserializationOptions.Default with { InitializeMaps = initialized }; + var mapLoaderSys = Server.EntMan.System(); + var mapSys = Server.System(); + + // Load our test map in and assert that it exists. + await Server.WaitAssertion(() => + { + Assert.That(mapLoaderSys.TryLoadMap(testMapPath, out var map, out var gridSet, deserializationOptions), + $"Failed to load map {testMapPath}."); + Assert.That(gridSet, Is.Not.Empty, "There were no grids loaded from the map!"); + + mapData.MapUid = map!.Value.Owner; + mapData.MapId = map!.Value.Comp.MapId; + mapData.Grid = gridSet!.First(); + mapData.GridCoords = new EntityCoordinates(mapData.Grid, 0, 0); + mapData.MapCoords = new MapCoordinates(0, 0, mapData.MapId); + mapData.Tile = mapSys.GetAllTiles(mapData.Grid.Owner, mapData.Grid.Comp).First(); + }); + + await RunTicksSync(10); + mapData.CMapUid = ToClientUid(mapData.MapUid); + mapData.CGridUid = ToClientUid(mapData.Grid); + mapData.CGridCoords = new EntityCoordinates(mapData.CGridUid, 0, 0); + + return mapData; + } + /// /// Set a user's antag preferences. Modified preferences are automatically reset at the end of the test. /// public async Task SetAntagPreference(ProtoId id, bool value, NetUserId? user = null) { user ??= Client.User!.Value; - if (user is not {} userId) + if (user is not { } userId) return; var prefMan = Server.ResolveDependency(); @@ -30,7 +71,7 @@ public sealed partial class TestPair // Automatic preference resetting only resets slot 0. Assert.That(prefs.SelectedCharacterIndex, Is.EqualTo(0)); - var profile = (HumanoidCharacterProfile) prefs.Characters[0]; + var profile = (HumanoidCharacterProfile)prefs.Characters[0]; var newProfile = profile.WithAntagPreference(id, value); _modifiedProfiles.Add(userId); await Server.WaitPost(() => prefMan.SetProfile(userId, 0, newProfile).Wait()); @@ -58,7 +99,7 @@ public sealed partial class TestPair var prefMan = Server.ResolveDependency(); var prefs = prefMan.GetPreferences(user); - var profile = (HumanoidCharacterProfile) prefs.Characters[0]; + var profile = (HumanoidCharacterProfile)prefs.Characters[0]; var dictionary = new Dictionary, JobPriority>(profile.JobPriorities); // Automatic preference resetting only resets slot 0. diff --git a/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs b/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs index 4a33fdc03b..746717e785 100644 --- a/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs +++ b/Content.IntegrationTests/Tests/Interaction/InteractionTest.cs @@ -24,6 +24,7 @@ using Robust.Shared.Map; using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Timing; +using Robust.Shared.Utility; using Robust.UnitTesting; namespace Content.IntegrationTests.Tests.Interaction; @@ -39,10 +40,20 @@ namespace Content.IntegrationTests.Tests.Interaction; [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] public abstract partial class InteractionTest { + /// + /// The prototype that will be spawned for the player entity at . + /// This is not a full humanoid and only has one hand by default. + /// protected virtual string PlayerPrototype => "InteractionTestMob"; + /// + /// The map path to load for the integration test. + /// If null an empty map with a single 1x1 plating grid will be generated. + /// + protected virtual ResPath? TestMapPath => null; + protected TestPair Pair = default!; - protected TestMapData MapData => Pair.TestMap!; + protected TestMapData MapData = default!; protected RobustIntegrationTest.ServerIntegrationInstance Server => Pair.Server; protected RobustIntegrationTest.ClientIntegrationInstance Client => Pair.Client; @@ -199,7 +210,10 @@ public abstract partial class InteractionTest CUiSys = CEntMan.System(); // Setup map. - await Pair.CreateTestMap(); + if (TestMapPath == null) + MapData = await Pair.CreateTestMap(); + else + MapData = await Pair.LoadTestMap(TestMapPath.Value); PlayerCoords = SEntMan.GetNetCoordinates(Transform.WithEntityId(MapData.GridCoords.Offset(new Vector2(0.5f, 0.5f)), MapData.MapUid)); TargetCoords = SEntMan.GetNetCoordinates(Transform.WithEntityId(MapData.GridCoords.Offset(new Vector2(1.5f, 0.5f)), MapData.MapUid)); diff --git a/Content.IntegrationTests/Tests/Interaction/InteractionTestTests.cs b/Content.IntegrationTests/Tests/Interaction/InteractionTestTests.cs new file mode 100644 index 0000000000..54417b6c0b --- /dev/null +++ b/Content.IntegrationTests/Tests/Interaction/InteractionTestTests.cs @@ -0,0 +1,31 @@ +using System.Linq; +using Robust.Shared.GameObjects; +using Robust.Shared.Map.Components; +using Robust.Shared.Utility; + +namespace Content.IntegrationTests.Tests.Interaction; + +/// +/// Makes sure that interaction test helper methods are working as intended. +/// +public sealed class InteractionTestTests : InteractionTest +{ + protected override ResPath? TestMapPath => new("Maps/Test/empty.yml"); + + /// + /// Tests that map loading is working correctly. + /// + [Test] + public void MapLoadingTest() + { + // Make sure that there is only one grid. + var grids = SEntMan.AllEntities().ToList(); + Assert.That(grids, Has.Count.EqualTo(1), "Test map did not have exactly one grid."); + Assert.That(grids, Does.Contain(MapData.Grid), "MapData did not contain the loaded grid."); + + // Make sure we loaded the right map. + // This name is defined in empty.yml + Assert.That(SEntMan.GetComponent(MapData.MapUid).EntityName, Is.EqualTo("Empty Debug Map")); + } +} + diff --git a/Content.Shared/Tests/TestMarkerComponent.cs b/Content.Shared/Tests/TestMarkerComponent.cs new file mode 100644 index 0000000000..7c9ff86152 --- /dev/null +++ b/Content.Shared/Tests/TestMarkerComponent.cs @@ -0,0 +1,16 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Tests; + +/// +/// Component that is used by integration tests to mark and easily find certain entities on a test map. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class TestMarkerComponent : Component +{ + /// + /// A string to keep multiple markers on the same map distinct. + /// + [DataField, AutoNetworkedField] + public string Id = "marker"; +} diff --git a/Resources/Maps/Test/empty.yml b/Resources/Maps/Test/empty.yml index e54a18422b..d7f1cad574 100644 --- a/Resources/Maps/Test/empty.yml +++ b/Resources/Maps/Test/empty.yml @@ -56,7 +56,7 @@ entities: - uid: 3 components: - type: MetaData - name: map 89 + name: "Empty Debug Map" - type: Transform - type: Map mapPaused: True diff --git a/Resources/Prototypes/Entities/Markers/integration_test.yml b/Resources/Prototypes/Entities/Markers/integration_test.yml new file mode 100644 index 0000000000..a18f79367b --- /dev/null +++ b/Resources/Prototypes/Entities/Markers/integration_test.yml @@ -0,0 +1,8 @@ +- type: entity + parent: MarkerBase + id: IntegrationTestMarker + name: Integration Test Marker + components: + - type: TestMarker + - type: Sprite + state: pink