/ GUNRPG.Tests / Core / SimultaneousIntentsValidationTests.cs
SimultaneousIntentsValidationTests.cs
  1  using GUNRPG.Core;
  2  using GUNRPG.Core.Intents;
  3  using GUNRPG.Core.Operators;
  4  
  5  namespace GUNRPG.Tests.Core;
  6  
  7  /// <summary>
  8  /// Domain-level tests for simultaneous intent validation.
  9  /// Tests the coordination and validation of multiple concurrent intents.
 10  /// </summary>
 11  public class SimultaneousIntentsValidationTests
 12  {
 13      [Fact]
 14      public void SimultaneousIntents_ValidatesPrimaryAction()
 15      {
 16          var op = CreateOperator();
 17          op.CurrentAmmo = 0;
 18  
 19          var intents = new SimultaneousIntents(op.Id)
 20          {
 21              Primary = PrimaryAction.Fire
 22          };
 23  
 24          var (isValid, errorMessage) = intents.Validate(op);
 25  
 26          Assert.False(isValid);
 27          Assert.Contains("ammo", errorMessage, StringComparison.OrdinalIgnoreCase);
 28      }
 29  
 30      [Fact]
 31      public void SimultaneousIntents_ValidatesMovementAction()
 32      {
 33          var op = CreateOperator();
 34          op.Stamina = 0;
 35  
 36          var intents = new SimultaneousIntents(op.Id)
 37          {
 38              Movement = MovementAction.SprintToward
 39          };
 40  
 41          var (isValid, errorMessage) = intents.Validate(op);
 42  
 43          Assert.False(isValid);
 44          Assert.Contains("stamina", errorMessage, StringComparison.OrdinalIgnoreCase);
 45      }
 46  
 47      [Fact]
 48      public void SimultaneousIntents_ValidatesStanceAction()
 49      {
 50          var op = CreateOperator();
 51          op.AimState = AimState.ADS;
 52  
 53          var intents = new SimultaneousIntents(op.Id)
 54          {
 55              Stance = StanceAction.EnterADS
 56          };
 57  
 58          var (isValid, errorMessage) = intents.Validate(op);
 59  
 60          Assert.False(isValid);
 61          Assert.Contains("already", errorMessage, StringComparison.OrdinalIgnoreCase);
 62      }
 63  
 64      [Fact]
 65      public void SimultaneousIntents_RejectsReloadWhileSliding()
 66      {
 67          var op = CreateOperator();
 68          op.CurrentAmmo = 5;
 69  
 70          var intents = new SimultaneousIntents(op.Id)
 71          {
 72              Primary = PrimaryAction.Reload,
 73              Movement = MovementAction.SlideToward
 74          };
 75  
 76          var (isValid, errorMessage) = intents.Validate(op);
 77  
 78          Assert.False(isValid);
 79          Assert.Contains("sliding", errorMessage, StringComparison.OrdinalIgnoreCase);
 80      }
 81  
 82      [Fact]
 83      public void SimultaneousIntents_AllowsFireAndMovement()
 84      {
 85          var op = CreateOperator();
 86  
 87          var intents = new SimultaneousIntents(op.Id)
 88          {
 89              Primary = PrimaryAction.Fire,
 90              Movement = MovementAction.WalkToward
 91          };
 92  
 93          var (isValid, errorMessage) = intents.Validate(op);
 94  
 95          Assert.True(isValid);
 96          Assert.Null(errorMessage);
 97      }
 98  
 99      [Fact]
100      public void SimultaneousIntents_AllowsFireAndStance()
101      {
102          var op = CreateOperator();
103  
104          var intents = new SimultaneousIntents(op.Id)
105          {
106              Primary = PrimaryAction.Fire,
107              Stance = StanceAction.EnterADS
108          };
109  
110          var (isValid, errorMessage) = intents.Validate(op);
111  
112          Assert.True(isValid);
113          Assert.Null(errorMessage);
114      }
115  
116      [Fact]
117      public void SimultaneousIntents_CreateStop_ReturnsValidIntent()
118      {
119          var op = CreateOperator();
120          var intents = SimultaneousIntents.CreateStop(op.Id);
121  
122          var (isValid, errorMessage) = intents.Validate(op);
123  
124          Assert.True(isValid);
125          Assert.Null(errorMessage);
126          Assert.False(intents.HasAnyAction());
127      }
128  
129      private static Operator CreateOperator()
130      {
131          return new Operator("TestOperator")
132          {
133              EquippedWeapon = WeaponFactory.CreateSokol545(),
134              CurrentAmmo = 30,
135              Stamina = 100,
136              AimState = AimState.Hip
137          };
138      }
139  }