PageRenderTime 83ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/src/framework/Composable.CQRS.Tests/CQRS/EventStoreTests.cs

https://github.com/mlidbom/Composable.Monolithic
C# | 197 lines | 162 code | 33 blank | 2 comment | 0 complexity | 5f06b5e3e71a2df880f52a7edf64807a MD5 | raw file
  1. using System;
  2. using System.Linq;
  3. using System.Transactions;
  4. using Composable.DependencyInjection;
  5. using Composable.Persistence.EventStore;
  6. using Composable.Refactoring.Naming;
  7. using Composable.SystemCE.LinqCE;
  8. using Composable.SystemCE.TransactionsCE;
  9. using Composable.Testing;
  10. using FluentAssertions;
  11. using NUnit.Framework;
  12. namespace Composable.Tests.CQRS
  13. {
  14. interface ISomeEvent : IAggregateEvent {}
  15. class SomeEvent : AggregateEvent, ISomeEvent
  16. {
  17. public SomeEvent(Guid aggregateId, int version) : base(aggregateId)
  18. {
  19. AggregateVersion = version;
  20. UtcTimeStamp = new DateTime(UtcTimeStamp.Year, UtcTimeStamp.Month, UtcTimeStamp.Day, UtcTimeStamp.Hour, UtcTimeStamp.Minute, UtcTimeStamp.Second);
  21. }
  22. }
  23. //[ConfigurationBasedDuplicateByDimensions]
  24. public class EventStoreTests : DuplicateByPluggableComponentTest
  25. {
  26. IEventStore EventStore => _serviceLocator.EventStore();
  27. IServiceLocator _serviceLocator;
  28. [SetUp] public void SetupTask()
  29. {
  30. _serviceLocator = TestWiringHelper.SetupTestingServiceLocator();
  31. _serviceLocator.Resolve<ITypeMappingRegistar>()
  32. .Map<SomeEvent>("9e71c8cb-397a-489c-8ff7-15805a7509e8")
  33. .Map<UserRegistered>("e965b5d4-6f1a-45fa-9660-2fec0abc4a0a");
  34. }
  35. [TearDown] public void TearDownTask() { _serviceLocator.Dispose(); }
  36. [Test] public void StreamEventsSinceReturnsWholeEventLogWhenFromEventIdIsNull() => _serviceLocator.ExecuteInIsolatedScope(() =>
  37. {
  38. var aggregateId = Guid.NewGuid();
  39. TransactionScopeCe.Execute(() => EventStore.SaveSingleAggregateEvents(1.Through(10)
  40. .Select(i => new SomeEvent(aggregateId, i)).ToList()));
  41. var stream = EventStore.ListAllEventsForTestingPurposesAbsolutelyNotUsableForARealEventStoreOfAnySize();
  42. stream.Should()
  43. .HaveCount(10);
  44. });
  45. [Test] public void StreamEventsSinceReturnsWholeEventLogWhenFetchingALargeNumberOfEvents_EnsureBatchingDoesNotBreakThings() => _serviceLocator.ExecuteInIsolatedScope(() =>
  46. {
  47. const int batchSize = 100;
  48. const int moreEventsThanTheBatchSizeForStreamingEvents = batchSize + 10;
  49. var aggregateId = Guid.NewGuid();
  50. TransactionScopeCe.Execute(() => EventStore.SaveSingleAggregateEvents(1.Through(moreEventsThanTheBatchSizeForStreamingEvents)
  51. .Select(i => new SomeEvent(aggregateId, i)).ToList()));
  52. var stream = EventStore.ListAllEventsForTestingPurposesAbsolutelyNotUsableForARealEventStoreOfAnySize(batchSize: batchSize)
  53. .ToList();
  54. var currentEventNumber = 0;
  55. stream.Should()
  56. .HaveCount(moreEventsThanTheBatchSizeForStreamingEvents);
  57. foreach(var aggregateEvent in stream)
  58. {
  59. aggregateEvent.AggregateVersion.Should()
  60. .Be(++currentEventNumber, "Incorrect event version detected");
  61. }
  62. });
  63. [Test] public void DeleteEventsDeletesTheEventsForOnlyTheSpecifiedAggregate() => _serviceLocator.ExecuteInIsolatedScope(() =>
  64. {
  65. var aggregatesWithEvents = 1.Through(10)
  66. .ToDictionary(i => i,
  67. i =>
  68. {
  69. var aggregateId = Guid.NewGuid();
  70. return 1.Through(10)
  71. .Select(j => new SomeEvent(aggregateId, j))
  72. .ToList();
  73. });
  74. TransactionScopeCe.Execute(() => aggregatesWithEvents.ForEach(@this => EventStore.SaveSingleAggregateEvents(@this.Value)));
  75. var toRemove = aggregatesWithEvents[2][0]
  76. .AggregateId;
  77. aggregatesWithEvents.Remove(2);
  78. TransactionScopeCe.Execute(() => EventStore.DeleteAggregate(toRemove));
  79. foreach(var kvp in aggregatesWithEvents)
  80. {
  81. var stream = EventStore.GetAggregateHistory(kvp.Value[0]
  82. .AggregateId);
  83. stream.Should()
  84. .HaveCount(10);
  85. }
  86. EventStore.GetAggregateHistory(toRemove)
  87. .Should()
  88. .BeEmpty();
  89. });
  90. [Test] public void GetListOfAggregateIds() => _serviceLocator.ExecuteInIsolatedScope(() =>
  91. {
  92. var aggregatesWithEvents = 1.Through(10)
  93. .ToDictionary(i => i,
  94. i =>
  95. {
  96. var aggregateId = Guid.NewGuid();
  97. return 1.Through(10)
  98. .Select(j => new SomeEvent(aggregateId, j))
  99. .ToList();
  100. });
  101. TransactionScopeCe.Execute(() => aggregatesWithEvents.ForEach(@this => EventStore.SaveSingleAggregateEvents(@this.Value)));
  102. var allAggregateIds = EventStore.StreamAggregateIdsInCreationOrder()
  103. .ToList();
  104. Assert.AreEqual(aggregatesWithEvents.Count, allAggregateIds.Count);
  105. });
  106. //Todo: This does not check that only aggregates of the correct type are returned since there are only events of type SomeEvent in the store..
  107. [Test] public void GetListOfAggregateIdsUsingEventType() => _serviceLocator.ExecuteInIsolatedScope(() =>
  108. {
  109. var aggregatesWithEvents = 1.Through(10)
  110. .ToDictionary(i => i,
  111. i =>
  112. {
  113. var aggregateId = Guid.NewGuid();
  114. return 1.Through(10)
  115. .Select(j => new SomeEvent(aggregateId, j))
  116. .ToList();
  117. });
  118. TransactionScopeCe.Execute(() => aggregatesWithEvents.ForEach(@this => EventStore.SaveSingleAggregateEvents(@this.Value)));
  119. var allAggregateIds = EventStore.StreamAggregateIdsInCreationOrder<ISomeEvent>()
  120. .ToList();
  121. Assert.AreEqual(aggregatesWithEvents.Count, allAggregateIds.Count);
  122. });
  123. [Test]
  124. public void Does_not_call_db_in_constructor() =>
  125. _serviceLocator.ExecuteInIsolatedScope(() => _serviceLocator.Resolve<IEventStoreUpdater>());
  126. [Test]
  127. public void ShouldNotCacheEventsSavedDuringFailedTransactionEvenIfReadDuringSameTransaction()
  128. {
  129. _serviceLocator.ExecuteInIsolatedScope(() =>
  130. {
  131. var eventStore = _serviceLocator.EventStore();
  132. var user = new User();
  133. user.Register("email@email.se", "password", Guid.NewGuid());
  134. using(new TransactionScope())
  135. {
  136. ((IEventStored)user).Commit(eventStore.SaveSingleAggregateEvents);
  137. eventStore.GetAggregateHistory(user.Id);
  138. Assert.That(eventStore.GetAggregateHistory(user.Id), Is.Not.Empty);
  139. }
  140. Assert.That(eventStore.GetAggregateHistory(user.Id), Is.Empty);
  141. });
  142. }
  143. [Test]
  144. public void ShouldCacheEventsBetweenInstancesTransaction()
  145. {
  146. var user = new User();
  147. using(_serviceLocator.BeginScope())
  148. {
  149. var eventStore = _serviceLocator.EventStore();
  150. user.Register("email@email.se", "password", Guid.NewGuid());
  151. TransactionScopeCe.Execute(() =>
  152. {
  153. ((IEventStored)user).Commit(eventStore.SaveSingleAggregateEvents);
  154. eventStore.GetAggregateHistory(user.Id);
  155. Assert.That(eventStore.GetAggregateHistory(user.Id), Is.Not.Empty);
  156. });
  157. }
  158. IAggregateEvent firstRead = _serviceLocator.ExecuteInIsolatedScope(() => _serviceLocator.EventStore().GetAggregateHistory(user.Id).Single());
  159. IAggregateEvent secondRead = _serviceLocator.ExecuteInIsolatedScope(() => _serviceLocator.EventStore().GetAggregateHistory(user.Id).Single());
  160. Assert.That(firstRead, Is.SameAs(secondRead));
  161. }
  162. public EventStoreTests(string _) : base(_) {}
  163. }
  164. }