/ GUNRPG.Tests / Stubs / StubOperatorEventStore.cs
StubOperatorEventStore.cs
  1  using GUNRPG.Application.Operators;
  2  using GUNRPG.Core.Operators;
  3  
  4  namespace GUNRPG.Tests.Stubs;
  5  
  6  /// <summary>
  7  /// Stub implementation of IOperatorEventStore for testing.
  8  /// Allows tests to specify operator mode and control validation behavior.
  9  /// </summary>
 10  public class StubOperatorEventStore : IOperatorEventStore
 11  {
 12      private readonly Dictionary<OperatorId, List<OperatorEvent>> _eventsByOperator = new();
 13      private readonly Dictionary<OperatorId, Guid> _accountByOperator = new();
 14  
 15      public Task<IReadOnlyList<OperatorEvent>> LoadEventsAsync(OperatorId operatorId)
 16      {
 17          if (_eventsByOperator.TryGetValue(operatorId, out var events))
 18          {
 19              return Task.FromResult<IReadOnlyList<OperatorEvent>>(events);
 20          }
 21          return Task.FromResult<IReadOnlyList<OperatorEvent>>(new List<OperatorEvent>());
 22      }
 23  
 24      public Task AppendEventAsync(OperatorEvent evt)
 25      {
 26          throw new NotImplementedException("AppendEventAsync not needed for current tests");
 27      }
 28  
 29      public Task AppendEventsAsync(IReadOnlyList<OperatorEvent> events)
 30      {
 31          throw new NotImplementedException("AppendEventsAsync not needed for current tests");
 32      }
 33  
 34      public Task<bool> OperatorExistsAsync(OperatorId operatorId)
 35      {
 36          return Task.FromResult(_eventsByOperator.ContainsKey(operatorId) && _eventsByOperator[operatorId].Count > 0);
 37      }
 38  
 39      public Task<long> GetCurrentSequenceAsync(OperatorId operatorId)
 40      {
 41          if (_eventsByOperator.TryGetValue(operatorId, out var events) && events.Count > 0)
 42          {
 43              return Task.FromResult(events[^1].SequenceNumber);
 44          }
 45          return Task.FromResult(-1L);
 46      }
 47  
 48      public Task<IReadOnlyList<OperatorId>> ListOperatorIdsAsync()
 49      {
 50          var operatorIds = _eventsByOperator.Keys.ToList();
 51          return Task.FromResult<IReadOnlyList<OperatorId>>(operatorIds);
 52      }
 53  
 54      public Task<IReadOnlyList<OperatorId>> ListOperatorIdsByAccountAsync(Guid accountId)
 55      {
 56          var operatorIds = _accountByOperator
 57              .Where(kvp => kvp.Value == accountId)
 58              .Select(kvp => kvp.Key)
 59              .ToList();
 60          return Task.FromResult<IReadOnlyList<OperatorId>>(operatorIds);
 61      }
 62  
 63      public Task<Guid?> GetOperatorAccountIdAsync(OperatorId operatorId)
 64      {
 65          Guid? accountId = _accountByOperator.TryGetValue(operatorId, out var id) ? id : null;
 66          return Task.FromResult(accountId);
 67      }
 68  
 69      public Task AssociateOperatorWithAccountAsync(OperatorId operatorId, Guid accountId)
 70      {
 71          _accountByOperator[operatorId] = accountId;
 72          return Task.CompletedTask;
 73      }
 74  
 75      /// <summary>
 76      /// Sets up an operator with the specified mode for testing.
 77      /// </summary>
 78      public void SetupOperatorWithMode(OperatorId operatorId, OperatorMode mode, string operatorName = "TestOperator", Guid? activeCombatSessionId = null)
 79      {
 80          var events = new List<OperatorEvent>
 81          {
 82              new OperatorCreatedEvent(operatorId, operatorName)
 83          };
 84  
 85          // Add InfilStartedEvent if mode is Infil
 86          if (mode == OperatorMode.Infil)
 87          {
 88              var createHash = events[0].Hash;
 89              events.Add(new InfilStartedEvent(
 90                  operatorId, 
 91                  1, 
 92                  Guid.NewGuid(), 
 93                  "SOKOL 545", // lockedLoadout
 94                  DateTimeOffset.UtcNow, // infilStartTime
 95                  createHash));
 96  
 97              // Add CombatSessionStartedEvent if an active combat session ID is specified
 98              if (activeCombatSessionId.HasValue)
 99              {
100                  var infilHash = events[^1].Hash;
101                  events.Add(new CombatSessionStartedEvent(
102                      operatorId,
103                      2,
104                      activeCombatSessionId.Value,
105                      infilHash));
106              }
107          }
108  
109          _eventsByOperator[operatorId] = events;
110      }
111  
112      /// <summary>
113      /// Sets up an operator that doesn't exist (returns empty event list).
114      /// </summary>
115      public void SetupNonExistentOperator(OperatorId operatorId)
116      {
117          _eventsByOperator[operatorId] = new List<OperatorEvent>();
118      }
119  }