public void GivenAnAggregateThenTheIdForThatAggregateIsReturned() { var aggregate = new SerializableEventCentricAggregateRoot(); Guid id = aggregate; Assert.Equal(aggregate.Id, id); }
public void GivenAnAggregateThenAReferenceForThatAggregateIsReturned() { var aggregate = new SerializableEventCentricAggregateRoot(); Reference reference = aggregate; Assert.True(reference.IsMatch(aggregate)); }
public async Task GivenAnIdWhenTwoExistingVersionedEntriesExistThenTheMostUpToDateEntryIsReturnedAsync() { var aggregate = new SerializableEventCentricAggregateRoot(); IRepository <SerializableEventCentricAggregateRoot> repository = Create <SerializableEventCentricAggregateRoot>(); await repository.SaveAsync(aggregate); var context = new SerializableMessage(); aggregate.Set(new SetRequest(context, Guid.NewGuid())); await repository.SaveAsync(aggregate); var other = new SerializableEventCentricAggregateRoot(); await repository.SaveAsync(other); SerializableEventCentricAggregateRoot?actual = await repository.GetAsync(aggregate.Id); Assert.NotNull(actual); Assert.NotSame(aggregate, actual); Assert.Equal(aggregate.Id, actual !.Id); Assert.Equal(aggregate.Version, actual.Version); }
public void GivenAnAggregateThenTheVersionOfThatAggregateIsReturned() { var aggregate = new SerializableEventCentricAggregateRoot(); SignedVersion version = aggregate; Assert.Equal(aggregate.Version, version); }
public async Task GivenAVersionThatIsNotTheCurrentVersionThenANullValueIsReturnedAsync() { var aggregate = new SerializableEventCentricAggregateRoot(); SignedVersion expectedFirst = aggregate.Version; IRepository <SerializableEventCentricAggregateRoot> repository = Create <SerializableEventCentricAggregateRoot>(); await repository.SaveAsync(aggregate); var context = new SerializableMessage(); aggregate.Set(new SetRequest(context, Guid.NewGuid())); SignedVersion expectedSecond = aggregate.Version; await repository.SaveAsync(aggregate); var other = new SerializableEventCentricAggregateRoot(); await repository.SaveAsync(other); SerializableEventCentricAggregateRoot?actualFirst = await repository.GetAsync(aggregate.Id, version : expectedFirst); SerializableEventCentricAggregateRoot?actualSecond = await repository.GetAsync(aggregate.Id, version : expectedSecond); Assert.Null(actualFirst); Assert.NotNull(actualSecond); Assert.NotSame(expectedSecond, actualSecond); Assert.Equal(aggregate.Id, actualSecond !.Id); Assert.Equal(expectedSecond, actualSecond.Version); }
public async Task GivenACommandThenTheAggregateIsRetrievedTheSetOperationInvokedAndTheChangesSavedAsync() { var identity = Guid.NewGuid(); var repository = new Mock <IRepository <SerializableEventCentricAggregateRoot> >(); var handler = new TestableCoordinatedOperationHandler <Message>(identity, repository.Object); var command = new SerializableMessage(); var aggregate = new SerializableEventCentricAggregateRoot(identity); Assert.NotEqual(identity, aggregate.Value); _ = repository .Setup(repo => repo.GetAsync( It.IsAny <Guid>(), It.IsAny <CancellationToken?>(), It.IsAny <SignedVersion?>())) .ReturnsAsync(aggregate); await handler.ExecuteAsync(command, CancellationToken.None); Assert.Equal(identity, aggregate.Value); repository.Verify( repo => repo.SaveAsync( It.IsAny <SerializableEventCentricAggregateRoot>(), It.IsAny <CancellationToken?>()), Times.Once); repository.Verify( repo => repo.SaveAsync( It.Is <SerializableEventCentricAggregateRoot>(source => source == aggregate), It.IsAny <CancellationToken?>()), Times.Once); }
public async Task GivenAnAggregateWithChangesWhenAggregateSavedIsRaisedThenTheChangesArePropagatedToTheBusAsync() { const int ExpectedTotalChanges = 2; var context = new SerializableMessage(); var aggregate = new SerializableEventCentricAggregateRoot(context); var request = new SetRequest(context, Guid.NewGuid()); var bus = new Mock <IBus>(); var cloner = new TestableCloner(); var repository = new UnversionedMemoryRepository <SerializableEventCentricAggregateRoot>(cloner); var propagator = new DomainEventPropagator <SerializableEventCentricAggregateRoot>(bus.Object, repository); IEnumerable <DomainEvent> changes = Enumerable.Empty <DomainEvent>(); _ = bus .Setup(b => b.PublishAsync( It.IsAny <IEnumerable <DomainEvent> >(), It.IsAny <CancellationToken?>())) .Callback <IEnumerable <DomainEvent>, CancellationToken?>((events, _) => changes = events); aggregate.Set(request); await repository.SaveAsync(aggregate); _ = Assert.Single(changes.OfType <SerializableCreatedDomainEvent>()); _ = Assert.Single(changes.OfType <SerializableSetDomainEvent>()); Assert.Equal(ExpectedTotalChanges, changes.Count()); }
public async Task GivenAPopulatedRepositoryThenAListOfTheMostUpToDateVersionsIsReturnedAsync() { const int ExpectedTotal = 2; var first = new SerializableEventCentricAggregateRoot(); var second = new SerializableEventCentricAggregateRoot(); IRepository <SerializableEventCentricAggregateRoot> repository = Create <SerializableEventCentricAggregateRoot>(); await repository.SaveAsync(first); await repository.SaveAsync(second); var context = new SerializableMessage(); second.Set(new SetRequest(context, Guid.NewGuid())); await repository.SaveAsync(second); IEnumerable <SerializableEventCentricAggregateRoot> results = await repository.GetAllAsync(); Assert.Equal(ExpectedTotal, results.Count()); Assert.Contains(results, result => result.Id == first.Id && result.Version == first.Version); Assert.Contains(results, result => result.Id == second.Id && result.Version == second.Version); }
public void WhenInvokedThenAnInvalidOperationExceptionIsThrown() { var aggregate = new SerializableEventCentricAggregateRoot(); _ = Assert.Throws <InvalidOperationException>( () => aggregate.TriggerRollbackUncommittedChanges()); }
protected override void PerformCoordinatedOperation( SerializableEventCentricAggregateRoot aggregate, TCommand message) { var request = new SetRequest(message, identity); aggregate.Set(request); }
public void GivenAnEventWhenCastToATypedReferenceThenTheTypedReferenceIsReturned() { var aggregate = new SerializableEventCentricAggregateRoot(); var message = new SerializableMessage(); var @event = new SerializableDomainEvent <SerializableEventCentricAggregateRoot>(message, aggregate); Reference <SerializableEventCentricAggregateRoot> reference = @event; Assert.True(reference.IsMatch(aggregate)); }
public void GivenAnAggregateThenAReferenceIsReturned() { var aggregate = new SerializableEventCentricAggregateRoot(); Reference reference = Create(aggregate); Assert.Equal(aggregate.Id, reference.Id); Assert.Equal(aggregate.GetType(), reference.Type); _ = Assert.IsType <Reference <SerializableEventCentricAggregateRoot> >(reference); }
public void GivenAnInstanceThenAllPropertiesAreSerialized() { var aggregate = new SerializableEventCentricAggregateRoot(); var original = new SerializableProjection <SerializableEventCentricAggregateRoot>(aggregate); SerializableProjection <SerializableEventCentricAggregateRoot> deserialized = original.Clone(); Assert.NotSame(original, deserialized); Assert.Equal(original.Aggregate, deserialized.Aggregate); }
public void GivenEventsThenAnInstanceIsReturnedWithTheEventsSet() { var aggregate = new SerializableEventCentricAggregateRoot(); var context = new SerializableMessage(); SerializableCreatedDomainEvent[] events = new[] { new SerializableCreatedDomainEvent(context, aggregate) }; var @event = new EventReconciliationAsyncEventArgs(events); Assert.Equal(events, @event.Events); }
public void GivenAnInstanceThenAllPropertiesAreSerialized() { var aggregate = new SerializableEventCentricAggregateRoot(); var context = new SerializableMessage(); SerializableCreatedDomainEvent[] events = new[] { new SerializableCreatedDomainEvent(context, aggregate) }; var original = new EventReconciliationAsyncEventArgs(events); EventReconciliationAsyncEventArgs deserialized = original.Clone(); Assert.NotSame(original, deserialized); Assert.Equal(original.Events, deserialized.Events); }
public void GivenChangesThenTheChangesArePropagatedToTheEvent() { var aggregate = new SerializableEventCentricAggregateRoot(); var context = new SerializableMessage(); ChangesMarkedAsCommittedEventArgs? @event = default; aggregate.ChangesMarkedAsCommitted += (sender, e) => @event = e as ChangesMarkedAsCommittedEventArgs; IEnumerable <DomainEvent> changes = aggregate.ApplyChanges(context, times: 1); Assert.Equal(changes, @event?.Changes); }
public void GivenUnorderedEventsThenAnAggregateEventSequenceUnorderedExceptionIsThrown() { var aggregate = new SerializableEventCentricAggregateRoot(); var context = new SerializableMessage(); IEnumerable <DomainEvent> events = aggregate.ApplyChanges(context, times: 3); AggregateEventSequenceUnorderedException exception = Assert.Throws <AggregateEventSequenceUnorderedException>( () => aggregate.LoadFromHistory(events.OrderByDescending(@event => @event.Aggregate.Version))); Assert.True(exception.Aggregate.IsMatch(aggregate)); }
public void GivenAnAggregateWithNoChangesThenTheChangesMarkedAsCommittedEventIsNotRaised() { bool wasInvoked = false; var aggregate = new SerializableEventCentricAggregateRoot(Guid.NewGuid()); aggregate.MarkChangesAsCommitted(); aggregate.ChangesMarkedAsCommitted += (sender, e) => wasInvoked = true; aggregate.MarkChangesAsCommitted(); Assert.False(wasInvoked); }
public void GivenAnAggregateThatHasChangesThenAnAggregateHasUncommittedChangesExceptionIsThrown() { var aggregate = new SerializableEventCentricAggregateRoot(); var context = new SerializableMessage(); IEnumerable <DomainEvent> events = aggregate.ApplyChanges(context, commit: false, times: 1); AggregateHasUncommittedChangesException exception = Assert.Throws <AggregateHasUncommittedChangesException>( () => aggregate.LoadFromHistory(events)); Assert.True(exception.Aggregate.IsMatch(aggregate)); }
public void GiveEventsFromTwoDifferentVersionsOfTheSameAggregateThenAnArgumentExceptionIsThrown() { var aggregate = new SerializableEventCentricAggregateRoot(); var context = new SerializableMessage(); var firstEvent = new SerializableDomainEvent <SerializableEventCentricAggregateRoot>(context, aggregate); aggregate.MarkChangesAsCommitted(); aggregate.Set(new SetRequest(context, Guid.NewGuid())); var secondEvent = new SerializableDomainEvent <SerializableEventCentricAggregateRoot>(context, aggregate); _ = Assert.Throws <ArgumentException>(() => new AtomicUnit(new[] { firstEvent, secondEvent })); }
public void GivenAValueThenTheValueIsPropagated() { var expected = Guid.NewGuid(); var context = new SerializableMessage(); var request = new SetRequest(context, expected); var aggregate = new SerializableEventCentricAggregateRoot(context); Assert.NotEqual(expected, aggregate.Value); aggregate.Set(request); Assert.Equal(expected, aggregate.Value); }
public void GivenEventsForADifferentAggregateIdThenAnAggregateEventMismatchExceptionIsThrown() { var first = new SerializableEventCentricAggregateRoot(); var second = new SerializableEventCentricAggregateRoot(); var context = new SerializableMessage(); IEnumerable <DomainEvent> events = first.ApplyChanges(context, times: 1); AggregateEventMismatchException exception = Assert.Throws <AggregateEventMismatchException>( () => second.LoadFromHistory(events)); Assert.True(exception.Aggregate.IsMatch(second)); }
public void GivenAStreamWithATargetThenTheSnapshotContainsTheAggregatesToTheTargetPointWithinThatStream() { SerializableEventCentricAggregateRoot first = CreateAggregate(out IEnumerable <DomainEvent> firstEvents); SerializableEventCentricAggregateRoot second = CreateAggregate(out IEnumerable <DomainEvent> secondEvents); SerializableEventCentricAggregateRoot third = CreateAggregate(out IEnumerable <DomainEvent> thirdEvents); var firstSnapshot = new SerializableEventCentricAggregateRoot(first.Id); var secondSnapshot = new SerializableEventCentricAggregateRoot(second.Id); var thirdSnapshot = new SerializableEventCentricAggregateRoot(third.Id); var aggregates = new Dictionary <Guid, (DomainEvent[] Events, EventCentricAggregateRoot Original, EventCentricAggregateRoot Snapshot)> { { first.Id, (firstEvents.ToArray(), first, firstSnapshot) }, { second.Id, (secondEvents.ToArray(), second, secondSnapshot) },
public void GivenAValueWhenTheAggregateIsNewThenTheVersionRemainsUnchanged() { var value = Guid.NewGuid(); var context = new SerializableMessage(); var request = new SetRequest(context, value); var aggregate = new SerializableEventCentricAggregateRoot(context); SignedVersion version = aggregate.Version; Assert.True(version.IsNew); aggregate.Set(request); Assert.Equal(version, aggregate.Version); }
public void GivenEventsThatOccurAfterTheCurrentSequeneThenAnAggregateHistoryInvalidForStateExceptionIsThrown() { var first = new SerializableEventCentricAggregateRoot(); var second = new SerializableEventCentricAggregateRoot(first.Id); var context = new SerializableMessage(); IEnumerable <DomainEvent> events = first.ApplyChanges(context, times: 5); second.LoadFromHistory(events.Take(2)); AggregateHistoryInvalidForStateException exception = Assert.Throws <AggregateHistoryInvalidForStateException>( () => second.LoadFromHistory(events.Skip(3))); Assert.True(exception.Aggregate.IsMatch(second)); }
public void GivenAnInstanceThenAllPropertiesAreSerialized() { var aggregate = new SerializableEventCentricAggregateRoot(); var context = new SerializableMessage(); IEnumerable <DomainEvent> events = aggregate.ApplyChanges(context, commit: false, times: 1); AggregateHasUncommittedChangesException original = Assert.Throws <AggregateHasUncommittedChangesException>( () => aggregate.LoadFromHistory(events)); AggregateHasUncommittedChangesException deserialized = original.Clone(); Assert.NotSame(original, deserialized); Assert.Equal(original.Aggregate, deserialized.Aggregate); }
public void GivenAnInstanceThenAllPropertiesAreSerialized() { var aggregate = new SerializableEventCentricAggregateRoot(); var context = new SerializableMessage(); ChangesMarkedAsCommittedEventArgs?original = default; aggregate.ChangesMarkedAsCommitted += (sender, e) => original = e as ChangesMarkedAsCommittedEventArgs; _ = aggregate.ApplyChanges(context, times: 1); ChangesMarkedAsCommittedEventArgs?deserialized = original !.Clone(); Assert.NotSame(original, deserialized); Assert.Equal(original !.Changes, deserialized.Changes); }
public void GivenAnAggregateAContextAndAMessageInstanceIsReturnedWithAllPropertiesPropagated() { var aggregate = new SerializableEventCentricAggregateRoot(); var context = new SerializableMessage(); const string Message = "Something something dark side."; var exception = new SerializableDomainException <SerializableEventCentricAggregateRoot>( context, aggregate, Message); Assert.Equal(aggregate.ToReference(), exception.Aggregate); Assert.Equal(context, exception.Context); Assert.Equal(Message, exception.Message); }
public void GivenAnInstanceThenAllPropertiesAreSerialized() { var aggregate = new SerializableEventCentricAggregateRoot(); var context = new SerializableMessage(); IEnumerable <DomainEvent> events = aggregate.ApplyChanges(context, times: 3); AggregateEventSequenceUnorderedException original = Assert.Throws <AggregateEventSequenceUnorderedException>( () => aggregate.LoadFromHistory(events.OrderByDescending(@event => @event.Aggregate.Version))); AggregateEventSequenceUnorderedException deserialized = original.Clone(); Assert.NotSame(original, deserialized); Assert.Equal(original.Aggregate, deserialized.Aggregate); Assert.Equal(original.Events, deserialized.Events); }
public void GivenAnInstanceWhenNoChangesArePendingThenAllPropertiesAreSerialized() { var expectedId = Guid.NewGuid(); var original = new SerializableEventCentricAggregateRoot(expectedId); original.MarkChangesAsCommitted(); SerializableEventCentricAggregateRoot deserialized = original.Clone(); Assert.Equal(original, deserialized); Assert.NotSame(original, deserialized); Assert.Empty(deserialized.GetUncommittedChanges()); Assert.Equal(expectedId, deserialized.Id); Assert.Equal(original.GetHashCode(), deserialized.GetHashCode()); }