public async Task Given_Three_Events_Stored_In_The_Event_Stream_Using_Discrete_Operations_When_The_Aggregate_Is_Loaded_Then_The_Aggregate_Revision_Is_Three() { // Arrange IEventStoreProvider eventStoreProvider = GetEventStoreProvider(); IDomainRepository eventStoreDomainRepository = new EventStoreDomainRepository(eventStoreProvider); string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); // Act TestAggregate testAggregateToSave = new TestAggregate(eventStreamId); testAggregateToSave.BusinessLogicThatResultsInEventA(string.Empty); await eventStoreDomainRepository.SaveAsync(testAggregateToSave).ConfigureAwait(false); testAggregateToSave.BusinessLogicThatResultsInEventA(string.Empty); await eventStoreDomainRepository.SaveAsync(testAggregateToSave).ConfigureAwait(false); testAggregateToSave.BusinessLogicThatResultsInEventA(string.Empty); await eventStoreDomainRepository.SaveAsync(testAggregateToSave).ConfigureAwait(false); TestAggregate testAggregateToLoad = new TestAggregate(eventStreamId); await eventStoreDomainRepository.LoadAsync(testAggregateToLoad).ConfigureAwait(false); // Assert Assert.Equal(3, testAggregateToLoad.EventStreamRevision); }
protected async Task Given_An_Aggregate_That_Has_Been_Saved_And_Had_A_Snapshot_Saved_And_Had_Subsequent_Events_Committed_When_The_Aggregate_Is_Loaded_From_The_Snapshot_Then_The_Aggregate_State_Includes_The_Events_Committed_After_The_Snapshot_Was_Saved(IDomainRepository domainRepository, Func <TestAggregate, Task> loadAggregateAsync) { // Arrange string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); const string firstTestValue = "value at time of snapshot"; const string secondTestValue = "value post snapshot"; // Act TestAggregate testAggregateToSave = new TestAggregate(eventStreamId); testAggregateToSave.BusinessLogicThatResultsInEventA(firstTestValue); await domainRepository.SaveAsync(testAggregateToSave).ConfigureAwait(false); await domainRepository.SaveSnapshotAsync(testAggregateToSave).ConfigureAwait(false); testAggregateToSave.BusinessLogicThatResultsInEventA(secondTestValue); await domainRepository.SaveAsync(testAggregateToSave).ConfigureAwait(false); TestAggregate testAggregateToLoad = new TestAggregate(eventStreamId); await loadAggregateAsync.Invoke(testAggregateToLoad).ConfigureAwait(false); // Assert Assert.Equal(eventStreamId, testAggregateToLoad.EventStreamId); Assert.Equal(2, testAggregateToLoad.EventStreamRevision); Assert.Equal(0, testAggregateToLoad.UncommittedEvents.Count); Assert.Equal(secondTestValue, testAggregateToLoad.LastTestMessageA.Stuff); }
public async Task Given_An_Aggregate_With_An_Existing_Stream_When_A_Second_Event_Is_Written_With_An_Event_Id_Already_Used_In_The_Stream_Then_The_Second_Event_Is_Not_Written_To_The_Stream_And_The_Stream_Revision_Of_The_Aggregate_Reflects_This() { // Arrange IEventStoreProvider eventStoreProvider = GetEventStoreProvider(); EventStoreDomainRepository eventStoreDomainRepository = new EventStoreDomainRepository(eventStoreProvider); string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); Guid eventIdThatWeAreGoingToReUseToCauseAnIdempotentAppend = Guid.NewGuid(); // Act TestAggregate testAggregateA = new TestAggregate(eventStreamId); testAggregateA.BusinessLogicThatResultsInEventA("some value 1", eventIdThatWeAreGoingToReUseToCauseAnIdempotentAppend); await eventStoreDomainRepository.SaveAsync(testAggregateA).ConfigureAwait(false); long eventStreamRevisionAfterFirstEvent = testAggregateA.EventStreamRevision; testAggregateA.BusinessLogicThatResultsInEventA("some value 2", eventIdThatWeAreGoingToReUseToCauseAnIdempotentAppend); await eventStoreDomainRepository.SaveAsync(testAggregateA).ConfigureAwait(false); long eventStreamRevisionAfterSecondEvent = testAggregateA.EventStreamRevision; // Assert Assert.Equal(1, eventStreamRevisionAfterFirstEvent); Assert.Equal(1, eventStreamRevisionAfterSecondEvent); }
protected async Task Given_An_Aggregate_With_Events_When_A_Snapshot_Is_Taken_Then_The_Number_Of_Events_Since_Last_Snapshot_Count_Is_One_Before_The_Snapshot_And_Zero_After_The_Snapshot(IDomainRepository domainRepository) { // Arrange string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); // Act TestAggregate testAggregate = new TestAggregate(eventStreamId); long numberOfEventsSinceLastSnapshotBeforeUpdate = testAggregate.NumberOfEventsSinceLastSnapshot; testAggregate.BusinessLogicThatResultsInEventA("value1"); long numberOfEventsSinceLastSnapshotBeforeSave = testAggregate.NumberOfEventsSinceLastSnapshot; await domainRepository.SaveAsync(testAggregate).ConfigureAwait(false); long numberOfEventsSinceLastSnapshotAfterSave = testAggregate.NumberOfEventsSinceLastSnapshot; await domainRepository.SaveSnapshotAsync(testAggregate).ConfigureAwait(false); long numberOfEventsSinceLastSnapshotAfterAfterSnapshot = testAggregate.NumberOfEventsSinceLastSnapshot; testAggregate.BusinessLogicThatResultsInEventA("value2"); long numberOfEventsSinceLastSnapshotAfterAfterSnapshotAfterUpdate = testAggregate.NumberOfEventsSinceLastSnapshot; // Assert Assert.Equal(0, numberOfEventsSinceLastSnapshotBeforeUpdate); Assert.Equal(1, numberOfEventsSinceLastSnapshotBeforeSave); Assert.Equal(1, numberOfEventsSinceLastSnapshotAfterSave); Assert.Equal(0, numberOfEventsSinceLastSnapshotAfterAfterSnapshot); Assert.Equal(1, numberOfEventsSinceLastSnapshotAfterAfterSnapshotAfterUpdate); }
protected async Task Given_An_Aggregate_Loaded_From_A_Snapshot_Then_The_Number_Of_Events_Since_Last_Snapshot_Count_Is_Zero_After_The_Load_And_One_After_An_Update(IDomainRepository domainRepository, Func <TestAggregate, Task> loadAggregateAsync) { // Arrange string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); // Act TestAggregate testAggregate = new TestAggregate(eventStreamId); testAggregate.BusinessLogicThatResultsInEventA("value1"); await domainRepository.SaveAsync(testAggregate).ConfigureAwait(false); await domainRepository.SaveSnapshotAsync(testAggregate).ConfigureAwait(false); TestAggregate testAggregateLoadedFromSnapshot = new TestAggregate(eventStreamId); await loadAggregateAsync.Invoke(testAggregateLoadedFromSnapshot).ConfigureAwait(false); long numberOfEventsSinceLastSnapshotAfterLoadFromSnapshot = testAggregateLoadedFromSnapshot.NumberOfEventsSinceLastSnapshot; testAggregateLoadedFromSnapshot.BusinessLogicThatResultsInEventA("valeu2"); long numberOfEventsSinceLastSnapshotAfterLoadFromSnapshotAfterUpdate = testAggregateLoadedFromSnapshot.NumberOfEventsSinceLastSnapshot; // Assert Assert.Equal(0, numberOfEventsSinceLastSnapshotAfterLoadFromSnapshot); Assert.Equal(1, numberOfEventsSinceLastSnapshotAfterLoadFromSnapshotAfterUpdate); }
public async Task Given_Preexisting_Aggregate_With_A_Stream_When_It_Is_Hydrated_Concurrently_Then_Acted_Upon_And_Saved_Should_Throw_Concurrency_Exception() { // Arrange string streamId = Guid.NewGuid().ToEventStreamIdFormattedString(); IEventStoreProvider eventStoreProvider = GetEventStoreProvider(); eventStoreProvider.AppendEvents(streamId, new TestMessageB()); await eventStoreProvider.CommitEventsAsync(streamId, ExpectedStreamRevision.New).ConfigureAwait(false); EventStoreDomainRepository eventStoreDomainRepository = new EventStoreDomainRepository(eventStoreProvider); // Act TestAggregate testAggregate1 = new TestAggregate(streamId); TestAggregate testAggregate2 = new TestAggregate(streamId); await eventStoreDomainRepository.LoadAsync(testAggregate1).ConfigureAwait(false); await eventStoreDomainRepository.LoadAsync(testAggregate2).ConfigureAwait(false); testAggregate1.BusinessLogicThatResultsInEventA(string.Empty); testAggregate2.BusinessLogicThatResultsInEventA(string.Empty); await eventStoreDomainRepository.SaveAsync(testAggregate1).ConfigureAwait(false); // Assert await AssertExtensions.ThrowsAsync <EventStreamNotFoundException>( async() => await eventStoreDomainRepository.SaveAsync(testAggregate2).ConfigureAwait(false)).ConfigureAwait(false); }
public async Task Given_A_Separate_Update_To_The_Event_Stream_When_Save_Is_Used_Then_An_Error_Is_Raised() { // Arrange IEventStoreProvider eventStoreProvider = GetEventStoreProvider(); IDomainRepository eventStoreDomainRepository = new EventStoreDomainRepository(eventStoreProvider); string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); // Act // Create an aggregate with some events and save it. TestAggregate testAggregateToSave = new TestAggregate(eventStreamId); testAggregateToSave.BusinessLogicThatResultsInEventA(string.Empty); await eventStoreDomainRepository.SaveAsync(testAggregateToSave).ConfigureAwait(false); // Load a new instance of the aggregate and add another event. TestAggregate loadedTestAggregateA = new TestAggregate(eventStreamId); await eventStoreDomainRepository.LoadAsync(loadedTestAggregateA).ConfigureAwait(false); loadedTestAggregateA.BusinessLogicThatResultsInEventA(string.Empty); // Load another instance of the aggregate, add another event and save it. TestAggregate loadedTestAggregateB = new TestAggregate(eventStreamId); await eventStoreDomainRepository.LoadAsync(loadedTestAggregateB).ConfigureAwait(false); loadedTestAggregateB.BusinessLogicThatResultsInEventA(string.Empty); await eventStoreDomainRepository.SaveAsync(loadedTestAggregateB).ConfigureAwait(false); // Assert // Save the first aggregate. await AssertExtensions.ThrowsAsync <EventStreamNotFoundException>( async() => await eventStoreDomainRepository.SaveAsync(loadedTestAggregateA).ConfigureAwait(false)).ConfigureAwait(false); }
protected async Task Should_Correctly_Count_Number_Of_Events_Since_Last_Snapshot_And_Load_From_Latest_Snapshot(IDomainRepository domainRepository) { // Arrange string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); TestAggregate testAggregateToSave = new TestAggregate(eventStreamId); testAggregateToSave.BusinessLogicThatResultsInEventA("init"); await domainRepository.SaveAsync(testAggregateToSave).ConfigureAwait(false); int snapshotsTaken = 0; // Act for (int i = 0; i < 100; i++) { testAggregateToSave = new TestAggregate(eventStreamId); await domainRepository.LoadFromLatestSnapshotIfExistsAsync(testAggregateToSave).ConfigureAwait(false); testAggregateToSave.BusinessLogicThatResultsInEventA(i.ToString(CultureInfo.InvariantCulture)); if (testAggregateToSave.UncommittedEvents.Count > 0) { await domainRepository.SaveAsync(testAggregateToSave).ConfigureAwait(false); if (testAggregateToSave.NumberOfEventsSinceLastSnapshot >= 25) { snapshotsTaken++; await domainRepository.SaveSnapshotAsync(testAggregateToSave).ConfigureAwait(false); } } } // Assert Assert.Equal(4, snapshotsTaken); }
public async Task Given_An_Uncommitted_Event_For_The_Aggregate_When_Save_Is_Called_Then_The_Event_Is_Added_To_The_Event_Store_With_Correct_Headers() { // Arrange IEventStoreProvider eventStoreProvider = GetEventStoreProvider(); IDomainRepository eventStoreDomainRepository = new EventStoreDomainRepository(eventStoreProvider); string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); // Act TestAggregate testAggregate = new TestAggregate(eventStreamId); testAggregate.BusinessLogicThatResultsInEventA(string.Empty); await eventStoreDomainRepository.SaveAsync(testAggregate).ConfigureAwait(false); IEnumerable <EventStoreMessage> messages = await eventStoreProvider.ReadEventsAsync(eventStreamId).ConfigureAwait(false); EventStoreMessage[] eventStoreMessages = messages.ToArray(); // Assert Assert.Single(eventStoreMessages); Assert.Equal(3, eventStoreMessages[0].Headers.Count); object headerValue = eventStoreMessages[0].Headers[EventStoreMessageHeaderKey.EventStreamId]; Assert.NotNull(headerValue); Assert.Equal(eventStreamId, headerValue); }
protected async Task Given_An_Aggregate_With_Two_Events_That_Have_The_Same_Id_When_Saving_A_Snapshot_Then_The_Revision_Should_Be_One(IDomainRepository domainRepository, Func <TestAggregate, Task> loadAggregateAsync) { // Arrange string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); Guid eventId = Guid.NewGuid(); // Act TestAggregate testAggregateToSaveAndSnapshot = new TestAggregate(eventStreamId); testAggregateToSaveAndSnapshot.BusinessLogicThatResultsInEventA("some value 1", eventId); testAggregateToSaveAndSnapshot.BusinessLogicThatResultsInEventA("some value 2", eventId); await domainRepository.SaveAsync(testAggregateToSaveAndSnapshot).ConfigureAwait(false); await domainRepository.SaveSnapshotAsync(testAggregateToSaveAndSnapshot).ConfigureAwait(false); TestAggregate testAggregateToLoad = new TestAggregate(eventStreamId); await loadAggregateAsync.Invoke(testAggregateToLoad).ConfigureAwait(false); // Assert Assert.Equal(1, testAggregateToLoad.EventStreamRevision); }
private static TestAggregate GetAggregateWithEvents(int numberOfEventsBetweenSnapshots, int numberOfEvents) { TestAggregate testAggregate = new TestAggregate( Guid.NewGuid().ToEventStreamIdFormattedString(), numberOfEventsBetweenSnapshots); for (int i = 0; i < numberOfEvents; i++) { testAggregate.BusinessLogicThatResultsInEventA("value"); } return(testAggregate); }
public void Given_An_Event_And_Matching_UpdateState_Method_When_The_Event_Is_Applied_Then_The_Uncommitted_Event_Is_The_Correct_Type() { // Arrange TestAggregate testAggregate = new TestAggregate(Guid.NewGuid().ToEventStreamIdFormattedString()); // Act testAggregate.BusinessLogicThatResultsInEventA(string.Empty); // Assert Assert.NotNull(testAggregate.LastTestMessageA); Assert.Equal(1, testAggregate.UncommittedEvents.Count); Assert.Equal(typeof(TestMessageA), testAggregate.UncommittedEvents[0].Body.GetType()); }
public async Task Given_An_Aggregate_Containing_Two_Events_With_The_Same_Id_When_The_Aggregate_Is_Saved_Then_Only_One_Event_Should_Written_To_The_Stream_And_A_Subsequent_Save_Of_The_Aggregate_Should_Succeed_Because_The_Stream_Revision_Of_The_Aggregate_Is_Kept_In_Sync() { // Arrange IEventStoreProvider eventStoreProvider = GetEventStoreProvider(); EventStoreDomainRepository eventStoreDomainRepository = new EventStoreDomainRepository(eventStoreProvider); string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); Guid eventIdA = Guid.NewGuid(); Guid eventIdB = Guid.NewGuid(); // Act TestAggregate testAggregate = new TestAggregate(eventStreamId); testAggregate.BusinessLogicThatResultsInEventA("some value 1", eventIdA); testAggregate.BusinessLogicThatResultsInEventA("some value 2", eventIdA); await eventStoreDomainRepository.SaveAsync(testAggregate).ConfigureAwait(false); testAggregate.BusinessLogicThatResultsInEventA("some value 3", eventIdB); await eventStoreDomainRepository.SaveAsync(testAggregate).ConfigureAwait(false); // Assert Assert.Equal(2, testAggregate.EventStreamRevision); }
public void Given_An_Event_And_Matching_UpdateState_Method_When_The_Event_Is_Raised_Then_The_Correct_UpdateState_Method_Is_Called_On_The_Aggregate() { // Arrange string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); TestAggregate testAggregate = new TestAggregate(eventStreamId); // Act testAggregate.BusinessLogicThatResultsInEventA("myValue"); // Assert Assert.NotNull(testAggregate.LastTestMessageA); Assert.Equal("myValue", testAggregate.LastTestMessageA.Stuff); }
public void Given_An_Aggregate_When_An_Event_Is_Applied_Then_The_Number_Of_Events_Since_Last_Snapshot_Count_Increases_By_One() { // Arrange TestAggregate testAggregate = new TestAggregate(Guid.NewGuid().ToEventStreamIdFormattedString()); // Act long countBefore = testAggregate.NumberOfEventsSinceLastSnapshot; testAggregate.BusinessLogicThatResultsInEventA("value"); // Assert Assert.Equal(0, countBefore); Assert.Equal(1, testAggregate.NumberOfEventsSinceLastSnapshot); }
public async Task Given_An_Aggregate_Containing_Two_Events_With_The_Same_Id_When_The_Aggregate_Is_Saved_Then_Only_The_First_Event_Should_Written_To_The_Stream() { // Arrange IEventStoreProvider eventStoreProvider = GetEventStoreProvider(); EventStoreDomainRepository eventStoreDomainRepository = new EventStoreDomainRepository(eventStoreProvider); string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); const string expectedValue = "the value we should end up with"; Guid eventId = Guid.NewGuid(); // Act TestAggregate testAggregate = new TestAggregate(eventStreamId); testAggregate.BusinessLogicThatResultsInEventA(expectedValue, eventId); testAggregate.BusinessLogicThatResultsInEventA("some other value", eventId); await eventStoreDomainRepository.SaveAsync(testAggregate).ConfigureAwait(false); // Assert TestAggregate testAggregateThatIsLoaded = new TestAggregate(eventStreamId); await eventStoreDomainRepository.LoadAsync(testAggregateThatIsLoaded).ConfigureAwait(false); Assert.Equal(1, testAggregateThatIsLoaded.EventStreamRevision); Assert.Equal(0, testAggregateThatIsLoaded.UncommittedEvents.Count); Assert.Equal(expectedValue, testAggregateThatIsLoaded.LastTestMessageA.Stuff); }
protected async Task Given_An_Aggregate_With_A_Stream_And_Snapshot_At_The_End_Of_The_Stream_When_The_Aggregate_Is_Loaded_From_The_Snapshot_And_Saved_Then_The_Number_Of_Events_Since_Last_Snapshot_Is_One(IDomainRepository domainRepository, Func <TestAggregate, Task> loadAggregateAsync) { // Arrange string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); // Act TestAggregate testAggregate = new TestAggregate(eventStreamId); testAggregate.BusinessLogicThatResultsInEventA("value1"); testAggregate.BusinessLogicThatResultsInEventA("value2"); testAggregate.BusinessLogicThatResultsInEventA("value3"); await domainRepository.SaveAsync(testAggregate).ConfigureAwait(false); await domainRepository.SaveSnapshotAsync(testAggregate).ConfigureAwait(false); TestAggregate testAggregateLoadedFromSnapshot = new TestAggregate(eventStreamId); await loadAggregateAsync.Invoke(testAggregateLoadedFromSnapshot).ConfigureAwait(false); testAggregateLoadedFromSnapshot.BusinessLogicThatResultsInEventA("value4"); await domainRepository.SaveAsync(testAggregateLoadedFromSnapshot).ConfigureAwait(false); // Assert Assert.Equal(1, testAggregateLoadedFromSnapshot.NumberOfEventsSinceLastSnapshot); }
public void Given_Multiple_Raised_Events_When_The_Aggregate_Is_Not_Saved_Then_StreamRevision_Should_Be_Zero() { // Arrange string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); ITestAggregate aggregate = new TestAggregate(eventStreamId); // Act for (int i = 0; i < 10; i++) { aggregate.BusinessLogicThatResultsInEventA(string.Empty); // Assert Assert.Equal(0, aggregate.EventStreamRevision); } }
public async Task Given_An_Aggregate_Which_Has_Not_Been_Saved_When_A_Snapshot_Is_Taken_Then_An_Error_Is_Raised() { // Arrange IEventStoreProvider eventStoreProvider = GetEventStoreProvider(); EventStoreDomainRepository eventStoreDomainRepository = new EventStoreDomainRepository(eventStoreProvider); string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); // Act TestAggregate testAggregateToSave = new TestAggregate(eventStreamId); testAggregateToSave.BusinessLogicThatResultsInEventA(string.Empty); // Assert await AssertExtensions.ThrowsAsync <EventStreamNotFoundException>( async() => await eventStoreDomainRepository.SaveSnapshotAsync(testAggregateToSave).ConfigureAwait(false)).ConfigureAwait(false); }
public async Task Given_An_Uncommitted_Event_For_The_Aggregate_When_Save_Is_Called_Then_The_Event_Is_Added_To_The_Event_Store_And_The_EventStreamRevision_And_UncommittedEvents_Are_Updated_On_The_Aggregate() { // Arrange IEventStoreProvider eventStoreProvider = GetEventStoreProvider(); IDomainRepository eventStoreDomainRepository = new EventStoreDomainRepository(eventStoreProvider); string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); // Act TestAggregate testAggregate = new TestAggregate(eventStreamId); testAggregate.BusinessLogicThatResultsInEventA(string.Empty); await eventStoreDomainRepository.SaveAsync(testAggregate).ConfigureAwait(false); // Assert Assert.Equal(0, testAggregate.UncommittedEvents.Count); Assert.Equal(1, testAggregate.EventStreamRevision); }
public async Task Given_An_Uncommitted_Event_For_The_Aggregate_When_Save_Is_Called_Then_The_Event_Is_Added_To_The_Event_Store() { // Arrange IEventStoreProvider eventStoreProvider = GetEventStoreProvider(); IDomainRepository eventStoreDomainRepository = new EventStoreDomainRepository(eventStoreProvider); string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); // Act TestAggregate testAggregate = new TestAggregate(eventStreamId); testAggregate.BusinessLogicThatResultsInEventA(string.Empty); await eventStoreDomainRepository.SaveAsync(testAggregate).ConfigureAwait(false); IEnumerable <EventStoreMessage> eventStoreMessages = await eventStoreProvider.ReadEventsAsync(eventStreamId).ConfigureAwait(false); // Assert Assert.Single(eventStoreMessages); }
public async Task Given_A_Valid_Event_Stream_Id_When_The_Exists_Check_Is_Called_Using_The_Aggregate_Reference_Then_The_Aggregate_Should_Report_As_Not_Existing() { // Arrange IEventStoreProvider eventStoreProvider = GetEventStoreProvider(); IDomainRepository eventStoreDomainRepository = new EventStoreDomainRepository(eventStoreProvider); string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); // Act TestAggregate testAggregateToSave = new TestAggregate(eventStreamId); testAggregateToSave.BusinessLogicThatResultsInEventA(string.Empty); await eventStoreDomainRepository.SaveAsync(testAggregateToSave).ConfigureAwait(false); bool existsByReference = await eventStoreDomainRepository.ExistsAsync(testAggregateToSave).ConfigureAwait(false); // Assert Assert.True(existsByReference); }
public async Task Given_An_Aggregate_With_No_Snapshots_When_Loading_From_Latest_Snapshot_Then_The_Aggregate_Should_Be_Loaded_From_The_Stream() { // Arrange IDomainRepository domainRepository = GetDomainRepository(); string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); Guid eventId = Guid.NewGuid(); // Act TestAggregate testAggregateToSaveAndSnapshot = new TestAggregate(eventStreamId); testAggregateToSaveAndSnapshot.BusinessLogicThatResultsInEventA("some value 1", eventId); await domainRepository.SaveAsync(testAggregateToSaveAndSnapshot).ConfigureAwait(false); TestAggregate testAggregateToLoad = new TestAggregate(eventStreamId); await domainRepository.LoadFromLatestSnapshotIfExistsAsync(testAggregateToLoad).ConfigureAwait(false); // Assert Assert.Equal(1, testAggregateToLoad.EventStreamRevision); }
public async Task Given_An_Empty_Stream_When_An_Event_Is_Written_To_The_Stream_Through_SaveWithoutConcurrencyCheck_Then_Aggregate_Reflects_The_Correct_Stream_Revision() { // Arrange IEventStoreProvider eventStoreProvider = GetEventStoreProvider(); EventStoreDomainRepository eventStoreDomainRepository = new EventStoreDomainRepository(eventStoreProvider); string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); Guid eventIdThatWeAreGoingToReUseToCauseAnIdempotentAppend = Guid.NewGuid(); // Act TestAggregate testAggregateA = new TestAggregate(eventStreamId); testAggregateA.BusinessLogicThatResultsInEventA("some value 1", eventIdThatWeAreGoingToReUseToCauseAnIdempotentAppend); await eventStoreDomainRepository.SaveWithoutConcurrencyCheckAsync(testAggregateA).ConfigureAwait(false); long eventStreamRevisionAfterFirstEvent = testAggregateA.EventStreamRevision; // Assert Assert.Equal(1, eventStreamRevisionAfterFirstEvent); }
protected async Task Given_An_Aggregate_Throughout_The_Lifecycle_When_The_Number_Of_Events_Since_Last_Snapshot_Checked_Then_It_Reports_The_Correct_Value(IDomainRepository domainRepository, Func <TestAggregate, Task> loadAggregateAsync) { // Arrange string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); // Act TestAggregate testAggregate = new TestAggregate(eventStreamId); testAggregate.BusinessLogicThatResultsInEventA("value1"); long numberOfEventsSinceLastSnapshotAfterApply = testAggregate.NumberOfEventsSinceLastSnapshot; await domainRepository.SaveAsync(testAggregate).ConfigureAwait(false); long numberOfEventsSinceLastSnapshotAfterSave = testAggregate.NumberOfEventsSinceLastSnapshot; TestAggregate testAggregateLoadedFromStream = new TestAggregate(eventStreamId); await domainRepository.LoadAsync(testAggregateLoadedFromStream).ConfigureAwait(false); long numberOfEventsSinceLastSnapshotAfterLoadFromStream = testAggregateLoadedFromStream.NumberOfEventsSinceLastSnapshot; await domainRepository.SaveSnapshotAsync(testAggregateLoadedFromStream).ConfigureAwait(false); long numberOfEventsSinceLastSnapshotAfterSnapshot = testAggregateLoadedFromStream.NumberOfEventsSinceLastSnapshot; TestAggregate testAggregateLoadedFromSnapshot = new TestAggregate(eventStreamId); await loadAggregateAsync.Invoke(testAggregateLoadedFromSnapshot).ConfigureAwait(false); long numberOfEventsSinceLastSnapshotAfterLoadFromSnapshot = testAggregateLoadedFromSnapshot.NumberOfEventsSinceLastSnapshot; testAggregateLoadedFromSnapshot.BusinessLogicThatResultsInEventA("value2"); await domainRepository.SaveAsync(testAggregateLoadedFromSnapshot).ConfigureAwait(false); TestAggregate testAggregateLoadedFromSnapshotAndSubsequentStreamEvents = new TestAggregate(eventStreamId); await loadAggregateAsync.Invoke(testAggregateLoadedFromSnapshotAndSubsequentStreamEvents).ConfigureAwait(false); long numberOfEventsSinceLastSnapshotAfterLoadFromSnapshotAndSubsequentStreamEvents = testAggregateLoadedFromSnapshotAndSubsequentStreamEvents.NumberOfEventsSinceLastSnapshot; // Assert Assert.Equal(1, numberOfEventsSinceLastSnapshotAfterApply); Assert.Equal(1, numberOfEventsSinceLastSnapshotAfterSave); Assert.Equal(1, numberOfEventsSinceLastSnapshotAfterLoadFromStream); Assert.Equal(0, numberOfEventsSinceLastSnapshotAfterSnapshot); Assert.Equal(0, numberOfEventsSinceLastSnapshotAfterLoadFromSnapshot); Assert.Equal(1, numberOfEventsSinceLastSnapshotAfterLoadFromSnapshotAndSubsequentStreamEvents); }
public async Task Given_An_Aggregate_With_Uncommitted_Events_When_The_Aggregate_Is_Saved_Then_Afterwards_The_Aggregate_Can_Be_Loaded_Successfully() { // Arrange IEventStoreProvider eventStoreProvider = GetEventStoreProvider(); IDomainRepository eventStoreDomainRepository = new EventStoreDomainRepository(eventStoreProvider); string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); // Act TestAggregate testAggregateToSave = new TestAggregate(eventStreamId); testAggregateToSave.BusinessLogicThatResultsInEventA(string.Empty); await eventStoreDomainRepository.SaveAsync(testAggregateToSave).ConfigureAwait(false); TestAggregate loadedTestAggregate = new TestAggregate(eventStreamId); await eventStoreDomainRepository.LoadAsync(loadedTestAggregate).ConfigureAwait(false); // Assert Assert.Equal(eventStreamId, loadedTestAggregate.EventStreamId); Assert.Equal(0, loadedTestAggregate.UncommittedEvents.Count); Assert.Equal(1, loadedTestAggregate.EventStreamRevision); }
public async Task Given_A_Separate_Update_To_The_Event_Stream_When_SaveWithoutConcurrencyCheck_Is_Used_Then_No_Error_Is_Raised() { // Arrange IEventStoreProvider eventStoreProvider = GetEventStoreProvider(); IDomainRepository eventStoreDomainRepository = new EventStoreDomainRepository(eventStoreProvider); string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); // Act // Create an aggregate with some events and save it. TestAggregate testAggregateToSave = new TestAggregate(eventStreamId); testAggregateToSave.BusinessLogicThatResultsInEventA(string.Empty); await eventStoreDomainRepository.SaveAsync(testAggregateToSave).ConfigureAwait(false); // Load a new instance of the aggregate and add another event. TestAggregate loadedTestAggregateA = new TestAggregate(eventStreamId); await eventStoreDomainRepository.LoadAsync(loadedTestAggregateA).ConfigureAwait(false); loadedTestAggregateA.BusinessLogicThatResultsInEventA(string.Empty); // Load another instance of the aggregate, add another event and save it. TestAggregate loadedTestAggregateB = new TestAggregate(eventStreamId); await eventStoreDomainRepository.LoadAsync(loadedTestAggregateB).ConfigureAwait(false); loadedTestAggregateB.BusinessLogicThatResultsInEventA(string.Empty); await eventStoreDomainRepository.SaveAsync(loadedTestAggregateB).ConfigureAwait(false); // Save the first aggregate. await eventStoreDomainRepository.SaveWithoutConcurrencyCheckAsync(loadedTestAggregateA).ConfigureAwait(false); // Reload the aggregate so we can check it. TestAggregate testAggregate = new TestAggregate(eventStreamId); await eventStoreDomainRepository.LoadAsync(testAggregate).ConfigureAwait(false); // Assert. // Check that all 3 events have been applied to the aggregate. Assert.Equal(3, testAggregate.EventStreamRevision); }
protected async Task Given_An_Aggregate_Which_Has_Been_Saved_When_A_Snapshot_Is_Taken_Then_The_Aggregate_Can_Be_Loaded_From_The_Latest_Snapshot(IDomainRepository domainRepository, Func <TestAggregate, Task> loadAggregateAsync) { // Arrange string eventStreamId = Guid.NewGuid().ToEventStreamIdFormattedString(); const string testValue = "some value"; // Act TestAggregate testAggregateToSave = new TestAggregate(eventStreamId); testAggregateToSave.BusinessLogicThatResultsInEventA(testValue); await domainRepository.SaveAsync(testAggregateToSave).ConfigureAwait(false); await domainRepository.SaveSnapshotAsync(testAggregateToSave).ConfigureAwait(false); TestAggregate testAggregateToLoad = new TestAggregate(eventStreamId); await loadAggregateAsync.Invoke(testAggregateToLoad).ConfigureAwait(false); // Assert Assert.Equal(testAggregateToSave.EventStreamId, testAggregateToLoad.EventStreamId); Assert.Equal(testAggregateToSave.EventStreamRevision, testAggregateToLoad.EventStreamRevision); Assert.Equal(testValue, testAggregateToLoad.LastTestMessageA.Stuff); Assert.Equal(0, testAggregateToLoad.UncommittedEvents.Count); }