public async Task SaveEvents_fails_if_version_of_first_event_not_follows_aggregate()
        {
            // Arrange
            var userId = Guid.NewGuid();

            using (var db = new FakeEventStoreDbContext(_dbContextOptions))
            {
                var aggregate = new Aggregate
                {
                    AggregateId   = userId,
                    AggregateType = typeof(FakeUser).FullName,
                    Version       = 1,
                };
                db.Aggregates.Add(aggregate);
                await db.SaveChangesAsync();
            }

            var usernameChanged = new FakeUsernameChanged();

            usernameChanged.Raise(userId, 2);

            var sut = new SqlEventStore(
                () => new FakeEventStoreDbContext(_dbContextOptions),
                new JsonMessageSerializer());

            // Act
            Func <Task> action = () => sut.SaveEvents <FakeUser>(new[] { usernameChanged });

            // Assert
            action.ShouldThrow <ArgumentException>().Where(x => x.ParamName == "events");
        }
        public async Task SaveEvents_updates_Aggregate_correctly_for_existing_aggregate_id()
        {
            // Arrange
            var userId = Guid.NewGuid();

            using (var db = new FakeEventStoreDbContext(_dbContextOptions))
            {
                var aggregate = new Aggregate
                {
                    AggregateId   = userId,
                    AggregateType = typeof(FakeUser).FullName,
                    Version       = 1,
                };
                db.Aggregates.Add(aggregate);
                await db.SaveChangesAsync();
            }

            var usernameChanged = new FakeUsernameChanged();

            usernameChanged.Raise(userId, 1);

            var sut = new SqlEventStore(
                () => new FakeEventStoreDbContext(_dbContextOptions),
                new JsonMessageSerializer());

            // Act
            await sut.SaveEvents <FakeUser>(new[] { usernameChanged });

            // Assert
            using (var db = new FakeEventStoreDbContext(_dbContextOptions))
            {
                Aggregate actual = await db
                                   .Aggregates
                                   .Where(a => a.AggregateId == userId)
                                   .SingleOrDefaultAsync();

                actual.Version.Should().Be(usernameChanged.Version);
            }
        }
        public async Task SaveEvents_removes_existing_UniqueIndexedProperty_if_property_value_is_null()
        {
            // Arrange
            var userId = Guid.NewGuid();

            var sut = new SqlEventStore(
                () => new FakeEventStoreDbContext(_dbContextOptions),
                new JsonMessageSerializer());

            var created = new FakeUserCreated();

            created.Raise(userId);
            await sut.SaveEvents <FakeUser>(new[] { created });

            var usernameChanged = new FakeUsernameChanged {
                Username = null
            };

            usernameChanged.Raise(userId, 1);

            // Act
            await sut.SaveEvents <FakeUser>(new[] { usernameChanged });

            // Assert
            using (var db = new FakeEventStoreDbContext(_dbContextOptions))
            {
                UniqueIndexedProperty actual = await db
                                               .UniqueIndexedProperties
                                               .Where(
                    p =>
                    p.AggregateType == typeof(FakeUser).FullName &&
                    p.PropertyName == nameof(FakeUserCreated.Username) &&
                    p.PropertyValue == created.Username)
                                               .SingleOrDefaultAsync();

                actual.Should().BeNull();
            }
        }