├── .gitignore ├── CoreIntegrationTests ├── App.config ├── CRUDObjectIdTests.cs ├── CRUDPartitionedCollectionNameAttributeTests.cs ├── CRUDPartitionedTests.cs ├── CRUDTKeyPartitionedCollectionNameAttributeTests.cs ├── CRUDTKeyPartitionedTests.cs ├── CRUDTKeyTests.cs ├── CRUDTests.cs ├── CoreIntegrationTests.csproj ├── IdentityUserTests.cs └── Infrastructure │ ├── BaseMongoDbRepositoryTests.cs │ ├── GlobalVariables.cs │ ├── ITestRepository.cs │ ├── MongoDbConfig.cs │ ├── MongoDbDocumentTestBase.Main.cs │ ├── MongoDbDocumentTestBase.Update.cs │ ├── MongoDbTKeyDocumentTestBase.Main.cs │ ├── MongoDbTKeyDocumentTestBase.Update.cs │ ├── MongoDbTestFixture.cs │ ├── RandomExtensions.cs │ ├── TestClasses.cs │ └── TestRepository.cs ├── CoreUnitTests ├── .editorconfig ├── BaseMongoRepositoryTests │ ├── AddTests │ │ ├── AddManyAsyncTests.cs │ │ ├── AddManyTests.cs │ │ ├── AddOneAsyncTests.cs │ │ └── AddOneTests.cs │ ├── DeleteTests │ │ ├── DeleteManyAsyncTests.cs │ │ ├── DeleteManyTests.cs │ │ ├── DeleteOneAsyncTests.cs │ │ └── DeleteOneTests.cs │ ├── IndexTests │ │ ├── BaseIndexTests.cs │ │ ├── CreateAscendingIndexAsyncTests.cs │ │ ├── CreateCombinedTextIndexAsyncTests.cs │ │ ├── CreateDescendingIndexAsyncTests.cs │ │ ├── CreateHashedIndexAsyncTests.cs │ │ ├── CreateTextIndexAsyncTests.cs │ │ ├── DropIndexAsyncTests.cs │ │ └── GetIndexNamesAsyncTests.cs │ └── UpdateTests │ │ ├── UpdateManyAsyncTests.cs │ │ ├── UpdateManyTests.cs │ │ ├── UpdateOneAsyncTests.cs │ │ └── UpdateOneTests.cs ├── CoreUnitTests.csproj ├── DataAccessTests │ ├── MongoDbCreatorTests │ │ ├── AddManyAsyncTests.cs │ │ ├── AddManyTests.cs │ │ ├── AddOneAsyncTests.cs │ │ └── AddOneTests.cs │ ├── MongoDbEraserTests │ │ ├── DeleteManyAsyncTests.cs │ │ ├── DeleteManyTests.cs │ │ ├── DeleteOneAsyncTests.cs │ │ └── DeleteOneTests.cs │ ├── MongoDbIndexHandlerTests │ │ ├── BaseIndexTests.cs │ │ ├── CreateAscendingIndexAsyncTests.cs │ │ ├── CreateCombinedTextIndexAsyncTests.cs │ │ ├── CreateDescendingIndexAsyncTests.cs │ │ ├── CreateHashedIndexAsyncTests.cs │ │ ├── CreateTextIndexAsyncTests.cs │ │ ├── DropIndexAsyncTests.cs │ │ └── GetIndexNamesAsyncTests.cs │ ├── MongoDbReaderTests │ │ ├── AnyAsyncTests.cs │ │ ├── AnyTests.cs │ │ ├── BaseReaderTests.cs │ │ ├── CountAsyncTests.cs │ │ ├── CountTests.cs │ │ ├── GetAllAsyncTests.cs │ │ ├── GetAllTests.cs │ │ ├── GetByIdAsyncTests.cs │ │ ├── GetByIdTests.cs │ │ ├── GetByMaxAsyncTests.cs │ │ ├── GetByMaxTests.cs │ │ ├── GetByMinAsyncTests.cs │ │ ├── GetByMinTests.cs │ │ ├── GetMaxValueAsyncTests .cs │ │ ├── GetMaxValueTests .cs │ │ ├── GetMinValueAsyncTests .cs │ │ ├── GetMinValueTests .cs │ │ ├── GetOneAsyncTests.cs │ │ ├── GetOneTests.cs │ │ ├── ProjectManyAsyncTests.cs │ │ ├── ProjectManyTests.cs │ │ ├── ProjectOneAsyncTests.cs │ │ └── ProjectOneTests.cs │ └── MongoDbUpdaterTests │ │ ├── UpdateManyAsyncTests.cs │ │ ├── UpdateManyTests.cs │ │ ├── UpdateOneAsyncTests.cs │ │ └── UpdateOneTests.cs ├── Infrastructure │ ├── FilterDefinitionExtensions.cs │ ├── GenericTestContext.cs │ ├── IndexExtensions.cs │ ├── Model │ │ ├── Child.cs │ │ ├── Nested.cs │ │ ├── PartitionedTestDocument.cs │ │ ├── TestDocument.cs │ │ ├── TestDocumentWithKey.cs │ │ └── TestProjection.cs │ ├── TestKeyedMongoRepository.cs │ ├── TestKeyedMongoRepositoryContext.cs │ ├── TestKeyedReadOnlyMongoRepository.cs │ ├── TestKeyedReadOnlyMongoRepositoryContext.cs │ ├── TestMongoRepository.cs │ ├── TestMongoRepositoryContext.cs │ ├── TestReadOnlyMongoRepository.cs │ ├── TestReadOnlyMongoRepositoryContext.cs │ └── UpdateDefinitionExtensions.cs ├── KeyTypedRepositoryTests │ ├── AddTests │ │ ├── AddManyAsyncTests.cs │ │ ├── AddManyTests.cs │ │ ├── AddOneAsyncTests.cs │ │ └── AddOneTests.cs │ ├── DeleteTests │ │ ├── DeleteManyAsyncTests.cs │ │ ├── DeleteManyTests.cs │ │ ├── DeleteOneAsyncTests.cs │ │ └── DeleteOneTests.cs │ ├── IndexTests │ │ ├── CreateAscendingIndexAsyncTests.cs │ │ ├── CreateCombinedTextIndexAsyncTests.cs │ │ ├── CreateDescendingIndexAsyncTests.cs │ │ ├── CreateHashedIndexAsyncTests.cs │ │ ├── CreateTextIndexAsyncTests.cs │ │ ├── DropIndexAsyncTests.cs │ │ └── GetIndexNamesAsyncTests.cs │ └── UpdateTests │ │ ├── UpdateManyAsyncTests.cs │ │ ├── UpdateManyTests.cs │ │ ├── UpdateOneAsyncTests.cs │ │ └── UpdateOneTests.cs ├── KeyedReadOnlyMongoRepositoryTests │ ├── AnyAsyncTests.cs │ ├── AnyTests.cs │ ├── CountAsyncTests.cs │ ├── CountTests.cs │ ├── GetAllAsyncTests.cs │ ├── GetAllTests.cs │ ├── GetByIdAsyncTests.cs │ ├── GetByIdTests.cs │ ├── GetByMaxAsyncTests.cs │ ├── GetByMaxTests.cs │ ├── GetByMinAsyncTests.cs │ ├── GetByMinTests.cs │ ├── GetMaxValueAsyncTests.cs │ ├── GetMaxValueTests.cs │ ├── GetMinValueAsyncTests.cs │ ├── GetMinValueTests.cs │ ├── GetOneAsyncTests.cs │ ├── GetOneTests.cs │ ├── GetSortedPaginatedAsyncTests.cs │ ├── GroupByTests.cs │ ├── ProjectManyAsyncTests.cs │ ├── ProjectManyTests.cs │ ├── ProjectOneAsyncTests.cs │ ├── ProjectOneTests.cs │ └── SumByAsyncTests.cs └── ReadOnlyMongoRepositoryTests │ ├── AnyAsyncTests.cs │ ├── AnyTests.cs │ ├── CountAsyncTests.cs │ ├── CountTests.cs │ ├── GetAllAsyncTests.cs │ ├── GetAllTests.cs │ ├── GetByIdAsyncTests.cs │ ├── GetByIdTests.cs │ ├── GetByMaxAsyncTests.cs │ ├── GetByMaxTests.cs │ ├── GetByMinAsyncTests.cs │ ├── GetByMinTests.cs │ ├── GetMaxValueAsyncTests.cs │ ├── GetMaxValueTests.cs │ ├── GetMinValueAsyncTests.cs │ ├── GetMinValueTests.cs │ ├── GetOneAsyncTests.cs │ ├── GetOneTests.cs │ ├── GetSortedPaginatedAsyncTests.cs │ ├── GroupByTests.cs │ ├── ProjectManyAsyncTests.cs │ ├── ProjectManyTests.cs │ ├── ProjectOneAsyncTests.cs │ ├── ProjectOneTests.cs │ └── SumByAsyncTests.cs ├── IntegrationTests ├── App.config ├── CRUDObjectIdTests.cs ├── CRUDPartitionedCollectionNameAttributeTests.cs ├── CRUDPartitionedTests.cs ├── CRUDTKeyPartitionedCollectionNameAttributeTests.cs ├── CRUDTKeyPartitionedTests.cs ├── CRUDTKeyTests.cs ├── CRUDTests.cs ├── Infrastructure │ ├── BaseMongoDbRepositoryTests.cs │ ├── GlobalVariables.cs │ ├── ITestRepository.cs │ ├── MongoDBDocumentTestBase.cs │ ├── MongoDbTKeyDocumentTestBase.cs │ ├── RandomExtensions.cs │ ├── TestClasses.cs │ └── TestRepository.cs ├── IntegrationTests.csproj ├── Properties │ └── AssemblyInfo.cs ├── libmongocrypt.dylib ├── libmongocrypt.so ├── mongocrypt.dll └── packages.config ├── LICENSE ├── MongoDbGenericRepository.sln ├── MongoDbGenericRepository ├── Abstractions │ ├── IBaseMongoRepository.cs │ ├── IBaseMongoRepository_Update.cs │ ├── IBaseMongoRepository_Update_ClientSession.cs │ ├── IBaseReadOnlyRepository.cs │ ├── IMongoDbContext.cs │ ├── IReadOnlyMongoRepository.TKey.cs │ └── IReadOnlyMongoRepository.cs ├── Attributes │ └── CollectionNameAttribute.cs ├── BaseMongoRepository.Create.cs ├── BaseMongoRepository.Delete.cs ├── BaseMongoRepository.Index.cs ├── BaseMongoRepository.Main.cs ├── BaseMongoRepository.Update.ClientSession.cs ├── BaseMongoRepository.Update.cs ├── DataAccess │ ├── Base │ │ ├── DataAccessBase.cs │ │ └── IDataAccessBase.cs │ ├── Create │ │ ├── IMongoDbCreator.cs │ │ └── MongoDbCreator.cs │ ├── Delete │ │ ├── IMongoDbEraser.cs │ │ └── MongoDbEraser.cs │ ├── Index │ │ ├── IMongoDbIndexHandler.cs │ │ └── MongoDbIndexHandler.cs │ ├── Read │ │ ├── IMongoDbReader.cs │ │ ├── MongoDbReader.GroupBy.cs │ │ ├── MongoDbReader.Main.cs │ │ └── MongoDbReader.Project.cs │ └── Update │ │ ├── IMongoDbUpdater.cs │ │ ├── MongoDbUpdater.ClientSession.cs │ │ └── MongoDbUpdater.cs ├── IBaseMongoRepository.Create.cs ├── IBaseMongoRepository.Delete.cs ├── IBaseMongoRepository.Index.cs ├── Internals │ └── RepositorySerializationProvider.cs ├── KeyTypedRepository │ ├── BaseMongoRepository.TKey.Create.cs │ ├── BaseMongoRepository.TKey.Delete.cs │ ├── BaseMongoRepository.TKey.Index.cs │ ├── BaseMongoRepository.TKey.Main.cs │ ├── BaseMongoRepository.TKey.ReadOnly.cs │ ├── BaseMongoRepository.TKey.Update.cs │ ├── IBaseMongoRepository.TKey.Create.cs │ ├── IBaseMongoRepository.TKey.Delete.cs │ ├── IBaseMongoRepository.TKey.Index.cs │ ├── IBaseMongoRepository.TKey.Update.cs │ └── IBaseMongoRepository.TKey.cs ├── Models │ ├── Document.cs │ ├── IDocument.cs │ ├── IPartitionedDocument.cs │ ├── IndexCreationOptions.cs │ └── PartitionedDocument.cs ├── MongoDbContext.cs ├── MongoDbGenericRepository.csproj ├── MongoDbGenericRepository.csproj.user ├── MongoDbGenericRepository.xml ├── ReadOnlyMongoRepository.cs ├── Utils │ ├── IdGenerator.cs │ ├── Pluralization.cs │ └── RandomExtensions.cs └── _rels │ └── .rels └── README.md /CoreIntegrationTests/App.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /CoreIntegrationTests/CRUDObjectIdTests.cs: -------------------------------------------------------------------------------- 1 | using CoreIntegrationTests.Infrastructure; 2 | using MongoDB.Bson; 3 | 4 | namespace CoreIntegrationTests 5 | { 6 | public class CoreObjectIdTestDocument : TestDoc 7 | { 8 | } 9 | 10 | public class CRUDObjectIdTests : MongoDbTKeyDocumentTestBase 11 | { 12 | public CRUDObjectIdTests(MongoDbTestFixture fixture) : base(fixture) 13 | { 14 | 15 | } 16 | 17 | public override string GetClassName() 18 | { 19 | return "CRUDObjectIdTests"; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /CoreIntegrationTests/CRUDPartitionedCollectionNameAttributeTests.cs: -------------------------------------------------------------------------------- 1 | using CoreIntegrationTests.Infrastructure; 2 | using MongoDbGenericRepository.Attributes; 3 | using MongoDbGenericRepository.Models; 4 | using System; 5 | 6 | namespace CoreIntegrationTests 7 | { 8 | [CollectionName("CoreTestingCNameAttrPart")] 9 | public class CorePartitionedCollectionNameDoc : TestDoc, IPartitionedDocument 10 | { 11 | public CorePartitionedCollectionNameDoc() 12 | { 13 | PartitionKey = "CoreTestPartitionKeyCollectionName"; 14 | } 15 | 16 | public string PartitionKey { get; set; } 17 | } 18 | 19 | public class CRUDPartitionedCollectionNameAttributeTests : MongoDbDocumentTestBase 20 | { 21 | public CRUDPartitionedCollectionNameAttributeTests(MongoDbTestFixture fixture) : base(fixture) 22 | { 23 | 24 | } 25 | 26 | public override string GetClassName() 27 | { 28 | return "CoreCRUDPartitionedCollectionNameAttributeTests"; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /CoreIntegrationTests/CRUDPartitionedTests.cs: -------------------------------------------------------------------------------- 1 | using CoreIntegrationTests.Infrastructure; 2 | using MongoDbGenericRepository.Models; 3 | using System; 4 | 5 | namespace CoreIntegrationTests 6 | { 7 | public class CorePartitionedDoc : TestDoc, IPartitionedDocument 8 | { 9 | public CorePartitionedDoc() 10 | { 11 | PartitionKey = "CoreTestPartitionKey"; 12 | } 13 | 14 | public string PartitionKey { get; set; } 15 | } 16 | 17 | public class CRUDPartitionedTests : MongoDbDocumentTestBase 18 | { 19 | public CRUDPartitionedTests(MongoDbTestFixture fixture) : base(fixture) 20 | { 21 | } 22 | 23 | public override string GetClassName() 24 | { 25 | return "CoreCRUDPartitionedTests"; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /CoreIntegrationTests/CRUDTKeyPartitionedCollectionNameAttributeTests.cs: -------------------------------------------------------------------------------- 1 | using CoreIntegrationTests.Infrastructure; 2 | using MongoDB.Bson; 3 | using MongoDbGenericRepository.Attributes; 4 | using MongoDbGenericRepository.Models; 5 | using System; 6 | 7 | namespace CoreIntegrationTests 8 | { 9 | #region Guid Type 10 | 11 | [CollectionName("TestingCNameAttrPartTKey")] 12 | public class CoreTKeyPartitionedCollectionNameDoc : TestDoc, IPartitionedDocument 13 | { 14 | public CoreTKeyPartitionedCollectionNameDoc() 15 | { 16 | PartitionKey = "CoreTestPartitionKey"; 17 | } 18 | 19 | public string PartitionKey { get; set; } 20 | } 21 | 22 | public class CRUDTKeyPartitionedCollectionNameAttributeTests : MongoDbTKeyDocumentTestBase 23 | { 24 | public CRUDTKeyPartitionedCollectionNameAttributeTests(MongoDbTestFixture fixture) : base(fixture) 25 | { 26 | 27 | } 28 | 29 | public override string GetClassName() 30 | { 31 | return "CoreCRUDTKeyPartitionedCollectionNameAttributeTests"; 32 | } 33 | } 34 | 35 | #endregion Guid Type 36 | 37 | 38 | #region ObjectId Type 39 | 40 | [CollectionName("TestingCNameAttrPartObjectId")] 41 | public class CoreObjectIdPartitionedCollectionNameDoc : TestDoc, IPartitionedDocument 42 | { 43 | public CoreObjectIdPartitionedCollectionNameDoc() 44 | { 45 | PartitionKey = "CoreTestPartitionKeyObjectId"; 46 | } 47 | 48 | public string PartitionKey { get; set; } 49 | } 50 | 51 | public class CRUDObjectIdPartitionedCollectionNameAttributeTests : MongoDbTKeyDocumentTestBase 52 | { 53 | public CRUDObjectIdPartitionedCollectionNameAttributeTests(MongoDbTestFixture fixture) : base(fixture) 54 | { 55 | 56 | } 57 | 58 | public override string GetClassName() 59 | { 60 | return "CoreCRUDTKeyPartitionedCollectionNameAttributeTests"; 61 | } 62 | } 63 | 64 | #endregion ObjectId Type 65 | } 66 | -------------------------------------------------------------------------------- /CoreIntegrationTests/CRUDTKeyPartitionedTests.cs: -------------------------------------------------------------------------------- 1 | using CoreIntegrationTests.Infrastructure; 2 | using MongoDbGenericRepository.Models; 3 | using System; 4 | 5 | namespace CoreIntegrationTests 6 | { 7 | public class CorePartitionedTKeyTestDocument : TestDoc, IPartitionedDocument 8 | { 9 | public CorePartitionedTKeyTestDocument() 10 | { 11 | PartitionKey = "CoreTestPartitionKey"; 12 | } 13 | public string PartitionKey { get; set; } 14 | } 15 | 16 | public class CRUDTKeyPartitionedTests : MongoDbTKeyDocumentTestBase 17 | { 18 | public CRUDTKeyPartitionedTests(MongoDbTestFixture fixture) : base(fixture) 19 | { 20 | 21 | } 22 | 23 | public override string GetClassName() 24 | { 25 | return "CoreCRUDTKeyPartitionedTests"; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /CoreIntegrationTests/CRUDTKeyTests.cs: -------------------------------------------------------------------------------- 1 | using CoreIntegrationTests.Infrastructure; 2 | using System; 3 | 4 | namespace CoreIntegrationTests 5 | { 6 | public class CoreTKeyTestDocument : TestDoc 7 | { 8 | } 9 | 10 | public class CRUDTKeyTests : MongoDbTKeyDocumentTestBase 11 | { 12 | public CRUDTKeyTests(MongoDbTestFixture fixture) : base(fixture) 13 | { 14 | 15 | } 16 | 17 | public override string GetClassName() 18 | { 19 | return "CreateTKeyTests"; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /CoreIntegrationTests/CRUDTests.cs: -------------------------------------------------------------------------------- 1 | using CoreIntegrationTests.Infrastructure; 2 | using System; 3 | 4 | namespace CoreIntegrationTests 5 | { 6 | public class CoreTestDocument : TestDoc 7 | { 8 | } 9 | 10 | public class CRUDTests : MongoDbDocumentTestBase 11 | { 12 | public CRUDTests(MongoDbTestFixture fixture) : base(fixture) 13 | { 14 | } 15 | 16 | public override string GetClassName() 17 | { 18 | return "CRUDTests"; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /CoreIntegrationTests/CoreIntegrationTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | disable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | all 14 | runtime; build; native; contentfiles; analyzers 15 | 16 | 17 | all 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | 20 | 21 | 22 | 23 | 24 | 25 | Always 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /CoreIntegrationTests/IdentityUserTests.cs: -------------------------------------------------------------------------------- 1 | using CoreIntegrationTests.Infrastructure; 2 | using MongoDbGenericRepository.Models; 3 | using System; 4 | using System.Collections.Generic; 5 | using Xunit; 6 | using Microsoft.AspNetCore.Identity; 7 | using System.Threading.Tasks; 8 | 9 | namespace CoreIntegrationTests 10 | { 11 | public class MongoIdentityUser : IdentityUser, IDocument 12 | where TKey : IEquatable 13 | { 14 | public int Version { get; set; } 15 | } 16 | 17 | public class IdentityUserTest : MongoIdentityUser, IDocument 18 | { 19 | public IdentityUserTest() 20 | { 21 | Id = Guid.NewGuid(); 22 | Version = 2; 23 | } 24 | public string SomeContent { get; set; } 25 | } 26 | 27 | public class IdentityUserTests : BaseMongoDbRepositoryTests 28 | { 29 | [Fact] 30 | public void AddOne() 31 | { 32 | // Arrange 33 | var document = new IdentityUserTest(); 34 | // Act 35 | SUT.AddOne(document); 36 | // Assert 37 | long count = SUT.Count(e => e.Id == document.Id); 38 | Assert.Equal(1, count); 39 | } 40 | 41 | [Fact] 42 | public async Task AddOneAsync() 43 | { 44 | // Arrange 45 | var document = new IdentityUserTest(); 46 | // Act 47 | await SUT.AddOneAsync(document); 48 | // Assert 49 | long count = SUT.Count(e => e.Id == document.Id); 50 | Assert.Equal(1, count); 51 | } 52 | 53 | [Fact] 54 | public void AddMany() 55 | { 56 | // Arrange 57 | var documents = new List { new IdentityUserTest(), new IdentityUserTest() }; 58 | // Act 59 | SUT.AddMany(documents); 60 | // Assert 61 | long count = SUT.Count(e => e.Id == documents[0].Id || e.Id == documents[1].Id); 62 | Assert.Equal(2, count); 63 | } 64 | 65 | [Fact] 66 | public async Task AddManyAsync() 67 | { 68 | // Arrange 69 | var documents = new List { new IdentityUserTest(), new IdentityUserTest() }; 70 | // Act 71 | await SUT.AddManyAsync(documents); 72 | // Assert 73 | long count = SUT.Count(e => e.Id == documents[0].Id || e.Id == documents[1].Id); 74 | Assert.Equal(2, count); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /CoreIntegrationTests/Infrastructure/BaseMongoDbRepositoryTests.cs: -------------------------------------------------------------------------------- 1 | using MongoDbGenericRepository.Models; 2 | using System.Collections.Generic; 3 | using System; 4 | 5 | namespace CoreIntegrationTests.Infrastructure 6 | { 7 | 8 | public class BaseMongoDbRepositoryTests : IDisposable where T : new() 9 | { 10 | public T CreateTestDocument() 11 | { 12 | return new T(); 13 | } 14 | 15 | public List CreateTestDocuments(int numberOfDocumentsToCreate) 16 | { 17 | var docs = new List(); 18 | for(var i = 0; i < numberOfDocumentsToCreate; i++) 19 | { 20 | docs.Add(new T()); 21 | } 22 | return docs; 23 | } 24 | 25 | /// 26 | /// Constructor, init code 27 | /// 28 | public BaseMongoDbRepositoryTests() 29 | { 30 | Init(); 31 | var type = CreateTestDocument(); 32 | if (type is IPartitionedDocument) 33 | { 34 | PartitionKey = ((IPartitionedDocument)type).PartitionKey; 35 | } 36 | } 37 | 38 | public string PartitionKey { get; set; } 39 | 40 | /// 41 | /// SUT: System Under Test 42 | /// 43 | protected static ITestRepository SUT { get; set; } 44 | 45 | public void Init() 46 | { 47 | MongoDbConfig.EnsureConfigured(); 48 | SUT = TestRepository.Instance; 49 | } 50 | 51 | public void Cleanup() 52 | { 53 | // We drop the collection at the end of each test session. 54 | if (!string.IsNullOrEmpty(PartitionKey)) 55 | { 56 | SUT.DropTestCollection(PartitionKey); 57 | } 58 | else 59 | { 60 | SUT.DropTestCollection(); 61 | } 62 | } 63 | 64 | #region IDisposable Support 65 | private bool _disposedValue; // Pour détecter les appels redondants 66 | 67 | protected virtual void Dispose(bool disposing) 68 | { 69 | if (!_disposedValue) 70 | { 71 | if (disposing) 72 | { 73 | Cleanup(); 74 | } 75 | 76 | _disposedValue = true; 77 | } 78 | } 79 | 80 | // Ce code est ajouté pour implémenter correctement le modèle supprimable. 81 | public void Dispose() 82 | { 83 | // Ne modifiez pas ce code. Placez le code de nettoyage dans Dispose(bool disposing) ci-dessus. 84 | Dispose(true); 85 | } 86 | #endregion 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /CoreIntegrationTests/Infrastructure/GlobalVariables.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoreIntegrationTests.Infrastructure 4 | { 5 | /// 6 | /// A class holding global variables. 7 | /// 8 | public static class GlobalVariables 9 | { 10 | /// 11 | /// A random number generator. 12 | /// 13 | public static Random Random = new Random(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /CoreIntegrationTests/Infrastructure/ITestRepository.cs: -------------------------------------------------------------------------------- 1 | using MongoDbGenericRepository; 2 | 3 | namespace CoreIntegrationTests 4 | { 5 | public interface ITestRepository : IBaseMongoRepository 6 | { 7 | void DropTestCollection(); 8 | void DropTestCollection(string partitionKey); 9 | } 10 | } -------------------------------------------------------------------------------- /CoreIntegrationTests/Infrastructure/MongoDbConfig.cs: -------------------------------------------------------------------------------- 1 | using MongoDB.Bson.Serialization.Conventions; 2 | using System.Threading; 3 | 4 | namespace CoreIntegrationTests.Infrastructure 5 | { 6 | internal static class MongoDbConfig 7 | { 8 | private static bool _initialized; 9 | private static object _initializationLock = new(); 10 | private static object _initializationTarget; 11 | 12 | public static void EnsureConfigured() 13 | { 14 | EnsureConfiguredImpl(); 15 | } 16 | 17 | private static void EnsureConfiguredImpl() 18 | { 19 | LazyInitializer.EnsureInitialized(ref _initializationTarget, ref _initialized, ref _initializationLock, () => 20 | { 21 | Configure(); 22 | return null; 23 | }); 24 | } 25 | 26 | private static void Configure() 27 | { 28 | RegisterConventions(); 29 | } 30 | 31 | private static void RegisterConventions() 32 | { 33 | var pack = new ConventionPack 34 | { 35 | new IgnoreIfNullConvention(false), 36 | new CamelCaseElementNameConvention(), 37 | }; 38 | } 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /CoreIntegrationTests/Infrastructure/MongoDbTestFixture.cs: -------------------------------------------------------------------------------- 1 | using MongoDbGenericRepository; 2 | using MongoDbGenericRepository.Models; 3 | using System; 4 | using System.Collections.Concurrent; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | 8 | namespace CoreIntegrationTests.Infrastructure 9 | { 10 | public class MongoDbTestFixture : IDisposable 11 | where T : IDocument, new() 12 | where TKey : IEquatable 13 | { 14 | 15 | public IMongoDbContext Context; 16 | 17 | public MongoDbTestFixture() 18 | { 19 | } 20 | 21 | public string PartitionKey { get; set; } 22 | 23 | public static ConcurrentBag DocsToDelete { get; set; } = new ConcurrentBag(); 24 | 25 | public virtual void Dispose() 26 | { 27 | 28 | if (DocsToDelete.Any()) 29 | { 30 | TestRepository.Instance.DeleteMany(DocsToDelete.ToList()); 31 | } 32 | } 33 | 34 | public T CreateTestDocument() 35 | { 36 | var doc = new T(); 37 | DocsToDelete.Add(doc); 38 | return doc; 39 | } 40 | 41 | public List CreateTestDocuments(int numberOfDocumentsToCreate) 42 | { 43 | var docs = new List(); 44 | for (var i = 0; i < numberOfDocumentsToCreate; i++) 45 | { 46 | var doc = new T(); 47 | docs.Add(doc); 48 | DocsToDelete.Add(doc); 49 | } 50 | return docs; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /CoreIntegrationTests/Infrastructure/RandomExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoreIntegrationTests.Infrastructure 4 | { 5 | // Thanks BlueRaja - Danny Pflughoeft https://stackoverflow.com/a/13095144/5103354 6 | /// 7 | /// Extensions for the random number generator 8 | /// 9 | public static class RandomExtensions 10 | { 11 | 12 | /// 13 | /// Returns a random long from min (inclusive) to max (exclusive) 14 | /// 15 | /// The given random instance 16 | /// The inclusive minimum bound 17 | /// The exclusive maximum bound. Must be greater than min 18 | public static long NextLong(this Random random, long min, long max) 19 | { 20 | if (max <= min) 21 | throw new ArgumentOutOfRangeException("max", "max must be > min!"); 22 | 23 | //Working with ulong so that modulo works correctly with values > long.MaxValue 24 | ulong uRange = (ulong)(max - min); 25 | 26 | //Prevent a modulo bias; see https://stackoverflow.com/a/10984975/238419 27 | //for more information. 28 | //In the worst case, the expected number of calls is 2 (though usually it's 29 | //much closer to 1) so this loop doesn't really hurt performance at all. 30 | ulong ulongRand; 31 | do 32 | { 33 | byte[] buf = new byte[8]; 34 | random.NextBytes(buf); 35 | ulongRand = (ulong)BitConverter.ToInt64(buf, 0); 36 | } while (ulongRand > ulong.MaxValue - ((ulong.MaxValue % uRange) + 1) % uRange); 37 | 38 | return (long)(ulongRand % uRange) + min; 39 | } 40 | 41 | /// 42 | /// Returns a random long from 0 (inclusive) to max (exclusive) 43 | /// 44 | /// The given random instance 45 | /// The exclusive maximum bound. Must be greater than 0 46 | public static long NextLong(this Random random, long max) 47 | { 48 | return random.NextLong(0, max); 49 | } 50 | 51 | /// 52 | /// Returns a random long over all possible values of long (except long.MaxValue, similar to 53 | /// random.Next()) 54 | /// 55 | /// The given random instance 56 | public static long NextLong(this Random random) 57 | { 58 | return random.NextLong(long.MinValue, long.MaxValue); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /CoreIntegrationTests/Infrastructure/TestClasses.cs: -------------------------------------------------------------------------------- 1 | using MongoDB.Bson; 2 | using MongoDB.Bson.Serialization.Attributes; 3 | using MongoDbGenericRepository.Models; 4 | using MongoDbGenericRepository.Utils; 5 | using System; 6 | using System.Collections.Generic; 7 | 8 | namespace CoreIntegrationTests.Infrastructure 9 | { 10 | public class ProjectedGroup 11 | { 12 | public int Key { get; set; } 13 | public List Content { get; set; } 14 | } 15 | 16 | public class MyTestProjection 17 | { 18 | public string SomeContent { get; set; } 19 | public DateTime SomeDate { get; set; } 20 | } 21 | 22 | public class Nested 23 | { 24 | public DateTime SomeDate { get; set; } 25 | [BsonRepresentation(BsonType.Decimal128)] 26 | public decimal SomeAmount { get; set; } 27 | } 28 | 29 | public class Child 30 | { 31 | public Child(string type, string value) 32 | { 33 | Type = type; 34 | Value = value; 35 | } 36 | 37 | public string Type { get; set; } 38 | public string Value { get; set; } 39 | } 40 | 41 | public class TestDoc : Document 42 | { 43 | public TestDoc() 44 | { 45 | Version = 2; 46 | Nested = new Nested 47 | { 48 | SomeDate = DateTime.UtcNow 49 | }; 50 | Children = new List(); 51 | } 52 | 53 | public int SomeValue { get; set; } 54 | 55 | public string SomeContent { get; set; } 56 | public string SomeContent2 { get; set; } 57 | public string SomeContent3 { get; set; } 58 | 59 | public int GroupingKey { get; set; } 60 | 61 | public Nested Nested { get; set; } 62 | 63 | public List Children { get; set; } 64 | 65 | } 66 | 67 | public class TestDoc : IDocument 68 | where TKey : IEquatable 69 | { 70 | [BsonId] 71 | public TKey Id { get; set; } 72 | public int Version { get; set; } 73 | 74 | public TestDoc() 75 | { 76 | InitializeFields(); 77 | Version = 2; 78 | Nested = new Nested 79 | { 80 | SomeDate = DateTime.UtcNow 81 | }; 82 | Children = new List(); 83 | } 84 | 85 | public int GroupingKey { get; set; } 86 | public string SomeContent { get; set; } 87 | public string SomeContent4 { get; set; } 88 | public string SomeContent5 { get; set; } 89 | 90 | public Nested Nested { get; set; } 91 | 92 | public List Children { get; set; } 93 | 94 | public TId Init() 95 | { 96 | return IdGenerator.GetId(); 97 | } 98 | 99 | private void InitializeFields() 100 | { 101 | Id = Init(); 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /CoreIntegrationTests/Infrastructure/TestRepository.cs: -------------------------------------------------------------------------------- 1 | using MongoDB.Bson; 2 | using MongoDbGenericRepository; 3 | using System; 4 | 5 | namespace CoreIntegrationTests.Infrastructure 6 | { 7 | public interface ITestRepository : IBaseMongoRepository where TKey : IEquatable 8 | { 9 | void DropTestCollection(); 10 | void DropTestCollection(string partitionKey); 11 | } 12 | 13 | public class TestTKeyRepository : BaseMongoRepository, ITestRepository where TKey : IEquatable 14 | { 15 | const string connectionString = "mongodb://localhost:27017/MongoDbTests"; 16 | private static readonly ITestRepository _instance = new TestTKeyRepository(connectionString); 17 | /// 18 | private TestTKeyRepository(string connectionString) : base(connectionString) 19 | { 20 | } 21 | 22 | public static ITestRepository Instance 23 | { 24 | get 25 | { 26 | return _instance; 27 | } 28 | } 29 | 30 | public void DropTestCollection() 31 | { 32 | MongoDbContext.DropCollection(); 33 | } 34 | 35 | public void DropTestCollection(string partitionKey) 36 | { 37 | MongoDbContext.DropCollection(partitionKey); 38 | } 39 | } 40 | 41 | /// 42 | /// A singleton implementation of the TestRepository 43 | /// 44 | public sealed class TestRepository : BaseMongoRepository, ITestRepository 45 | { 46 | 47 | const string connectionString = "mongodb://localhost:27017"; 48 | private static readonly ITestRepository _instance = new TestRepository(connectionString, "MongoDbTests"); 49 | 50 | // Explicit static constructor to tell C# compiler 51 | // not to mark type as beforefieldinit 52 | static TestRepository() 53 | { 54 | } 55 | 56 | /// 57 | private TestRepository(string connectionString, string databaseName) : base(connectionString, databaseName) 58 | { 59 | } 60 | 61 | public static ITestRepository Instance 62 | { 63 | get 64 | { 65 | return _instance; 66 | } 67 | } 68 | 69 | public void DropTestCollection() 70 | { 71 | MongoDbContext.DropCollection(); 72 | } 73 | 74 | public void DropTestCollection(string partitionKey) 75 | { 76 | MongoDbContext.DropCollection(partitionKey); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /CoreUnitTests/BaseMongoRepositoryTests/AddTests/AddManyAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using AutoFixture; 6 | using CoreUnitTests.Infrastructure; 7 | using CoreUnitTests.Infrastructure.Model; 8 | using MongoDbGenericRepository.DataAccess.Create; 9 | using Moq; 10 | using Xunit; 11 | 12 | namespace CoreUnitTests.BaseMongoRepositoryTests.AddTests; 13 | 14 | public class AddManyAsyncTests : TestMongoRepositoryContext 15 | { 16 | [Fact] 17 | public async Task WithDocument_ShouldAddOne() 18 | { 19 | // Arrange 20 | var documents = Fixture.CreateMany().ToList(); 21 | Creator = new Mock(); 22 | 23 | // Act 24 | await Sut.AddManyAsync(documents); 25 | 26 | // Assert 27 | Creator.Verify(x => x.AddManyAsync(documents, CancellationToken.None), Times.Once); 28 | } 29 | 30 | [Fact] 31 | public async Task WithDocumentAndCancellationToken_ShouldAddOne() 32 | { 33 | // Arrange 34 | var documents = Fixture.CreateMany().ToList(); 35 | var token = new CancellationToken(true); 36 | Creator = new Mock(); 37 | 38 | // Act 39 | await Sut.AddManyAsync(documents, token); 40 | 41 | // Assert 42 | Creator.Verify(x => x.AddManyAsync(documents, token), Times.Once); 43 | } 44 | 45 | #region Keyed 46 | 47 | [Fact] 48 | public async Task Keyed_WithDocument_ShouldAddOne() 49 | { 50 | // Arrange 51 | var documents = Fixture.CreateMany>().ToList(); 52 | Creator = new Mock(); 53 | 54 | // Act 55 | await Sut.AddManyAsync, int>(documents); 56 | 57 | // Assert 58 | Creator.Verify(x => x.AddManyAsync, int>(documents, CancellationToken.None), Times.Once); 59 | } 60 | 61 | [Fact] 62 | public async Task Keyed_WithDocumentAndCancellationToken_ShouldAddOne() 63 | { 64 | // Arrange 65 | var documents = Fixture.CreateMany>().ToList(); 66 | var token = new CancellationToken(true); 67 | Creator = new Mock(); 68 | 69 | // Act 70 | await Sut.AddManyAsync, int>(documents, token); 71 | 72 | // Assert 73 | Creator.Verify(x => x.AddManyAsync, int>(documents, token), Times.Once); 74 | } 75 | 76 | #endregion 77 | } 78 | -------------------------------------------------------------------------------- /CoreUnitTests/BaseMongoRepositoryTests/AddTests/AddManyTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading; 4 | using AutoFixture; 5 | using CoreUnitTests.Infrastructure; 6 | using CoreUnitTests.Infrastructure.Model; 7 | using MongoDbGenericRepository.DataAccess.Create; 8 | using Moq; 9 | using Xunit; 10 | 11 | namespace CoreUnitTests.BaseMongoRepositoryTests.AddTests; 12 | 13 | public class AddManyTests : TestMongoRepositoryContext 14 | { 15 | 16 | [Fact] 17 | public void WithDocument_ShouldAddOne() 18 | { 19 | // Arrange 20 | var documents = Fixture.CreateMany().ToList(); 21 | Creator = new Mock(); 22 | 23 | // Act 24 | Sut.AddMany(documents); 25 | 26 | // Assert 27 | Creator.Verify(x => x.AddMany(documents, CancellationToken.None), Times.Once); 28 | } 29 | 30 | [Fact] 31 | public void WithDocumentAndCancellationToken_ShouldAddOne() 32 | { 33 | // Arrange 34 | var documents = Fixture.CreateMany().ToList(); 35 | var token = new CancellationToken(true); 36 | Creator = new Mock(); 37 | 38 | // Act 39 | Sut.AddMany(documents, token); 40 | 41 | // Assert 42 | Creator.Verify(x => x.AddMany(documents, token), Times.Once); 43 | } 44 | 45 | #region Keyed 46 | 47 | [Fact] 48 | public void Keyed_WithDocument_ShouldAddOne() 49 | { 50 | // Arrange 51 | var documents = Fixture.CreateMany>().ToList(); 52 | Creator = new Mock(); 53 | 54 | // Act 55 | Sut.AddMany, int>(documents); 56 | 57 | // Assert 58 | Creator.Verify(x => x.AddMany, int>(documents, CancellationToken.None), Times.Once); 59 | } 60 | 61 | [Fact] 62 | public void Keyed_WithDocumentAndCancellationToken_ShouldAddOne() 63 | { 64 | // Arrange 65 | var documents = Fixture.CreateMany>().ToList(); 66 | var token = new CancellationToken(true); 67 | Creator = new Mock(); 68 | 69 | // Act 70 | Sut.AddMany, int>(documents, token); 71 | 72 | // Assert 73 | Creator.Verify(x => x.AddMany, int>(documents, token), Times.Once); 74 | } 75 | 76 | #endregion 77 | } 78 | -------------------------------------------------------------------------------- /CoreUnitTests/BaseMongoRepositoryTests/AddTests/AddOneAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using AutoFixture; 5 | using CoreUnitTests.Infrastructure; 6 | using CoreUnitTests.Infrastructure.Model; 7 | using MongoDbGenericRepository.DataAccess.Create; 8 | using Moq; 9 | using Xunit; 10 | 11 | namespace CoreUnitTests.BaseMongoRepositoryTests.AddTests; 12 | 13 | public class AddOneAsyncTests : TestMongoRepositoryContext 14 | { 15 | [Fact] 16 | public async Task WithDocument_ShouldAddOne() 17 | { 18 | // Arrange 19 | var document = Fixture.Create(); 20 | Creator = new Mock(); 21 | 22 | // Act 23 | await Sut.AddOneAsync(document); 24 | 25 | // Assert 26 | Creator.Verify(x => x.AddOneAsync(document, CancellationToken.None), Times.Once); 27 | } 28 | 29 | [Fact] 30 | public async Task WithDocumentAndCancellationToken_ShouldAddOne() 31 | { 32 | // Arrange 33 | var document = Fixture.Create(); 34 | var token = new CancellationToken(true); 35 | Creator = new Mock(); 36 | 37 | // Act 38 | await Sut.AddOneAsync(document, token); 39 | 40 | // Assert 41 | Creator.Verify(x => x.AddOneAsync(document, token), Times.Once); 42 | } 43 | 44 | #region Keyed 45 | 46 | [Fact] 47 | public async Task Keyed_WithDocument_ShouldAddOne() 48 | { 49 | // Arrange 50 | var document = Fixture.Create>(); 51 | Creator = new Mock(); 52 | 53 | // Act 54 | await Sut.AddOneAsync, int>(document); 55 | 56 | // Assert 57 | Creator.Verify(x => x.AddOneAsync, int>(document, CancellationToken.None), Times.Once); 58 | } 59 | 60 | [Fact] 61 | public async Task Keyed_WithDocumentAndCancellationToken_ShouldAddOne() 62 | { 63 | // Arrange 64 | var document = Fixture.Create>(); 65 | var token = new CancellationToken(true); 66 | Creator = new Mock(); 67 | 68 | // Act 69 | await Sut.AddOneAsync, int>(document, token); 70 | 71 | // Assert 72 | Creator.Verify(x => x.AddOneAsync, int>(document, token), Times.Once); 73 | } 74 | 75 | #endregion 76 | } 77 | -------------------------------------------------------------------------------- /CoreUnitTests/BaseMongoRepositoryTests/AddTests/AddOneTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using AutoFixture; 4 | using CoreUnitTests.Infrastructure; 5 | using CoreUnitTests.Infrastructure.Model; 6 | using MongoDbGenericRepository.DataAccess.Create; 7 | using Moq; 8 | using Xunit; 9 | 10 | namespace CoreUnitTests.BaseMongoRepositoryTests.AddTests; 11 | 12 | public class AddOneTests : TestMongoRepositoryContext 13 | { 14 | [Fact] 15 | public void WithDocument_ShouldAddOne() 16 | { 17 | // Arrange 18 | var document = Fixture.Create(); 19 | Creator = new Mock(); 20 | 21 | // Act 22 | Sut.AddOne(document); 23 | 24 | // Assert 25 | Creator.Verify(x => x.AddOne(document, CancellationToken.None), Times.Once); 26 | } 27 | 28 | [Fact] 29 | public void WithDocumentAndCancellationToken_ShouldAddOne() 30 | { 31 | // Arrange 32 | var document = Fixture.Create(); 33 | var token = new CancellationToken(true); 34 | Creator = new Mock(); 35 | 36 | // Act 37 | Sut.AddOne(document, token); 38 | 39 | // Assert 40 | Creator.Verify(x => x.AddOne(document, token), Times.Once); 41 | } 42 | 43 | #region Keyed 44 | 45 | [Fact] 46 | public void Keyed_WithDocument_ShouldAddOne() 47 | { 48 | // Arrange 49 | var document = Fixture.Create>(); 50 | Creator = new Mock(); 51 | 52 | // Act 53 | Sut.AddOne, int>(document); 54 | 55 | // Assert 56 | Creator.Verify(x => x.AddOne, int>(document, CancellationToken.None), Times.Once); 57 | } 58 | 59 | [Fact] 60 | public void Keyed_WithDocumentAndCancellationToken_ShouldAddOne() 61 | { 62 | // Arrange 63 | var document = Fixture.Create>(); 64 | var token = new CancellationToken(true); 65 | Creator = new Mock(); 66 | 67 | // Act 68 | Sut.AddOne, int>(document, token); 69 | 70 | // Assert 71 | Creator.Verify(x => x.AddOne, int>(document, token), Times.Once); 72 | } 73 | 74 | #endregion 75 | } 76 | -------------------------------------------------------------------------------- /CoreUnitTests/BaseMongoRepositoryTests/IndexTests/BaseIndexTests.cs: -------------------------------------------------------------------------------- 1 | using CoreUnitTests.Infrastructure; 2 | using MongoDB.Bson; 3 | using MongoDB.Driver; 4 | using Moq; 5 | 6 | namespace CoreUnitTests.BaseMongoRepositoryTests.IndexTests; 7 | 8 | public class BaseIndexTests : TestMongoRepositoryContext 9 | { 10 | protected static Mock> SetupIndex(BsonDocument index, Mock> collection) 11 | { 12 | var asyncCursor = new Mock>(); 13 | asyncCursor 14 | .SetupSequence(x => x.MoveNextAsync(It.IsAny())) 15 | .ReturnsAsync(true) 16 | .ReturnsAsync(false); 17 | 18 | asyncCursor 19 | .SetupGet(x => x.Current) 20 | .Returns([index]); 21 | 22 | var indexManager = new Mock>(); 23 | indexManager 24 | .Setup(x => x.ListAsync(It.IsAny())) 25 | .ReturnsAsync(asyncCursor.Object); 26 | 27 | collection 28 | .SetupGet(x => x.Indexes) 29 | .Returns(indexManager.Object); 30 | 31 | return asyncCursor; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CoreUnitTests/CoreUnitTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | warnings 6 | enable 7 | false 8 | true 9 | latest 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | all 23 | runtime; build; native; contentfiles; analyzers 24 | 25 | 26 | all 27 | runtime; build; native; contentfiles; analyzers; buildtransitive 28 | 29 | 30 | runtime; build; native; contentfiles; analyzers; buildtransitive 31 | all 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteOneAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using AutoFixture; 6 | using CoreUnitTests.Infrastructure; 7 | using CoreUnitTests.Infrastructure.Model; 8 | using FluentAssertions; 9 | using MongoDB.Driver; 10 | using MongoDbGenericRepository; 11 | using MongoDbGenericRepository.DataAccess.Delete; 12 | using Moq; 13 | using Xunit; 14 | 15 | namespace CoreUnitTests.DataAccessTests.MongoDbEraserTests; 16 | 17 | public class DeleteOneAsyncTests : GenericTestContext 18 | { 19 | [Fact] 20 | public async Task WithDocumentAndCancellationToken_DeletesOne() 21 | { 22 | // Arrange 23 | var count = Fixture.Create(); 24 | var document = Fixture.Create(); 25 | var token = new CancellationToken(true); 26 | 27 | var collection = MockOf>(); 28 | collection 29 | .Setup(x => x.DeleteOneAsync(It.IsAny>(), It.IsAny())) 30 | .ReturnsAsync(new DeleteResult.Acknowledged(count)); 31 | 32 | var dbContext = MockOf(); 33 | dbContext 34 | .Setup(x => x.GetCollection(null)) 35 | .Returns(collection.Object); 36 | 37 | // Act 38 | var result = await Sut.DeleteOneAsync(document, token); 39 | 40 | // Assert 41 | result.Should().Be(count); 42 | 43 | var expectedFilter = Builders.Filter.Eq("Id", document.Id); 44 | collection.Verify( 45 | x => x.DeleteOneAsync( 46 | It.Is>(f => f.EquivalentTo(expectedFilter)), 47 | token), 48 | Times.Once()); 49 | } 50 | 51 | [Fact] 52 | public async Task WithFilterAndPartitionKeyAndCancellationToken_DeletesOne() 53 | { 54 | // Arrange 55 | var count = Fixture.Create(); 56 | var document = Fixture.Create(); 57 | var partitionKey = Fixture.Create(); 58 | var token = new CancellationToken(true); 59 | 60 | var collection = MockOf>(); 61 | collection 62 | .Setup(x => x.DeleteOneAsync(It.IsAny>(), It.IsAny())) 63 | .ReturnsAsync(new DeleteResult.Acknowledged(count)); 64 | 65 | var dbContext = MockOf(); 66 | dbContext 67 | .Setup(x => x.GetCollection(It.IsAny())) 68 | .Returns(collection.Object); 69 | 70 | Expression> filter = d => d.Id == document.Id; 71 | 72 | // Act 73 | var result = await Sut.DeleteOneAsync(filter, partitionKey, token); 74 | 75 | // Assert 76 | result.Should().Be(count); 77 | collection.Verify( 78 | x => x.DeleteOneAsync( 79 | It.Is>(f => f.EquivalentTo(filter)), 80 | token), 81 | Times.Once()); 82 | 83 | dbContext.Verify(x => x.GetCollection(partitionKey)); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteOneTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using AutoFixture; 5 | using CoreUnitTests.Infrastructure; 6 | using CoreUnitTests.Infrastructure.Model; 7 | using FluentAssertions; 8 | using MongoDB.Driver; 9 | using MongoDbGenericRepository; 10 | using MongoDbGenericRepository.DataAccess.Delete; 11 | using Moq; 12 | using Xunit; 13 | 14 | namespace CoreUnitTests.DataAccessTests.MongoDbEraserTests; 15 | 16 | public class DeleteOneTests : GenericTestContext 17 | { 18 | [Fact] 19 | public void WithDocumentAndCancellationToken_DeletesOne() 20 | { 21 | // Arrange 22 | var count = Fixture.Create(); 23 | var document = Fixture.Create(); 24 | var token = new CancellationToken(true); 25 | 26 | var collection = MockOf>(); 27 | collection 28 | .Setup(x => x.DeleteOne(It.IsAny>(), It.IsAny())) 29 | .Returns(new DeleteResult.Acknowledged(count)); 30 | 31 | var dbContext = MockOf(); 32 | dbContext 33 | .Setup(x => x.GetCollection(null)) 34 | .Returns(collection.Object); 35 | 36 | // Act 37 | var result = Sut.DeleteOne(document, token); 38 | 39 | // Assert 40 | result.Should().Be(count); 41 | 42 | var expectedFilter = Builders.Filter.Eq("Id", document.Id); 43 | collection.Verify( 44 | x => x.DeleteOne( 45 | It.Is>(f => f.EquivalentTo(expectedFilter)), 46 | token), 47 | Times.Once()); 48 | } 49 | 50 | [Fact] 51 | public void WithFilterAndPartitionKeyAndCancellationToken_DeletesOne() 52 | { 53 | // Arrange 54 | var count = Fixture.Create(); 55 | var document = Fixture.Create(); 56 | var partitionKey = Fixture.Create(); 57 | var token = new CancellationToken(true); 58 | 59 | var collection = MockOf>(); 60 | collection 61 | .Setup(x => x.DeleteOne(It.IsAny>(), It.IsAny())) 62 | .Returns(new DeleteResult.Acknowledged(count)); 63 | 64 | var dbContext = MockOf(); 65 | dbContext 66 | .Setup(x => x.GetCollection(It.IsAny())) 67 | .Returns(collection.Object); 68 | 69 | Expression> filter = d => d.Id == document.Id; 70 | 71 | // Act 72 | var result = Sut.DeleteOne(filter, partitionKey, token); 73 | 74 | // Assert 75 | result.Should().Be(count); 76 | collection.Verify( 77 | x => x.DeleteOne( 78 | It.Is>(f => f.EquivalentTo(filter)), 79 | token), 80 | Times.Once()); 81 | 82 | dbContext.Verify(x => x.GetCollection(partitionKey)); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /CoreUnitTests/DataAccessTests/MongoDbIndexHandlerTests/BaseIndexTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading; 3 | using CoreUnitTests.Infrastructure; 4 | using MongoDB.Bson; 5 | using MongoDB.Driver; 6 | using MongoDbGenericRepository.DataAccess.Index; 7 | using Moq; 8 | 9 | namespace CoreUnitTests.DataAccessTests.MongoDbIndexHandlerTests; 10 | 11 | public class BaseIndexTests : GenericTestContext 12 | { 13 | protected (Mock>, Mock>) SetupIndexes( 14 | List indexes, 15 | Mock> collection) 16 | { 17 | var asyncCursor = MockOf>(); 18 | var moveNextSequence = asyncCursor 19 | .SetupSequence(x => x.MoveNextAsync(It.IsAny())); 20 | 21 | var currentSequence = asyncCursor 22 | .SetupSequence(x => x.Current); 23 | 24 | foreach (var bsonDocument in indexes) 25 | { 26 | moveNextSequence.ReturnsAsync(true); 27 | currentSequence.Returns(new[] {bsonDocument}); 28 | } 29 | 30 | moveNextSequence.ReturnsAsync(false); 31 | 32 | var indexManager = MockOf>(); 33 | indexManager 34 | .Setup(x => x.ListAsync(It.IsAny())) 35 | .ReturnsAsync(asyncCursor.Object); 36 | 37 | collection 38 | .SetupGet(x => x.Indexes) 39 | .Returns(indexManager.Object); 40 | 41 | return (asyncCursor, indexManager); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /CoreUnitTests/DataAccessTests/MongoDbReaderTests/BaseReaderTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading; 3 | using CoreUnitTests.Infrastructure; 4 | using MongoDB.Driver; 5 | using MongoDbGenericRepository.DataAccess.Read; 6 | using Moq; 7 | 8 | namespace CoreUnitTests.DataAccessTests.MongoDbReaderTests; 9 | 10 | public class BaseReaderTests : GenericTestContext 11 | { 12 | protected Mock> SetupSyncCursor(List documents) 13 | { 14 | var asyncCursor = MockOf>(); 15 | 16 | var moveNextSequence = asyncCursor 17 | .SetupSequence(x => x.MoveNext(It.IsAny())); 18 | 19 | var currentSequence = asyncCursor 20 | .SetupSequence(x => x.Current); 21 | 22 | foreach (var projection in documents) 23 | { 24 | moveNextSequence.Returns(true); 25 | currentSequence.Returns(new[] {projection}); 26 | } 27 | 28 | moveNextSequence.Returns(false); 29 | return asyncCursor; 30 | } 31 | 32 | protected Mock> SetupAsyncCursor(List documents) 33 | { 34 | var asyncCursor = MockOf>(); 35 | 36 | var moveNextSequence = asyncCursor 37 | .SetupSequence(x => x.MoveNextAsync(It.IsAny())); 38 | 39 | var currentSequence = asyncCursor 40 | .SetupSequence(x => x.Current); 41 | 42 | foreach (var projection in documents) 43 | { 44 | moveNextSequence.ReturnsAsync(true); 45 | currentSequence.Returns(new[] {projection}); 46 | } 47 | 48 | moveNextSequence.ReturnsAsync(false); 49 | return asyncCursor; 50 | } 51 | 52 | protected static void SetupFindAsync(Mock> collection, Mock> asyncCursor) => 53 | collection 54 | .Setup( 55 | x => x.FindAsync( 56 | It.IsAny>(), 57 | It.IsAny>(), 58 | It.IsAny())) 59 | .ReturnsAsync(asyncCursor.Object); 60 | 61 | protected static void SetupFindSync(Mock> collection, Mock> asyncCursor) => 62 | collection 63 | .Setup( 64 | x => x.FindSync( 65 | It.IsAny>(), 66 | It.IsAny>(), 67 | It.IsAny())) 68 | .Returns(asyncCursor.Object); 69 | } 70 | -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/FilterDefinitionExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace CoreUnitTests.Infrastructure; 2 | 3 | using MongoDB.Bson; 4 | using MongoDB.Bson.Serialization; 5 | using MongoDB.Driver; 6 | 7 | public static class FilterDefinitionExtensions 8 | { 9 | public static string RenderToJson(this FilterDefinition filter) 10 | => filter.Render(new RenderArgs(BsonSerializer.SerializerRegistry.GetSerializer(), BsonSerializer.SerializerRegistry)).ToJson(); 11 | 12 | public static bool EquivalentTo(this FilterDefinition filter, FilterDefinition other) 13 | => filter.RenderToJson() == other.RenderToJson(); 14 | } 15 | -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/GenericTestContext.cs: -------------------------------------------------------------------------------- 1 | using AutoFixture; 2 | using AutoFixture.AutoMoq; 3 | using Moq; 4 | 5 | namespace CoreUnitTests.Infrastructure; 6 | 7 | public class GenericTestContext 8 | { 9 | public GenericTestContext() => Fixture = new Fixture().Customize(new AutoMoqCustomization()); 10 | 11 | protected Mock MockOf() 12 | where T : class => 13 | Fixture.Freeze>(); 14 | 15 | protected IFixture Fixture { get; set; } 16 | 17 | protected TSut Sut => Fixture.Create(); 18 | } 19 | -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/IndexExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MongoDB.Bson.Serialization; 3 | using MongoDB.Driver; 4 | using MongoDbGenericRepository.Models; 5 | using Xunit.Abstractions; 6 | 7 | namespace CoreUnitTests.Infrastructure; 8 | 9 | public static class IndexExtensions 10 | { 11 | public static bool EqualToJson(this IndexKeysDefinition keys, string json, ITestOutputHelper output) 12 | { 13 | var indexModelRendered = RenderIndexModelKeys(keys); 14 | var result = indexModelRendered.Equals(json, StringComparison.Ordinal); 15 | if (!result && output != null) 16 | { 17 | output.WriteLine($"Expected: {json}"); 18 | output.WriteLine($"Actual: {indexModelRendered}"); 19 | } 20 | 21 | return result; 22 | } 23 | 24 | public static bool EqualToJson(this IndexKeysDefinition keys, string json) 25 | { 26 | var indexModelRendered = RenderIndexModelKeys(keys); 27 | return indexModelRendered.Equals(json, StringComparison.Ordinal); 28 | } 29 | 30 | public static bool EqualTo(this IndexCreationOptions x, CreateIndexOptions y) => 31 | x.Unique == y.Unique && 32 | x.TextIndexVersion == y.TextIndexVersion && 33 | x.SphereIndexVersion == y.SphereIndexVersion && 34 | x.Sparse == y.Sparse && 35 | x.Name == y.Name && 36 | x.Min == y.Min && 37 | x.Max == y.Max && 38 | x.LanguageOverride == y.LanguageOverride && 39 | x.ExpireAfter == y.ExpireAfter && 40 | x.DefaultLanguage == y.DefaultLanguage && 41 | x.Bits == y.Bits && 42 | x.Background == y.Background && 43 | x.Version == y.Version; 44 | 45 | public static bool EqualTo(this CreateIndexOptions x, IndexCreationOptions y) => 46 | x.Unique == y.Unique && 47 | x.TextIndexVersion == y.TextIndexVersion && 48 | x.SphereIndexVersion == y.SphereIndexVersion && 49 | x.Sparse == y.Sparse && 50 | x.Name == y.Name && 51 | x.Min == y.Min && 52 | x.Max == y.Max && 53 | x.LanguageOverride == y.LanguageOverride && 54 | x.ExpireAfter == y.ExpireAfter && 55 | x.DefaultLanguage == y.DefaultLanguage && 56 | x.Bits == y.Bits && 57 | x.Background == y.Background && 58 | x.Version == y.Version; 59 | 60 | private static string RenderIndexModelKeys(IndexKeysDefinition keys) 61 | { 62 | var indexModelRendered = keys.Render(new RenderArgs( 63 | BsonSerializer.SerializerRegistry.GetSerializer(), BsonSerializer.SerializerRegistry)); 64 | 65 | var result = indexModelRendered.ToString(); 66 | return result.Replace(" ", ""); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/Model/Child.cs: -------------------------------------------------------------------------------- 1 | namespace CoreUnitTests.Infrastructure.Model; 2 | 3 | public class Child 4 | { 5 | public Child(string type, string value) 6 | { 7 | Type = type; 8 | Value = value; 9 | } 10 | 11 | public string Type { get; set; } 12 | public string Value { get; set; } 13 | } -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/Model/Nested.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MongoDB.Bson; 3 | using MongoDB.Bson.Serialization.Attributes; 4 | 5 | namespace CoreUnitTests.Infrastructure.Model; 6 | 7 | public class Nested 8 | { 9 | public DateTime SomeDate { get; set; } 10 | 11 | [BsonRepresentation(BsonType.Decimal128)] 12 | public decimal SomeAmount { get; set; } 13 | } -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/Model/PartitionedTestDocument.cs: -------------------------------------------------------------------------------- 1 | using MongoDbGenericRepository.Models; 2 | 3 | namespace CoreUnitTests.Infrastructure.Model; 4 | 5 | public class PartitionedTestDocument : TestDocument, IPartitionedDocument 6 | { 7 | /// 8 | public string PartitionKey { get; set; } = "PartitionedTestDocument"; 9 | } 10 | -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/Model/TestDocument.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using MongoDbGenericRepository.Models; 4 | 5 | namespace CoreUnitTests.Infrastructure.Model; 6 | 7 | public class TestDocument : Document 8 | { 9 | public TestDocument() 10 | { 11 | Version = 2; 12 | Nested = new Nested {SomeDate = DateTime.UtcNow}; 13 | Children = new List(); 14 | } 15 | 16 | public int SomeValue { get; set; } 17 | 18 | public decimal SomeDecimalValue { get; set; } 19 | 20 | public string SomeContent { get; set; } 21 | 22 | public string SomeContent2 { get; set; } 23 | 24 | public string SomeContent3 { get; set; } 25 | 26 | public int GroupingKey { get; set; } 27 | 28 | public Guid OtherGroupingKey { get; set; } 29 | 30 | public Nested Nested { get; set; } 31 | 32 | public List Children { get; set; } 33 | } 34 | -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/Model/TestDocumentWithKey.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using MongoDbGenericRepository.Models; 4 | 5 | namespace CoreUnitTests.Infrastructure.Model; 6 | 7 | public class TestDocumentWithKey : IDocument 8 | where TKey : IEquatable 9 | { 10 | public TKey Id { get; set; } 11 | public int Version { get; set; } 12 | 13 | public TestDocumentWithKey() 14 | { 15 | Version = 2; 16 | Nested = new Nested 17 | { 18 | SomeDate = DateTime.UtcNow 19 | }; 20 | Children = new List(); 21 | } 22 | 23 | public int SomeValue { get; set; } 24 | 25 | public int SomeDecimalValue { get; set; } 26 | 27 | public string SomeContent { get; set; } 28 | public string SomeContent2 { get; set; } 29 | public string SomeContent3 { get; set; } 30 | 31 | public int GroupingKey { get; set; } 32 | 33 | public Nested Nested { get; set; } 34 | 35 | public List Children { get; set; } 36 | } 37 | -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/Model/TestProjection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CoreUnitTests.Infrastructure.Model; 4 | 5 | public class TestProjection 6 | { 7 | public Guid TestDocumentId { get; set; } 8 | 9 | public DateTime NestedData { get; set; } 10 | 11 | public int Count { get; set; } 12 | } 13 | -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/TestKeyedMongoRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MongoDB.Driver; 3 | using MongoDbGenericRepository; 4 | using MongoDbGenericRepository.DataAccess.Create; 5 | using MongoDbGenericRepository.DataAccess.Delete; 6 | using MongoDbGenericRepository.DataAccess.Index; 7 | using MongoDbGenericRepository.DataAccess.Read; 8 | using MongoDbGenericRepository.DataAccess.Update; 9 | 10 | namespace CoreUnitTests.Infrastructure; 11 | 12 | public class TestKeyedMongoRepository : BaseMongoRepository 13 | where TKey : IEquatable 14 | { 15 | public TestKeyedMongoRepository(IMongoDatabase mongoDatabase) 16 | : base(mongoDatabase) 17 | { 18 | } 19 | 20 | public void SetIndexHandler(IMongoDbIndexHandler indexHandler) => MongoDbIndexHandler = indexHandler; 21 | 22 | public void SetDbCreator(IMongoDbCreator creator) => MongoDbCreator = creator; 23 | 24 | public void SetReader(IMongoDbReader reader) => MongoDbReader = reader; 25 | 26 | public void SetEraser(IMongoDbEraser eraser) => MongoDbEraser = eraser; 27 | 28 | public void SetUpdater(IMongoDbUpdater updater) => MongoDbUpdater = updater; 29 | } 30 | -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/TestKeyedMongoRepositoryContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using AutoFixture; 3 | using MongoDB.Driver; 4 | using MongoDbGenericRepository.DataAccess.Create; 5 | using MongoDbGenericRepository.DataAccess.Delete; 6 | using MongoDbGenericRepository.DataAccess.Index; 7 | using MongoDbGenericRepository.DataAccess.Read; 8 | using MongoDbGenericRepository.DataAccess.Update; 9 | using Moq; 10 | 11 | namespace CoreUnitTests.Infrastructure; 12 | 13 | public class TestKeyedMongoRepositoryContext 14 | where TKey : IEquatable 15 | { 16 | private readonly Mock mongoDatabase; 17 | 18 | private TestKeyedMongoRepository sut; 19 | 20 | protected TestKeyedMongoRepositoryContext() 21 | { 22 | mongoDatabase = new Mock(); 23 | Fixture = new Fixture(); 24 | } 25 | 26 | protected Fixture Fixture { get; set; } 27 | 28 | protected TestKeyedMongoRepository Sut 29 | { 30 | get 31 | { 32 | if (sut != null) 33 | { 34 | return sut; 35 | } 36 | 37 | sut = new TestKeyedMongoRepository(mongoDatabase.Object); 38 | if (IndexHandler != null) 39 | { 40 | sut.SetIndexHandler(IndexHandler.Object); 41 | } 42 | 43 | if (Creator != null) 44 | { 45 | sut.SetDbCreator(Creator.Object); 46 | } 47 | 48 | if (Reader != null) 49 | { 50 | sut.SetReader(Reader.Object); 51 | } 52 | 53 | if (Eraser != null) 54 | { 55 | sut.SetEraser(Eraser.Object); 56 | } 57 | 58 | if (Updater != null) 59 | { 60 | sut.SetUpdater(Updater.Object); 61 | } 62 | 63 | return sut; 64 | } 65 | } 66 | 67 | protected Mock IndexHandler { get; set; } 68 | 69 | protected Mock Creator { get; set; } 70 | 71 | protected Mock Reader { get; set; } 72 | 73 | protected Mock Eraser { get; set; } 74 | 75 | protected Mock Updater { get; set; } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/TestKeyedReadOnlyMongoRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MongoDB.Driver; 3 | using MongoDbGenericRepository; 4 | using MongoDbGenericRepository.DataAccess.Read; 5 | 6 | namespace CoreUnitTests.Infrastructure; 7 | 8 | public class TestKeyedReadOnlyMongoRepository : ReadOnlyMongoRepository 9 | where TKey : IEquatable 10 | { 11 | /// 12 | public TestKeyedReadOnlyMongoRepository(string connectionString, string databaseName = null) 13 | : base(connectionString, databaseName) 14 | { 15 | } 16 | 17 | /// 18 | public TestKeyedReadOnlyMongoRepository(IMongoDatabase mongoDatabase) 19 | : base(mongoDatabase) 20 | { 21 | } 22 | 23 | /// 24 | public TestKeyedReadOnlyMongoRepository(IMongoDbContext mongoDbContext) 25 | : base(mongoDbContext) 26 | { 27 | } 28 | 29 | public void SetReader(IMongoDbReader reader) => MongoDbReader = reader; 30 | } 31 | -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/TestKeyedReadOnlyMongoRepositoryContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using AutoFixture; 3 | using MongoDB.Driver; 4 | using MongoDbGenericRepository.DataAccess.Read; 5 | using Moq; 6 | 7 | namespace CoreUnitTests.Infrastructure; 8 | 9 | public class TestKeyedReadOnlyMongoRepositoryContext 10 | where TKey : IEquatable 11 | { 12 | private readonly Mock mongoDatabase; 13 | 14 | private TestKeyedReadOnlyMongoRepository sut; 15 | 16 | protected TestKeyedReadOnlyMongoRepositoryContext() 17 | { 18 | mongoDatabase = new Mock(); 19 | Fixture = new Fixture(); 20 | } 21 | 22 | protected Fixture Fixture { get; set; } 23 | 24 | protected TestKeyedReadOnlyMongoRepository Sut 25 | { 26 | get 27 | { 28 | if (sut != null) 29 | { 30 | return sut; 31 | } 32 | 33 | sut = new TestKeyedReadOnlyMongoRepository(mongoDatabase.Object); 34 | 35 | if (Reader != null) 36 | { 37 | sut.SetReader(Reader.Object); 38 | } 39 | 40 | return sut; 41 | } 42 | } 43 | 44 | protected Mock Reader { get; set; } 45 | } 46 | -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/TestMongoRepository.cs: -------------------------------------------------------------------------------- 1 | using MongoDB.Driver; 2 | using MongoDbGenericRepository; 3 | using MongoDbGenericRepository.DataAccess.Create; 4 | using MongoDbGenericRepository.DataAccess.Delete; 5 | using MongoDbGenericRepository.DataAccess.Index; 6 | using MongoDbGenericRepository.DataAccess.Read; 7 | using MongoDbGenericRepository.DataAccess.Update; 8 | 9 | namespace CoreUnitTests.Infrastructure; 10 | 11 | public class TestMongoRepository : BaseMongoRepository 12 | { 13 | public TestMongoRepository(IMongoDatabase mongoDatabase) 14 | : base(mongoDatabase) 15 | { 16 | } 17 | 18 | public void SetIndexHandler(IMongoDbIndexHandler indexHandler) => MongoDbIndexHandler = indexHandler; 19 | 20 | public void SetDbCreator(IMongoDbCreator creator) => MongoDbCreator = creator; 21 | 22 | public void SetReader(IMongoDbReader reader) => MongoDbReader = reader; 23 | 24 | public void SetEraser(IMongoDbEraser eraser) => MongoDbEraser = eraser; 25 | 26 | public void SetUpdater(IMongoDbUpdater updater) => MongoDbUpdater = updater; 27 | } 28 | -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/TestMongoRepositoryContext.cs: -------------------------------------------------------------------------------- 1 | using AutoFixture; 2 | using MongoDB.Driver; 3 | using MongoDbGenericRepository.DataAccess.Create; 4 | using MongoDbGenericRepository.DataAccess.Delete; 5 | using MongoDbGenericRepository.DataAccess.Index; 6 | using MongoDbGenericRepository.DataAccess.Read; 7 | using MongoDbGenericRepository.DataAccess.Update; 8 | using Moq; 9 | 10 | namespace CoreUnitTests.Infrastructure; 11 | 12 | public class TestMongoRepositoryContext 13 | { 14 | private readonly Mock _mongoDatabase; 15 | 16 | private TestMongoRepository _sut; 17 | 18 | protected TestMongoRepositoryContext() 19 | { 20 | _mongoDatabase = new Mock(); 21 | Fixture = new Fixture(); 22 | } 23 | 24 | public Fixture Fixture { get; set; } 25 | 26 | protected TestMongoRepository Sut 27 | { 28 | get 29 | { 30 | if (_sut == null) 31 | { 32 | _sut = new TestMongoRepository(_mongoDatabase.Object); 33 | if (IndexHandler != null) 34 | { 35 | _sut.SetIndexHandler(IndexHandler.Object); 36 | } 37 | 38 | if (Creator != null) 39 | { 40 | _sut.SetDbCreator(Creator.Object); 41 | } 42 | 43 | if (Reader != null) 44 | { 45 | _sut.SetReader(Reader.Object); 46 | } 47 | 48 | if (Eraser != null) 49 | { 50 | _sut.SetEraser(Eraser.Object); 51 | } 52 | 53 | if (Updater != null) 54 | { 55 | _sut.SetUpdater(Updater.Object); 56 | } 57 | } 58 | 59 | return _sut; 60 | } 61 | } 62 | 63 | protected Mock IndexHandler { get; set; } 64 | 65 | protected Mock Creator { get; set; } 66 | 67 | protected Mock Reader { get; set; } 68 | 69 | protected Mock Eraser { get; set; } 70 | 71 | protected Mock Updater { get; set; } 72 | } 73 | -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/TestReadOnlyMongoRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MongoDB.Driver; 3 | using MongoDbGenericRepository; 4 | using MongoDbGenericRepository.DataAccess.Read; 5 | 6 | namespace CoreUnitTests.Infrastructure; 7 | 8 | public class TestReadOnlyMongoRepository : ReadOnlyMongoRepository 9 | { 10 | /// 11 | public TestReadOnlyMongoRepository(string connectionString, string databaseName = null) 12 | : base(connectionString, databaseName) 13 | { 14 | } 15 | 16 | /// 17 | public TestReadOnlyMongoRepository(IMongoDatabase mongoDatabase) 18 | : base(mongoDatabase) 19 | { 20 | } 21 | 22 | /// 23 | public TestReadOnlyMongoRepository(IMongoDbContext mongoDbContext) 24 | : base(mongoDbContext) 25 | { 26 | } 27 | 28 | public void SetReader(IMongoDbReader reader) => MongoDbReader = reader; 29 | } 30 | -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/TestReadOnlyMongoRepositoryContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using AutoFixture; 3 | using AutoFixture.AutoMoq; 4 | using MongoDB.Driver; 5 | using MongoDbGenericRepository.DataAccess.Read; 6 | using Moq; 7 | 8 | namespace CoreUnitTests.Infrastructure; 9 | 10 | public class TestReadOnlyMongoRepositoryContext 11 | { 12 | private readonly Mock mongoDatabase; 13 | 14 | private TestReadOnlyMongoRepository sut; 15 | 16 | protected TestReadOnlyMongoRepositoryContext() 17 | { 18 | mongoDatabase = new Mock(); 19 | Fixture = new Fixture().Customize(new AutoMoqCustomization()); 20 | } 21 | 22 | protected IFixture Fixture { get; set; } 23 | 24 | protected TestReadOnlyMongoRepository Sut 25 | { 26 | get 27 | { 28 | if (sut != null) 29 | { 30 | return sut; 31 | } 32 | 33 | sut = Fixture.Create(); 34 | 35 | if (Reader != null) 36 | { 37 | sut.SetReader(Reader.Object); 38 | } 39 | 40 | return sut; 41 | } 42 | } 43 | 44 | protected Mock Reader { get; set; } 45 | 46 | protected Mock MockOf() 47 | where T : class => 48 | Fixture.Freeze>(); 49 | } 50 | -------------------------------------------------------------------------------- /CoreUnitTests/Infrastructure/UpdateDefinitionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MongoDB.Bson.Serialization; 3 | using MongoDB.Driver; 4 | 5 | namespace CoreUnitTests.Infrastructure; 6 | 7 | public static class UpdateDefinitionExtensions 8 | { 9 | public static bool EquivalentTo(this UpdateDefinition update, UpdateDefinition expected) 10 | { 11 | var renderedUpdate = update.Render(new RenderArgs( 12 | BsonSerializer.SerializerRegistry.GetSerializer(), 13 | BsonSerializer.SerializerRegistry)); 14 | 15 | var renderedExpected = expected.Render(new RenderArgs( 16 | BsonSerializer.SerializerRegistry.GetSerializer(), 17 | BsonSerializer.SerializerRegistry)); 18 | 19 | return renderedUpdate.Equals(renderedExpected); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyTypedRepositoryTests/AddTests/AddManyAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using AutoFixture; 5 | using CoreUnitTests.Infrastructure; 6 | using CoreUnitTests.Infrastructure.Model; 7 | using MongoDbGenericRepository.DataAccess.Create; 8 | using Moq; 9 | using Xunit; 10 | 11 | namespace CoreUnitTests.KeyTypedRepositoryTests.AddTests; 12 | 13 | public class AddManyAsyncTests : TestKeyedMongoRepositoryContext 14 | { 15 | [Fact] 16 | public async Task WithDocument_ShouldAddOne() 17 | { 18 | // Arrange 19 | var documents = Fixture.CreateMany>().ToList(); 20 | Creator = new Mock(); 21 | 22 | // Act 23 | await Sut.AddManyAsync(documents); 24 | 25 | // Assert 26 | Creator.Verify(x => x.AddManyAsync, int>(documents, CancellationToken.None), Times.Once); 27 | } 28 | 29 | [Fact] 30 | public async Task WithDocumentAndCancellationToken_ShouldAddOne() 31 | { 32 | // Arrange 33 | var documents = Fixture.CreateMany>().ToList(); 34 | var token = new CancellationToken(true); 35 | Creator = new Mock(); 36 | 37 | // Act 38 | await Sut.AddManyAsync(documents, token); 39 | 40 | // Assert 41 | Creator.Verify(x => x.AddManyAsync, int>(documents, token), Times.Once); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyTypedRepositoryTests/AddTests/AddManyTests.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using AutoFixture; 5 | using CoreUnitTests.Infrastructure; 6 | using CoreUnitTests.Infrastructure.Model; 7 | using MongoDbGenericRepository.DataAccess.Create; 8 | using Moq; 9 | using Xunit; 10 | 11 | namespace CoreUnitTests.KeyTypedRepositoryTests.AddTests; 12 | 13 | public class AddManyTests : TestKeyedMongoRepositoryContext 14 | { 15 | [Fact] 16 | public void WithDocument_ShouldAddOne() 17 | { 18 | // Arrange 19 | var documents = Fixture.CreateMany>().ToList(); 20 | Creator = new Mock(); 21 | 22 | // Act 23 | Sut.AddMany(documents); 24 | 25 | // Assert 26 | Creator.Verify(x => x.AddMany, int>(documents, CancellationToken.None), Times.Once); 27 | } 28 | 29 | [Fact] 30 | public void WithDocumentAndCancellationToken_ShouldAddOne() 31 | { 32 | // Arrange 33 | var documents = Fixture.CreateMany>().ToList(); 34 | var token = new CancellationToken(true); 35 | Creator = new Mock(); 36 | 37 | // Act 38 | Sut.AddMany(documents, token); 39 | 40 | // Assert 41 | Creator.Verify(x => x.AddMany, int>(documents, token), Times.Once); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyTypedRepositoryTests/AddTests/AddOneAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using AutoFixture; 4 | using CoreUnitTests.Infrastructure; 5 | using CoreUnitTests.Infrastructure.Model; 6 | using MongoDbGenericRepository.DataAccess.Create; 7 | using Moq; 8 | using Xunit; 9 | 10 | namespace CoreUnitTests.KeyTypedRepositoryTests.AddTests; 11 | 12 | public class AddOneAsyncTests : TestKeyedMongoRepositoryContext 13 | { 14 | [Fact] 15 | public async Task WithDocument_ShouldAddOne() 16 | { 17 | // Arrange 18 | var document = Fixture.Create>(); 19 | Creator = new Mock(); 20 | 21 | // Act 22 | await Sut.AddOneAsync(document); 23 | 24 | // Assert 25 | Creator.Verify(x => x.AddOneAsync, int>(document, CancellationToken.None), Times.Once); 26 | } 27 | 28 | [Fact] 29 | public async Task WithDocumentAndCancellationToken_ShouldAddOne() 30 | { 31 | // Arrange 32 | var document = Fixture.Create>(); 33 | var token = new CancellationToken(true); 34 | Creator = new Mock(); 35 | 36 | // Act 37 | await Sut.AddOneAsync(document, token); 38 | 39 | // Assert 40 | Creator.Verify(x => x.AddOneAsync, int>(document, token), Times.Once); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyTypedRepositoryTests/AddTests/AddOneTests.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using AutoFixture; 3 | using CoreUnitTests.Infrastructure; 4 | using CoreUnitTests.Infrastructure.Model; 5 | using MongoDbGenericRepository.DataAccess.Create; 6 | using Moq; 7 | using Xunit; 8 | 9 | namespace CoreUnitTests.KeyTypedRepositoryTests.AddTests; 10 | 11 | public class AddOneTests : TestKeyedMongoRepositoryContext 12 | { 13 | [Fact] 14 | public void WithDocument_ShouldAddOne() 15 | { 16 | // Arrange 17 | var document = Fixture.Create>(); 18 | Creator = new Mock(); 19 | 20 | // Act 21 | Sut.AddOne(document); 22 | 23 | // Assert 24 | Creator.Verify(x => x.AddOne, int>(document, CancellationToken.None), Times.Once); 25 | } 26 | 27 | [Fact] 28 | public void WithDocumentAndCancellationToken_ShouldAddOne() 29 | { 30 | // Arrange 31 | var document = Fixture.Create>(); 32 | var token = new CancellationToken(true); 33 | Creator = new Mock(); 34 | 35 | // Act 36 | Sut.AddOne(document, token); 37 | 38 | // Assert 39 | Creator.Verify(x => x.AddOne, int>(document, token), Times.Once); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyTypedRepositoryTests/IndexTests/DropIndexAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using AutoFixture; 4 | using CoreUnitTests.Infrastructure; 5 | using CoreUnitTests.Infrastructure.Model; 6 | using MongoDbGenericRepository.DataAccess.Index; 7 | using Moq; 8 | using Xunit; 9 | 10 | namespace CoreUnitTests.KeyTypedRepositoryTests.IndexTests; 11 | 12 | public class DropIndexAsyncTests : TestKeyedMongoRepositoryContext 13 | { 14 | [Fact] 15 | public async Task WitIndexName_DropsIndex() 16 | { 17 | // Arrange 18 | var indexName = Fixture.Create(); 19 | IndexHandler = new Mock(); 20 | 21 | // Act 22 | await Sut.DropIndexAsync>(indexName); 23 | 24 | // Assert 25 | IndexHandler.Verify( 26 | x => x.DropIndexAsync, int>(indexName, null, CancellationToken.None)); 27 | } 28 | 29 | [Fact] 30 | public async Task WitIndexNameAndCancellationToken_DropsIndex() 31 | { 32 | // Arrange 33 | var indexName = Fixture.Create(); 34 | var token = new CancellationToken(true); 35 | IndexHandler = new Mock(); 36 | 37 | // Act 38 | await Sut.DropIndexAsync>(indexName, token); 39 | 40 | // Assert 41 | IndexHandler.Verify( 42 | x => x.DropIndexAsync, int>(indexName, null, token)); 43 | } 44 | 45 | [Fact] 46 | public async Task WitIndexNameAndPartitionKey_DropsIndex() 47 | { 48 | // Arrange 49 | var indexName = Fixture.Create(); 50 | var partitionKey = Fixture.Create(); 51 | IndexHandler = new Mock(); 52 | 53 | // Act 54 | await Sut.DropIndexAsync>(indexName, partitionKey); 55 | 56 | // Assert 57 | IndexHandler.Verify( 58 | x => x.DropIndexAsync, int>(indexName, partitionKey, CancellationToken.None)); 59 | } 60 | 61 | [Fact] 62 | public async Task WitIndexNameAndPartitionKeyAndCancellationToken_DropsIndex() 63 | { 64 | // Arrange 65 | var indexName = Fixture.Create(); 66 | var partitionKey = Fixture.Create(); 67 | var token = new CancellationToken(true); 68 | IndexHandler = new Mock(); 69 | 70 | // Act 71 | await Sut.DropIndexAsync>(indexName, partitionKey, token); 72 | 73 | // Assert 74 | IndexHandler.Verify( 75 | x => x.DropIndexAsync, int>(indexName, partitionKey, token)); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyTypedRepositoryTests/IndexTests/GetIndexNamesAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using AutoFixture; 5 | using CoreUnitTests.Infrastructure; 6 | using CoreUnitTests.Infrastructure.Model; 7 | using MongoDbGenericRepository.DataAccess.Index; 8 | using Moq; 9 | using Xunit; 10 | 11 | namespace CoreUnitTests.KeyTypedRepositoryTests.IndexTests; 12 | 13 | public class GetIndexNamesAsyncTests : TestKeyedMongoRepositoryContext 14 | { 15 | [Fact] 16 | public async Task WithNoParameters_ReturnsIndexNames() 17 | { 18 | // Arrange 19 | IndexHandler = new Mock(); 20 | var indexName = Fixture.Create(); 21 | 22 | IndexHandler 23 | .Setup(x => x.GetIndexesNamesAsync, int>(It.IsAny(), It.IsAny())) 24 | .ReturnsAsync(new List { indexName }); 25 | 26 | // Act 27 | var result = await Sut.GetIndexesNamesAsync>(); 28 | 29 | // Assert 30 | Assert.NotNull(result); 31 | Assert.Contains(result, x => x == indexName); 32 | IndexHandler.Verify(x => x.GetIndexesNamesAsync, int>(null, CancellationToken.None), Times.Once()); 33 | } 34 | 35 | [Fact] 36 | public async Task WithCancellationToken_ReturnsIndexNames() 37 | { 38 | // Arrange 39 | IndexHandler = new Mock(); 40 | var indexName = Fixture.Create(); 41 | var token = new CancellationToken(true); 42 | 43 | IndexHandler 44 | .Setup(x => x.GetIndexesNamesAsync, int>(It.IsAny(), It.IsAny())) 45 | .ReturnsAsync(new List { indexName }); 46 | 47 | // Act 48 | var result = await Sut.GetIndexesNamesAsync>(token); 49 | 50 | // Assert 51 | Assert.NotNull(result); 52 | Assert.Contains(result, x => x == indexName); 53 | IndexHandler.Verify(x => x.GetIndexesNamesAsync, int>(null, token), Times.Once()); 54 | } 55 | 56 | [Fact] 57 | public async Task WithPartitionKey_ReturnsIndexNames() 58 | { 59 | // Arrange 60 | IndexHandler = new Mock(); 61 | var indexName = Fixture.Create(); 62 | var partitionKey = Fixture.Create(); 63 | 64 | IndexHandler 65 | .Setup(x => x.GetIndexesNamesAsync, int>(It.IsAny(), It.IsAny())) 66 | .ReturnsAsync(new List { indexName }); 67 | 68 | // Act 69 | var result = await Sut.GetIndexesNamesAsync>(partitionKey); 70 | 71 | // Assert 72 | Assert.NotNull(result); 73 | Assert.Contains(result, x => x == indexName); 74 | IndexHandler.Verify(x => x.GetIndexesNamesAsync, int>(partitionKey, CancellationToken.None), Times.Once()); 75 | } 76 | 77 | [Fact] 78 | public async Task WithPartitionKeyAndCancellationToken_ReturnsIndexNames() 79 | { 80 | // Arrange 81 | IndexHandler = new Mock(); 82 | var indexName = Fixture.Create(); 83 | var partitionKey = Fixture.Create(); 84 | var token = new CancellationToken(true); 85 | 86 | IndexHandler 87 | .Setup(x => x.GetIndexesNamesAsync, int>(It.IsAny(), It.IsAny())) 88 | .ReturnsAsync(new List { indexName }); 89 | 90 | // Act 91 | var result = await Sut.GetIndexesNamesAsync>(partitionKey, token); 92 | 93 | // Assert 94 | Assert.NotNull(result); 95 | Assert.Contains(result, x => x == indexName); 96 | IndexHandler.Verify(x => x.GetIndexesNamesAsync, int>(partitionKey, token), Times.Once()); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/AnyAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using AutoFixture; 6 | using CoreUnitTests.Infrastructure; 7 | using CoreUnitTests.Infrastructure.Model; 8 | using FluentAssertions; 9 | using MongoDbGenericRepository.DataAccess.Read; 10 | using Moq; 11 | using Xunit; 12 | 13 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 14 | 15 | public class AnyAsyncTests : TestKeyedReadOnlyMongoRepositoryContext 16 | { 17 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 18 | 19 | [Fact] 20 | public async Task WithFilter_GetsResult() 21 | { 22 | // Arrange 23 | SetupReader(); 24 | 25 | // Act 26 | var result = await Sut.AnyAsync(filter); 27 | 28 | // Assert 29 | result.Should().BeTrue(); 30 | Reader.Verify( 31 | x => x.AnyAsync, int>(filter, null, CancellationToken.None), 32 | Times.Once); 33 | } 34 | 35 | [Fact] 36 | public async Task WithFilterAndCancellationToken_GetsResult() 37 | { 38 | // Arrange 39 | var token = new CancellationToken(true); 40 | 41 | SetupReader(); 42 | 43 | // Act 44 | var result = await Sut.AnyAsync(filter, token); 45 | 46 | // Assert 47 | result.Should().BeTrue(); 48 | Reader.Verify( 49 | x => x.AnyAsync, int>(filter, null, token), 50 | Times.Once); 51 | } 52 | 53 | [Fact] 54 | public async Task WithFilterAndPartitionKey_GetsResult() 55 | { 56 | // Arrange 57 | var partitionKey = Fixture.Create(); 58 | 59 | SetupReader(); 60 | 61 | // Act 62 | var result = await Sut.AnyAsync(filter, partitionKey); 63 | 64 | // Assert 65 | result.Should().BeTrue(); 66 | Reader.Verify( 67 | x => x.AnyAsync, int>(filter, partitionKey, CancellationToken.None), 68 | Times.Once); 69 | } 70 | 71 | [Fact] 72 | public async Task WithFilterAndPartitionKeyAndCancellationToken_GetsResult() 73 | { 74 | // Arrange 75 | var partitionKey = Fixture.Create(); 76 | var token = new CancellationToken(true); 77 | 78 | SetupReader(); 79 | 80 | // Act 81 | var result = await Sut.AnyAsync(filter, partitionKey, token); 82 | 83 | // Assert 84 | result.Should().BeTrue(); 85 | Reader.Verify( 86 | x => x.AnyAsync, int>(filter, partitionKey, token), 87 | Times.Once); 88 | } 89 | 90 | private void SetupReader() 91 | { 92 | Reader = new Mock(); 93 | Reader 94 | .Setup( 95 | x => x.AnyAsync, int>( 96 | It.IsAny, bool>>>(), 97 | It.IsAny(), 98 | It.IsAny())) 99 | .ReturnsAsync(true); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/AnyTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using AutoFixture; 5 | using CoreUnitTests.Infrastructure; 6 | using CoreUnitTests.Infrastructure.Model; 7 | using FluentAssertions; 8 | using MongoDbGenericRepository.DataAccess.Read; 9 | using Moq; 10 | using Xunit; 11 | 12 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 13 | 14 | public class AnyTests : TestKeyedReadOnlyMongoRepositoryContext 15 | { 16 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 17 | 18 | [Fact] 19 | public void WithFilter_GetsResult() 20 | { 21 | // Arrange 22 | SetupReader(); 23 | 24 | // Act 25 | var result = Sut.Any(filter); 26 | 27 | // Assert 28 | result.Should().BeTrue(); 29 | Reader.Verify( 30 | x => x.Any, int>(filter, null, CancellationToken.None), 31 | Times.Once); 32 | } 33 | 34 | [Fact] 35 | public void WithFilterAndCancellationToken_GetsResult() 36 | { 37 | // Arrange 38 | var token = new CancellationToken(true); 39 | 40 | SetupReader(); 41 | 42 | // Act 43 | var result = Sut.Any(filter, token); 44 | 45 | // Assert 46 | result.Should().BeTrue(); 47 | Reader.Verify( 48 | x => x.Any, int>(filter, null, token), 49 | Times.Once); 50 | } 51 | 52 | [Fact] 53 | public void WithFilterAndPartitionKey_GetsResult() 54 | { 55 | // Arrange 56 | var partitionKey = Fixture.Create(); 57 | 58 | SetupReader(); 59 | 60 | // Act 61 | var result = Sut.Any(filter, partitionKey); 62 | 63 | // Assert 64 | result.Should().BeTrue(); 65 | Reader.Verify( 66 | x => x.Any, int>(filter, partitionKey, CancellationToken.None), 67 | Times.Once); 68 | } 69 | 70 | [Fact] 71 | public void WithFilterAndPartitionKeyAndCancellationToken_GetsResult() 72 | { 73 | // Arrange 74 | var partitionKey = Fixture.Create(); 75 | var token = new CancellationToken(true); 76 | 77 | SetupReader(); 78 | 79 | // Act 80 | var result = Sut.Any(filter, partitionKey, token); 81 | 82 | // Assert 83 | result.Should().BeTrue(); 84 | Reader.Verify( 85 | x => x.Any, int>(filter, partitionKey, token), 86 | Times.Once); 87 | } 88 | 89 | private void SetupReader() 90 | { 91 | Reader = new Mock(); 92 | Reader 93 | .Setup( 94 | x => x.Any, int>( 95 | It.IsAny, bool>>>(), 96 | It.IsAny(), 97 | It.IsAny())) 98 | .Returns(true); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/CountAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Linq.Expressions; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using AutoFixture; 8 | using CoreUnitTests.Infrastructure; 9 | using CoreUnitTests.Infrastructure.Model; 10 | using FluentAssertions; 11 | using MongoDbGenericRepository.DataAccess.Read; 12 | using Moq; 13 | using Xunit; 14 | 15 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 16 | 17 | public class CountAsyncTests : TestKeyedReadOnlyMongoRepositoryContext 18 | { 19 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 20 | 21 | [Fact] 22 | public async Task WithFilter_GetsOne() 23 | { 24 | // Arrange 25 | var count = Fixture.Create(); 26 | 27 | SetupReader(count); 28 | 29 | // Act 30 | var result = await Sut.CountAsync(filter); 31 | 32 | // Assert 33 | result.Should().Be(count); 34 | Reader.Verify( 35 | x => x.CountAsync, int>(filter, null, CancellationToken.None), 36 | Times.Once); 37 | } 38 | 39 | [Fact] 40 | public async Task WithFilterAndCancellationToken_GetsOne() 41 | { 42 | // Arrange 43 | var count = Fixture.Create(); 44 | var token = new CancellationToken(true); 45 | 46 | SetupReader(count); 47 | 48 | // Act 49 | var result = await Sut.CountAsync(filter, token); 50 | 51 | // Assert 52 | result.Should().Be(count); 53 | Reader.Verify( 54 | x => x.CountAsync, int>(filter, null, token), 55 | Times.Once); 56 | } 57 | 58 | [Fact] 59 | public async Task WithFilterAndPartitionKey_GetsOne() 60 | { 61 | // Arrange 62 | var count = Fixture.Create(); 63 | var partitionKey = Fixture.Create(); 64 | 65 | SetupReader(count); 66 | 67 | // Act 68 | var result = await Sut.CountAsync(filter, partitionKey); 69 | 70 | // Assert 71 | result.Should().Be(count); 72 | Reader.Verify( 73 | x => x.CountAsync, int>(filter, partitionKey, CancellationToken.None), 74 | Times.Once); 75 | } 76 | 77 | [Fact] 78 | public async Task WithFilterAndPartitionKeyAndCancellationToken_GetsOne() 79 | { 80 | // Arrange 81 | var count = Fixture.Create(); 82 | var partitionKey = Fixture.Create(); 83 | var token = new CancellationToken(true); 84 | 85 | SetupReader(count); 86 | 87 | // Act 88 | var result = await Sut.CountAsync(filter, partitionKey, token); 89 | 90 | // Assert 91 | result.Should().Be(count); 92 | Reader.Verify( 93 | x => x.CountAsync, int>(filter, partitionKey, token), 94 | Times.Once); 95 | } 96 | 97 | private void SetupReader(long count) 98 | { 99 | Reader = new Mock(); 100 | Reader 101 | .Setup( 102 | x => x.CountAsync, int>( 103 | It.IsAny, bool>>>(), 104 | It.IsAny(), 105 | It.IsAny())) 106 | .ReturnsAsync(count); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/CountTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using AutoFixture; 5 | using CoreUnitTests.Infrastructure; 6 | using CoreUnitTests.Infrastructure.Model; 7 | using FluentAssertions; 8 | using MongoDbGenericRepository.DataAccess.Read; 9 | using Moq; 10 | using Xunit; 11 | 12 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 13 | 14 | public class CountTests : TestKeyedReadOnlyMongoRepositoryContext 15 | { 16 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 17 | 18 | [Fact] 19 | public void WithFilter_GetsOne() 20 | { 21 | // Arrange 22 | var count = Fixture.Create(); 23 | 24 | SetupReader(count); 25 | 26 | // Act 27 | var result = Sut.Count(filter); 28 | 29 | // Assert 30 | result.Should().Be(count); 31 | Reader.Verify( 32 | x => x.Count, int>(filter, null, CancellationToken.None), 33 | Times.Once); 34 | } 35 | 36 | [Fact] 37 | public void WithFilterAndCancellationToken_GetsOne() 38 | { 39 | // Arrange 40 | var count = Fixture.Create(); 41 | var token = new CancellationToken(true); 42 | 43 | SetupReader(count); 44 | 45 | // Act 46 | var result = Sut.Count(filter, token); 47 | 48 | // Assert 49 | result.Should().Be(count); 50 | Reader.Verify( 51 | x => x.Count, int>(filter, null, token), 52 | Times.Once); 53 | } 54 | 55 | [Fact] 56 | public void WithFilterAndPartitionKey_GetsOne() 57 | { 58 | // Arrange 59 | var count = Fixture.Create(); 60 | var partitionKey = Fixture.Create(); 61 | 62 | SetupReader(count); 63 | 64 | // Act 65 | var result = Sut.Count(filter, partitionKey); 66 | 67 | // Assert 68 | result.Should().Be(count); 69 | Reader.Verify( 70 | x => x.Count, int>(filter, partitionKey, CancellationToken.None), 71 | Times.Once); 72 | } 73 | 74 | [Fact] 75 | public void WithFilterAndPartitionKeyAndCancellationToken_GetsOne() 76 | { 77 | // Arrange 78 | var count = Fixture.Create(); 79 | var partitionKey = Fixture.Create(); 80 | var token = new CancellationToken(true); 81 | 82 | SetupReader(count); 83 | 84 | // Act 85 | var result = Sut.Count(filter, partitionKey, token); 86 | 87 | // Assert 88 | result.Should().Be(count); 89 | Reader.Verify( 90 | x => x.Count, int>(filter, partitionKey, token), 91 | Times.Once); 92 | } 93 | 94 | private void SetupReader(long count) 95 | { 96 | Reader = new Mock(); 97 | Reader 98 | .Setup( 99 | x => x.Count, int>( 100 | It.IsAny, bool>>>(), 101 | It.IsAny(), 102 | It.IsAny())) 103 | .Returns(count); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/GetAllAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Linq.Expressions; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using AutoFixture; 8 | using CoreUnitTests.Infrastructure; 9 | using CoreUnitTests.Infrastructure.Model; 10 | using FluentAssertions; 11 | using MongoDbGenericRepository.DataAccess.Read; 12 | using Moq; 13 | using Xunit; 14 | 15 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 16 | 17 | public class GetAllAsyncTests : TestKeyedReadOnlyMongoRepositoryContext 18 | { 19 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 20 | 21 | [Fact] 22 | public async Task WithFilter_GetsOne() 23 | { 24 | // Arrange 25 | var document = Fixture.CreateMany>().ToList(); 26 | 27 | SetupReader(document); 28 | 29 | // Act 30 | var result = await Sut.GetAllAsync(filter); 31 | 32 | // Assert 33 | result.Should().NotBeNull(); 34 | result.Should().BeEquivalentTo(document); 35 | Reader.Verify( 36 | x => x.GetAllAsync, int>(filter, null, CancellationToken.None), 37 | Times.Once); 38 | } 39 | 40 | [Fact] 41 | public async Task WithFilterAndCancellationToken_GetsOne() 42 | { 43 | // Arrange 44 | var document = Fixture.CreateMany>().ToList(); 45 | var token = new CancellationToken(true); 46 | 47 | SetupReader(document); 48 | 49 | // Act 50 | var result = await Sut.GetAllAsync(filter, token); 51 | 52 | // Assert 53 | result.Should().NotBeNull(); 54 | result.Should().BeEquivalentTo(document); 55 | Reader.Verify( 56 | x => x.GetAllAsync, int>(filter, null, token), 57 | Times.Once); 58 | } 59 | 60 | [Fact] 61 | public async Task WithFilterAndPartitionKey_GetsOne() 62 | { 63 | // Arrange 64 | var document = Fixture.CreateMany>().ToList(); 65 | var partitionKey = Fixture.Create(); 66 | 67 | SetupReader(document); 68 | 69 | // Act 70 | var result = await Sut.GetAllAsync(filter, partitionKey); 71 | 72 | // Assert 73 | result.Should().NotBeNull(); 74 | result.Should().BeEquivalentTo(document); 75 | Reader.Verify( 76 | x => x.GetAllAsync, int>(filter, partitionKey, CancellationToken.None), 77 | Times.Once); 78 | } 79 | 80 | [Fact] 81 | public async Task WithFilterAndPartitionKeyAndCancellationToken_GetsOne() 82 | { 83 | // Arrange 84 | var document = Fixture.CreateMany>().ToList(); 85 | var partitionKey = Fixture.Create(); 86 | var token = new CancellationToken(true); 87 | 88 | SetupReader(document); 89 | 90 | // Act 91 | var result = await Sut.GetAllAsync(filter, partitionKey, token); 92 | 93 | // Assert 94 | result.Should().NotBeNull(); 95 | result.Should().BeEquivalentTo(document); 96 | Reader.Verify( 97 | x => x.GetAllAsync, int>(filter, partitionKey, token), 98 | Times.Once); 99 | } 100 | 101 | private void SetupReader(List> documents) 102 | { 103 | Reader = new Mock(); 104 | Reader 105 | .Setup( 106 | x => x.GetAllAsync, int>( 107 | It.IsAny, bool>>>(), 108 | It.IsAny(), 109 | It.IsAny())) 110 | .ReturnsAsync(documents); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/GetAllTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Linq.Expressions; 5 | using System.Threading; 6 | using AutoFixture; 7 | using CoreUnitTests.Infrastructure; 8 | using CoreUnitTests.Infrastructure.Model; 9 | using FluentAssertions; 10 | using MongoDbGenericRepository.DataAccess.Read; 11 | using Moq; 12 | using Xunit; 13 | 14 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 15 | 16 | public class GetAllTests : TestKeyedReadOnlyMongoRepositoryContext 17 | { 18 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 19 | 20 | [Fact] 21 | public void WithFilter_GetsOne() 22 | { 23 | // Arrange 24 | var document = Fixture.CreateMany>().ToList(); 25 | 26 | SetupReader(document); 27 | 28 | // Act 29 | var result = Sut.GetAll(filter); 30 | 31 | // Assert 32 | result.Should().NotBeNull(); 33 | result.Should().BeEquivalentTo(document); 34 | Reader.Verify( 35 | x => x.GetAll, int>(filter, null, CancellationToken.None), 36 | Times.Once); 37 | } 38 | 39 | [Fact] 40 | public void WithFilterAndCancellationToken_GetsOne() 41 | { 42 | // Arrange 43 | var document = Fixture.CreateMany>().ToList(); 44 | var token = new CancellationToken(true); 45 | 46 | SetupReader(document); 47 | 48 | // Act 49 | var result = Sut.GetAll(filter, token); 50 | 51 | // Assert 52 | result.Should().NotBeNull(); 53 | result.Should().BeEquivalentTo(document); 54 | Reader.Verify( 55 | x => x.GetAll, int>(filter, null, token), 56 | Times.Once); 57 | } 58 | 59 | [Fact] 60 | public void WithFilterAndPartitionKey_GetsOne() 61 | { 62 | // Arrange 63 | var document = Fixture.CreateMany>().ToList(); 64 | var partitionKey = Fixture.Create(); 65 | 66 | SetupReader(document); 67 | 68 | // Act 69 | var result = Sut.GetAll(filter, partitionKey); 70 | 71 | // Assert 72 | result.Should().NotBeNull(); 73 | result.Should().BeEquivalentTo(document); 74 | Reader.Verify( 75 | x => x.GetAll, int>(filter, partitionKey, CancellationToken.None), 76 | Times.Once); 77 | } 78 | 79 | [Fact] 80 | public void WithFilterAndPartitionKeyAndCancellationToken_GetsOne() 81 | { 82 | // Arrange 83 | var document = Fixture.CreateMany>().ToList(); 84 | var partitionKey = Fixture.Create(); 85 | var token = new CancellationToken(true); 86 | 87 | SetupReader(document); 88 | 89 | // Act 90 | var result = Sut.GetAll(filter, partitionKey, token); 91 | 92 | // Assert 93 | result.Should().NotBeNull(); 94 | result.Should().BeEquivalentTo(document); 95 | Reader.Verify( 96 | x => x.GetAll, int>(filter, partitionKey, token), 97 | Times.Once); 98 | } 99 | 100 | private void SetupReader(List> documents) 101 | { 102 | Reader = new Mock(); 103 | Reader 104 | .Setup( 105 | x => x.GetAll, int>( 106 | It.IsAny, bool>>>(), 107 | It.IsAny(), 108 | It.IsAny())) 109 | .Returns(documents); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/GetByIdAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using AutoFixture; 4 | using CoreUnitTests.Infrastructure; 5 | using CoreUnitTests.Infrastructure.Model; 6 | using FluentAssertions; 7 | using MongoDbGenericRepository.DataAccess.Read; 8 | using Moq; 9 | using Xunit; 10 | 11 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 12 | 13 | public class GetByIdAsyncTests : TestKeyedReadOnlyMongoRepositoryContext 14 | { 15 | [Fact] 16 | public async Task WithId_Gets() 17 | { 18 | // Arrange 19 | var document = Fixture.Create>(); 20 | 21 | SetupReader(document); 22 | 23 | // Act 24 | var result = await Sut.GetByIdAsync>(document.Id); 25 | 26 | // Assert 27 | result.Should().NotBeNull(); 28 | result.Should().BeEquivalentTo(document); 29 | Reader.Verify( 30 | x => x.GetByIdAsync, int>(document.Id, null, CancellationToken.None), 31 | Times.Once); 32 | } 33 | 34 | [Fact] 35 | public async Task WithIdAndCancellationToken_Gets() 36 | { 37 | // Arrange 38 | var document = Fixture.Create>(); 39 | var token = new CancellationToken(true); 40 | 41 | SetupReader(document); 42 | 43 | // Act 44 | var result = await Sut.GetByIdAsync>(document.Id, token); 45 | 46 | // Assert 47 | result.Should().NotBeNull(); 48 | result.Should().BeEquivalentTo(document); 49 | Reader.Verify( 50 | x => x.GetByIdAsync, int>(document.Id, null, token), 51 | Times.Once); 52 | } 53 | 54 | [Fact] 55 | public async Task WithIdAndPartitionKey_Gets() 56 | { 57 | // Arrange 58 | var document = Fixture.Create>(); 59 | var partitionKey = Fixture.Create(); 60 | 61 | SetupReader(document); 62 | 63 | // Act 64 | var result = await Sut.GetByIdAsync>(document.Id, partitionKey); 65 | 66 | // Assert 67 | result.Should().NotBeNull(); 68 | result.Should().BeEquivalentTo(document); 69 | Reader.Verify( 70 | x => x.GetByIdAsync, int>(document.Id, partitionKey, CancellationToken.None), 71 | Times.Once); 72 | } 73 | 74 | [Fact] 75 | public async Task WithIdAndPartitionKeyAndCancellationToken_Gets() 76 | { 77 | // Arrange 78 | var document = Fixture.Create>(); 79 | var partitionKey = Fixture.Create(); 80 | var token = new CancellationToken(true); 81 | 82 | SetupReader(document); 83 | 84 | // Act 85 | var result = await Sut.GetByIdAsync>(document.Id, partitionKey, token); 86 | 87 | // Assert 88 | result.Should().NotBeNull(); 89 | result.Should().BeEquivalentTo(document); 90 | Reader.Verify( 91 | x => x.GetByIdAsync, int>(document.Id, partitionKey, token), 92 | Times.Once); 93 | } 94 | 95 | private void SetupReader(TestDocumentWithKey document) 96 | { 97 | Reader = new Mock(); 98 | Reader 99 | .Setup( 100 | x => x.GetByIdAsync, int>( 101 | It.IsAny(), 102 | It.IsAny(), 103 | It.IsAny())) 104 | .ReturnsAsync(document); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/GetByIdTests.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using AutoFixture; 3 | using CoreUnitTests.Infrastructure; 4 | using CoreUnitTests.Infrastructure.Model; 5 | using FluentAssertions; 6 | using MongoDbGenericRepository.DataAccess.Read; 7 | using Moq; 8 | using Xunit; 9 | 10 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 11 | 12 | public class GetByIdTests : TestKeyedReadOnlyMongoRepositoryContext 13 | { 14 | [Fact] 15 | public void WithId_Gets() 16 | { 17 | // Arrange 18 | var document = Fixture.Create>(); 19 | 20 | SetupReader(document); 21 | 22 | // Act 23 | var result = Sut.GetById>(document.Id); 24 | 25 | // Assert 26 | result.Should().NotBeNull(); 27 | result.Should().BeEquivalentTo(document); 28 | Reader.Verify( 29 | x => x.GetById, int>(document.Id, null, CancellationToken.None), 30 | Times.Once); 31 | } 32 | 33 | [Fact] 34 | public void WithIdAndCancellationToken_Gets() 35 | { 36 | // Arrange 37 | var document = Fixture.Create>(); 38 | var token = new CancellationToken(true); 39 | 40 | SetupReader(document); 41 | 42 | // Act 43 | var result = Sut.GetById>(document.Id, token); 44 | 45 | // Assert 46 | result.Should().NotBeNull(); 47 | result.Should().BeEquivalentTo(document); 48 | Reader.Verify( 49 | x => x.GetById, int>(document.Id, null, token), 50 | Times.Once); 51 | } 52 | 53 | [Fact] 54 | public void WithIdAndPartitionKey_Gets() 55 | { 56 | // Arrange 57 | var document = Fixture.Create>(); 58 | var partitionKey = Fixture.Create(); 59 | 60 | SetupReader(document); 61 | 62 | // Act 63 | var result = Sut.GetById>(document.Id, partitionKey); 64 | 65 | // Assert 66 | result.Should().NotBeNull(); 67 | result.Should().BeEquivalentTo(document); 68 | Reader.Verify( 69 | x => x.GetById, int>(document.Id, partitionKey, CancellationToken.None), 70 | Times.Once); 71 | } 72 | 73 | [Fact] 74 | public void WithIdAndPartitionKeyAndCancellationToken_Gets() 75 | { 76 | // Arrange 77 | var document = Fixture.Create>(); 78 | var partitionKey = Fixture.Create(); 79 | var token = new CancellationToken(true); 80 | 81 | SetupReader(document); 82 | 83 | // Act 84 | var result = Sut.GetById>(document.Id, partitionKey, token); 85 | 86 | // Assert 87 | result.Should().NotBeNull(); 88 | result.Should().BeEquivalentTo(document); 89 | Reader.Verify( 90 | x => x.GetById, int>(document.Id, partitionKey, token), 91 | Times.Once); 92 | } 93 | 94 | private void SetupReader(TestDocumentWithKey document) 95 | { 96 | Reader = new Mock(); 97 | Reader 98 | .Setup( 99 | x => x.GetById, int>( 100 | It.IsAny(), 101 | It.IsAny(), 102 | It.IsAny())) 103 | .Returns(document); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/GetByMaxAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using AutoFixture; 6 | using CoreUnitTests.Infrastructure; 7 | using CoreUnitTests.Infrastructure.Model; 8 | using FluentAssertions; 9 | using MongoDbGenericRepository.DataAccess.Read; 10 | using Moq; 11 | using Xunit; 12 | 13 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 14 | 15 | public class GetByMaxAsyncTests : TestKeyedReadOnlyMongoRepositoryContext 16 | { 17 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 18 | private readonly Expression, object>> selector = document => document.SomeValue; 19 | 20 | [Fact] 21 | public async Task WithFilterAndSelector_GetsOne() 22 | { 23 | // Arrange 24 | var document = Fixture.Create>(); 25 | 26 | SetupReader(document); 27 | 28 | // Act 29 | var result = await Sut.GetByMaxAsync(filter, selector); 30 | 31 | // Assert 32 | result.Should().NotBeNull(); 33 | result.Should().BeEquivalentTo(document); 34 | Reader.Verify( 35 | x => x.GetByMaxAsync, int>(filter, selector, null, CancellationToken.None), 36 | Times.Once); 37 | } 38 | 39 | [Fact] 40 | public async Task WithFilterAndSelectorAndCancellationToken_GetsOne() 41 | { 42 | // Arrange 43 | var document = Fixture.Create>(); 44 | var token = new CancellationToken(true); 45 | 46 | SetupReader(document); 47 | 48 | // Act 49 | var result = await Sut.GetByMaxAsync(filter, selector, token); 50 | 51 | // Assert 52 | result.Should().NotBeNull(); 53 | result.Should().BeEquivalentTo(document); 54 | Reader.Verify( 55 | x => x.GetByMaxAsync, int>(filter, selector, null, token), 56 | Times.Once); 57 | } 58 | 59 | [Fact] 60 | public async Task WithFilterAndSelectorAndPartitionKey_GetsOne() 61 | { 62 | // Arrange 63 | var document = Fixture.Create>(); 64 | var partitionKey = Fixture.Create(); 65 | 66 | SetupReader(document); 67 | 68 | // Act 69 | var result = await Sut.GetByMaxAsync(filter, selector, partitionKey); 70 | 71 | // Assert 72 | result.Should().NotBeNull(); 73 | result.Should().BeEquivalentTo(document); 74 | Reader.Verify( 75 | x => x.GetByMaxAsync, int>(filter, selector, partitionKey, CancellationToken.None), 76 | Times.Once); 77 | } 78 | 79 | [Fact] 80 | public async Task WithFilterAndSelectorAndPartitionKeyAndCancellationToken_GetsOne() 81 | { 82 | // Arrange 83 | var document = Fixture.Create>(); 84 | var partitionKey = Fixture.Create(); 85 | var token = new CancellationToken(true); 86 | 87 | SetupReader(document); 88 | 89 | // Act 90 | var result = await Sut.GetByMaxAsync(filter, selector, partitionKey, token); 91 | 92 | // Assert 93 | result.Should().NotBeNull(); 94 | result.Should().BeEquivalentTo(document); 95 | Reader.Verify( 96 | x => x.GetByMaxAsync, int>(filter, selector, partitionKey, token), 97 | Times.Once); 98 | } 99 | 100 | private void SetupReader(TestDocumentWithKey document) 101 | { 102 | Reader = new Mock(); 103 | Reader 104 | .Setup( 105 | x => x.GetByMaxAsync, int>( 106 | It.IsAny, bool>>>(), 107 | It.IsAny, object>>>(), 108 | It.IsAny(), 109 | It.IsAny())) 110 | .ReturnsAsync(document); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/GetByMaxTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using AutoFixture; 5 | using CoreUnitTests.Infrastructure; 6 | using CoreUnitTests.Infrastructure.Model; 7 | using FluentAssertions; 8 | using MongoDbGenericRepository.DataAccess.Read; 9 | using Moq; 10 | using Xunit; 11 | 12 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 13 | 14 | public class GetByMaxTests : TestKeyedReadOnlyMongoRepositoryContext 15 | { 16 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 17 | private readonly Expression, object>> selector = document => document.SomeValue; 18 | 19 | [Fact] 20 | public void WithFilterAndSelector_GetsOne() 21 | { 22 | // Arrange 23 | var document = Fixture.Create>(); 24 | 25 | SetupReader(document); 26 | 27 | // Act 28 | var result = Sut.GetByMax(filter, selector); 29 | 30 | // Assert 31 | result.Should().NotBeNull(); 32 | result.Should().BeEquivalentTo(document); 33 | Reader.Verify( 34 | x => x.GetByMax, int>(filter, selector, null, CancellationToken.None), 35 | Times.Once); 36 | } 37 | 38 | [Fact] 39 | public void WithFilterAndSelectorAndCancellationToken_GetsOne() 40 | { 41 | // Arrange 42 | var document = Fixture.Create>(); 43 | var token = new CancellationToken(true); 44 | 45 | SetupReader(document); 46 | 47 | // Act 48 | var result = Sut.GetByMax(filter, selector, token); 49 | 50 | // Assert 51 | result.Should().NotBeNull(); 52 | result.Should().BeEquivalentTo(document); 53 | Reader.Verify( 54 | x => x.GetByMax, int>(filter, selector, null, token), 55 | Times.Once); 56 | } 57 | 58 | [Fact] 59 | public void WithFilterAndSelectorAndPartitionKey_GetsOne() 60 | { 61 | // Arrange 62 | var document = Fixture.Create>(); 63 | var partitionKey = Fixture.Create(); 64 | 65 | SetupReader(document); 66 | 67 | // Act 68 | var result = Sut.GetByMax(filter, selector, partitionKey); 69 | 70 | // Assert 71 | result.Should().NotBeNull(); 72 | result.Should().BeEquivalentTo(document); 73 | Reader.Verify( 74 | x => x.GetByMax, int>(filter, selector, partitionKey, CancellationToken.None), 75 | Times.Once); 76 | } 77 | 78 | [Fact] 79 | public void WithFilterAndSelectorAndPartitionKeyAndCancellationToken_GetsOne() 80 | { 81 | // Arrange 82 | var document = Fixture.Create>(); 83 | var partitionKey = Fixture.Create(); 84 | var token = new CancellationToken(true); 85 | 86 | SetupReader(document); 87 | 88 | // Act 89 | var result = Sut.GetByMax(filter, selector, partitionKey, token); 90 | 91 | // Assert 92 | result.Should().NotBeNull(); 93 | result.Should().BeEquivalentTo(document); 94 | Reader.Verify( 95 | x => x.GetByMax, int>(filter, selector, partitionKey, token), 96 | Times.Once); 97 | } 98 | 99 | private void SetupReader(TestDocumentWithKey document) 100 | { 101 | Reader = new Mock(); 102 | Reader 103 | .Setup( 104 | x => x.GetByMax, int>( 105 | It.IsAny, bool>>>(), 106 | It.IsAny, object>>>(), 107 | It.IsAny(), 108 | It.IsAny())) 109 | .Returns(document); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/GetByMinAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using AutoFixture; 6 | using CoreUnitTests.Infrastructure; 7 | using CoreUnitTests.Infrastructure.Model; 8 | using FluentAssertions; 9 | using MongoDbGenericRepository.DataAccess.Read; 10 | using Moq; 11 | using Xunit; 12 | 13 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 14 | 15 | public class GetByMinAsyncTests : TestKeyedReadOnlyMongoRepositoryContext 16 | { 17 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 18 | private readonly Expression, object>> selector = document => document.SomeValue; 19 | 20 | [Fact] 21 | public async Task WithFilterAndSelector_GetsOne() 22 | { 23 | // Arrange 24 | var document = Fixture.Create>(); 25 | 26 | SetupReader(document); 27 | 28 | // Act 29 | var result = await Sut.GetByMinAsync(filter, selector); 30 | 31 | // Assert 32 | result.Should().NotBeNull(); 33 | result.Should().BeEquivalentTo(document); 34 | Reader.Verify( 35 | x => x.GetByMinAsync, int>(filter, selector, null, CancellationToken.None), 36 | Times.Once); 37 | } 38 | 39 | [Fact] 40 | public async Task WithFilterAndSelectorAndCancellationToken_GetsOne() 41 | { 42 | // Arrange 43 | var document = Fixture.Create>(); 44 | var token = new CancellationToken(true); 45 | 46 | SetupReader(document); 47 | 48 | // Act 49 | var result = await Sut.GetByMinAsync(filter, selector, token); 50 | 51 | // Assert 52 | result.Should().NotBeNull(); 53 | result.Should().BeEquivalentTo(document); 54 | Reader.Verify( 55 | x => x.GetByMinAsync, int>(filter, selector, null, token), 56 | Times.Once); 57 | } 58 | 59 | [Fact] 60 | public async Task WithFilterAndSelectorAndPartitionKey_GetsOne() 61 | { 62 | // Arrange 63 | var document = Fixture.Create>(); 64 | var partitionKey = Fixture.Create(); 65 | 66 | SetupReader(document); 67 | 68 | // Act 69 | var result = await Sut.GetByMinAsync(filter, selector, partitionKey); 70 | 71 | // Assert 72 | result.Should().NotBeNull(); 73 | result.Should().BeEquivalentTo(document); 74 | Reader.Verify( 75 | x => x.GetByMinAsync, int>(filter, selector, partitionKey, CancellationToken.None), 76 | Times.Once); 77 | } 78 | 79 | [Fact] 80 | public async Task WithFilterAndSelectorAndPartitionKeyAndCancellationToken_GetsOne() 81 | { 82 | // Arrange 83 | var document = Fixture.Create>(); 84 | var partitionKey = Fixture.Create(); 85 | var token = new CancellationToken(true); 86 | 87 | SetupReader(document); 88 | 89 | // Act 90 | var result = await Sut.GetByMinAsync(filter, selector, partitionKey, token); 91 | 92 | // Assert 93 | result.Should().NotBeNull(); 94 | result.Should().BeEquivalentTo(document); 95 | Reader.Verify( 96 | x => x.GetByMinAsync, int>(filter, selector, partitionKey, token), 97 | Times.Once); 98 | } 99 | 100 | private void SetupReader(TestDocumentWithKey document) 101 | { 102 | Reader = new Mock(); 103 | Reader 104 | .Setup( 105 | x => x.GetByMinAsync, int>( 106 | It.IsAny, bool>>>(), 107 | It.IsAny, object>>>(), 108 | It.IsAny(), 109 | It.IsAny())) 110 | .ReturnsAsync(document); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/GetByMinTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using AutoFixture; 5 | using CoreUnitTests.Infrastructure; 6 | using CoreUnitTests.Infrastructure.Model; 7 | using FluentAssertions; 8 | using MongoDbGenericRepository.DataAccess.Read; 9 | using Moq; 10 | using Xunit; 11 | 12 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 13 | 14 | public class GetByMinTests : TestKeyedReadOnlyMongoRepositoryContext 15 | { 16 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 17 | private readonly Expression, object>> selector = document => document.SomeValue; 18 | 19 | [Fact] 20 | public void WithFilterAndSelector_GetsOne() 21 | { 22 | // Arrange 23 | var document = Fixture.Create>(); 24 | 25 | SetupReader(document); 26 | 27 | // Act 28 | var result = Sut.GetByMin(filter, selector); 29 | 30 | // Assert 31 | result.Should().NotBeNull(); 32 | result.Should().BeEquivalentTo(document); 33 | Reader.Verify( 34 | x => x.GetByMin, int>(filter, selector, null, CancellationToken.None), 35 | Times.Once); 36 | } 37 | 38 | [Fact] 39 | public void WithFilterAndSelectorAndCancellationToken_GetsOne() 40 | { 41 | // Arrange 42 | var document = Fixture.Create>(); 43 | var token = new CancellationToken(true); 44 | 45 | SetupReader(document); 46 | 47 | // Act 48 | var result = Sut.GetByMin(filter, selector, token); 49 | 50 | // Assert 51 | result.Should().NotBeNull(); 52 | result.Should().BeEquivalentTo(document); 53 | Reader.Verify( 54 | x => x.GetByMin, int>(filter, selector, null, token), 55 | Times.Once); 56 | } 57 | 58 | [Fact] 59 | public void WithFilterAndSelectorAndPartitionKey_GetsOne() 60 | { 61 | // Arrange 62 | var document = Fixture.Create>(); 63 | var partitionKey = Fixture.Create(); 64 | 65 | SetupReader(document); 66 | 67 | // Act 68 | var result = Sut.GetByMin(filter, selector, partitionKey); 69 | 70 | // Assert 71 | result.Should().NotBeNull(); 72 | result.Should().BeEquivalentTo(document); 73 | Reader.Verify( 74 | x => x.GetByMin, int>(filter, selector, partitionKey, CancellationToken.None), 75 | Times.Once); 76 | } 77 | 78 | [Fact] 79 | public void WithFilterAndSelectorAndPartitionKeyAndCancellationToken_GetsOne() 80 | { 81 | // Arrange 82 | var document = Fixture.Create>(); 83 | var partitionKey = Fixture.Create(); 84 | var token = new CancellationToken(true); 85 | 86 | SetupReader(document); 87 | 88 | // Act 89 | var result = Sut.GetByMin(filter, selector, partitionKey, token); 90 | 91 | // Assert 92 | result.Should().NotBeNull(); 93 | result.Should().BeEquivalentTo(document); 94 | Reader.Verify( 95 | x => x.GetByMin, int>(filter, selector, partitionKey, token), 96 | Times.Once); 97 | } 98 | 99 | private void SetupReader(TestDocumentWithKey document) 100 | { 101 | Reader = new Mock(); 102 | Reader 103 | .Setup( 104 | x => x.GetByMin, int>( 105 | It.IsAny, bool>>>(), 106 | It.IsAny, object>>>(), 107 | It.IsAny(), 108 | It.IsAny())) 109 | .Returns(document); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/GetMaxValueAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using AutoFixture; 6 | using CoreUnitTests.Infrastructure; 7 | using CoreUnitTests.Infrastructure.Model; 8 | using FluentAssertions; 9 | using MongoDbGenericRepository.DataAccess.Read; 10 | using Moq; 11 | using Xunit; 12 | 13 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 14 | 15 | public class GetMaxValueAsyncTests : TestKeyedReadOnlyMongoRepositoryContext 16 | { 17 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 18 | private readonly Expression, int>> selector = document => document.SomeValue; 19 | 20 | [Fact] 21 | public async Task WithFilterAndSelector_GetsMaxValue() 22 | { 23 | // Arrange 24 | var value = Fixture.Create(); 25 | 26 | SetupReader(value); 27 | 28 | // Act 29 | var result = await Sut.GetMaxValueAsync(filter, selector); 30 | 31 | // Assert 32 | result.Should().Be(value); 33 | Reader.Verify( 34 | x => x.GetMaxValueAsync, int, int>(filter, selector, null, CancellationToken.None), 35 | Times.Once); 36 | } 37 | 38 | [Fact] 39 | public async Task WithFilterAndSelectorAndCancellationToken_GetsMaxValue() 40 | { 41 | // Arrange 42 | var value = Fixture.Create(); 43 | var token = new CancellationToken(true); 44 | 45 | SetupReader(value); 46 | 47 | // Act 48 | var result = await Sut.GetMaxValueAsync(filter, selector, token); 49 | 50 | // Assert 51 | result.Should().Be(value); 52 | Reader.Verify( 53 | x => x.GetMaxValueAsync, int, int>(filter, selector, null, token), 54 | Times.Once); 55 | } 56 | 57 | [Fact] 58 | public async Task WithFilterAndSelectorAndPartitionKey_GetsMaxValue() 59 | { 60 | // Arrange 61 | var value = Fixture.Create(); 62 | var partitionKey = Fixture.Create(); 63 | 64 | SetupReader(value); 65 | 66 | // Act 67 | var result = await Sut.GetMaxValueAsync(filter, selector, partitionKey); 68 | 69 | // Assert 70 | result.Should().Be(value); 71 | Reader.Verify( 72 | x => x.GetMaxValueAsync, int, int>(filter, selector, partitionKey, CancellationToken.None), 73 | Times.Once); 74 | } 75 | 76 | [Fact] 77 | public async Task WithFilterAndSelectorAndPartitionKeyAndCancellationToken_GetsMaxValue() 78 | { 79 | // Arrange 80 | var value = Fixture.Create(); 81 | var partitionKey = Fixture.Create(); 82 | var token = new CancellationToken(true); 83 | 84 | SetupReader(value); 85 | 86 | // Act 87 | var result = await Sut.GetMaxValueAsync(filter, selector, partitionKey, token); 88 | 89 | // Assert 90 | result.Should().Be(value); 91 | Reader.Verify( 92 | x => x.GetMaxValueAsync, int, int>(filter, selector, partitionKey, token), 93 | Times.Once); 94 | } 95 | 96 | private void SetupReader(int value) 97 | { 98 | Reader = new Mock(); 99 | Reader 100 | .Setup( 101 | x => x.GetMaxValueAsync, int, int>( 102 | It.IsAny, bool>>>(), 103 | It.IsAny, int>>>(), 104 | It.IsAny(), 105 | It.IsAny())) 106 | .ReturnsAsync(value); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/GetMaxValueTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using AutoFixture; 5 | using CoreUnitTests.Infrastructure; 6 | using CoreUnitTests.Infrastructure.Model; 7 | using FluentAssertions; 8 | using MongoDbGenericRepository.DataAccess.Read; 9 | using Moq; 10 | using Xunit; 11 | 12 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 13 | 14 | public class GetMaxValueTests : TestKeyedReadOnlyMongoRepositoryContext 15 | { 16 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 17 | private readonly Expression, int>> selector = document => document.SomeValue; 18 | 19 | [Fact] 20 | public void WithFilterAndSelector_GetsMaxValue() 21 | { 22 | // Arrange 23 | var value = Fixture.Create(); 24 | 25 | SetupReader(value); 26 | 27 | // Act 28 | var result = Sut.GetMaxValue(filter, selector); 29 | 30 | // Assert 31 | result.Should().Be(value); 32 | Reader.Verify( 33 | x => x.GetMaxValue, int, int>(filter, selector, null, CancellationToken.None), 34 | Times.Once); 35 | } 36 | 37 | [Fact] 38 | public void WithFilterAndSelectorAndCancellationToken_GetsMaxValue() 39 | { 40 | // Arrange 41 | var value = Fixture.Create(); 42 | var token = new CancellationToken(true); 43 | 44 | SetupReader(value); 45 | 46 | // Act 47 | var result = Sut.GetMaxValue(filter, selector, token); 48 | 49 | // Assert 50 | result.Should().Be(value); 51 | Reader.Verify( 52 | x => x.GetMaxValue, int, int>(filter, selector, null, token), 53 | Times.Once); 54 | } 55 | 56 | [Fact] 57 | public void WithFilterAndSelectorAndPartitionKey_GetsMaxValue() 58 | { 59 | // Arrange 60 | var value = Fixture.Create(); 61 | var partitionKey = Fixture.Create(); 62 | 63 | SetupReader(value); 64 | 65 | // Act 66 | var result = Sut.GetMaxValue(filter, selector, partitionKey); 67 | 68 | // Assert 69 | result.Should().Be(value); 70 | Reader.Verify( 71 | x => x.GetMaxValue, int, int>(filter, selector, partitionKey, CancellationToken.None), 72 | Times.Once); 73 | } 74 | 75 | [Fact] 76 | public void WithFilterAndSelectorAndPartitionKeyAndCancellationToken_GetsMaxValue() 77 | { 78 | // Arrange 79 | var value = Fixture.Create(); 80 | var partitionKey = Fixture.Create(); 81 | var token = new CancellationToken(true); 82 | 83 | SetupReader(value); 84 | 85 | // Act 86 | var result = Sut.GetMaxValue(filter, selector, partitionKey, token); 87 | 88 | // Assert 89 | result.Should().Be(value); 90 | Reader.Verify( 91 | x => x.GetMaxValue, int, int>(filter, selector, partitionKey, token), 92 | Times.Once); 93 | } 94 | 95 | private void SetupReader(int value) 96 | { 97 | Reader = new Mock(); 98 | Reader 99 | .Setup( 100 | x => x.GetMaxValue, int, int>( 101 | It.IsAny, bool>>>(), 102 | It.IsAny, int>>>(), 103 | It.IsAny(), 104 | It.IsAny())) 105 | .Returns(value); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/GetMinValueAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using AutoFixture; 6 | using CoreUnitTests.Infrastructure; 7 | using CoreUnitTests.Infrastructure.Model; 8 | using FluentAssertions; 9 | using MongoDbGenericRepository.DataAccess.Read; 10 | using Moq; 11 | using Xunit; 12 | 13 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 14 | 15 | public class GetMinValueAsyncTests : TestKeyedReadOnlyMongoRepositoryContext 16 | { 17 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 18 | private readonly Expression, int>> selector = document => document.SomeValue; 19 | 20 | [Fact] 21 | public async Task WithFilterAndSelector_GetsMaxValue() 22 | { 23 | // Arrange 24 | var value = Fixture.Create(); 25 | 26 | SetupReader(value); 27 | 28 | // Act 29 | var result = await Sut.GetMinValueAsync(filter, selector); 30 | 31 | // Assert 32 | result.Should().Be(value); 33 | Reader.Verify( 34 | x => x.GetMinValueAsync, int, int>(filter, selector, null, CancellationToken.None), 35 | Times.Once); 36 | } 37 | 38 | [Fact] 39 | public async Task WithFilterAndSelectorAndCancellationToken_GetsMaxValue() 40 | { 41 | // Arrange 42 | var value = Fixture.Create(); 43 | var token = new CancellationToken(true); 44 | 45 | SetupReader(value); 46 | 47 | // Act 48 | var result = await Sut.GetMinValueAsync(filter, selector, token); 49 | 50 | // Assert 51 | result.Should().Be(value); 52 | Reader.Verify( 53 | x => x.GetMinValueAsync, int, int>(filter, selector, null, token), 54 | Times.Once); 55 | } 56 | 57 | [Fact] 58 | public async Task WithFilterAndSelectorAndPartitionKey_GetsMaxValue() 59 | { 60 | // Arrange 61 | var value = Fixture.Create(); 62 | var partitionKey = Fixture.Create(); 63 | 64 | SetupReader(value); 65 | 66 | // Act 67 | var result = await Sut.GetMinValueAsync(filter, selector, partitionKey); 68 | 69 | // Assert 70 | result.Should().Be(value); 71 | Reader.Verify( 72 | x => x.GetMinValueAsync, int, int>(filter, selector, partitionKey, CancellationToken.None), 73 | Times.Once); 74 | } 75 | 76 | [Fact] 77 | public async Task WithFilterAndSelectorAndPartitionKeyAndCancellationToken_GetsMaxValue() 78 | { 79 | // Arrange 80 | var value = Fixture.Create(); 81 | var partitionKey = Fixture.Create(); 82 | var token = new CancellationToken(true); 83 | 84 | SetupReader(value); 85 | 86 | // Act 87 | var result = await Sut.GetMinValueAsync(filter, selector, partitionKey, token); 88 | 89 | // Assert 90 | result.Should().Be(value); 91 | Reader.Verify( 92 | x => x.GetMinValueAsync, int, int>(filter, selector, partitionKey, token), 93 | Times.Once); 94 | } 95 | 96 | private void SetupReader(int value) 97 | { 98 | Reader = new Mock(); 99 | Reader 100 | .Setup( 101 | x => x.GetMinValueAsync, int, int>( 102 | It.IsAny, bool>>>(), 103 | It.IsAny, int>>>(), 104 | It.IsAny(), 105 | It.IsAny())) 106 | .ReturnsAsync(value); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/GetMinValueTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using AutoFixture; 5 | using CoreUnitTests.Infrastructure; 6 | using CoreUnitTests.Infrastructure.Model; 7 | using FluentAssertions; 8 | using MongoDbGenericRepository.DataAccess.Read; 9 | using Moq; 10 | using Xunit; 11 | 12 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 13 | 14 | public class GetMinValueTests : TestKeyedReadOnlyMongoRepositoryContext 15 | { 16 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 17 | private readonly Expression, int>> selector = document => document.SomeValue; 18 | 19 | [Fact] 20 | public void WithFilterAndSelector_GetsMinValue() 21 | { 22 | // Arrange 23 | var value = Fixture.Create(); 24 | 25 | SetupReader(value); 26 | 27 | // Act 28 | var result = Sut.GetMinValue(filter, selector); 29 | 30 | // Assert 31 | result.Should().Be(value); 32 | Reader.Verify( 33 | x => x.GetMinValue, int, int>(filter, selector, null, CancellationToken.None), 34 | Times.Once); 35 | } 36 | 37 | [Fact] 38 | public void WithFilterAndSelectorAndCancellationToken_GetsMinValue() 39 | { 40 | // Arrange 41 | var value = Fixture.Create(); 42 | var token = new CancellationToken(true); 43 | 44 | SetupReader(value); 45 | 46 | // Act 47 | var result = Sut.GetMinValue(filter, selector, token); 48 | 49 | // Assert 50 | result.Should().Be(value); 51 | Reader.Verify( 52 | x => x.GetMinValue, int, int>(filter, selector, null, token), 53 | Times.Once); 54 | } 55 | 56 | [Fact] 57 | public void WithFilterAndSelectorAndPartitionKey_GetsMinValue() 58 | { 59 | // Arrange 60 | var value = Fixture.Create(); 61 | var partitionKey = Fixture.Create(); 62 | 63 | SetupReader(value); 64 | 65 | // Act 66 | var result = Sut.GetMinValue(filter, selector, partitionKey); 67 | 68 | // Assert 69 | result.Should().Be(value); 70 | Reader.Verify( 71 | x => x.GetMinValue, int, int>(filter, selector, partitionKey, CancellationToken.None), 72 | Times.Once); 73 | } 74 | 75 | [Fact] 76 | public void WithFilterAndSelectorAndPartitionKeyAndCancellationToken_GetsMinValue() 77 | { 78 | // Arrange 79 | var value = Fixture.Create(); 80 | var partitionKey = Fixture.Create(); 81 | var token = new CancellationToken(true); 82 | 83 | SetupReader(value); 84 | 85 | // Act 86 | var result = Sut.GetMinValue(filter, selector, partitionKey, token); 87 | 88 | // Assert 89 | result.Should().Be(value); 90 | Reader.Verify( 91 | x => x.GetMinValue, int, int>(filter, selector, partitionKey, token), 92 | Times.Once); 93 | } 94 | 95 | private void SetupReader(int value) 96 | { 97 | Reader = new Mock(); 98 | Reader 99 | .Setup( 100 | x => x.GetMinValue, int, int>( 101 | It.IsAny, bool>>>(), 102 | It.IsAny, int>>>(), 103 | It.IsAny(), 104 | It.IsAny())) 105 | .Returns(value); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/GetOneAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using AutoFixture; 6 | using CoreUnitTests.Infrastructure; 7 | using CoreUnitTests.Infrastructure.Model; 8 | using FluentAssertions; 9 | using MongoDbGenericRepository.DataAccess.Read; 10 | using Moq; 11 | using Xunit; 12 | 13 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 14 | 15 | public class GetOneAsyncTests : TestKeyedReadOnlyMongoRepositoryContext 16 | { 17 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 18 | 19 | [Fact] 20 | public async Task WithFilter_GetsOne() 21 | { 22 | // Arrange 23 | var document = Fixture.Create>(); 24 | 25 | SetupReader(document); 26 | 27 | // Act 28 | var result = await Sut.GetOneAsync(filter); 29 | 30 | // Assert 31 | result.Should().NotBeNull(); 32 | result.Should().BeEquivalentTo(document); 33 | Reader.Verify( 34 | x => x.GetOneAsync, int>(filter, null, CancellationToken.None), 35 | Times.Once); 36 | } 37 | 38 | [Fact] 39 | public async Task WithFilterAndCancellationToken_GetsOne() 40 | { 41 | // Arrange 42 | var document = Fixture.Create>(); 43 | var token = new CancellationToken(true); 44 | 45 | SetupReader(document); 46 | 47 | // Act 48 | var result = await Sut.GetOneAsync(filter, token); 49 | 50 | // Assert 51 | result.Should().NotBeNull(); 52 | result.Should().BeEquivalentTo(document); 53 | Reader.Verify( 54 | x => x.GetOneAsync, int>(filter, null, token), 55 | Times.Once); 56 | } 57 | 58 | [Fact] 59 | public async Task WithFilterAndPartitionKey_GetsOne() 60 | { 61 | // Arrange 62 | var document = Fixture.Create>(); 63 | var partitionKey = Fixture.Create(); 64 | 65 | SetupReader(document); 66 | 67 | // Act 68 | var result = await Sut.GetOneAsync(filter, partitionKey); 69 | 70 | // Assert 71 | result.Should().NotBeNull(); 72 | result.Should().BeEquivalentTo(document); 73 | Reader.Verify( 74 | x => x.GetOneAsync, int>(filter, partitionKey, CancellationToken.None), 75 | Times.Once); 76 | } 77 | 78 | [Fact] 79 | public async Task WithFilterAndPartitionKeyAndCancellationToken_GetsOne() 80 | { 81 | // Arrange 82 | var document = Fixture.Create>(); 83 | var partitionKey = Fixture.Create(); 84 | var token = new CancellationToken(true); 85 | 86 | SetupReader(document); 87 | 88 | // Act 89 | var result = await Sut.GetOneAsync(filter, partitionKey, token); 90 | 91 | // Assert 92 | result.Should().NotBeNull(); 93 | result.Should().BeEquivalentTo(document); 94 | Reader.Verify( 95 | x => x.GetOneAsync, int>(filter, partitionKey, token), 96 | Times.Once); 97 | } 98 | 99 | private void SetupReader(TestDocumentWithKey document) 100 | { 101 | Reader = new Mock(); 102 | Reader 103 | .Setup( 104 | x => x.GetOneAsync, int>( 105 | It.IsAny, bool>>>(), 106 | It.IsAny(), 107 | It.IsAny())) 108 | .ReturnsAsync(document); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/GetOneTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using AutoFixture; 5 | using CoreUnitTests.Infrastructure; 6 | using CoreUnitTests.Infrastructure.Model; 7 | using FluentAssertions; 8 | using MongoDbGenericRepository.DataAccess.Read; 9 | using Moq; 10 | using Xunit; 11 | 12 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 13 | 14 | public class GetOneTests : TestKeyedReadOnlyMongoRepositoryContext 15 | { 16 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 17 | 18 | [Fact] 19 | public void WithFilter_GetsOne() 20 | { 21 | // Arrange 22 | var document = Fixture.Create>(); 23 | 24 | SetupReader(document); 25 | 26 | // Act 27 | var result = Sut.GetOne(filter); 28 | 29 | // Assert 30 | result.Should().NotBeNull(); 31 | result.Should().BeEquivalentTo(document); 32 | Reader.Verify( 33 | x => x.GetOne, int>(filter, null, CancellationToken.None), 34 | Times.Once); 35 | } 36 | 37 | [Fact] 38 | public void WithFilterAndCancellationToken_GetsOne() 39 | { 40 | // Arrange 41 | var document = Fixture.Create>(); 42 | var token = new CancellationToken(true); 43 | 44 | SetupReader(document); 45 | 46 | // Act 47 | var result = Sut.GetOne(filter, token); 48 | 49 | // Assert 50 | result.Should().NotBeNull(); 51 | result.Should().BeEquivalentTo(document); 52 | Reader.Verify( 53 | x => x.GetOne, int>(filter, null, token), 54 | Times.Once); 55 | } 56 | 57 | [Fact] 58 | public void WithFilterAndPartitionKey_GetsOne() 59 | { 60 | // Arrange 61 | var document = Fixture.Create>(); 62 | var partitionKey = Fixture.Create(); 63 | 64 | SetupReader(document); 65 | 66 | // Act 67 | var result = Sut.GetOne(filter, partitionKey); 68 | 69 | // Assert 70 | result.Should().NotBeNull(); 71 | result.Should().BeEquivalentTo(document); 72 | Reader.Verify( 73 | x => x.GetOne, int>(filter, partitionKey, CancellationToken.None), 74 | Times.Once); 75 | } 76 | 77 | [Fact] 78 | public void WithFilterAndPartitionKeyAndCancellationToken_GetsOne() 79 | { 80 | // Arrange 81 | var document = Fixture.Create>(); 82 | var partitionKey = Fixture.Create(); 83 | var token = new CancellationToken(true); 84 | 85 | SetupReader(document); 86 | 87 | // Act 88 | var result = Sut.GetOne(filter, partitionKey, token); 89 | 90 | // Assert 91 | result.Should().NotBeNull(); 92 | result.Should().BeEquivalentTo(document); 93 | Reader.Verify( 94 | x => x.GetOne, int>(filter, partitionKey, token), 95 | Times.Once); 96 | } 97 | 98 | private void SetupReader(TestDocumentWithKey document) 99 | { 100 | Reader = new Mock(); 101 | Reader 102 | .Setup( 103 | x => x.GetOne, int>( 104 | It.IsAny, bool>>>(), 105 | It.IsAny(), 106 | It.IsAny())) 107 | .Returns(document); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/ProjectOneAsyncTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using AutoFixture; 6 | using CoreUnitTests.Infrastructure; 7 | using CoreUnitTests.Infrastructure.Model; 8 | using FluentAssertions; 9 | using MongoDbGenericRepository.DataAccess.Read; 10 | using Moq; 11 | using Xunit; 12 | 13 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 14 | 15 | public class ProjectOneAsyncTests : TestKeyedReadOnlyMongoRepositoryContext 16 | { 17 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 18 | private readonly Expression, TestProjection>> projection = document => new TestProjection {NestedData = document.Nested.SomeDate}; 19 | 20 | [Fact] 21 | public async Task WithFilterAndProjection_Projects() 22 | { 23 | // Arrange 24 | var expected = Fixture.Create(); 25 | 26 | SetupReader(expected); 27 | 28 | // Act 29 | var result = await Sut.ProjectOneAsync(filter, projection); 30 | 31 | // Assert 32 | result.Should().Be(expected); 33 | Reader.Verify( 34 | x => x.ProjectOneAsync, TestProjection, int>( 35 | filter, 36 | projection, 37 | null, 38 | CancellationToken.None), 39 | Times.Once); 40 | } 41 | 42 | [Fact] 43 | public async Task WithFilterAndProjectionAndCancellationToken_Projects() 44 | { 45 | // Arrange 46 | var expected = Fixture.Create(); 47 | var token = new CancellationToken(true); 48 | 49 | SetupReader(expected); 50 | 51 | // Act 52 | var result = await Sut.ProjectOneAsync(filter, projection, token); 53 | 54 | // Assert 55 | result.Should().Be(expected); 56 | Reader.Verify( 57 | x => x.ProjectOneAsync, TestProjection, int>(filter, projection, null, token), 58 | Times.Once); 59 | } 60 | 61 | [Fact] 62 | public async Task WithFilterAndProjectionAndPartitionKey_Projects() 63 | { 64 | // Arrange 65 | var expected = Fixture.Create(); 66 | var partitionKey = Fixture.Create(); 67 | 68 | SetupReader(expected); 69 | 70 | // Act 71 | var result = await Sut.ProjectOneAsync(filter, projection, partitionKey); 72 | 73 | // Assert 74 | result.Should().Be(expected); 75 | Reader.Verify( 76 | x => x.ProjectOneAsync, TestProjection, int>(filter, projection, partitionKey, CancellationToken.None), 77 | Times.Once); 78 | } 79 | 80 | [Fact] 81 | public async Task WithFilterAndProjectionAndPartitionKeyAndCancellationToken_Projects() 82 | { 83 | // Arrange 84 | var expected = Fixture.Create(); 85 | var partitionKey = Fixture.Create(); 86 | var token = new CancellationToken(true); 87 | 88 | SetupReader(expected); 89 | 90 | // Act 91 | var result = await Sut.ProjectOneAsync(filter, projection, partitionKey, token); 92 | 93 | // Assert 94 | result.Should().Be(expected); 95 | Reader.Verify( 96 | x => x.ProjectOneAsync, TestProjection, int>(filter, projection, partitionKey, token), 97 | Times.Once); 98 | } 99 | 100 | private void SetupReader(TestProjection result) 101 | { 102 | Reader = new Mock(); 103 | Reader 104 | .Setup( 105 | x => x.ProjectOneAsync, TestProjection, int>( 106 | It.IsAny, bool>>>(), 107 | It.IsAny, TestProjection>>>(), 108 | It.IsAny(), 109 | It.IsAny())) 110 | .ReturnsAsync(result); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /CoreUnitTests/KeyedReadOnlyMongoRepositoryTests/ProjectOneTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Threading; 4 | using AutoFixture; 5 | using CoreUnitTests.Infrastructure; 6 | using CoreUnitTests.Infrastructure.Model; 7 | using FluentAssertions; 8 | using MongoDbGenericRepository.DataAccess.Read; 9 | using Moq; 10 | using Xunit; 11 | 12 | namespace CoreUnitTests.KeyedReadOnlyMongoRepositoryTests; 13 | 14 | public class ProjectOneTests : TestKeyedReadOnlyMongoRepositoryContext 15 | { 16 | private readonly Expression, bool>> filter = document => document.SomeContent == "SomeContent"; 17 | private readonly Expression, TestProjection>> projection = document => new TestProjection {NestedData = document.Nested.SomeDate}; 18 | 19 | [Fact] 20 | public void WithFilterAndProjection_Projects() 21 | { 22 | // Arrange 23 | var expected = Fixture.Create(); 24 | 25 | SetupReader(expected); 26 | 27 | // Act 28 | var result = Sut.ProjectOne(filter, projection); 29 | 30 | // Assert 31 | result.Should().Be(expected); 32 | Reader.Verify( 33 | x => x.ProjectOne, TestProjection, int>( 34 | filter, 35 | projection, 36 | null, 37 | CancellationToken.None), 38 | Times.Once); 39 | } 40 | 41 | [Fact] 42 | public void WithFilterAndProjectionAndCancellationToken_Projects() 43 | { 44 | // Arrange 45 | var expected = Fixture.Create(); 46 | var token = new CancellationToken(true); 47 | 48 | SetupReader(expected); 49 | 50 | // Act 51 | var result = Sut.ProjectOne(filter, projection, token); 52 | 53 | // Assert 54 | result.Should().Be(expected); 55 | Reader.Verify( 56 | x => x.ProjectOne, TestProjection, int>(filter, projection, null, token), 57 | Times.Once); 58 | } 59 | 60 | [Fact] 61 | public void WithFilterAndProjectionAndPartitionKey_Projects() 62 | { 63 | // Arrange 64 | var expected = Fixture.Create(); 65 | var partitionKey = Fixture.Create(); 66 | 67 | SetupReader(expected); 68 | 69 | // Act 70 | var result = Sut.ProjectOne(filter, projection, partitionKey); 71 | 72 | // Assert 73 | result.Should().Be(expected); 74 | Reader.Verify( 75 | x => x.ProjectOne, TestProjection, int>(filter, projection, partitionKey, CancellationToken.None), 76 | Times.Once); 77 | } 78 | 79 | [Fact] 80 | public void WithFilterAndProjectionAndPartitionKeyAndCancellationToken_Projects() 81 | { 82 | // Arrange 83 | var expected = Fixture.Create(); 84 | var partitionKey = Fixture.Create(); 85 | var token = new CancellationToken(true); 86 | 87 | SetupReader(expected); 88 | 89 | // Act 90 | var result = Sut.ProjectOne(filter, projection, partitionKey, token); 91 | 92 | // Assert 93 | result.Should().Be(expected); 94 | Reader.Verify( 95 | x => x.ProjectOne, TestProjection, int>(filter, projection, partitionKey, token), 96 | Times.Once); 97 | } 98 | 99 | private void SetupReader(TestProjection result) 100 | { 101 | Reader = new Mock(); 102 | Reader 103 | .Setup( 104 | x => x.ProjectOne, TestProjection, int>( 105 | It.IsAny, bool>>>(), 106 | It.IsAny, TestProjection>>>(), 107 | It.IsAny(), 108 | It.IsAny())) 109 | .Returns(result); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /IntegrationTests/App.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /IntegrationTests/CRUDObjectIdTests.cs: -------------------------------------------------------------------------------- 1 | using IntegrationTests.Infrastructure; 2 | using MongoDB.Bson; 3 | using NUnit.Framework; 4 | 5 | namespace IntegrationTests 6 | { 7 | public class ObjectIdTestDocument : TestDoc 8 | { 9 | } 10 | 11 | [TestFixture] 12 | public class CRUDObjectIdTests : MongoDbTKeyDocumentTestBase 13 | { 14 | public override string GetClassName() 15 | { 16 | return "CRUDObjectIdTests"; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /IntegrationTests/CRUDPartitionedCollectionNameAttributeTests.cs: -------------------------------------------------------------------------------- 1 | using IntegrationTests.Infrastructure; 2 | using MongoDB.Bson.Serialization.Attributes; 3 | using MongoDbGenericRepository.Attributes; 4 | using MongoDbGenericRepository.Models; 5 | using System; 6 | 7 | namespace IntegrationTests 8 | { 9 | [CollectionName("TestingCollectionNameAttributePartitionedTKey")] 10 | public class PartitionedCollectionNameDoc : TestDoc, IPartitionedDocument 11 | { 12 | public PartitionedCollectionNameDoc() 13 | { 14 | PartitionKey = "TestPartitionKey"; 15 | } 16 | 17 | public string PartitionKey { get; set; } 18 | } 19 | 20 | public class CRUDPartitionedCollectionNameAttributeTests : MongoDbDocumentTestBase 21 | { 22 | public override string GetClassName() 23 | { 24 | return "CRUDPartitionedCollectionNameAttributeTests"; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IntegrationTests/CRUDPartitionedTests.cs: -------------------------------------------------------------------------------- 1 | using IntegrationTests.Infrastructure; 2 | using MongoDbGenericRepository.Models; 3 | 4 | namespace IntegrationTests 5 | { 6 | public class PartitionedDoc : TestDoc, IPartitionedDocument 7 | { 8 | public PartitionedDoc() 9 | { 10 | PartitionKey = "TestPartitionKey"; 11 | } 12 | 13 | public string PartitionKey { get; set; } 14 | } 15 | 16 | public class CRUDPartitionedTests : MongoDbDocumentTestBase 17 | { 18 | public override string GetClassName() 19 | { 20 | return "CRUDPartitionedCollectionNameAttributeTests"; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /IntegrationTests/CRUDTKeyPartitionedCollectionNameAttributeTests.cs: -------------------------------------------------------------------------------- 1 | using IntegrationTests.Infrastructure; 2 | using MongoDbGenericRepository.Attributes; 3 | using MongoDbGenericRepository.Models; 4 | using System; 5 | 6 | namespace IntegrationTests 7 | { 8 | [CollectionName("TestingCollectionNameAttributePartitionedTKey")] 9 | public class TKeyPartitionedCollectionNameDoc : TestDoc, IPartitionedDocument 10 | { 11 | public TKeyPartitionedCollectionNameDoc() 12 | { 13 | PartitionKey = "TestPartitionKey"; 14 | } 15 | 16 | public string PartitionKey { get; set; } 17 | } 18 | 19 | public class CRUDTKeyPartitionedCollectionNameAttributeTests : MongoDbTKeyDocumentTestBase 20 | { 21 | public override string GetClassName() 22 | { 23 | return "CRUDTKeyPartitionedCollectionNameAttributeTests"; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /IntegrationTests/CRUDTKeyPartitionedTests.cs: -------------------------------------------------------------------------------- 1 | using IntegrationTests.Infrastructure; 2 | using MongoDB.Bson.Serialization.Attributes; 3 | using MongoDbGenericRepository.Models; 4 | using NUnit.Framework; 5 | using System; 6 | 7 | namespace IntegrationTests 8 | { 9 | public class PartitionedTKeyTestDocument : TestDoc, IPartitionedDocument 10 | { 11 | public PartitionedTKeyTestDocument() 12 | { 13 | PartitionKey = "TestPartitionKey"; 14 | } 15 | public string PartitionKey { get; set; } 16 | } 17 | 18 | [TestFixture] 19 | public class CRUDTKeyPartitionedTests : MongoDbTKeyDocumentTestBase 20 | { 21 | public override string GetClassName() 22 | { 23 | return "CRUDTKeyPartitionedTests"; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /IntegrationTests/CRUDTKeyTests.cs: -------------------------------------------------------------------------------- 1 | using IntegrationTests.Infrastructure; 2 | using MongoDB.Bson.Serialization.Attributes; 3 | using MongoDbGenericRepository.Models; 4 | using NUnit.Framework; 5 | using System; 6 | 7 | namespace IntegrationTests 8 | { 9 | public class TKeyTestDocument : TestDoc 10 | { 11 | } 12 | 13 | [TestFixture] 14 | public class CRUDTKeyTests : MongoDbTKeyDocumentTestBase 15 | { 16 | public override string GetClassName() 17 | { 18 | return "CreateTKeyTests"; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /IntegrationTests/CRUDTests.cs: -------------------------------------------------------------------------------- 1 | using IntegrationTests.Infrastructure; 2 | using NUnit.Framework; 3 | 4 | namespace IntegrationTests 5 | { 6 | public class TestDocument : TestDoc 7 | { 8 | } 9 | 10 | [TestFixture] 11 | public class CRUDTests : MongoDbDocumentTestBase 12 | { 13 | public override string GetClassName() 14 | { 15 | return "CRUDTests"; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /IntegrationTests/Infrastructure/BaseMongoDbRepositoryTests.cs: -------------------------------------------------------------------------------- 1 | using MongoDbGenericRepository.Models; 2 | using NUnit.Framework; 3 | using System.Collections.Generic; 4 | using System.Configuration; 5 | 6 | namespace IntegrationTests.Infrastructure 7 | { 8 | public class BaseMongoDbRepositoryTests where T : class, new() 9 | { 10 | public T CreateTestDocument() 11 | { 12 | return new T(); 13 | } 14 | 15 | public List CreateTestDocuments(int numberOfDocumentsToCreate) 16 | { 17 | var docs = new List(); 18 | for(var i = 0; i < numberOfDocumentsToCreate; i++) 19 | { 20 | docs.Add(new T()); 21 | } 22 | return docs; 23 | } 24 | 25 | public BaseMongoDbRepositoryTests() 26 | { 27 | var type = CreateTestDocument(); 28 | if (type is IPartitionedDocument) 29 | { 30 | PartitionKey = ((IPartitionedDocument)type).PartitionKey; 31 | } 32 | } 33 | 34 | public string PartitionKey { get; set; } 35 | 36 | /// 37 | /// SUT: System Under Test 38 | /// 39 | protected static ITestRepository SUT { get; set; } 40 | 41 | [OneTimeSetUp] 42 | public void Init() 43 | { 44 | var connectionString = ConfigurationManager.ConnectionStrings["MongoDbTests"].ConnectionString; 45 | SUT = new TestRepository(connectionString, "MongoDbTests"); 46 | } 47 | 48 | [OneTimeTearDown] 49 | public void Cleanup() 50 | { 51 | // We drop the collection at the end of each test session. 52 | if (!string.IsNullOrEmpty(PartitionKey)) 53 | { 54 | SUT.DropTestCollection(PartitionKey); 55 | } 56 | else 57 | { 58 | SUT.DropTestCollection(); 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /IntegrationTests/Infrastructure/GlobalVariables.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace IntegrationTests.Infrastructure 4 | { 5 | /// 6 | /// A class holding global variables. 7 | /// 8 | public static class GlobalVariables 9 | { 10 | /// 11 | /// A random number generator. 12 | /// 13 | public static Random Random = new Random(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /IntegrationTests/Infrastructure/ITestRepository.cs: -------------------------------------------------------------------------------- 1 | using MongoDbGenericRepository; 2 | 3 | namespace IntegrationTests 4 | { 5 | public interface ITestRepository : IBaseMongoRepository 6 | { 7 | void DropTestCollection(); 8 | void DropTestCollection(string partitionKey); 9 | } 10 | } -------------------------------------------------------------------------------- /IntegrationTests/Infrastructure/RandomExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace IntegrationTests.Infrastructure 4 | { 5 | // Thanks BlueRaja - Danny Pflughoeft https://stackoverflow.com/a/13095144/5103354 6 | /// 7 | /// Extensions for the random number generator 8 | /// 9 | public static class RandomExtensions 10 | { 11 | 12 | /// 13 | /// Returns a random long from min (inclusive) to max (exclusive) 14 | /// 15 | /// The given random instance 16 | /// The inclusive minimum bound 17 | /// The exclusive maximum bound. Must be greater than min 18 | public static long NextLong(this Random random, long min, long max) 19 | { 20 | if (max <= min) 21 | throw new ArgumentOutOfRangeException("max", "max must be > min!"); 22 | 23 | //Working with ulong so that modulo works correctly with values > long.MaxValue 24 | ulong uRange = (ulong)(max - min); 25 | 26 | //Prevent a modulo bias; see https://stackoverflow.com/a/10984975/238419 27 | //for more information. 28 | //In the worst case, the expected number of calls is 2 (though usually it's 29 | //much closer to 1) so this loop doesn't really hurt performance at all. 30 | ulong ulongRand; 31 | do 32 | { 33 | byte[] buf = new byte[8]; 34 | random.NextBytes(buf); 35 | ulongRand = (ulong)BitConverter.ToInt64(buf, 0); 36 | } while (ulongRand > ulong.MaxValue - ((ulong.MaxValue % uRange) + 1) % uRange); 37 | 38 | return (long)(ulongRand % uRange) + min; 39 | } 40 | 41 | /// 42 | /// Returns a random long from 0 (inclusive) to max (exclusive) 43 | /// 44 | /// The given random instance 45 | /// The exclusive maximum bound. Must be greater than 0 46 | public static long NextLong(this Random random, long max) 47 | { 48 | return random.NextLong(0, max); 49 | } 50 | 51 | /// 52 | /// Returns a random long over all possible values of long (except long.MaxValue, similar to 53 | /// random.Next()) 54 | /// 55 | /// The given random instance 56 | public static long NextLong(this Random random) 57 | { 58 | return random.NextLong(long.MinValue, long.MaxValue); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /IntegrationTests/Infrastructure/TestClasses.cs: -------------------------------------------------------------------------------- 1 | using MongoDB.Bson.Serialization.Attributes; 2 | using MongoDbGenericRepository.Models; 3 | using MongoDbGenericRepository.Utils; 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace IntegrationTests.Infrastructure 8 | { 9 | public class ProjectedGroup 10 | { 11 | public int Key { get; set; } 12 | public List Content { get; set; } 13 | } 14 | 15 | public class MyTestProjection 16 | { 17 | public string SomeContent { get; set; } 18 | public DateTime SomeDate { get; set; } 19 | } 20 | 21 | public class Nested 22 | { 23 | public DateTime SomeDate { get; set; } 24 | } 25 | 26 | public class Child 27 | { 28 | public Child(string type, string value) 29 | { 30 | Type = type; 31 | Value = value; 32 | } 33 | 34 | public string Type { get; set; } 35 | public string Value { get; set; } 36 | } 37 | 38 | public class TestDoc : Document 39 | { 40 | public TestDoc() 41 | { 42 | Version = 2; 43 | Nested = new Nested 44 | { 45 | SomeDate = DateTime.UtcNow 46 | }; 47 | Children = new List(); 48 | } 49 | 50 | public string SomeContent { get; set; } 51 | 52 | public int GroupingKey { get; set; } 53 | 54 | public Nested Nested { get; set; } 55 | 56 | public List Children { get; set; } 57 | 58 | } 59 | 60 | public class TestDoc : IDocument 61 | where TKey : IEquatable 62 | { 63 | [BsonId] 64 | public TKey Id { get; set; } 65 | public int Version { get; set; } 66 | 67 | public TestDoc() 68 | { 69 | InitializeFields(); 70 | Version = 2; 71 | Nested = new Nested 72 | { 73 | SomeDate = DateTime.UtcNow 74 | }; 75 | Children = new List(); 76 | } 77 | 78 | public string SomeContent { get; set; } 79 | 80 | public Nested Nested { get; set; } 81 | 82 | public List Children { get; set; } 83 | 84 | public TId Init() 85 | { 86 | return IdGenerator.GetId(); 87 | } 88 | 89 | private void InitializeFields() 90 | { 91 | Id = Init(); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /IntegrationTests/Infrastructure/TestRepository.cs: -------------------------------------------------------------------------------- 1 | using MongoDB.Driver; 2 | using MongoDbGenericRepository; 3 | using MongoDbGenericRepository.Models; 4 | using System; 5 | using System.Linq.Expressions; 6 | using System.Threading.Tasks; 7 | 8 | namespace IntegrationTests.Infrastructure 9 | { 10 | public class TestRepository : BaseMongoRepository, ITestRepository 11 | { 12 | /// 13 | public TestRepository(string connectionString, string databaseName) : base(connectionString, databaseName) 14 | { 15 | } 16 | 17 | public void DropTestCollection() 18 | { 19 | MongoDbContext.DropCollection(); 20 | } 21 | 22 | public void DropTestCollection(string partitionKey) 23 | { 24 | MongoDbContext.DropCollection(partitionKey); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IntegrationTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Les informations générales relatives à un assembly dépendent de 6 | // l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations 7 | // associées à un assembly. 8 | [assembly: AssemblyTitle("IntegrationTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("IntegrationTests")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly 18 | // aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de 19 | // COM, affectez la valeur true à l'attribut ComVisible sur ce type. 20 | [assembly: ComVisible(false)] 21 | 22 | // Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM 23 | [assembly: Guid("a484a355-a015-40cc-9b35-a4e872421128")] 24 | 25 | // Les informations de version pour un assembly se composent des quatre valeurs suivantes : 26 | // 27 | // Version principale 28 | // Version secondaire 29 | // Numéro de build 30 | // Révision 31 | // 32 | // Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut 33 | // en utilisant '*', comme indiqué ci-dessous : 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /IntegrationTests/libmongocrypt.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandre-spieser/mongodb-generic-repository/2c06abe203832546982b3a913c65b3552777a067/IntegrationTests/libmongocrypt.dylib -------------------------------------------------------------------------------- /IntegrationTests/libmongocrypt.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandre-spieser/mongodb-generic-repository/2c06abe203832546982b3a913c65b3552777a067/IntegrationTests/libmongocrypt.so -------------------------------------------------------------------------------- /IntegrationTests/mongocrypt.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandre-spieser/mongodb-generic-repository/2c06abe203832546982b3a913c65b3552777a067/IntegrationTests/mongocrypt.dll -------------------------------------------------------------------------------- /IntegrationTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Alexandre SPIESER 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MongoDbGenericRepository.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.12.35521.163 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IntegrationTests", "IntegrationTests\IntegrationTests.csproj", "{A484A355-A015-40CC-9B35-A4E872421128}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MongoDbGenericRepository", "MongoDbGenericRepository\MongoDbGenericRepository.csproj", "{EFC776C4-2AF3-440C-BE80-3FBE335817A5}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CoreIntegrationTests", "CoreIntegrationTests\CoreIntegrationTests.csproj", "{C640C106-7A25-4E49-A0CF-E4F248E5A97F}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoreUnitTests", "CoreUnitTests\CoreUnitTests.csproj", "{8BE513ED-84F4-47E1-946D-84958CF95E6B}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {A484A355-A015-40CC-9B35-A4E872421128}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {A484A355-A015-40CC-9B35-A4E872421128}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {A484A355-A015-40CC-9B35-A4E872421128}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {A484A355-A015-40CC-9B35-A4E872421128}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {EFC776C4-2AF3-440C-BE80-3FBE335817A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {EFC776C4-2AF3-440C-BE80-3FBE335817A5}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {EFC776C4-2AF3-440C-BE80-3FBE335817A5}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {EFC776C4-2AF3-440C-BE80-3FBE335817A5}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {C640C106-7A25-4E49-A0CF-E4F248E5A97F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {C640C106-7A25-4E49-A0CF-E4F248E5A97F}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {C640C106-7A25-4E49-A0CF-E4F248E5A97F}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {C640C106-7A25-4E49-A0CF-E4F248E5A97F}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {8BE513ED-84F4-47E1-946D-84958CF95E6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {8BE513ED-84F4-47E1-946D-84958CF95E6B}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {8BE513ED-84F4-47E1-946D-84958CF95E6B}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {8BE513ED-84F4-47E1-946D-84958CF95E6B}.Release|Any CPU.Build.0 = Release|Any CPU 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | GlobalSection(ExtensibilityGlobals) = postSolution 41 | SolutionGuid = {78214390-EFBD-403C-8AAA-5CD4CA5AE2ED} 42 | EndGlobalSection 43 | EndGlobal 44 | -------------------------------------------------------------------------------- /MongoDbGenericRepository/Abstractions/IMongoDbContext.cs: -------------------------------------------------------------------------------- 1 | using MongoDB.Driver; 2 | 3 | namespace MongoDbGenericRepository 4 | { 5 | /// 6 | /// This is the interface of the IMongoDbContext which is managed by the . 7 | /// 8 | public interface IMongoDbContext 9 | { 10 | /// 11 | /// The IMongoClient from the official MongoDb driver 12 | /// 13 | IMongoClient Client { get; } 14 | 15 | /// 16 | /// The IMongoDatabase from the official Mongodb driver 17 | /// 18 | IMongoDatabase Database { get; } 19 | 20 | /// 21 | /// Returns a collection for a document type that has a partition key. 22 | /// 23 | /// 24 | /// The value of the partition key. 25 | IMongoCollection GetCollection(string partitionKey = null); 26 | 27 | /// 28 | /// Drops a collection having a partitionKey, use very carefully. 29 | /// 30 | /// 31 | void DropCollection(string partitionKey = null); 32 | 33 | /// 34 | /// Sets the Guid representation of the MongoDb Driver. 35 | /// 36 | /// The new value of the GuidRepresentation 37 | void SetGuidRepresentation(MongoDB.Bson.GuidRepresentation guidRepresentation); 38 | } 39 | } -------------------------------------------------------------------------------- /MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MongoDbGenericRepository 4 | { 5 | /// 6 | /// The IReadOnlyMongoRepository exposes the readonly functionality of the BaseMongoRepository. 7 | /// 8 | public interface IReadOnlyMongoRepository : IBaseReadOnlyRepository, IReadOnlyMongoRepository 9 | { 10 | } 11 | } -------------------------------------------------------------------------------- /MongoDbGenericRepository/Attributes/CollectionNameAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MongoDbGenericRepository.Attributes 4 | { 5 | /// 6 | /// This attribute allows you to specify of the name of the collection. 7 | /// Added at commit c117bf2a7fee378f1e02199dea9b2023a7089ee2 by https://github.com/Etchelon 8 | /// who has included the CollectionName attribute into the repo to give another choice to the user on how 9 | /// to name their collections. 10 | /// The attribute takes precedence of course, and if not present the library will fall back to your Pluralize method. 11 | /// 12 | [AttributeUsage(AttributeTargets.Class)] 13 | public class CollectionNameAttribute : Attribute 14 | { 15 | /// 16 | /// The name of the collection in which your documents are stored. 17 | /// 18 | public string Name { get; set; } 19 | 20 | /// 21 | /// The constructor. 22 | /// 23 | /// The name of the collection. 24 | public CollectionNameAttribute(string name) 25 | { 26 | this.Name = name; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /MongoDbGenericRepository/DataAccess/Base/IDataAccessBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using MongoDB.Driver; 4 | using MongoDB.Driver.Linq; 5 | using MongoDbGenericRepository.Models; 6 | 7 | namespace MongoDbGenericRepository.DataAccess.Base 8 | { 9 | /// 10 | /// A interface for accessing the Database and its Collections. 11 | /// 12 | public interface IDataAccessBase 13 | { 14 | /// 15 | /// Gets a IMongoQueryable for a potentially partitioned document type and a filter. 16 | /// 17 | /// The document type. 18 | /// The type of the primary key. 19 | /// The filter definition. 20 | /// The collection partition key. 21 | /// 22 | IMongoQueryable GetQuery(Expression> filter, string partitionKey = null) 23 | where TDocument : IDocument 24 | where TKey : IEquatable; 25 | 26 | /// 27 | /// Gets a collections for a potentially partitioned document type. 28 | /// 29 | /// The document type. 30 | /// The type of the primary key. 31 | /// The document. 32 | /// 33 | IMongoCollection HandlePartitioned(TDocument document) 34 | where TDocument : IDocument 35 | where TKey : IEquatable; 36 | 37 | /// 38 | /// Gets a collections for a potentially partitioned document type. 39 | /// 40 | /// The document type. 41 | /// The type of the primary key. 42 | /// The collection partition key. 43 | /// 44 | IMongoCollection HandlePartitioned(string partitionKey) 45 | where TDocument : IDocument 46 | where TKey : IEquatable; 47 | 48 | /// 49 | /// Gets a collections for the type TDocument with a partition key. 50 | /// 51 | /// The document type. 52 | /// The type of the primary key. 53 | /// The collection partition key. 54 | /// 55 | IMongoCollection GetCollection(string partitionKey = null) 56 | where TDocument : IDocument 57 | where TKey : IEquatable; 58 | } 59 | } -------------------------------------------------------------------------------- /MongoDbGenericRepository/DataAccess/Create/IMongoDbCreator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using MongoDbGenericRepository.DataAccess.Base; 6 | using MongoDbGenericRepository.Models; 7 | 8 | namespace MongoDbGenericRepository.DataAccess.Create 9 | { 10 | /// 11 | /// A interface for adding documents to the Database and its Collections. 12 | /// 13 | public interface IMongoDbCreator : IDataAccessBase 14 | { 15 | /// 16 | /// Asynchronously adds a document to the collection. 17 | /// Populates the Id and AddedAtUtc fields if necessary. 18 | /// 19 | /// The type representing a Document. 20 | /// The type of the primary key for a Document. 21 | /// The document you want to add. 22 | /// An optional cancellation Token. 23 | Task AddOneAsync(TDocument document, CancellationToken cancellationToken = default) 24 | where TDocument : IDocument 25 | where TKey : IEquatable; 26 | 27 | /// 28 | /// Adds a document to the collection. 29 | /// Populates the Id and AddedAtUtc fields if necessary. 30 | /// 31 | /// The type representing a Document. 32 | /// The type of the primary key for a Document. 33 | /// The document you want to add. 34 | /// An optional cancellation Token. 35 | void AddOne(TDocument document, CancellationToken cancellationToken = default) 36 | where TDocument : IDocument 37 | where TKey : IEquatable; 38 | 39 | /// 40 | /// Asynchronously adds a list of documents to the collection. 41 | /// Populates the Id and AddedAtUtc fields if necessary. 42 | /// 43 | /// The type representing a Document. 44 | /// The type of the primary key for a Document. 45 | /// The documents you want to add. 46 | /// An optional cancellation Token. 47 | Task AddManyAsync(IEnumerable documents, CancellationToken cancellationToken = default) 48 | where TDocument : IDocument 49 | where TKey : IEquatable; 50 | 51 | /// 52 | /// Adds a list of documents to the collection. 53 | /// Populates the Id and AddedAtUtc fields if necessary. 54 | /// 55 | /// The type representing a Document. 56 | /// The type of the primary key for a Document. 57 | /// The documents you want to add. 58 | /// An optional cancellation Token. 59 | void AddMany(IEnumerable documents, CancellationToken cancellationToken = default) 60 | where TDocument : IDocument 61 | where TKey : IEquatable; 62 | } 63 | } -------------------------------------------------------------------------------- /MongoDbGenericRepository/DataAccess/Read/MongoDbReader.Project.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using MongoDB.Driver; 7 | using MongoDbGenericRepository.Models; 8 | 9 | namespace MongoDbGenericRepository.DataAccess.Read 10 | { 11 | public partial class MongoDbReader 12 | { 13 | /// 14 | public virtual async Task ProjectOneAsync( 15 | Expression> filter, 16 | Expression> projection, 17 | string partitionKey = null, 18 | CancellationToken cancellationToken = default) 19 | where TDocument : IDocument 20 | where TKey : IEquatable 21 | where TProjection : class 22 | { 23 | return await HandlePartitioned(partitionKey) 24 | .Find(filter) 25 | .Project(projection) 26 | .FirstOrDefaultAsync(cancellationToken); 27 | } 28 | 29 | /// 30 | public virtual async Task> ProjectManyAsync( 31 | Expression> filter, 32 | Expression> projection, 33 | string partitionKey = null, 34 | CancellationToken cancellationToken = default) 35 | where TDocument : IDocument 36 | where TKey : IEquatable 37 | where TProjection : class 38 | { 39 | return await HandlePartitioned(partitionKey).Find(filter) 40 | .Project(projection) 41 | .ToListAsync(cancellationToken); 42 | } 43 | 44 | /// 45 | public virtual TProjection ProjectOne( 46 | Expression> filter, 47 | Expression> projection, 48 | string partitionKey = null, 49 | CancellationToken cancellationToken = default) 50 | where TDocument : IDocument 51 | where TKey : IEquatable 52 | where TProjection : class 53 | { 54 | return HandlePartitioned(partitionKey).Find(filter) 55 | .Project(projection) 56 | .FirstOrDefault(cancellationToken); 57 | } 58 | 59 | /// 60 | public virtual List ProjectMany( 61 | Expression> filter, 62 | Expression> projection, 63 | string partitionKey = null, 64 | CancellationToken cancellationToken = default) 65 | where TDocument : IDocument 66 | where TKey : IEquatable 67 | where TProjection : class 68 | { 69 | return HandlePartitioned(partitionKey).Find(filter) 70 | .Project(projection) 71 | .ToList(cancellationToken); 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /MongoDbGenericRepository/Internals/RepositorySerializationProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using MongoDB.Bson.Serialization; 4 | 5 | namespace MongoDbGenericRepository.Internals 6 | { 7 | /// 8 | /// An that can handle multiple serializer registration calls. 9 | /// 10 | internal class RepositorySerializationProvider : IBsonSerializationProvider 11 | { 12 | private static volatile RepositorySerializationProvider _instance; 13 | private static readonly object LockObject = new object(); 14 | 15 | private readonly ConcurrentDictionary _cache; 16 | 17 | private RepositorySerializationProvider() 18 | { 19 | _cache = new ConcurrentDictionary(); 20 | } 21 | 22 | public static RepositorySerializationProvider Instance 23 | { 24 | get 25 | { 26 | if (_instance == null) 27 | { 28 | lock (LockObject) 29 | { 30 | if (_instance == null) 31 | { 32 | _instance = new RepositorySerializationProvider(); 33 | BsonSerializer.RegisterSerializationProvider(_instance); 34 | } 35 | } 36 | } 37 | 38 | return _instance; 39 | } 40 | } 41 | 42 | /// 43 | public IBsonSerializer GetSerializer(Type type) 44 | { 45 | if (type == null) 46 | { 47 | throw new ArgumentNullException(nameof(type)); 48 | } 49 | 50 | return _cache.TryGetValue(type, out var serializer) ? serializer : null; 51 | } 52 | 53 | internal void RegisterSerializer(IBsonSerializer serializer) => 54 | RegisterSerializer(typeof(T), serializer); 55 | 56 | internal void RegisterSerializer(Type type, IBsonSerializer serializer) => 57 | _cache.TryAdd(type, serializer); 58 | } 59 | } -------------------------------------------------------------------------------- /MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Create.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using MongoDbGenericRepository.DataAccess.Create; 6 | using MongoDbGenericRepository.Models; 7 | 8 | namespace MongoDbGenericRepository 9 | { 10 | /// 11 | /// The base Repository, it is meant to be inherited from by your custom custom MongoRepository implementation. 12 | /// Its constructor must be given a connection string and a database name. 13 | /// 14 | public abstract partial class BaseMongoRepository : IBaseMongoRepository_Create 15 | where TKey : IEquatable 16 | { 17 | private IMongoDbCreator _mongoDbCreator; 18 | 19 | /// 20 | /// The MongoDb accessor to insert data. 21 | /// 22 | protected virtual IMongoDbCreator MongoDbCreator 23 | { 24 | get 25 | { 26 | if (_mongoDbCreator == null) 27 | { 28 | lock (_initLock) 29 | { 30 | if (_mongoDbCreator == null) 31 | { 32 | _mongoDbCreator = new MongoDbCreator(MongoDbContext); 33 | } 34 | } 35 | } 36 | 37 | return _mongoDbCreator; 38 | } 39 | 40 | set => _mongoDbCreator = value; 41 | } 42 | 43 | /// 44 | public virtual async Task AddOneAsync(TDocument document) 45 | where TDocument : IDocument 46 | { 47 | await AddOneAsync(document, CancellationToken.None); 48 | } 49 | 50 | /// 51 | public virtual async Task AddOneAsync(TDocument document, CancellationToken cancellationToken) 52 | where TDocument : IDocument 53 | { 54 | await MongoDbCreator.AddOneAsync(document, cancellationToken); 55 | } 56 | 57 | /// 58 | public virtual void AddOne(TDocument document) 59 | where TDocument : IDocument 60 | { 61 | AddOne(document, CancellationToken.None); 62 | } 63 | 64 | /// 65 | public virtual void AddOne(TDocument document, CancellationToken cancellationToken) 66 | where TDocument : IDocument 67 | { 68 | MongoDbCreator.AddOne(document, cancellationToken); 69 | } 70 | 71 | /// 72 | public virtual async Task AddManyAsync(IEnumerable documents) 73 | where TDocument : IDocument 74 | { 75 | await AddManyAsync(documents, CancellationToken.None); 76 | } 77 | 78 | /// 79 | public virtual async Task AddManyAsync(IEnumerable documents, CancellationToken cancellationToken) 80 | where TDocument : IDocument 81 | { 82 | await MongoDbCreator.AddManyAsync(documents, cancellationToken); 83 | } 84 | 85 | /// 86 | public virtual void AddMany(IEnumerable documents) 87 | where TDocument : IDocument 88 | { 89 | AddMany(documents, CancellationToken.None); 90 | } 91 | 92 | /// 93 | public virtual void AddMany(IEnumerable documents, CancellationToken cancellationToken) 94 | where TDocument : IDocument 95 | { 96 | MongoDbCreator.AddMany(documents, cancellationToken); 97 | } 98 | } 99 | } -------------------------------------------------------------------------------- /MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Main.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MongoDB.Driver; 3 | using MongoDbGenericRepository.Models; 4 | 5 | namespace MongoDbGenericRepository 6 | { 7 | /// 8 | /// The base Repository, it is meant to be inherited from by your custom custom MongoRepository implementation. 9 | /// Its constructor must be given a connection string and a database name. 10 | /// 11 | /// The type of the document Id. 12 | public abstract partial class BaseMongoRepository : 13 | ReadOnlyMongoRepository, 14 | IBaseMongoRepository 15 | where TKey : IEquatable 16 | { 17 | private readonly object _initLock = new object(); 18 | 19 | /// 20 | /// The constructor taking a connection string and a database name. 21 | /// 22 | /// The connection string of the MongoDb server. 23 | /// The name of the database against which you want to perform operations. 24 | protected BaseMongoRepository(string connectionString, string databaseName = null) : base(connectionString, databaseName) 25 | { 26 | } 27 | 28 | /// 29 | /// The constructor taking a . 30 | /// 31 | /// A mongodb context implementing 32 | protected BaseMongoRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext) 33 | { 34 | } 35 | 36 | /// 37 | /// The constructor taking a . 38 | /// 39 | /// A mongodb context implementing 40 | protected BaseMongoRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase) 41 | { 42 | } 43 | 44 | /// 45 | /// Gets a collections for a potentially partitioned document type. 46 | /// 47 | /// The document type. 48 | /// The collection partition key. 49 | /// 50 | protected virtual IMongoCollection HandlePartitioned(string partitionKey) 51 | where TDocument : IDocument 52 | { 53 | if (!string.IsNullOrEmpty(partitionKey)) 54 | { 55 | return GetCollection(partitionKey); 56 | } 57 | 58 | return GetCollection(); 59 | } 60 | 61 | /// 62 | /// Gets a collections for the type TDocument with a partition key. 63 | /// 64 | /// The document type. 65 | /// The collection partition key. 66 | /// 67 | protected virtual IMongoCollection GetCollection(string partitionKey = null) 68 | where TDocument : IDocument 69 | { 70 | return MongoDbContext.GetCollection(partitionKey); 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /MongoDbGenericRepository/KeyTypedRepository/IBaseMongoRepository.TKey.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MongoDbGenericRepository 4 | { 5 | /// 6 | /// The interface exposing all the CRUD and Index functionalities for Key typed repositories. 7 | /// 8 | /// The type of the document Id. 9 | public interface IBaseMongoRepository : 10 | IReadOnlyMongoRepository, 11 | IBaseMongoRepository_Create, 12 | IBaseMongoRepository_Delete, 13 | IBaseMongoRepository_Index, 14 | IBaseMongoRepository_Update 15 | where TKey : IEquatable 16 | { 17 | } 18 | } -------------------------------------------------------------------------------- /MongoDbGenericRepository/Models/Document.cs: -------------------------------------------------------------------------------- 1 | using MongoDB.Bson.Serialization.Attributes; 2 | using System; 3 | 4 | namespace MongoDbGenericRepository.Models 5 | { 6 | /// 7 | /// This class represents a basic document that can be stored in MongoDb. 8 | /// Your document must implement this class in order for the MongoDbRepository to handle them. 9 | /// 10 | public class Document : IDocument 11 | { 12 | /// 13 | /// The document constructor 14 | /// 15 | public Document() 16 | { 17 | Id = Guid.NewGuid(); 18 | AddedAtUtc = DateTime.UtcNow; 19 | } 20 | 21 | /// 22 | /// The Id of the document 23 | /// 24 | [BsonId] 25 | public Guid Id { get; set; } 26 | 27 | /// 28 | /// The datetime in UTC at which the document was added. 29 | /// 30 | public DateTime AddedAtUtc { get; set; } 31 | 32 | /// 33 | /// The version of the schema of the document 34 | /// 35 | public int Version { get; set; } 36 | } 37 | } -------------------------------------------------------------------------------- /MongoDbGenericRepository/Models/IDocument.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MongoDbGenericRepository.Models 4 | { 5 | /// 6 | /// This class represents a basic document that can be stored in MongoDb. 7 | /// Your document must implement this class in order for the MongoDbRepository to handle them. 8 | /// 9 | public interface IDocument where TKey : IEquatable 10 | { 11 | /// 12 | /// The Primary Key, which must be decorated with the [BsonId] attribute 13 | /// if you want the MongoDb C# driver to consider it to be the document ID. 14 | /// 15 | TKey Id { get; set; } 16 | /// 17 | /// A version number, to indicate the version of the schema. 18 | /// 19 | int Version { get; set; } 20 | } 21 | 22 | /// 23 | /// This class represents a basic document that can be stored in MongoDb. 24 | /// Your document must implement this class in order for the MongoDbRepository to handle them. 25 | /// 26 | public interface IDocument : IDocument 27 | { 28 | } 29 | } -------------------------------------------------------------------------------- /MongoDbGenericRepository/Models/IPartitionedDocument.cs: -------------------------------------------------------------------------------- 1 | namespace MongoDbGenericRepository.Models 2 | { 3 | /// 4 | /// This class represents a document that can be inserted in a collection that can be partitioned. 5 | /// The partition key allows for the creation of different collections having the same document schema. 6 | /// This can be useful if you are planning to build a Software as a Service (SaaS) Platform, or if you want to reduce indexing. 7 | /// You could for example insert Logs in different collections based on the week and year they where created, or their Log category/source. 8 | /// 9 | public interface IPartitionedDocument 10 | { 11 | /// 12 | /// The partition key used to partition your collection. 13 | /// 14 | string PartitionKey { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /MongoDbGenericRepository/Models/IndexCreationOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MongoDbGenericRepository.Models 4 | { 5 | /// 6 | /// Options for creating an index. 7 | /// 8 | public class IndexCreationOptions 9 | { 10 | /// 11 | /// Gets or sets a value indicating whether the index is a unique index. 12 | /// 13 | public bool? Unique { get; set; } 14 | /// 15 | /// Gets or sets the index version for text indexes. 16 | /// 17 | public int? TextIndexVersion { get; set; } 18 | /// 19 | /// Gets or sets the index version for 2dsphere indexes. 20 | /// 21 | public int? SphereIndexVersion { get; set; } 22 | /// 23 | /// Gets or sets a value indicating whether the index is a sparse index. 24 | /// 25 | public bool? Sparse { get; set; } 26 | /// 27 | /// Gets or sets the index name. 28 | /// 29 | public string Name { get; set; } 30 | /// 31 | /// Gets or sets the min value for 2d indexes. 32 | /// 33 | public double? Min { get; set; } 34 | /// 35 | /// Gets or sets the max value for 2d indexes. 36 | /// 37 | public double? Max { get; set; } 38 | /// 39 | /// Gets or sets the language override. 40 | /// 41 | public string LanguageOverride { get; set; } 42 | /// 43 | /// Gets or sets when documents expire (used with TTL indexes). 44 | /// 45 | public TimeSpan? ExpireAfter { get; set; } 46 | /// 47 | /// Gets or sets the default language. 48 | /// 49 | public string DefaultLanguage { get; set; } 50 | /// 51 | /// Gets or sets the precision, in bits, used with geohash indexes. 52 | /// 53 | public int? Bits { get; set; } 54 | /// 55 | /// Gets or sets a value indicating whether to create the index in the background. 56 | /// 57 | public bool? Background { get; set; } 58 | /// 59 | /// Gets or sets the version of the index. 60 | /// 61 | public int? Version { get; set; } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /MongoDbGenericRepository/Models/PartitionedDocument.cs: -------------------------------------------------------------------------------- 1 | namespace MongoDbGenericRepository.Models 2 | { 3 | /// 4 | /// This class represents a document that can be inserted in a collection that can be partitioned. 5 | /// The partition key allows for the creation of different collections having the same document schema. 6 | /// This can be useful if you are planning to build a Software as a Service (SaaS) Platform, or if you want to reduce indexing. 7 | /// You could for example insert Logs in different collections based on the week and year they where created, or their Log category/source. 8 | /// 9 | public class PartitionedDocument : Document, IPartitionedDocument 10 | { 11 | /// 12 | /// The constructor, it needs a partition key. 13 | /// 14 | /// 15 | public PartitionedDocument(string partitionKey) 16 | { 17 | PartitionKey = partitionKey; 18 | } 19 | /// 20 | /// The name of the property used for partitioning the collection 21 | /// This will not be inserted into the collection. 22 | /// This partition key will be prepended to the collection name to create a new collection. 23 | /// 24 | public string PartitionKey { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MongoDbGenericRepository/MongoDbGenericRepository.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net472;netstandard2.0;netstandard2.1 5 | disable 6 | enable 7 | 12.0 8 | true 9 | MongoDbGenericRepository 10 | Alexandre Spieser 11 | MongoDb Generic Repository 12 | A generic repository implementation using the MongoDB C# 2.x driver. 13 | MIT 14 | https://github.com/alexandre-spieser/mongodb-generic-repository 15 | false 16 | https://github.com/alexandre-spieser/mongodb-generic-repository/releases 17 | Copyright 2024 (c) Alexandre Spieser. All rights reserved. 18 | MongoDb Repository Generic NoSql 19 | true 20 | 1.6.3 21 | https://github.com/alexandre-spieser/mongodb-generic-repository 22 | Git 23 | README.md 24 | bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /MongoDbGenericRepository/MongoDbGenericRepository.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | -------------------------------------------------------------------------------- /MongoDbGenericRepository/Utils/IdGenerator.cs: -------------------------------------------------------------------------------- 1 | using MongoDB.Bson; 2 | using System; 3 | 4 | namespace MongoDbGenericRepository.Utils 5 | { 6 | /// 7 | /// The IdGenerator instance, used to generate Ids of different types. 8 | /// 9 | public static class IdGenerator 10 | { 11 | private static readonly Random Random = new Random(); 12 | 13 | /// 14 | /// Generates a random value of a given type. 15 | /// 16 | /// The type of the value to generate. 17 | /// A value of type TKey. 18 | public static TKey GetId() 19 | { 20 | var idTypeName = typeof(TKey).Name; 21 | switch (idTypeName) 22 | { 23 | case "Guid": 24 | return (TKey)(object)Guid.NewGuid(); 25 | case "Int16": 26 | return (TKey)(object)Random.Next(1, short.MaxValue); 27 | case "Int32": 28 | return (TKey)(object)Random.Next(1, int.MaxValue); 29 | case "Int64": 30 | return (TKey)(object)(Random.NextLong(1, long.MaxValue)); 31 | case "String": 32 | return (TKey)(object)Guid.NewGuid().ToString(); 33 | case "ObjectId": 34 | return (TKey)(object)ObjectId.GenerateNewId(); 35 | } 36 | throw new ArgumentException($"{idTypeName} is not a supported Id type, the Id of the document cannot be set."); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /MongoDbGenericRepository/Utils/RandomExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MongoDbGenericRepository.Utils 4 | { 5 | // Thanks BlueRaja - Danny Pflughoeft https://stackoverflow.com/a/13095144/5103354 6 | /// 7 | /// Extensions for the random number generator 8 | /// 9 | public static class RandomExtensions 10 | { 11 | /// 12 | /// Returns a random long from min (inclusive) to max (exclusive) 13 | /// 14 | /// The given random instance 15 | /// The inclusive minimum bound 16 | /// The exclusive maximum bound. Must be greater than min 17 | public static long NextLong(this Random random, long min, long max) 18 | { 19 | if (max <= min) 20 | throw new ArgumentOutOfRangeException("max", "max must be > min!"); 21 | 22 | //Working with ulong so that modulo works correctly with values > long.MaxValue 23 | ulong uRange = (ulong)(max - min); 24 | 25 | //Prevent a modulo bias; see https://stackoverflow.com/a/10984975/238419 26 | //for more information. 27 | //In the worst case, the expected number of calls is 2 (though usually it's 28 | //much closer to 1) so this loop doesn't really hurt performance at all. 29 | ulong ulongRand; 30 | do 31 | { 32 | byte[] buf = new byte[8]; 33 | random.NextBytes(buf); 34 | ulongRand = (ulong)BitConverter.ToInt64(buf, 0); 35 | } while (ulongRand > ulong.MaxValue - ((ulong.MaxValue % uRange) + 1) % uRange); 36 | 37 | return (long)(ulongRand % uRange) + min; 38 | } 39 | 40 | /// 41 | /// Returns a random long from 0 (inclusive) to max (exclusive) 42 | /// 43 | /// The given random instance 44 | /// The exclusive maximum bound. Must be greater than 0 45 | public static long NextLong(this Random random, long max) 46 | { 47 | return random.NextLong(0, max); 48 | } 49 | 50 | /// 51 | /// Returns a random long over all possible values of long (except long.MaxValue, similar to 52 | /// random.Next()) 53 | /// 54 | /// The given random instance 55 | public static long NextLong(this Random random) 56 | { 57 | return random.NextLong(long.MinValue, long.MaxValue); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /MongoDbGenericRepository/_rels/.rels: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | --------------------------------------------------------------------------------