Beispiel #1
0
        public void GivenAnAggregateThenTheIdForThatAggregateIsReturned()
        {
            var  aggregate = new SerializableEventCentricAggregateRoot();
            Guid id        = aggregate;

            Assert.Equal(aggregate.Id, id);
        }
Beispiel #2
0
        public void GivenAnAggregateThenAReferenceForThatAggregateIsReturned()
        {
            var       aggregate = new SerializableEventCentricAggregateRoot();
            Reference reference = aggregate;

            Assert.True(reference.IsMatch(aggregate));
        }
Beispiel #3
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #7
0
        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());
        }
Beispiel #8
0
        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));
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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);
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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);
        }
Beispiel #29
0
        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);
        }
Beispiel #30
0
        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());
        }