public void RegisterConflictingOpenTypesTryToConflictWithEventWithDifferentGenericParameter()
        {
            var targetType = typeof(Event2<>);
            var conflictingTypes = new List<Type>
            {
                typeof(Event2<>)
            };
            var actualType = typeof(Event2<EventConstraint1>);
            var actualConflictingTypes = new List<Type> { typeof(Event2<EventConstraintAnother1>) };
            var resolver = new ConcurrencyConflictResolver();

            resolver.RegisterConflictList(targetType, conflictingTypes);

            Assert.False(resolver.ConflictsWith(actualType, actualConflictingTypes));
        }
        public void RegisterEmptyConflictingTypeListExpectNoConflicts()
        {
            var targetType = typeof(Event1);
            var conflictingTypes = new List<Type>
            {
                typeof(Event1),
                typeof(Event2<EventConstraint1>)
            };
            var resolver = new ConcurrencyConflictResolver();

            resolver.RegisterConflictList(targetType, new List<Type>());

            foreach (var conflictingType in conflictingTypes)
            {
                Assert.False(resolver.ConflictsWith(targetType, new List<Type> { conflictingType }));
            }
        }
        public void RegisterConflictingTypesAndExpectHasConflictToReturnTrue()
        {
            var targetType = typeof(Event1);
            var conflictingTypes = new List<Type>
            {
                typeof(Event1),
                typeof(Event2<EventConstraint1>)
            };
            var resolver = new ConcurrencyConflictResolver();

            resolver.RegisterConflictList(targetType, conflictingTypes);

            foreach (var conflictingType in conflictingTypes)
            {
                Assert.True(resolver.ConflictsWith(targetType, new List<Type> {conflictingType}));
            }
        }
        public void RegisterNonEventConflictListExpectException()
        {
            var targetType = typeof (Event1);
            var conflictingTypes = new List<Type>
            {
                typeof(EventConstraintBase1),
                typeof(Event2<EventConstraint1>)
            };
            var resolver = new ConcurrencyConflictResolver();

            Assert.Throws<ArgumentException>(() =>
                resolver.RegisterConflictList(targetType, conflictingTypes));
        }
        public void RegisterAndThenRegisterAgainAddsThoseToConflictList()
        {
            var targetType = typeof(Event1);
            var conflictingTypesOne = new List<Type>
            {
                typeof(Event1),
                typeof(Event2<EventConstraint1>)
            };
            var conflictingTypesTwo = new List<Type>
            {
                typeof (Event2<EventConstraint1>)
            };
            var resolver = new ConcurrencyConflictResolver();

            resolver.RegisterConflictList(targetType, conflictingTypesOne);
            resolver.RegisterConflictList(targetType, conflictingTypesTwo);

            foreach (var conflictingType in conflictingTypesTwo)
            {
                Assert.True(resolver.ConflictsWith(targetType, new List<Type> { conflictingType }));
            }

            foreach (var conflictingType in conflictingTypesOne)
            {
                Assert.True(resolver.ConflictsWith(targetType, new List<Type> { conflictingType }));
            }
        }
        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 AddingImproperlyVersionedEventsWithConflictResolutionPopulatesDatabase()
        {
            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() - 2;
            IConcurrencyConflictResolver conflictResolver = new ConcurrencyConflictResolver();
            conflictResolver.RegisterConflictList(typeof(Event1), new List<Type>());
            var newEvents = new List<Event>
            {
                new Event1(),
                new Event1()
            };

            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 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));
        }