public void AddingEventsWithProperExpectedVersionToExistingEventDescriptorsPopulatesDatabase()
        {
            var aggregateId = Guid.NewGuid();
            var databaseMock = new DatabaseMock<EventDescriptors>();
            var existingEvents = new EventDescriptors{ Id = aggregateId };
            existingEvents.Add(new EventDescriptor(Guid.NewGuid(), new Event(), 0));
            existingEvents.Add(new EventDescriptor(Guid.NewGuid(), new Event(), 1));
            databaseMock.Put(existingEvents);
            var initialCount = existingEvents.Count();

            var expectedVersion = existingEvents.Count() - 1;
            IConcurrencyConflictResolver conflictResolver = null;
            var newEvents = new List<Event>
            {
                new Event(),
                new Event()
            };
            
            var publisherMock = new EventPublisherMock();

            var eventStore = new EventStore(publisherMock, databaseMock);

            eventStore.SaveEvents(
                aggregateId,
                newEvents,
                expectedVersion,
                conflictResolver);

            var actual = databaseMock.Get(aggregateId.ToString());

            Assert.NotNull(actual);
            Assert.Equal(newEvents.Count + initialCount, actual.Count());
            publisherMock.AssertPublishCount<Event>(newEvents.Count());
        }
        public void FetchingAggregateRootWhenExistsGetsProperListOfEvents()
        {
            var aggregateId = Guid.NewGuid();
            var databaseMock = new DatabaseMock<EventDescriptors>();
            var expected = new EventDescriptors { Id = aggregateId };
            expected.Add(new EventDescriptor(Guid.NewGuid(), new Event(), 0));
            expected.Add(new EventDescriptor(Guid.NewGuid(), new Event(), 1));
            databaseMock.Put(expected);
            var publisherMock = new EventPublisherMock();

            var eventStore = new EventStore(publisherMock, databaseMock);

            var actual = eventStore.GetEventsForAggregate(aggregateId);

            Assert.NotNull(actual);
            Assert.Equal(expected.Count(), actual.Count());
            Assert.Null(publisherMock.GetLastPublishedObject<Event>());
        }
        public void AddingImproperlyVersionedEventsWithNoConflictResolutionExpectException()
        {
            var aggregateId = Guid.NewGuid();
            var databaseMock = new DatabaseMock<EventDescriptors>();
            var existingEvents = new EventDescriptors { Id = aggregateId };
            existingEvents.Add(new EventDescriptor(Guid.NewGuid(), new Event1(), 0));
            existingEvents.Add(new EventDescriptor(Guid.NewGuid(), new Event1(), 1));
            databaseMock.Put(existingEvents);

            var expectedVersion = existingEvents.Count() - 2;
            IConcurrencyConflictResolver conflictResolver = new ConcurrencyConflictResolver();
            conflictResolver.RegisterConflictList(typeof(Event1), new List<Type> {typeof(Event1)});
            var newEvents = new List<Event>
            {
                new Event1(),
                new Event1()
            };

            var publisherMock = new EventPublisherMock();

            var eventStore = new EventStore(publisherMock, databaseMock);

            Assert.Throws<EventStoreConcurrencyException>(() =>
                eventStore.SaveEvents(
                    aggregateId,
                    newEvents,
                    expectedVersion,
                    conflictResolver));
        }
        public async void AddingImproperlyVersionedEventsConcurrentlyWithConflictResolutionPopulatesDatabase()
        {
            var aggregateId = Guid.NewGuid();
            var databaseMock = new DatabaseMock<EventDescriptors>();
            var existingEvents = new EventDescriptors {Id = aggregateId};
            existingEvents.Add(new EventDescriptor(Guid.NewGuid(), new Event(), 0));
            existingEvents.Add(new EventDescriptor(Guid.NewGuid(), new Event(), 1));
            databaseMock.Put(existingEvents);
            var initialCount = existingEvents.Count();

            var expectedVersion = 0;
            IConcurrencyConflictResolver conflictResolver = new ConcurrencyConflictResolver();
            conflictResolver.RegisterConflictList(typeof (Event2<EventConstraint1>), new List<Type>());
            conflictResolver.RegisterConflictList(typeof (Event2<EventConstraintAnother1>), new List<Type>());
            var newEventsSource1 = new List<Event>
            {
                new Event2<EventConstraint1>()
            };
            var newEventsSource2 = new List<Event>
            {
                new Event2<EventConstraintAnother1>()
            };

            var publisherMock = new EventPublisherMock();

            var eventStore = new EventStore(publisherMock, databaseMock);

            var task1 = Task.Run(() =>
                eventStore.SaveEvents(
                    aggregateId,
                    newEventsSource1,
                    expectedVersion,
                    conflictResolver));

            var task2 = Task.Run(()=>
                    eventStore.SaveEvents(
                    aggregateId,
                    newEventsSource2,
                    expectedVersion,
                    conflictResolver));

            await Task.WhenAll(task1, task2).ConfigureAwait(false);

            var actual = databaseMock.Get(aggregateId.ToString());

            Assert.NotNull(actual);
            Assert.Equal(newEventsSource1.Count + newEventsSource2.Count + initialCount, actual.Count());
            publisherMock.AssertPublishCount<Event>(newEventsSource1.Count + newEventsSource2.Count);
        }
        public void AddingEventsWithImproperExpectedVersionAndNullConflictResolverExpectException()
        {
            var aggregateId = Guid.NewGuid();
            var databaseMock = new DatabaseMock<EventDescriptors>();
            var existingEvents = new EventDescriptors { Id = aggregateId };
            existingEvents.Add(new EventDescriptor(Guid.NewGuid(), new Event(), 0));
            existingEvents.Add(new EventDescriptor(Guid.NewGuid(), new Event(), 1));
            databaseMock.Put(existingEvents);

            var expectedVersion = existingEvents.Count() - 2;
            IConcurrencyConflictResolver conflictResolver = null;
            var newEvents = new List<Event>
            {
                new Event(),
                new Event()
            };

            var publisherMock = new EventPublisherMock();

            var eventStore = new EventStore(publisherMock, databaseMock);

            Assert.Throws<EventStoreConcurrencyException>(() => 
                eventStore.SaveEvents(
                    aggregateId,
                    newEvents,
                    expectedVersion,
                    conflictResolver));
        }