From be58460bf1ca919e50c963803dcb168c1b3adc96 Mon Sep 17 00:00:00 2001 From: Sean Garrett Date: Wed, 5 Jul 2023 20:20:08 +0100 Subject: [PATCH] tokens for updater and unit tests --- CoreUnitTests/CoreUnitTests.csproj | 4 + .../UpdateManyAsyncTests.cs | 582 +++++++++++++ .../MongoDbUpdaterTests/UpdateManyTests.cs | 581 +++++++++++++ .../UpdateOneAsyncTests.cs | 806 ++++++++++++++++++ .../MongoDbUpdaterTests/UpdateOneTests.cs | 805 +++++++++++++++++ .../UpdateDefinitionExtensions.cs | 21 + .../DataAccess/Update/IMongoDbUpdater.cs | 75 +- .../Update/MongoDbUpdater.ClientSession.cs | 22 +- .../DataAccess/Update/MongoDbUpdater.cs | 180 ++-- 9 files changed, 2978 insertions(+), 98 deletions(-) create mode 100644 CoreUnitTests/DataAccessTests/MongoDbUpdaterTests/UpdateManyAsyncTests.cs create mode 100644 CoreUnitTests/DataAccessTests/MongoDbUpdaterTests/UpdateManyTests.cs create mode 100644 CoreUnitTests/DataAccessTests/MongoDbUpdaterTests/UpdateOneAsyncTests.cs create mode 100644 CoreUnitTests/DataAccessTests/MongoDbUpdaterTests/UpdateOneTests.cs create mode 100644 CoreUnitTests/Infrastructure/UpdateDefinitionExtensions.cs diff --git a/CoreUnitTests/CoreUnitTests.csproj b/CoreUnitTests/CoreUnitTests.csproj index d417073..58aa65b 100644 --- a/CoreUnitTests/CoreUnitTests.csproj +++ b/CoreUnitTests/CoreUnitTests.csproj @@ -30,4 +30,8 @@ + + + + diff --git a/CoreUnitTests/DataAccessTests/MongoDbUpdaterTests/UpdateManyAsyncTests.cs b/CoreUnitTests/DataAccessTests/MongoDbUpdaterTests/UpdateManyAsyncTests.cs new file mode 100644 index 0000000..f0322d1 --- /dev/null +++ b/CoreUnitTests/DataAccessTests/MongoDbUpdaterTests/UpdateManyAsyncTests.cs @@ -0,0 +1,582 @@ +using System; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; +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 UpdateManyAsyncTests : GenericTestContext +{ + [Fact] + public async Task 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 = await Sut.UpdateManyAsync( + filter, + updateDefinition); + + // Assert + result.Should().Be(count); + + collection + .Verify( + x => x.UpdateManyAsync( + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(updateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task 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 = await Sut.UpdateManyAsync( + filter, + updateDefinition, + cancellationToken: token); + + // Assert + result.Should().Be(count); + + collection + .Verify( + x => x.UpdateManyAsync( + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(updateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public async Task 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 = await Sut.UpdateManyAsync( + filter, + updateDefinition, + partitionKey); + + // Assert + result.Should().Be(count); + + collection + .Verify( + x => x.UpdateManyAsync( + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(updateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task 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 = await Sut.UpdateManyAsync( + filter, + updateDefinition, + partitionKey, + cancellationToken: token); + + // Assert + result.Should().Be(count); + + collection + .Verify( + x => x.UpdateManyAsync( + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(updateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public async Task 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 = await Sut.UpdateManyAsync( + filter, + fieldExpression, + value); + + // Assert + result.Should().Be(count); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateManyAsync( + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + + [Fact] + public async Task 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 = await Sut.UpdateManyAsync( + filter, + fieldExpression, + value, + partitionKey); + + // Assert + result.Should().Be(count); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateManyAsync( + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task 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 = await Sut.UpdateManyAsync( + filter, + fieldExpression, + value, + cancellationToken: token); + + // Assert + result.Should().Be(count); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateManyAsync( + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public async Task 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 = await Sut.UpdateManyAsync( + filter, + fieldExpression, + value, + partitionKey, + token); + + // Assert + result.Should().Be(count); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateManyAsync( + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public async Task 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 = await Sut.UpdateManyAsync( + 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.UpdateManyAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task 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 = await Sut.UpdateManyAsync( + 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.UpdateManyAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public async Task 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 = await Sut.UpdateManyAsync( + 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.UpdateManyAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task 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 = await Sut.UpdateManyAsync( + 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.UpdateManyAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public async Task 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 = await Sut.UpdateManyAsync( + 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.UpdateManyAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task 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 = await Sut.UpdateManyAsync( + 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.UpdateManyAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public async Task 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 = await Sut.UpdateManyAsync( + 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.UpdateManyAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task 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 = await Sut.UpdateManyAsync( + 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.UpdateManyAsync( + 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.UpdateManyAsync( + It.IsAny>(), + It.IsAny>(), + It.IsAny(), + It.IsAny())) + .ReturnsAsync(updateResult); + + collection + .Setup( + x => x.ReplaceOneAsync( + It.IsAny(), + It.IsAny>(), + It.IsAny(), + It.IsAny(), + It.IsAny())) + .ReturnsAsync(replaceResult); + + collection + .Setup( + x => x.UpdateManyAsync( + It.IsAny(), + It.IsAny>(), + It.IsAny>(), + It.IsAny(), + It.IsAny())) + .ReturnsAsync(updateResult); + + var dbContext = MockOf(); + dbContext + .Setup(x => x.GetCollection(partitionKey)) + .Returns(collection.Object); + return collection; + } +} diff --git a/CoreUnitTests/DataAccessTests/MongoDbUpdaterTests/UpdateManyTests.cs b/CoreUnitTests/DataAccessTests/MongoDbUpdaterTests/UpdateManyTests.cs new file mode 100644 index 0000000..1b87b86 --- /dev/null +++ b/CoreUnitTests/DataAccessTests/MongoDbUpdaterTests/UpdateManyTests.cs @@ -0,0 +1,581 @@ +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; + } +} diff --git a/CoreUnitTests/DataAccessTests/MongoDbUpdaterTests/UpdateOneAsyncTests.cs b/CoreUnitTests/DataAccessTests/MongoDbUpdaterTests/UpdateOneAsyncTests.cs new file mode 100644 index 0000000..5149e07 --- /dev/null +++ b/CoreUnitTests/DataAccessTests/MongoDbUpdaterTests/UpdateOneAsyncTests.cs @@ -0,0 +1,806 @@ +using System; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; +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 UpdateOneAsyncTests : GenericTestContext +{ + [Fact] + public async Task WithDocument_ReplacesOne() + { + // Arrange + var document = Fixture.Create(); + + var collection = SetupCollection(); + + // Act + var result = await Sut.UpdateOneAsync(document); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + ReplaceOptions expectedOptions = null; + collection + .Verify( + x => x.ReplaceOneAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + document, + expectedOptions, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task WithDocumentAndCancellationToken_ReplacesOne() + { + // Arrange + var document = Fixture.Create(); + var token = new CancellationToken(true); + var collection = SetupCollection(); + + // Act + var result = await Sut.UpdateOneAsync(document, token); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + ReplaceOptions expectedOptions = null; + collection + .Verify( + x => x.ReplaceOneAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + document, + expectedOptions, + token), + Times.Once()); + } + + [Fact] + public async Task WithDocumentAndUpdateDefinition_ReplacesOne() + { + // Arrange + var document = Fixture.Create(); + var collection = SetupCollection(); + var updateDefinition = Builders.Update.Set(x => x.Id, document.Id); + + // Act + var result = await Sut.UpdateOneAsync(document, updateDefinition); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + collection + .Verify( + x => x.UpdateOneAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + updateDefinition, + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task WithDocumentAndUpdateDefinitionAndCancellationToken_ReplacesOne() + { + // Arrange + var document = Fixture.Create(); + var collection = SetupCollection(); + var updateDefinition = Builders.Update.Set(x => x.Id, document.Id); + var token = new CancellationToken(true); + + // Act + var result = await Sut.UpdateOneAsync(document, updateDefinition, token); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + collection + .Verify( + x => x.UpdateOneAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + updateDefinition, + null, + token), + Times.Once()); + } + + [Fact] + public async Task WithDocumentAndFieldExpressionAndValue_ReplacesOne() + { + // Arrange + var document = Fixture.Create(); + var value = Fixture.Create(); + var collection = SetupCollection(); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = await Sut.UpdateOneAsync(document, fieldExpression, value); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOneAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task WithDocumentAndFieldExpressionAndValueAndCancellationToken_ReplacesOne() + { + // Arrange + var document = Fixture.Create(); + var value = Fixture.Create(); + var collection = SetupCollection(); + var token = new CancellationToken(true); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = await Sut.UpdateOneAsync(document, fieldExpression, value, token); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOneAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public async Task WithFilterAndFieldExpressionAndValueAndPartitionKey_ReplacesOne() + { + // Arrange + var value = Fixture.Create(); + var partitionKey = Fixture.Create(); + var collection = SetupCollection(partitionKey); + var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = await Sut.UpdateOneAsync( + filter, + fieldExpression, + value, + partitionKey); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOneAsync( + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task WithFilterAndFieldExpressionAndValueAndCancellationToken_ReplacesOne() + { + // Arrange + var value = Fixture.Create(); + var collection = SetupCollection(); + var token = new CancellationToken(true); + var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = await Sut.UpdateOneAsync( + filter, + fieldExpression, + value, + cancellationToken: token); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOneAsync( + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public async Task WithFilterAndFieldExpressionAndValueAndPartitionKeyAndCancellationToken_ReplacesOne() + { + // Arrange + var value = Fixture.Create(); + var partitionKey = Fixture.Create(); + var collection = SetupCollection(partitionKey); + var token = new CancellationToken(true); + var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = await Sut.UpdateOneAsync( + filter, + fieldExpression, + value, + partitionKey, + token); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOneAsync( + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public async Task WithFilterExpressionAndFieldExpressionAndValueAndCancellationToken_ReplacesOne() + { + // Arrange + var value = Fixture.Create(); + var collection = SetupCollection(); + var token = new CancellationToken(true); + Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = await Sut.UpdateOneAsync( + filterExpression, + fieldExpression, + value, + cancellationToken: token); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + var expectedFilter = Builders.Filter.Where(filterExpression); + collection + .Verify( + x => x.UpdateOneAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public async Task WithFilterExpressionAndFieldExpressionAndValueAndPartitionKey_ReplacesOne() + { + // Arrange + var value = Fixture.Create(); + var partitionKey = Fixture.Create(); + var collection = SetupCollection(partitionKey); + + Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = await Sut.UpdateOneAsync( + filterExpression, + fieldExpression, + value, + partitionKey); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + var expectedFilter = Builders.Filter.Where(filterExpression); + collection + .Verify( + x => x.UpdateOneAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task WithFilterExpressionAndFieldExpressionAndValueAndPartitionKeyAndCancellationToken_ReplacesOne() + { + // Arrange + var value = Fixture.Create(); + var partitionKey = Fixture.Create(); + var collection = SetupCollection(partitionKey); + var token = new CancellationToken(true); + Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = await Sut.UpdateOneAsync( + filterExpression, + fieldExpression, + value, + partitionKey, + token); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + var expectedFilter = Builders.Filter.Where(filterExpression); + collection + .Verify( + x => x.UpdateOneAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public async Task WithClientSessionAndDocument_ReplacesOne() + { + // Arrange + var session = MockOf(); + var document = Fixture.Create(); + + var collection = SetupCollection(); + + // Act + var result = await Sut.UpdateOneAsync(session.Object, document); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + ReplaceOptions expectedOptions = null; + collection + .Verify( + x => x.ReplaceOneAsync( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + document, + expectedOptions, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task WithClientSessionAndDocumentAndCancellationToken_ReplacesOne() + { + // Arrange + var session = MockOf(); + var document = Fixture.Create(); + var token = new CancellationToken(true); + var collection = SetupCollection(); + + // Act + var result = await Sut.UpdateOneAsync(session.Object, document, token); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + ReplaceOptions expectedOptions = null; + collection + .Verify( + x => x.ReplaceOneAsync( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + document, + expectedOptions, + token), + Times.Once()); + } + + [Fact] + public async Task WithClientSessionAndDocumentAndUpdateDefinition_ReplacesOne() + { + // Arrange + var session = MockOf(); + var document = Fixture.Create(); + var collection = SetupCollection(); + var updateDefinition = Builders.Update.Set(x => x.Id, document.Id); + + // Act + var result = await Sut.UpdateOneAsync(session.Object, document, updateDefinition); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + collection + .Verify( + x => x.UpdateOneAsync( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + updateDefinition, + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task WithClientSessionAndDocumentAndUpdateDefinitionAndCancellationToken_ReplacesOne() + { + // Arrange + var session = MockOf(); + var document = Fixture.Create(); + var collection = SetupCollection(); + var updateDefinition = Builders.Update.Set(x => x.Id, document.Id); + var token = new CancellationToken(true); + + // Act + var result = await Sut.UpdateOneAsync(session.Object, document, updateDefinition, token); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + collection + .Verify( + x => x.UpdateOneAsync( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + updateDefinition, + null, + token), + Times.Once()); + } + + [Fact] + public async Task WithClientSessionAndDocumentAndFieldExpressionAndValue_ReplacesOne() + { + // Arrange + var session = MockOf(); + var document = Fixture.Create(); + var value = Fixture.Create(); + var collection = SetupCollection(); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = await Sut.UpdateOneAsync(session.Object, document, fieldExpression, value); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOneAsync( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task WithClientSessionAndDocumentAndFieldExpressionAndValueAndCancellationToken_ReplacesOne() + { + // Arrange + var session = MockOf(); + var document = Fixture.Create(); + var value = Fixture.Create(); + var collection = SetupCollection(); + var token = new CancellationToken(true); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = await Sut.UpdateOneAsync(session.Object, document, fieldExpression, value, token); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOneAsync( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public async Task WithClientSessionAndFilterAndFieldExpressionAndValueAndPartitionKey_ReplacesOne() + { + // Arrange + var session = MockOf(); + var value = Fixture.Create(); + var partitionKey = Fixture.Create(); + var collection = SetupCollection(partitionKey); + var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = await Sut.UpdateOneAsync( + session.Object, + filter, + fieldExpression, + value, + partitionKey); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOneAsync( + session.Object, + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task WithClientSessionAndFilterAndFieldExpressionAndValueAndCancellationToken_ReplacesOne() + { + // Arrange + var session = MockOf(); + var value = Fixture.Create(); + var collection = SetupCollection(); + var token = new CancellationToken(true); + var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = await Sut.UpdateOneAsync( + session.Object, + filter, + fieldExpression, + value, + cancellationToken: token); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOneAsync( + session.Object, + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public async Task WithClientSessionAndFilterAndFieldExpressionAndValueAndPartitionKeyAndCancellationToken_ReplacesOne() + { + // Arrange + var session = MockOf(); + var value = Fixture.Create(); + var partitionKey = Fixture.Create(); + var collection = SetupCollection(partitionKey); + var token = new CancellationToken(true); + var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = await Sut.UpdateOneAsync( + session.Object, + filter, + fieldExpression, + value, + partitionKey, + token); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOneAsync( + session.Object, + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public async Task WithClientSessionAndFilterExpressionAndFieldExpressionAndValueAndCancellationToken_ReplacesOne() + { + // Arrange + var session = MockOf(); + var value = Fixture.Create(); + var collection = SetupCollection(); + var token = new CancellationToken(true); + Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = await Sut.UpdateOneAsync( + session.Object, + filterExpression, + fieldExpression, + value, + cancellationToken: token); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + var expectedFilter = Builders.Filter.Where(filterExpression); + collection + .Verify( + x => x.UpdateOneAsync( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public async Task WithClientSessionAndFilterExpressionAndFieldExpressionAndValueAndPartitionKey_ReplacesOne() + { + // Arrange + var session = MockOf(); + var value = Fixture.Create(); + var partitionKey = Fixture.Create(); + var collection = SetupCollection(partitionKey); + + Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = await Sut.UpdateOneAsync( + session.Object, + filterExpression, + fieldExpression, + value, + partitionKey); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + var expectedFilter = Builders.Filter.Where(filterExpression); + collection + .Verify( + x => x.UpdateOneAsync( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public async Task WithClientSessionAndFilterExpressionAndFieldExpressionAndValueAndPartitionKeyAndCancellationToken_ReplacesOne() + { + // Arrange + var session = MockOf(); + var value = Fixture.Create(); + var partitionKey = Fixture.Create(); + var collection = SetupCollection(partitionKey); + var token = new CancellationToken(true); + Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = await Sut.UpdateOneAsync( + session.Object, + filterExpression, + fieldExpression, + value, + partitionKey, + token); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + var expectedFilter = Builders.Filter.Where(filterExpression); + collection + .Verify( + x => x.UpdateOneAsync( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + private Mock> SetupCollection(string partitionKey = null) + { + var replacedId = Fixture.Create(); + var count = Fixture.Create(); + var replaceResult = new ReplaceOneResult.Acknowledged(count, 1, BsonValue.Create(replacedId)); + var updateResult = new UpdateResult.Acknowledged(count, 1, 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.UpdateOneAsync( + It.IsAny>(), + It.IsAny>(), + It.IsAny(), + It.IsAny())) + .ReturnsAsync(updateResult); + + collection + .Setup( + x => x.ReplaceOneAsync( + It.IsAny(), + It.IsAny>(), + It.IsAny(), + It.IsAny(), + It.IsAny())) + .ReturnsAsync(replaceResult); + + collection + .Setup( + x => x.UpdateOneAsync( + It.IsAny(), + It.IsAny>(), + It.IsAny>(), + It.IsAny(), + It.IsAny())) + .ReturnsAsync(updateResult); + + var dbContext = MockOf(); + dbContext + .Setup(x => x.GetCollection(partitionKey)) + .Returns(collection.Object); + return collection; + } +} diff --git a/CoreUnitTests/DataAccessTests/MongoDbUpdaterTests/UpdateOneTests.cs b/CoreUnitTests/DataAccessTests/MongoDbUpdaterTests/UpdateOneTests.cs new file mode 100644 index 0000000..e73728c --- /dev/null +++ b/CoreUnitTests/DataAccessTests/MongoDbUpdaterTests/UpdateOneTests.cs @@ -0,0 +1,805 @@ +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 UpdateOneTests : GenericTestContext +{ + [Fact] + public void WithDocument_ReplacesOne() + { + // Arrange + var document = Fixture.Create(); + + var collection = SetupCollection(); + + // Act + var result = Sut.UpdateOne(document); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + ReplaceOptions expectedOptions = null; + collection + .Verify( + x => x.ReplaceOne( + It.Is>(f => f.EquivalentTo(expectedFilter)), + document, + expectedOptions, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public void WithDocumentAndCancellationToken_ReplacesOne() + { + // Arrange + var document = Fixture.Create(); + var token = new CancellationToken(true); + var collection = SetupCollection(); + + // Act + var result = Sut.UpdateOne(document, token); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + ReplaceOptions expectedOptions = null; + collection + .Verify( + x => x.ReplaceOne( + It.Is>(f => f.EquivalentTo(expectedFilter)), + document, + expectedOptions, + token), + Times.Once()); + } + + [Fact] + public void WithDocumentAndUpdateDefinition_ReplacesOne() + { + // Arrange + var document = Fixture.Create(); + var collection = SetupCollection(); + var updateDefinition = Builders.Update.Set(x => x.Id, document.Id); + + // Act + var result = Sut.UpdateOne(document, updateDefinition); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + collection + .Verify( + x => x.UpdateOne( + It.Is>(f => f.EquivalentTo(expectedFilter)), + updateDefinition, + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public void WithDocumentAndUpdateDefinitionAndCancellationToken_ReplacesOne() + { + // Arrange + var document = Fixture.Create(); + var collection = SetupCollection(); + var updateDefinition = Builders.Update.Set(x => x.Id, document.Id); + var token = new CancellationToken(true); + + // Act + var result = Sut.UpdateOne(document, updateDefinition, token); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + collection + .Verify( + x => x.UpdateOne( + It.Is>(f => f.EquivalentTo(expectedFilter)), + updateDefinition, + null, + token), + Times.Once()); + } + + [Fact] + public void WithDocumentAndFieldExpressionAndValue_ReplacesOne() + { + // Arrange + var document = Fixture.Create(); + var value = Fixture.Create(); + var collection = SetupCollection(); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = Sut.UpdateOne(document, fieldExpression, value); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOne( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public void WithDocumentAndFieldExpressionAndValueAndCancellationToken_ReplacesOne() + { + // Arrange + var document = Fixture.Create(); + var value = Fixture.Create(); + var collection = SetupCollection(); + var token = new CancellationToken(true); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = Sut.UpdateOne(document, fieldExpression, value, token); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOne( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public void WithFilterAndFieldExpressionAndValueAndPartitionKey_ReplacesOne() + { + // Arrange + var value = Fixture.Create(); + var partitionKey = Fixture.Create(); + var collection = SetupCollection(partitionKey); + var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = Sut.UpdateOne( + filter, + fieldExpression, + value, + partitionKey); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOne( + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public void WithFilterAndFieldExpressionAndValueAndCancellationToken_ReplacesOne() + { + // Arrange + var value = Fixture.Create(); + var collection = SetupCollection(); + var token = new CancellationToken(true); + var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = Sut.UpdateOne( + filter, + fieldExpression, + value, + cancellationToken: token); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOne( + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public void WithFilterAndFieldExpressionAndValueAndPartitionKeyAndCancellationToken_ReplacesOne() + { + // Arrange + var value = Fixture.Create(); + var partitionKey = Fixture.Create(); + var collection = SetupCollection(partitionKey); + var token = new CancellationToken(true); + var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = Sut.UpdateOne( + filter, + fieldExpression, + value, + partitionKey, + token); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOne( + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public void WithFilterExpressionAndFieldExpressionAndValueAndCancellationToken_ReplacesOne() + { + // Arrange + var value = Fixture.Create(); + var collection = SetupCollection(); + var token = new CancellationToken(true); + Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = Sut.UpdateOne( + filterExpression, + fieldExpression, + value, + cancellationToken: token); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + var expectedFilter = Builders.Filter.Where(filterExpression); + collection + .Verify( + x => x.UpdateOne( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public void WithFilterExpressionAndFieldExpressionAndValueAndPartitionKey_ReplacesOne() + { + // Arrange + var value = Fixture.Create(); + var partitionKey = Fixture.Create(); + var collection = SetupCollection(partitionKey); + + Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = Sut.UpdateOne( + filterExpression, + fieldExpression, + value, + partitionKey); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + var expectedFilter = Builders.Filter.Where(filterExpression); + collection + .Verify( + x => x.UpdateOne( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public void WithFilterExpressionAndFieldExpressionAndValueAndPartitionKeyAndCancellationToken_ReplacesOne() + { + // Arrange + var value = Fixture.Create(); + var partitionKey = Fixture.Create(); + var collection = SetupCollection(partitionKey); + var token = new CancellationToken(true); + Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = Sut.UpdateOne( + filterExpression, + fieldExpression, + value, + partitionKey, + token); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + var expectedFilter = Builders.Filter.Where(filterExpression); + collection + .Verify( + x => x.UpdateOne( + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public void WithClientSessionAndDocument_ReplacesOne() + { + // Arrange + var session = MockOf(); + var document = Fixture.Create(); + + var collection = SetupCollection(); + + // Act + var result = Sut.UpdateOne(session.Object, document); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + ReplaceOptions expectedOptions = null; + collection + .Verify( + x => x.ReplaceOne( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + document, + expectedOptions, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public void WithClientSessionAndDocumentAndCancellationToken_ReplacesOne() + { + // Arrange + var session = MockOf(); + var document = Fixture.Create(); + var token = new CancellationToken(true); + var collection = SetupCollection(); + + // Act + var result = Sut.UpdateOne(session.Object, document, token); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + ReplaceOptions expectedOptions = null; + collection + .Verify( + x => x.ReplaceOne( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + document, + expectedOptions, + token), + Times.Once()); + } + + [Fact] + public void WithClientSessionAndDocumentAndUpdateDefinition_ReplacesOne() + { + // Arrange + var session = MockOf(); + var document = Fixture.Create(); + var collection = SetupCollection(); + var updateDefinition = Builders.Update.Set(x => x.Id, document.Id); + + // Act + var result = Sut.UpdateOne(session.Object, document, updateDefinition); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + collection + .Verify( + x => x.UpdateOne( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + updateDefinition, + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public void WithClientSessionAndDocumentAndUpdateDefinitionAndCancellationToken_ReplacesOne() + { + // Arrange + var session = MockOf(); + var document = Fixture.Create(); + var collection = SetupCollection(); + var updateDefinition = Builders.Update.Set(x => x.Id, document.Id); + var token = new CancellationToken(true); + + // Act + var result = Sut.UpdateOne(session.Object, document, updateDefinition, token); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + collection + .Verify( + x => x.UpdateOne( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + updateDefinition, + null, + token), + Times.Once()); + } + + [Fact] + public void WithClientSessionAndDocumentAndFieldExpressionAndValue_ReplacesOne() + { + // Arrange + var session = MockOf(); + var document = Fixture.Create(); + var value = Fixture.Create(); + var collection = SetupCollection(); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = Sut.UpdateOne(session.Object, document, fieldExpression, value); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOne( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public void WithClientSessionAndDocumentAndFieldExpressionAndValueAndCancellationToken_ReplacesOne() + { + // Arrange + var session = MockOf(); + var document = Fixture.Create(); + var value = Fixture.Create(); + var collection = SetupCollection(); + var token = new CancellationToken(true); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = Sut.UpdateOne(session.Object, document, fieldExpression, value, token); + + // Assert + result.Should().BeTrue(); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOne( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public void WithClientSessionAndFilterAndFieldExpressionAndValueAndPartitionKey_ReplacesOne() + { + // Arrange + var session = MockOf(); + var value = Fixture.Create(); + var partitionKey = Fixture.Create(); + var collection = SetupCollection(partitionKey); + var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = Sut.UpdateOne( + session.Object, + filter, + fieldExpression, + value, + partitionKey); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOne( + session.Object, + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public void WithClientSessionAndFilterAndFieldExpressionAndValueAndCancellationToken_ReplacesOne() + { + // Arrange + var session = MockOf(); + var value = Fixture.Create(); + var collection = SetupCollection(); + var token = new CancellationToken(true); + var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = Sut.UpdateOne( + session.Object, + filter, + fieldExpression, + value, + cancellationToken: token); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOne( + session.Object, + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public void WithClientSessionAndFilterAndFieldExpressionAndValueAndPartitionKeyAndCancellationToken_ReplacesOne() + { + // Arrange + var session = MockOf(); + var value = Fixture.Create(); + var partitionKey = Fixture.Create(); + var collection = SetupCollection(partitionKey); + var token = new CancellationToken(true); + var filter = Builders.Filter.Eq(x => x.SomeContent, "SomeContent"); + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = Sut.UpdateOne( + session.Object, + filter, + fieldExpression, + value, + partitionKey, + token); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + collection + .Verify( + x => x.UpdateOne( + session.Object, + It.Is>(f => f.EquivalentTo(filter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public void WithClientSessionAndFilterExpressionAndFieldExpressionAndValueAndCancellationToken_ReplacesOne() + { + // Arrange + var session = MockOf(); + var value = Fixture.Create(); + var collection = SetupCollection(); + var token = new CancellationToken(true); + Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = Sut.UpdateOne( + session.Object, + filterExpression, + fieldExpression, + value, + cancellationToken: token); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + var expectedFilter = Builders.Filter.Where(filterExpression); + collection + .Verify( + x => x.UpdateOne( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + [Fact] + public void WithClientSessionAndFilterExpressionAndFieldExpressionAndValueAndPartitionKey_ReplacesOne() + { + // Arrange + var session = MockOf(); + var value = Fixture.Create(); + var partitionKey = Fixture.Create(); + var collection = SetupCollection(partitionKey); + + Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = Sut.UpdateOne( + session.Object, + filterExpression, + fieldExpression, + value, + partitionKey); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + var expectedFilter = Builders.Filter.Where(filterExpression); + collection + .Verify( + x => x.UpdateOne( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + CancellationToken.None), + Times.Once()); + } + + [Fact] + public void WithClientSessionAndFilterExpressionAndFieldExpressionAndValueAndPartitionKeyAndCancellationToken_ReplacesOne() + { + // Arrange + var session = MockOf(); + var value = Fixture.Create(); + var partitionKey = Fixture.Create(); + var collection = SetupCollection(partitionKey); + var token = new CancellationToken(true); + Expression> filterExpression = testDocument => testDocument.SomeContent == "SomeContent"; + Expression> fieldExpression = testDocument => testDocument.SomeContent; + + // Act + var result = Sut.UpdateOne( + session.Object, + filterExpression, + fieldExpression, + value, + partitionKey, + token); + + // Assert + result.Should().BeTrue(); + + var expectedUpdateDefinition = Builders.Update.Set(x => x.SomeContent, value); + var expectedFilter = Builders.Filter.Where(filterExpression); + collection + .Verify( + x => x.UpdateOne( + session.Object, + It.Is>(f => f.EquivalentTo(expectedFilter)), + It.Is>(u => u.EquivalentTo(expectedUpdateDefinition)), + null, + token), + Times.Once()); + } + + private Mock> SetupCollection(string partitionKey = null) + { + var replacedId = Fixture.Create(); + var count = Fixture.Create(); + var replaceResult = new ReplaceOneResult.Acknowledged(count, 1, BsonValue.Create(replacedId)); + var updateResult = new UpdateResult.Acknowledged(count, 1, BsonValue.Create(replacedId)); + + var collection = MockOf>(); + collection + .Setup( + x => x.ReplaceOne( + It.IsAny>(), + It.IsAny(), + It.IsAny(), + It.IsAny())) + .Returns(replaceResult); + + collection + .Setup( + x => x.UpdateOne( + It.IsAny>(), + It.IsAny>(), + It.IsAny(), + It.IsAny())) + .Returns(updateResult); + + collection + .Setup( + x => x.ReplaceOne( + It.IsAny(), + It.IsAny>(), + It.IsAny(), + It.IsAny(), + It.IsAny())) + .Returns(replaceResult); + + collection + .Setup( + x => x.UpdateOne( + 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; + } +} diff --git a/CoreUnitTests/Infrastructure/UpdateDefinitionExtensions.cs b/CoreUnitTests/Infrastructure/UpdateDefinitionExtensions.cs new file mode 100644 index 0000000..e4cd92b --- /dev/null +++ b/CoreUnitTests/Infrastructure/UpdateDefinitionExtensions.cs @@ -0,0 +1,21 @@ +using System; +using MongoDB.Bson.Serialization; +using MongoDB.Driver; + +namespace CoreUnitTests.Infrastructure; + +public static class UpdateDefinitionExtensions +{ + public static bool EquivalentTo(this UpdateDefinition update, UpdateDefinition expected) + { + var renderedUpdate = update.Render( + BsonSerializer.SerializerRegistry.GetSerializer(), + BsonSerializer.SerializerRegistry); + + var renderedExpected = expected.Render( + BsonSerializer.SerializerRegistry.GetSerializer(), + BsonSerializer.SerializerRegistry); + + return renderedUpdate.Equals(renderedExpected); + } +} diff --git a/MongoDbGenericRepository/DataAccess/Update/IMongoDbUpdater.cs b/MongoDbGenericRepository/DataAccess/Update/IMongoDbUpdater.cs index abc8124..1d96fca 100644 --- a/MongoDbGenericRepository/DataAccess/Update/IMongoDbUpdater.cs +++ b/MongoDbGenericRepository/DataAccess/Update/IMongoDbUpdater.cs @@ -19,7 +19,8 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The type representing a Document. /// The type of the primary key for a Document. /// The document with the modifications you want to persist. - Task UpdateOneAsync(TDocument modifiedDocument) + /// An optional cancellation token. + Task UpdateOneAsync(TDocument modifiedDocument, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -30,7 +31,8 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The type of the primary key for a Document. /// The document you want to modify. /// The update definition for the document. - Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update) + /// An optional cancellation token. + Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -43,7 +45,8 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The document you want to modify. /// The field selector. /// The new value of the property field. - Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value) + /// An optional cancellation token. + Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -57,7 +60,8 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The field selector. /// The new value of the property field. /// The value of the partition key. - Task UpdateOneAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + /// An optional cancellation token. + Task UpdateOneAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -71,7 +75,8 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The field selector. /// The new value of the property field. /// The partition key for the document. - Task UpdateOneAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) + /// An optional cancellation token. + Task UpdateOneAsync(Expression> filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -84,7 +89,7 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The document with the modifications you want to persist. /// The optional cancellation token. /// - Task UpdateOneAsync(IClientSessionHandle session, TDocument modifiedDocument, CancellationToken cancellationToken = default(CancellationToken)) + Task UpdateOneAsync(IClientSessionHandle session, TDocument modifiedDocument, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -98,7 +103,7 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The update definition. /// The optional cancellation token. /// - Task UpdateOneAsync(IClientSessionHandle session, TDocument documentToModify, UpdateDefinition update, CancellationToken cancellationToken = default(CancellationToken)) + Task UpdateOneAsync(IClientSessionHandle session, TDocument documentToModify, UpdateDefinition update, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -108,13 +113,13 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The type representing a Document. /// The type of the primary key for a Document. /// The type of the field to update. - /// The client session. + /// The client session. /// The document to modify. /// The field to update. /// The value of the field. /// The optional cancellation token. /// - Task UpdateOneAsync(IClientSessionHandle session, TDocument documentToModify, Expression> field, TField value, CancellationToken cancellationToken = default(CancellationToken)) + Task UpdateOneAsync(IClientSessionHandle session, TDocument documentToModify, Expression> field, TField value, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -131,7 +136,7 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The optional partition key. /// The optional cancellation token. /// - Task UpdateOneAsync(IClientSessionHandle session, FilterDefinition filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken)) + Task UpdateOneAsync(IClientSessionHandle session, FilterDefinition filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -148,7 +153,7 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The optional partition key. /// The optional cancellation token. /// - Task UpdateOneAsync(IClientSessionHandle session, Expression> filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken)) + Task UpdateOneAsync(IClientSessionHandle session, Expression> filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -158,7 +163,8 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The type representing a Document. /// The type of the primary key for a Document. /// The document with the modifications you want to persist. - bool UpdateOne(TDocument modifiedDocument) + /// The optional cancellation token. + bool UpdateOne(TDocument modifiedDocument, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -169,7 +175,8 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The type of the primary key for a Document. /// The document you want to modify. /// The update definition for the document. - bool UpdateOne(TDocument documentToModify, UpdateDefinition update) + /// The optional cancellation token. + bool UpdateOne(TDocument documentToModify, UpdateDefinition update, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -182,7 +189,8 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The document you want to modify. /// The field selector. /// The new value of the property field. - bool UpdateOne(TDocument documentToModify, Expression> field, TField value) + /// The optional cancellation token. + bool UpdateOne(TDocument documentToModify, Expression> field, TField value, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -196,7 +204,8 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The field selector. /// The new value of the property field. /// The value of the partition key. - bool UpdateOne(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + /// The optional cancellation token. + bool UpdateOne(FilterDefinition filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -210,7 +219,8 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The field selector. /// The new value of the property field. /// The partition key for the document. - bool UpdateOne(Expression> filter, Expression> field, TField value, string partitionKey = null) + /// The optional cancellation token. + bool UpdateOne(Expression> filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -223,7 +233,7 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The document with the modifications you want to persist. /// The optional cancellation token. /// - bool UpdateOne(IClientSessionHandle session, TDocument modifiedDocument, CancellationToken cancellationToken = default(CancellationToken)) + bool UpdateOne(IClientSessionHandle session, TDocument modifiedDocument, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -237,7 +247,7 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The update definition. /// The optional cancellation token. /// - bool UpdateOne(IClientSessionHandle session, TDocument documentToModify, UpdateDefinition update, CancellationToken cancellationToken = default(CancellationToken)) + bool UpdateOne(IClientSessionHandle session, TDocument documentToModify, UpdateDefinition update, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -253,7 +263,7 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The value of the field. /// The optional cancellation token. /// - bool UpdateOne(IClientSessionHandle session, TDocument documentToModify, Expression> field, TField value, CancellationToken cancellationToken = default(CancellationToken)) + bool UpdateOne(IClientSessionHandle session, TDocument documentToModify, Expression> field, TField value, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -270,7 +280,7 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The optional partition key. /// The optional cancellation token. /// - bool UpdateOne(IClientSessionHandle session, FilterDefinition filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken)) + bool UpdateOne(IClientSessionHandle session, FilterDefinition filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -287,7 +297,7 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The optional partition key. /// The optional cancellation token. /// - bool UpdateOne(IClientSessionHandle session, Expression> filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken)) + bool UpdateOne(IClientSessionHandle session, Expression> filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -301,7 +311,8 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The field selector. /// The new value of the property field. /// The partition key for the document. - Task UpdateManyAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) + /// The optional cancellation token. + Task UpdateManyAsync(Expression> filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -315,7 +326,8 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The field selector. /// The new value of the property field. /// The value of the partition key. - Task UpdateManyAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + /// The optional cancellation token. + Task UpdateManyAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -325,9 +337,10 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The type representing a Document. /// The type of the primary key for a Document. /// The document filter. - /// the update definiton + /// the update definition /// The value of the partition key. - Task UpdateManyAsync(Expression> filter, UpdateDefinition update, string partitionKey = null) + /// The optional cancellation token. + Task UpdateManyAsync(Expression> filter, UpdateDefinition update, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -339,7 +352,8 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The document filter. /// The update definition. /// The value of the partition key. - Task UpdateManyAsync(FilterDefinition filter, UpdateDefinition updateDefinition, string partitionKey = null) + /// The optional cancellation token. + Task UpdateManyAsync(FilterDefinition filter, UpdateDefinition updateDefinition, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -353,7 +367,8 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The field selector. /// The new value of the property field. /// The partition key for the document. - long UpdateMany(Expression> filter, Expression> field, TField value, string partitionKey = null) + /// The optional cancellation token. + long UpdateMany(Expression> filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -367,7 +382,8 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The field selector. /// The new value of the property field. /// The value of the partition key. - long UpdateMany(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + /// The optional cancellation token. + long UpdateMany(FilterDefinition filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; @@ -379,7 +395,8 @@ namespace MongoDbGenericRepository.DataAccess.Update /// The document filter. /// The update definition. /// The value of the partition key. - long UpdateMany(FilterDefinition filter, UpdateDefinition updateDefinition, string partitionKey = null) + /// The optional cancellation token. + long UpdateMany(FilterDefinition filter, UpdateDefinition updateDefinition, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable; } diff --git a/MongoDbGenericRepository/DataAccess/Update/MongoDbUpdater.ClientSession.cs b/MongoDbGenericRepository/DataAccess/Update/MongoDbUpdater.ClientSession.cs index edc0c5c..8726c6f 100644 --- a/MongoDbGenericRepository/DataAccess/Update/MongoDbUpdater.ClientSession.cs +++ b/MongoDbGenericRepository/DataAccess/Update/MongoDbUpdater.ClientSession.cs @@ -10,7 +10,7 @@ namespace MongoDbGenericRepository.DataAccess.Update public partial class MongoDbUpdater { /// - public virtual async Task UpdateOneAsync(IClientSessionHandle session, TDocument modifiedDocument, CancellationToken cancellationToken = default(CancellationToken)) + public virtual async Task UpdateOneAsync(IClientSessionHandle session, TDocument modifiedDocument, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { @@ -22,7 +22,7 @@ namespace MongoDbGenericRepository.DataAccess.Update } /// - public virtual bool UpdateOne(IClientSessionHandle session, TDocument modifiedDocument, CancellationToken cancellationToken = default(CancellationToken)) + public virtual bool UpdateOne(IClientSessionHandle session, TDocument modifiedDocument, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { @@ -32,7 +32,7 @@ namespace MongoDbGenericRepository.DataAccess.Update } /// - public virtual async Task UpdateOneAsync(IClientSessionHandle session, TDocument documentToModify, UpdateDefinition update, CancellationToken cancellationToken = default(CancellationToken)) + public virtual async Task UpdateOneAsync(IClientSessionHandle session, TDocument documentToModify, UpdateDefinition update, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { @@ -42,7 +42,7 @@ namespace MongoDbGenericRepository.DataAccess.Update } /// - public virtual bool UpdateOne(IClientSessionHandle session, TDocument documentToModify, UpdateDefinition update, CancellationToken cancellationToken = default(CancellationToken)) + public virtual bool UpdateOne(IClientSessionHandle session, TDocument documentToModify, UpdateDefinition update, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { @@ -52,7 +52,7 @@ namespace MongoDbGenericRepository.DataAccess.Update } /// - public virtual async Task UpdateOneAsync(IClientSessionHandle session, TDocument documentToModify, Expression> field, TField value, CancellationToken cancellationToken = default(CancellationToken)) + public virtual async Task UpdateOneAsync(IClientSessionHandle session, TDocument documentToModify, Expression> field, TField value, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { @@ -65,7 +65,7 @@ namespace MongoDbGenericRepository.DataAccess.Update } /// - public virtual bool UpdateOne(IClientSessionHandle session, TDocument documentToModify, Expression> field, TField value, CancellationToken cancellationToken = default(CancellationToken)) + public virtual bool UpdateOne(IClientSessionHandle session, TDocument documentToModify, Expression> field, TField value, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { @@ -75,7 +75,7 @@ namespace MongoDbGenericRepository.DataAccess.Update } /// - public virtual async Task UpdateOneAsync(IClientSessionHandle session, FilterDefinition filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken)) + public virtual async Task UpdateOneAsync(IClientSessionHandle session, FilterDefinition filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { @@ -85,7 +85,7 @@ namespace MongoDbGenericRepository.DataAccess.Update } /// - public virtual Task UpdateOneAsync(IClientSessionHandle session, Expression> filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken)) + public virtual Task UpdateOneAsync(IClientSessionHandle session, Expression> filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { @@ -93,7 +93,7 @@ namespace MongoDbGenericRepository.DataAccess.Update } /// - public virtual bool UpdateOne(IClientSessionHandle session, FilterDefinition filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken)) + public virtual bool UpdateOne(IClientSessionHandle session, FilterDefinition filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { @@ -103,11 +103,11 @@ namespace MongoDbGenericRepository.DataAccess.Update } /// - public virtual bool UpdateOne(IClientSessionHandle session, Expression> filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken)) + public virtual bool UpdateOne(IClientSessionHandle session, Expression> filter, Expression> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { return UpdateOne(session, Builders.Filter.Where(filter), field, value, partitionKey, cancellationToken); } } -} +} \ No newline at end of file diff --git a/MongoDbGenericRepository/DataAccess/Update/MongoDbUpdater.cs b/MongoDbGenericRepository/DataAccess/Update/MongoDbUpdater.cs index 2d59aba..b5ffa7b 100644 --- a/MongoDbGenericRepository/DataAccess/Update/MongoDbUpdater.cs +++ b/MongoDbGenericRepository/DataAccess/Update/MongoDbUpdater.cs @@ -1,183 +1,247 @@ -using MongoDB.Driver; +using System; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; +using MongoDB.Driver; using MongoDbGenericRepository.DataAccess.Base; using MongoDbGenericRepository.Models; -using System; -using System.Linq.Expressions; -using System.Threading.Tasks; namespace MongoDbGenericRepository.DataAccess.Update { /// - /// The MongoDb updater. + /// The MongoDb updater. /// public partial class MongoDbUpdater : DataAccessBase, IMongoDbUpdater { /// - /// Constructor + /// Constructor /// /// public MongoDbUpdater(IMongoDbContext mongoDbContext) : base(mongoDbContext) { } - /// - public virtual async Task UpdateOneAsync(TDocument modifiedDocument) + /// + public virtual async Task UpdateOneAsync(TDocument modifiedDocument, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { var filter = Builders.Filter.Eq("Id", modifiedDocument.Id); - var updateRes = await HandlePartitioned(modifiedDocument).ReplaceOneAsync(filter, modifiedDocument); + var updateRes = await HandlePartitioned(modifiedDocument) + .ReplaceOneAsync(filter, modifiedDocument, cancellationToken: cancellationToken); return updateRes.ModifiedCount == 1; } - /// - public virtual bool UpdateOne(TDocument modifiedDocument) + /// + public virtual bool UpdateOne(TDocument modifiedDocument, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { var filter = Builders.Filter.Eq("Id", modifiedDocument.Id); - var updateRes = HandlePartitioned(modifiedDocument).ReplaceOne(filter, modifiedDocument); + var updateRes = HandlePartitioned(modifiedDocument).ReplaceOne(filter, modifiedDocument, cancellationToken: cancellationToken); return updateRes.ModifiedCount == 1; } - /// - public virtual async Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update) + /// + public virtual async Task UpdateOneAsync( + TDocument documentToModify, + UpdateDefinition update, + CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { var filter = Builders.Filter.Eq("Id", documentToModify.Id); - var updateRes = await HandlePartitioned(documentToModify).UpdateOneAsync(filter, update); + var updateRes = await HandlePartitioned(documentToModify).UpdateOneAsync(filter, update, cancellationToken: cancellationToken); return updateRes.ModifiedCount == 1; } - /// - public virtual bool UpdateOne(TDocument documentToModify, UpdateDefinition update) + /// + public virtual bool UpdateOne(TDocument documentToModify, UpdateDefinition update, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { var filter = Builders.Filter.Eq("Id", documentToModify.Id); - var updateRes = HandlePartitioned(documentToModify).UpdateOne(filter, update); + var updateRes = HandlePartitioned(documentToModify).UpdateOne(filter, update, cancellationToken: cancellationToken); return updateRes.ModifiedCount == 1; } - /// - public virtual async Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value) + /// + public virtual async Task UpdateOneAsync( + TDocument documentToModify, + Expression> field, + TField value, + CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { var filter = Builders.Filter.Eq("Id", documentToModify.Id); - var updateRes = await HandlePartitioned(documentToModify).UpdateOneAsync(filter, Builders.Update.Set(field, value)); + var updateRes = await HandlePartitioned(documentToModify).UpdateOneAsync( + filter, + Builders.Update.Set(field, value), + cancellationToken: cancellationToken); return updateRes.ModifiedCount == 1; } - /// - public virtual bool UpdateOne(TDocument documentToModify, Expression> field, TField value) + /// + public virtual bool UpdateOne(TDocument documentToModify, Expression> field, TField value, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { var filter = Builders.Filter.Eq("Id", documentToModify.Id); - var updateRes = HandlePartitioned(documentToModify).UpdateOne(filter, Builders.Update.Set(field, value)); + var updateRes = HandlePartitioned(documentToModify).UpdateOne(filter, Builders.Update.Set(field, value), cancellationToken: cancellationToken); return updateRes.ModifiedCount == 1; } - /// - public virtual async Task UpdateOneAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + /// + public virtual async Task UpdateOneAsync( + FilterDefinition filter, + Expression> field, + TField value, + string partitionKey = null, + CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); - var updateRes = await collection.UpdateOneAsync(filter, Builders.Update.Set(field, value)); + var updateRes = await collection.UpdateOneAsync(filter, Builders.Update.Set(field, value), cancellationToken: cancellationToken); return updateRes.ModifiedCount == 1; } - /// - public virtual async Task UpdateOneAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) + /// + public virtual async Task UpdateOneAsync( + Expression> filter, + Expression> field, + TField value, + string partitionKey = null, + CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { - return await UpdateOneAsync(Builders.Filter.Where(filter), field, value, partitionKey); + return await UpdateOneAsync(Builders.Filter.Where(filter), field, value, partitionKey, cancellationToken); } - /// - public virtual bool UpdateOne(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + /// + public virtual bool UpdateOne( + FilterDefinition filter, + Expression> field, + TField value, + string partitionKey = null, + CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); - var updateRes = collection.UpdateOne(filter, Builders.Update.Set(field, value)); + var updateRes = collection.UpdateOne(filter, Builders.Update.Set(field, value), cancellationToken: cancellationToken); return updateRes.ModifiedCount == 1; } - /// - public virtual bool UpdateOne(Expression> filter, Expression> field, TField value, string partitionKey = null) + /// + public virtual bool UpdateOne( + Expression> filter, + Expression> field, + TField value, + string partitionKey = null, + CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { - return UpdateOne(Builders.Filter.Where(filter), field, value, partitionKey); + return UpdateOne(Builders.Filter.Where(filter), field, value, partitionKey, cancellationToken); } - /// - public virtual async Task UpdateManyAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) + /// + public virtual async Task UpdateManyAsync( + Expression> filter, + Expression> field, + TField value, + string partitionKey = null, + CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { - return await UpdateManyAsync(Builders.Filter.Where(filter), field, value, partitionKey); + return await UpdateManyAsync(Builders.Filter.Where(filter), field, value, partitionKey, cancellationToken); } - /// - public virtual async Task UpdateManyAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + /// + public virtual async Task UpdateManyAsync( + FilterDefinition filter, + Expression> field, + TField value, + string partitionKey = null, + CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); - var updateRes = await collection.UpdateManyAsync(filter, Builders.Update.Set(field, value)); + var updateRes = await collection.UpdateManyAsync(filter, Builders.Update.Set(field, value), cancellationToken: cancellationToken); return updateRes.ModifiedCount; } - /// - public virtual async Task UpdateManyAsync(Expression> filter, UpdateDefinition update, string partitionKey = null) + /// + public virtual async Task UpdateManyAsync( + Expression> filter, + UpdateDefinition update, + string partitionKey = null, + CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { - return await UpdateManyAsync(Builders.Filter.Where(filter), update, partitionKey); + return await UpdateManyAsync(Builders.Filter.Where(filter), update, partitionKey, cancellationToken); } - /// - public virtual async Task UpdateManyAsync(FilterDefinition filter, UpdateDefinition updateDefinition, string partitionKey = null) + /// + public virtual async Task UpdateManyAsync( + FilterDefinition filter, + UpdateDefinition updateDefinition, + string partitionKey = null, + CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); - var updateRes = await collection.UpdateManyAsync(filter, updateDefinition); + var updateRes = await collection.UpdateManyAsync(filter, updateDefinition, cancellationToken: cancellationToken); return updateRes.ModifiedCount; } - /// - public virtual long UpdateMany(Expression> filter, Expression> field, TField value, string partitionKey = null) + /// + public virtual long UpdateMany( + Expression> filter, + Expression> field, + TField value, + string partitionKey = null, + CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { - return UpdateMany(Builders.Filter.Where(filter), field, value, partitionKey); + return UpdateMany(Builders.Filter.Where(filter), field, value, partitionKey, cancellationToken); } - /// - public virtual long UpdateMany(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + /// + public virtual long UpdateMany( + FilterDefinition filter, + Expression> field, + TField value, + string partitionKey = null, + CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); - var updateRes = collection.UpdateMany(filter, Builders.Update.Set(field, value)); + var updateRes = collection.UpdateMany(filter, Builders.Update.Set(field, value), cancellationToken: cancellationToken); return updateRes.ModifiedCount; } - /// - public virtual long UpdateMany(FilterDefinition filter, UpdateDefinition updateDefinition, string partitionKey = null) + /// + public virtual long UpdateMany( + FilterDefinition filter, + UpdateDefinition updateDefinition, + string partitionKey = null, + CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); - var updateRes = collection.UpdateMany(filter, updateDefinition); + var updateRes = collection.UpdateMany(filter, updateDefinition, cancellationToken: cancellationToken); return updateRes.ModifiedCount; } } -} +} \ No newline at end of file