public async Task Should_dispatch_events()
        {
            //Arrange
            var eventStoreMock = new Mock <IEventStore>();
            //var wasCalled = false;
            //var mediatorMock = new Mock<IMediator>();
            //mediatorMock
            //    .Setup(m => m.Publish(It.IsAny<TestDomainEvent>(), It.IsAny<CancellationToken>()))
            //    .Callback(() =>
            //    {
            //        wasCalled = true;
            //    });
            //    .Returns(Task.CompletedTask);

            //.ReturnsAsync(Task.CompletedTask); //<-- return Task to allow await to continue
            //mediatorMock.Setup(x=> x.Publish())
            var mediatorMock = new TestMediator();

            var sut           = new EventSourcedRepository <TestEventSourcedAggregateRoot>(eventStoreMock.Object, Mock.Of <ISnapshotStore>(), mediatorMock, new EventSourcingOptions(), Mock.Of <ILogger <EventSourcedRepository <TestEventSourcedAggregateRoot> > >());
            var testAggregate = new Mock <TestEventSourcedAggregateRoot>();
            var domainEvent   = new TestDomainEvent();
            var domainEvents  = new List <IDomainEvent> {
                domainEvent
            };

            testAggregate.Setup(a => a.GetUncommittedChanges()).Returns(domainEvents);
            //Act
            await sut.SaveAsync(testAggregate.Object, CancellationToken.None);

            //Assert
            //mediatorMock.Verify(m => m.Publish(domainEvent, It.IsAny<CancellationToken>()), Times.Once());

            mediatorMock.PublishCallsCount.Should().Be(1);
        }
        public async Task Should_mark_changes_as_committed_for_aggregate_when_aggregate_is_saved()
        {
            //Arrange
            var eventStoreMock = new Mock <IEventStore>();
            var sut            = new EventSourcedRepository <TestEventSourcedAggregateRoot>(eventStoreMock.Object, Mock.Of <ISnapshotStore>(), Mock.Of <IMediator>(), new EventSourcingOptions(), Mock.Of <ILogger <EventSourcedRepository <TestEventSourcedAggregateRoot> > >());
            var domainEvent    = Mock.Of <IDomainEvent>();
            var domainEvents   = new List <IDomainEvent> {
                domainEvent
            };
            var testAggregate = new Mock <TestEventSourcedAggregateRoot>();

            testAggregate.Setup(a => a.GetUncommittedChanges()).Returns(domainEvents);

            //Act
            await sut.SaveAsync(testAggregate.Object, CancellationToken.None);

            //Assert
            testAggregate.Verify(a => a.MarkChangesAsCommitted(), Times.Once);
        }
        public async Task Should_save_events_in_event_store_when_aggregate_is_saved()
        {
            //Arrange
            //var eventStoreMock = new Mock<IEventStore>();
            var eventStoreMock = new TestEventStore();
            var sut            = new EventSourcedRepository <TestEventSourcedAggregateRoot>(eventStoreMock, Mock.Of <ISnapshotStore>(), Mock.Of <IMediator>(), new EventSourcingOptions(), Mock.Of <ILogger <EventSourcedRepository <TestEventSourcedAggregateRoot> > >());
            var domainEvent    = Mock.Of <IDomainEvent>();
            var domainEvents   = new List <IDomainEvent> {
                domainEvent
            };
            var testAggregate = new TestEventSourcedAggregateRoot(Guid.NewGuid(), 5, domainEvents);

            //Act
            await sut.SaveAsync(testAggregate, CancellationToken.None);

            //Assert
            //eventStoreMock.Verify(es => es.AppendEventsToStreamAsync(It.IsAny<string>(), It.Is<IEnumerable<IDomainEvent>>(de=> de.Single() == domainEvent), null, It.IsAny<CancellationToken>()));
            eventStoreMock.AppendEventsToStreamAsyncCallsCount.Should().Be(1);
        }
        public async Task Should_save_snapshot_in_snapshot_store_when_aggregate_is_saved()
        {
            //Arrange
            var snapshotStore = Mock.Of <ISnapshotStore>();
            var sut           = new EventSourcedRepository <TestSnapshotAggregateRoot>(Mock.Of <IEventStore>(), snapshotStore, Mock.Of <IMediator>(), new EventSourcingOptions {
                DefaultSnapshotVersionFrequency = 1
            }, Mock.Of <ILogger <EventSourcedRepository <TestSnapshotAggregateRoot> > >());

            var domainEvent  = Mock.Of <IDomainEvent>();
            var domainEvents = new List <IDomainEvent> {
                domainEvent
            };
            var testAggregate = new TestSnapshotAggregateRoot(Guid.NewGuid(), 1000, 1, 10, domainEvents);

            //Act
            await sut.SaveAsync(testAggregate, CancellationToken.None);

            //Assert
            Mock.Get(snapshotStore)
            .Verify(
                x => x.StoreSnapshotAsync(It.IsAny <SnapshotEnvelope>(), It.IsAny <CancellationToken>()),
                Times.Once);
        }
        public async Task Should_not_take_snapshot_below_custom_frequency()
        {
            //Arrange
            var snapshotStore = Mock.Of <ISnapshotStore>();
            var options       = new EventSourcingOptions {
                DefaultSnapshotVersionFrequency = 10
            };
            var sut = new EventSourcedRepository <TestSnapshotAggregateRoot>(Mock.Of <IEventStore>(), snapshotStore, Mock.Of <IMediator>(), options, Mock.Of <ILogger <EventSourcedRepository <TestSnapshotAggregateRoot> > >());

            var domainEvent  = Mock.Of <IDomainEvent>();
            var domainEvents = new List <IDomainEvent> {
                domainEvent
            };
            var testAggregate = new TestSnapshotAggregateRoot(Guid.NewGuid(), 2, 1, 2, domainEvents);

            //Act
            await sut.SaveAsync(testAggregate, CancellationToken.None);

            //Assert
            Mock.Get(snapshotStore)
            .Verify(
                x => x.StoreSnapshotAsync(It.IsAny <SnapshotEnvelope>(), It.IsAny <CancellationToken>()),
                Times.Never);
        }