neon-sprawl/server/NeonSprawl.Server.Tests/Game/PositionState/MoveCommandValidationTests.cs

91 lines
3.3 KiB
C#

using NeonSprawl.Server.Game.PositionState;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.PositionState;
public class MoveCommandValidationTests
{
private static MovementValidationOptions Rules(double maxH, double maxV, bool bounds = false) =>
new()
{
MaxHorizontalStep = maxH,
MaxVerticalStep = maxV,
DistrictBoundsEnabled = bounds,
DistrictMinX = 0,
DistrictMaxX = 10,
DistrictMinY = 0,
DistrictMaxY = 10,
DistrictMinZ = 0,
DistrictMaxZ = 10,
};
[Fact]
public void TryValidate_ShouldAllow_WhenHorizontalExactlyAtMax()
{
var from = new PositionSnapshot(0, 0, 0, 0);
var to = new PositionVector { X = 5, Y = 0, Z = 0 };
Assert.True(MoveCommandValidation.TryValidate(from, to, Rules(5, 10), out var code));
Assert.Equal("", code);
}
[Fact]
public void TryValidate_ShouldRejectHorizontal_WhenJustOutsideMax()
{
var from = new PositionSnapshot(0, 0, 0, 0);
var to = new PositionVector { X = 5 + 1e-6, Y = 0, Z = 0 };
Assert.False(MoveCommandValidation.TryValidate(from, to, Rules(5, 10), out var code));
Assert.Equal(MoveCommandReasonCodes.HorizontalStepExceeded, code);
}
[Fact]
public void TryValidate_ShouldAllow_WhenVerticalExactlyAtMax()
{
var from = new PositionSnapshot(0, 1, 0, 0);
var to = new PositionVector { X = 0, Y = 2.5, Z = 0 };
Assert.True(MoveCommandValidation.TryValidate(from, to, Rules(10, 1.5), out _));
}
[Fact]
public void TryValidate_ShouldRejectVertical_WhenJustOutsideMax()
{
var from = new PositionSnapshot(0, 1, 0, 0);
var to = new PositionVector { X = 0, Y = 2.5 + 1e-9, Z = 0 };
Assert.False(MoveCommandValidation.TryValidate(from, to, Rules(10, 1.5), out var code));
Assert.Equal(MoveCommandReasonCodes.VerticalStepExceeded, code);
}
[Fact]
public void TryValidate_ShouldPreferHorizontalReason_WhenBothWouldFail()
{
var from = new PositionSnapshot(0, 0, 0, 0);
var to = new PositionVector { X = 100, Y = 100, Z = 0 };
Assert.False(MoveCommandValidation.TryValidate(from, to, Rules(1, 1), out var code));
Assert.Equal(MoveCommandReasonCodes.HorizontalStepExceeded, code);
}
[Fact]
public void TryValidate_ShouldIgnoreBounds_WhenDistrictDisabled()
{
var from = new PositionSnapshot(0, 0, 0, 0);
var to = new PositionVector { X = -50, Y = 0, Z = 0 };
Assert.True(MoveCommandValidation.TryValidate(from, to, Rules(100, 100, bounds: false), out _));
}
[Fact]
public void TryValidate_ShouldRejectOutOfBounds_WhenDistrictEnabled()
{
var from = new PositionSnapshot(5, 5, 5, 0);
var to = new PositionVector { X = 5, Y = 5, Z = 11 };
Assert.False(MoveCommandValidation.TryValidate(from, to, Rules(20, 20, bounds: true), out var code));
Assert.Equal(MoveCommandReasonCodes.OutOfBounds, code);
}
[Fact]
public void TryValidate_ShouldAllowOnBoundsSurface_WhenDistrictEnabled()
{
var from = new PositionSnapshot(5, 5, 5, 0);
var to = new PositionVector { X = 10, Y = 10, Z = 10 };
Assert.True(MoveCommandValidation.TryValidate(from, to, Rules(20, 20, bounds: true), out _));
}
}