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 }