using System; using System.Linq.Expressions; using System.Threading; using AutoFixture; using CoreUnitTests.Infrastructure; using CoreUnitTests.Infrastructure.Model; using FluentAssertions; using MongoDB.Bson; using MongoDB.Driver; using MongoDbGenericRepository; using MongoDbGenericRepository.DataAccess.Update; using Moq; using Xunit; namespace CoreUnitTests.DataAccessTests.MongoDbUpdaterTests; public class UpdateManyTests : GenericTestContext { [Fact] public void WithFilterAndUpdateDefinition_UpdatesMany() { // Arrange var count = Fixture.Create(); var value = Fixture.Create(); var updateDefinition = Builders.Update.Set(x => x.SomeContent, value); var collection = SetupCollection(count); var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); // Act var result = Sut.UpdateMany( filter, updateDefinition); // Assert result.Should().Be(count); collection .Verify( x => x.UpdateMany( It.Is>(f => f.EquivalentTo(filter)), It.Is>(u => u.EquivalentTo(updateDefinition)), null, CancellationToken.None), Times.Once()); } [Fact] public void WithFilterAndUpdateDefinitionAndCancellationToken_UpdatesMany() { // Arrange var count = Fixture.Create(); var value = Fixture.Create(); var updateDefinition = Builders.Update.Set(x => x.SomeContent, value); var collection = SetupCollection(count); var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); var token = new CancellationToken(true); // Act var result = Sut.UpdateMany( filter, updateDefinition, cancellationToken: token); // Assert result.Should().Be(count); collection .Verify( x => x.UpdateMany( It.Is>(f => f.EquivalentTo(filter)), It.Is>(u => u.EquivalentTo(updateDefinition)), null, token), Times.Once()); } [Fact] public void WithFilterAndUpdateDefinitionAndPartitionKey_UpdatesMany() { // Arrange var count = Fixture.Create(); var value = Fixture.Create(); var partitionKey = Fixture.Create(); var updateDefinition = Builders.Update.Set(x => x.SomeContent, value); var collection = SetupCollection(count, partitionKey); var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); // Act var result = Sut.UpdateMany( filter, updateDefinition, partitionKey); // Assert result.Should().Be(count); collection .Verify( x => x.UpdateMany( It.Is>(f => f.EquivalentTo(filter)), It.Is>(u => u.EquivalentTo(updateDefinition)), null, CancellationToken.None), Times.Once()); } [Fact] public void WithFilterAndUpdateDefinitionAndPartitionKeyAndCancellationToken_UpdatesMany() { // Arrange var count = Fixture.Create(); var value = Fixture.Create(); var partitionKey = Fixture.Create(); var updateDefinition = Builders.Update.Set(x => x.SomeContent, value); var collection = SetupCollection(count, partitionKey); var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); var token = new CancellationToken(true); // Act var result = Sut.UpdateMany( filter, updateDefinition, partitionKey, token); // Assert result.Should().Be(count); collection .Verify( x => x.UpdateMany( It.Is>(f => f.EquivalentTo(filter)), It.Is>(u => u.EquivalentTo(updateDefinition)), null, token), Times.Once()); } [Fact] public void WithFilterAndFieldExpressionAndValue_UpdatesMany() { // Arrange var count = Fixture.Create(); var value = Fixture.Create(); var collection = SetupCollection(count); var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); Expression> fieldExpression = testDocument => testDocument.SomeContent; // Act var result = Sut.UpdateMany( filter, fieldExpression, value); // Assert result.Should().Be(count); var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); collection .Verify( x => x.UpdateMany( It.Is>(f => f.EquivalentTo(filter)), It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), null, CancellationToken.None), Times.Once()); } [Fact] public void WithFilterAndFieldExpressionAndValueAndPartitionKey_UpdatesMany() { // Arrange var count = Fixture.Create(); var value = Fixture.Create(); var partitionKey = Fixture.Create(); var collection = SetupCollection(count, partitionKey); var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); Expression> fieldExpression = testDocument => testDocument.SomeContent; // Act var result = Sut.UpdateMany( filter, fieldExpression, value, partitionKey); // Assert result.Should().Be(count); var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); collection .Verify( x => x.UpdateMany( It.Is>(f => f.EquivalentTo(filter)), It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), null, CancellationToken.None), Times.Once()); } [Fact] public void WithFilterAndFieldExpressionAndValueAndCancellationToken_UpdatesMany() { // Arrange var count = Fixture.Create(); var value = Fixture.Create(); var collection = SetupCollection(count); var token = new CancellationToken(true); var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); Expression> fieldExpression = testDocument => testDocument.SomeContent; // Act var result = Sut.UpdateMany( filter, fieldExpression, value, cancellationToken: token); // Assert result.Should().Be(count); var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); collection .Verify( x => x.UpdateMany( It.Is>(f => f.EquivalentTo(filter)), It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), null, token), Times.Once()); } [Fact] public void WithFilterAndFieldExpressionAndValueAndPartitionKeyAndCancellationToken_UpdatesMany() { // Arrange var count = Fixture.Create(); var value = Fixture.Create(); var partitionKey = Fixture.Create(); var collection = SetupCollection(count, partitionKey); var token = new CancellationToken(true); var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); Expression> fieldExpression = testDocument => testDocument.SomeContent; // Act var result = Sut.UpdateMany( filter, fieldExpression, value, partitionKey, token); // Assert result.Should().Be(count); var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); collection .Verify( x => x.UpdateMany( It.Is>(f => f.EquivalentTo(filter)), It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), null, token), Times.Once()); } [Fact] public void WithFilterExpressionAndFieldExpressionAndValue_UpdatesMany() { // Arrange var count = Fixture.Create(); var value = Fixture.Create(); var collection = SetupCollection(count); Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; Expression> fieldExpression = testDocument => testDocument.SomeContent; // Act var result = Sut.UpdateMany( filterExpression, fieldExpression, value); // Assert result.Should().Be(count); var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); var expectedFilter = Builders.Filter.Where(filterExpression); collection .Verify( x => x.UpdateMany( It.Is>(f => f.EquivalentTo(expectedFilter)), It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), null, CancellationToken.None), Times.Once()); } [Fact] public void WithFilterExpressionAndFieldExpressionAndValueAndCancellationToken_UpdatesMany() { // Arrange var count = Fixture.Create(); var value = Fixture.Create(); var collection = SetupCollection(count); var token = new CancellationToken(true); Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; Expression> fieldExpression = testDocument => testDocument.SomeContent; // Act var result = Sut.UpdateMany( filterExpression, fieldExpression, value, cancellationToken: token); // Assert result.Should().Be(count); var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); var expectedFilter = Builders.Filter.Where(filterExpression); collection .Verify( x => x.UpdateMany( It.Is>(f => f.EquivalentTo(expectedFilter)), It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), null, token), Times.Once()); } [Fact] public void WithFilterExpressionAndFieldExpressionAndValueAndPartitionKey_UpdatesMany() { // Arrange var value = Fixture.Create(); var partitionKey = Fixture.Create(); var count = Fixture.Create(); var collection = SetupCollection(count, partitionKey); Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; Expression> fieldExpression = testDocument => testDocument.SomeContent; // Act var result = Sut.UpdateMany( filterExpression, fieldExpression, value, partitionKey); // Assert result.Should().Be(count); var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); var expectedFilter = Builders.Filter.Where(filterExpression); collection .Verify( x => x.UpdateMany( It.Is>(f => f.EquivalentTo(expectedFilter)), It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), null, CancellationToken.None), Times.Once()); } [Fact] public void WithFilterExpressionAndFieldExpressionAndValueAndPartitionKeyAndCancellationToken_UpdatesMany() { // Arrange var value = Fixture.Create(); var count = Fixture.Create(); var partitionKey = Fixture.Create(); var collection = SetupCollection(count, partitionKey); var token = new CancellationToken(true); Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; Expression> fieldExpression = testDocument => testDocument.SomeContent; // Act var result = Sut.UpdateMany( filterExpression, fieldExpression, value, partitionKey, token); // Assert result.Should().Be(count); var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); var expectedFilter = Builders.Filter.Where(filterExpression); collection .Verify( x => x.UpdateMany( It.Is>(f => f.EquivalentTo(expectedFilter)), It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), null, token), Times.Once()); } [Fact] public void WithFilterExpressionAndUpdateDefinition_UpdatesMany() { // Arrange var count = Fixture.Create(); var value = Fixture.Create(); var updateDefinition = Builders.Update.Set(x => x.SomeContent, value); var collection = SetupCollection(count); Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; // Act var result = Sut.UpdateMany( filterExpression, updateDefinition); // Assert result.Should().Be(count); var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); var expectedFilter = Builders.Filter.Where(filterExpression); collection .Verify( x => x.UpdateMany( It.Is>(f => f.EquivalentTo(expectedFilter)), It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), null, CancellationToken.None), Times.Once()); } [Fact] public void WithFilterExpressionAndUpdateDefinitionAndCancellationToken_UpdatesMany() { // Arrange var count = Fixture.Create(); var value = Fixture.Create(); var updateDefinition = Builders.Update.Set(x => x.SomeContent, value); var collection = SetupCollection(count); var token = new CancellationToken(true); Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; // Act var result = Sut.UpdateMany( filterExpression, updateDefinition, cancellationToken: token); // Assert result.Should().Be(count); var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); var expectedFilter = Builders.Filter.Where(filterExpression); collection .Verify( x => x.UpdateMany( It.Is>(f => f.EquivalentTo(expectedFilter)), It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), null, token), Times.Once()); } [Fact] public void WithFilterExpressionAndUpdateDefinitionAndPartitionKey_UpdatesMany() { // Arrange var value = Fixture.Create(); var partitionKey = Fixture.Create(); var updateDefinition = Builders.Update.Set(x => x.SomeContent, value); var count = Fixture.Create(); var collection = SetupCollection(count, partitionKey); Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; // Act var result = Sut.UpdateMany( filterExpression, updateDefinition, partitionKey); // Assert result.Should().Be(count); var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); var expectedFilter = Builders.Filter.Where(filterExpression); collection .Verify( x => x.UpdateMany( It.Is>(f => f.EquivalentTo(expectedFilter)), It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), null, CancellationToken.None), Times.Once()); } [Fact] public void WithFilterExpressionAndUpdateDefinitionAndPartitionKeyAndCancellationToken_UpdatesMany() { // Arrange var value = Fixture.Create(); var count = Fixture.Create(); var updateDefinition = Builders.Update.Set(x => x.SomeContent, value); var partitionKey = Fixture.Create(); var collection = SetupCollection(count, partitionKey); var token = new CancellationToken(true); Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; // Act var result = Sut.UpdateMany( filterExpression, updateDefinition, partitionKey, token); // Assert result.Should().Be(count); var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); var expectedFilter = Builders.Filter.Where(filterExpression); collection .Verify( x => x.UpdateMany( It.Is>(f => f.EquivalentTo(expectedFilter)), It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), null, token), Times.Once()); } private Mock> SetupCollection(long count, string partitionKey = null) { var replacedId = Fixture.Create(); var replaceResult = new ReplaceOneResult.Acknowledged(count, count, BsonValue.Create(replacedId)); var updateResult = new UpdateResult.Acknowledged(count, count, BsonValue.Create(replacedId)); var collection = MockOf>(); collection .Setup( x => x.ReplaceOneAsync( It.IsAny>(), It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(replaceResult); collection .Setup( x => x.UpdateMany( It.IsAny>(), It.IsAny>(), It.IsAny(), It.IsAny())) .Returns(updateResult); collection .Setup( x => x.ReplaceOneAsync( It.IsAny(), It.IsAny>(), It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(replaceResult); collection .Setup( x => x.UpdateMany( It.IsAny(), It.IsAny>(), It.IsAny>(), It.IsAny(), It.IsAny())) .Returns(updateResult); var dbContext = MockOf(); dbContext .Setup(x => x.GetCollection(partitionKey)) .Returns(collection.Object); return collection; } }