using MongoDbGenericRepository.Models; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; using Xunit; namespace CoreIntegrationTests.Infrastructure { public abstract class MongoDbTKeyDocumentTestBase : IClassFixture> where T: TestDoc, new() where TKey : IEquatable { private readonly MongoDbTestFixture _fixture; protected MongoDbTKeyDocumentTestBase(MongoDbTestFixture fixture) { _fixture = fixture; var type = CreateTestDocument(); DocumentTypeName = type.GetType().FullName; if (type is IPartitionedDocument) { PartitionKey = ((IPartitionedDocument)type).PartitionKey; } _fixture.PartitionKey = PartitionKey; TestClassName = GetClassName(); MongoDbConfig.EnsureConfigured(); SUT = TestRepository.Instance; } public abstract string GetClassName(); public T CreateTestDocument() { return _fixture.CreateTestDocument(); } public List CreateTestDocuments(int numberOfDocumentsToCreate) { return _fixture.CreateTestDocuments(numberOfDocumentsToCreate); } /// /// The partition key for the collection, if any /// protected string PartitionKey { get; set; } /// /// the name of the test class /// protected string TestClassName { get; set; } /// /// The name of the document used for tests /// protected string DocumentTypeName { get; set; } /// /// SUT: System Under Test /// protected static ITestRepository SUT { get; set; } #region Add [Fact] public void AddOne() { // Arrange var document = new T(); // Act SUT.AddOne(document); // Assert long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count(e => e.Id.Equals(document.Id)) : SUT.Count(e => e.Id.Equals(document.Id), PartitionKey); Assert.True(1 == count, GetTestName()); } [Fact] public async Task AddOneAsync() { // Arrange var document = new T(); // Act await SUT.AddOneAsync(document); // Assert long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count(e => e.Id.Equals(document.Id)) : SUT.Count(e => e.Id.Equals(document.Id), PartitionKey); Assert.True (1 == count, GetTestName()); } [Fact] public void AddMany() { // Arrange var documents = new List { new T(), new T() }; // Act SUT.AddMany(documents); // Assert long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count(e => e.Id.Equals(documents[0].Id) || e.Id.Equals(documents[1].Id)) : SUT.Count(e => e.Id.Equals(documents[0].Id) || e.Id.Equals(documents[1].Id), PartitionKey); Assert.True (2 == count, GetTestName()); } [Fact] public void AddManyWithDifferentPartitionKey() { // only run this test for tests on documents with partition key if (!string.IsNullOrEmpty(PartitionKey)) { // Arrange var documents = new List { new T(), new T(), new T(), new T() }; if (documents.Any(e => e is IPartitionedDocument)) { var secondPartitionKey = $"{PartitionKey}-2"; ((IPartitionedDocument)documents[2]).PartitionKey = secondPartitionKey; ((IPartitionedDocument)documents[3]).PartitionKey = secondPartitionKey; // Act SUT.AddMany(documents); // Assert long count = SUT.Count(e => e.Id.Equals(documents[0].Id) || e.Id.Equals(documents[1].Id), PartitionKey); long secondPartitionCount = SUT.Count(e => e.Id.Equals(documents[2].Id) || e.Id.Equals(documents[3].Id), secondPartitionKey); // Cleanup second partition SUT.DeleteMany(e => e.Id.Equals(documents[2].Id) || e.Id.Equals(documents[3].Id), secondPartitionKey); Assert.True(2 == count, GetTestName()); Assert.True(2 == secondPartitionCount, GetTestName()); } } } [Fact] public async Task AddManyAsync() { // Arrange var documents = new List { new T(), new T() }; // Act await SUT.AddManyAsync(documents); // Assert long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count(e => e.Id.Equals(documents[0].Id) || e.Id.Equals(documents[1].Id)) : SUT.Count(e => e.Id.Equals(documents[0].Id) || e.Id.Equals(documents[1].Id), PartitionKey); Assert.True (2 == count, GetTestName()); } [Fact] public async Task AddManyAsyncWithDifferentPartitionKey() { // only run this test for tests on documents with partition key if (!string.IsNullOrEmpty(PartitionKey)) { // Arrange var documents = new List { new T(), new T(), new T(), new T() }; if (documents.Any(e => e is IPartitionedDocument)) { var secondPartitionKey = $"{PartitionKey}-2"; ((IPartitionedDocument)documents[2]).PartitionKey = secondPartitionKey; ((IPartitionedDocument)documents[3]).PartitionKey = secondPartitionKey; // Act await SUT.AddManyAsync(documents); // Assert long count = SUT.Count(e => e.Id.Equals(documents[0].Id) || e.Id.Equals(documents[1].Id), PartitionKey); long secondPartitionCount = SUT.Count(e => e.Id.Equals(documents[2].Id) || e.Id.Equals(documents[3].Id), secondPartitionKey); // Cleanup second partition SUT.DeleteMany(e => e.Id.Equals(documents[2].Id) || e.Id.Equals(documents[3].Id), secondPartitionKey); Assert.True(2 == count, GetTestName()); Assert.True(2 == secondPartitionCount, GetTestName()); } } } #endregion Add #region Read [Fact] public async Task GetByIdAsync() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = await SUT.GetByIdAsync(document.Id, PartitionKey); // Assert Assert.True(null != result, GetTestName()); } [Fact] public void GetById() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = SUT.GetById(document.Id, PartitionKey); // Assert Assert.True(null != result, GetTestName()); } [Fact] public async Task GetOneAsync() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = await SUT.GetOneAsync(x => x.Id.Equals(document.Id), PartitionKey); // Assert Assert.True(null != result, GetTestName()); } [Fact] public void GetOne() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = SUT.GetOne(x => x.Id.Equals(document.Id), PartitionKey); // Assert Assert.True(null != result, GetTestName()); } [Fact] public void GetCursor() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var cursor = SUT.GetCursor(x => x.Id.Equals(document.Id), PartitionKey); var count = cursor.Count(); // Assert Assert.True (1 == count, GetTestName()); } [Fact] public async Task AnyAsyncReturnsTrue() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = await SUT.AnyAsync(x => x.Id.Equals(document.Id), PartitionKey); // Assert Assert.True(result, GetTestName()); } [Fact] public async Task AnyAsyncReturnsFalse() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = await SUT.AnyAsync(x => x.Id.Equals(document.Init()), PartitionKey); // Assert Assert.False(result, GetTestName()); } [Fact] public void AnyReturnsTrue() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = SUT.Any(x => x.Id.Equals(document.Id), PartitionKey); // Assert Assert.True(result, GetTestName()); } [Fact] public void AnyReturnsFalse() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = SUT.Any(x => x.Id.Equals(document.Init()), PartitionKey); // Assert Assert.False(result, GetTestName()); } [Fact] public async Task GetAllAsync() { // Arrange var documents = CreateTestDocuments(5); var content = GetContent(); documents.ForEach(e => e.SomeContent = content); SUT.AddMany(documents); // Act var result = await SUT.GetAllAsync(x => x.SomeContent == content, PartitionKey); // Assert Assert.True(5 == result.Count, GetTestName()); } [Fact] public void GetAll() { // Arrange var documents = CreateTestDocuments(5); var content = GetContent(); documents.ForEach(e => e.SomeContent = content); SUT.AddMany(documents); // Act var result = SUT.GetAll(x => x.SomeContent == content, PartitionKey); // Assert Assert.True(5 == result.Count, GetTestName()); } [Fact] public async Task CountAsync() { // Arrange var documents = CreateTestDocuments(5); var content = GetContent(); documents.ForEach(e => e.SomeContent = content); SUT.AddMany(documents); // Act var result = await SUT.CountAsync(x => x.SomeContent == content, PartitionKey); // Assert Assert.True(5 == result, GetTestName()); } [Fact] public void Count() { // Arrange var documents = CreateTestDocuments(5); var content = GetContent(); documents.ForEach(e => e.SomeContent = content); SUT.AddMany(documents); // Act var result = SUT.Count(x => x.SomeContent == content, PartitionKey); // Assert Assert.True(5 == result, GetTestName()); } #endregion Read #region Update [Fact] public void UpdateOne() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); var content = GetContent(); document.SomeContent = content; // Act var result = SUT.UpdateOne(document); // Assert Assert.True(result); var updatedDocument = SUT.GetById(document.Id, PartitionKey); Assert.True(null != updatedDocument, GetTestName()); Assert.True(content == updatedDocument.SomeContent, GetTestName()); } [Fact] public async Task UpdateOneAsync() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); var content = GetContent(); document.SomeContent = content; // Act var result = await SUT.UpdateOneAsync(document); // Assert Assert.True(result); var updatedDocument = SUT.GetById(document.Id, PartitionKey); Assert.True(null != updatedDocument, GetTestName()); Assert.True(content == updatedDocument.SomeContent, GetTestName()); } [Fact] public void UpdateOneField() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); var content = GetContent(); // Act var result = SUT.UpdateOne(document, x => x.SomeContent, content); // Assert Assert.True(result, GetTestName()); var updatedDocument = SUT.GetById(document.Id, PartitionKey); Assert.True(null != updatedDocument, GetTestName()); Assert.True(content == updatedDocument.SomeContent, GetTestName()); } [Fact] public async Task UpdateOneFieldAsync() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); var content = GetContent(); // Act var result = await SUT.UpdateOneAsync(document, x => x.SomeContent, content); // Assert Assert.True(result, GetTestName()); var updatedDocument = SUT.GetById(document.Id, PartitionKey); Assert.True(null != updatedDocument, GetTestName()); Assert.True(content == updatedDocument.SomeContent, GetTestName()); } [Fact] public void UpdateOneFieldWithFilter() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); var content = GetContent(); // Act var result = SUT.UpdateOne(x => x.Id.Equals(document.Id), x => x.SomeContent, content, PartitionKey); // Assert Assert.True(result, GetTestName()); var updatedDocument = SUT.GetById(document.Id, PartitionKey); Assert.True(null != updatedDocument, GetTestName()); Assert.True(content == updatedDocument.SomeContent, GetTestName()); } [Fact] public async Task UpdateOneFieldWithFilterAsync() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); var content = GetContent(); // Act var result = await SUT.UpdateOneAsync(x => x.Id.Equals(document.Id), x => x.SomeContent, content, PartitionKey); // Assert Assert.True(result, GetTestName()); var updatedDocument = SUT.GetById(document.Id, PartitionKey); Assert.True(null != updatedDocument, GetTestName()); Assert.True(content == updatedDocument.SomeContent, GetTestName()); } [Fact] public async Task UpdateOneAsyncWithUpdateDefinition() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); var childrenToAdd = new List { new Child("testType1", "testValue1"), new Child("testType2", "testValue2") }; var updateDef = MongoDB.Driver.Builders.Update.AddToSetEach(p => p.Children, childrenToAdd); // Act var result = await SUT.UpdateOneAsync(document, updateDef); // Assert Assert.True(result); var updatedDocument = SUT.GetById(document.Id, PartitionKey); Assert.True(null != updatedDocument); Assert.True(childrenToAdd[0].Type == updatedDocument.Children[0].Type, GetTestName()); Assert.True(childrenToAdd[0].Value == updatedDocument.Children[0].Value, GetTestName()); Assert.True(childrenToAdd[1].Type == updatedDocument.Children[1].Type, GetTestName()); Assert.True(childrenToAdd[1].Value == updatedDocument.Children[1].Value, GetTestName()); } [Fact] public void UpdateOneWithUpdateDefinition() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); var childrenToAdd = new List { new Child("testType1", "testValue1"), new Child("testType2", "testValue2") }; var updateDef = MongoDB.Driver.Builders.Update.AddToSetEach(p => p.Children, childrenToAdd); // Act var result = SUT.UpdateOne(document, updateDef); // Assert Assert.True(result); var updatedDocument = SUT.GetById(document.Id, PartitionKey); Assert.True(null != updatedDocument); Assert.True(childrenToAdd[0].Type== updatedDocument.Children[0].Type, GetTestName()); Assert.True(childrenToAdd[0].Value== updatedDocument.Children[0].Value, GetTestName()); Assert.True(childrenToAdd[1].Type== updatedDocument.Children[1].Type, GetTestName()); Assert.True(childrenToAdd[1].Value== updatedDocument.Children[1].Value, GetTestName()); } #endregion Update #region Delete [Fact] public void DeleteOne() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = SUT.DeleteOne(document); // Assert Assert.True (1 == result); Assert.False(SUT.Any(e => e.Id.Equals(document.Id), PartitionKey), GetTestName()); } [Fact] public void DeleteOneLinq() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = SUT.DeleteOne(e => e.Id.Equals(document.Id), PartitionKey); // Assert Assert.True (1 == result); Assert.False(SUT.Any(e => e.Id.Equals(document.Id), PartitionKey), GetTestName()); } [Fact] public async Task DeleteOneAsync() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = await SUT.DeleteOneAsync(document); // Assert Assert.True (1 == result); Assert.False(SUT.Any(e => e.Id.Equals(document.Id), PartitionKey), GetTestName()); } [Fact] public async Task DeleteOneAsyncLinq() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = await SUT.DeleteOneAsync(e => e.Id.Equals(document.Id), PartitionKey); // Assert Assert.True (1 == result); Assert.False(SUT.Any(e => e.Id.Equals(document.Id), PartitionKey), GetTestName()); } [Fact] public async Task DeleteManyAsyncLinq() { // Arrange var criteria = $"{GetTestName()}.{DocumentTypeName}"; var documents = CreateTestDocuments(5); documents.ForEach(e => e.SomeContent = criteria); SUT.AddMany(documents); // Act var result = await SUT.DeleteManyAsync(e => e.SomeContent == criteria, PartitionKey); // Assert Assert.True(5 == result); Assert.False(SUT.Any(e => e.SomeContent == criteria, PartitionKey), GetTestName()); } [Fact] public async Task DeleteManyAsync() { // Arrange var criteria = $"{GetTestName()}.{DocumentTypeName}"; var documents = CreateTestDocuments(5); documents.ForEach(e => e.SomeContent = criteria); var canPartition = !string.IsNullOrEmpty(PartitionKey) && documents.Any(e => e is IPartitionedDocument); string secondKey = null; if (canPartition) { secondKey = $"{PartitionKey}-2"; ((IPartitionedDocument)documents[3]).PartitionKey = secondKey; ((IPartitionedDocument)documents[4]).PartitionKey = secondKey; } SUT.AddMany(documents); // Act var result = await SUT.DeleteManyAsync(documents); // Assert Assert.True(5 == result); Assert.False(SUT.Any(e => e.SomeContent == criteria, PartitionKey), GetTestName()); if (canPartition) { Assert.False(SUT.Any(e => e.SomeContent == criteria, secondKey), GetTestName()); } } [Fact] public void DeleteManyLinq() { // Arrange var criteria = $"{GetTestName()}.{DocumentTypeName}"; var documents = CreateTestDocuments(5); documents.ForEach(e => e.SomeContent = criteria); SUT.AddMany(documents); // Act var result = SUT.DeleteMany(e => e.SomeContent == criteria, PartitionKey); // Assert Assert.True(5 == result); Assert.False(SUT.Any(e => e.SomeContent == criteria, PartitionKey), GetTestName()); } [Fact] public void DeleteMany() { // Arrange var criteria = $"{GetTestName()}.{DocumentTypeName}"; var documents = CreateTestDocuments(5); documents.ForEach(e => e.SomeContent = criteria); var canPartition = !string.IsNullOrEmpty(PartitionKey) && documents.Any(e => e is IPartitionedDocument); string secondKey = null; if (canPartition) { secondKey = $"{PartitionKey}-2"; ((IPartitionedDocument)documents[3]).PartitionKey = secondKey; ((IPartitionedDocument)documents[4]).PartitionKey = secondKey; } SUT.AddMany(documents); // Act var result = SUT.DeleteMany(documents); // Assert Assert.True(5 == result); Assert.False(SUT.Any(e => e.SomeContent == criteria, PartitionKey), GetTestName()); if (canPartition) { Assert.False(SUT.Any(e => e.SomeContent == criteria, secondKey), GetTestName()); } } #endregion Delete #region Project [Fact] public async Task ProjectOneAsync() { // Arrange var someContent = GetContent(); var someDate = DateTime.UtcNow; var document = CreateTestDocument(); document.SomeContent = someContent; document.Nested.SomeDate = someDate; SUT.AddOne(document); // Act var result = await SUT.ProjectOneAsync( x => x.Id.Equals(document.Id), x => new MyTestProjection { SomeContent = x.SomeContent, SomeDate = x.Nested.SomeDate }, PartitionKey); // Assert Assert.True(null != result, GetTestName()); Assert.True(someContent == result.SomeContent, GetTestName()); Assert.True(someDate.Minute == result.SomeDate.Minute, GetTestName()); Assert.True(someDate.Second == result.SomeDate.Second, GetTestName()); } [Fact] public void ProjectOne() { // Arrange var someContent = GetContent(); var someDate = DateTime.UtcNow; var document = CreateTestDocument(); document.SomeContent = someContent; document.Nested.SomeDate = someDate; SUT.AddOne(document); // Act var result = SUT.ProjectOne( x => x.Id.Equals(document.Id), x => new MyTestProjection { SomeContent = x.SomeContent, SomeDate = x.Nested.SomeDate }, PartitionKey); // Assert Assert.True(null != result, GetTestName()); Assert.True(someContent == result.SomeContent, GetTestName()); Assert.True(someDate.Minute == result.SomeDate.Minute, GetTestName()); Assert.True(someDate.Second == result.SomeDate.Second, GetTestName()); } [Fact] public async Task ProjectManyAsync() { // Arrange var someContent = GetContent(); var someDate = DateTime.UtcNow; var documents = CreateTestDocuments(5); documents.ForEach(e => { e.SomeContent = someContent; e.Nested.SomeDate = someDate; }); SUT.AddMany(documents); // Act var result = await SUT.ProjectManyAsync( x => x.SomeContent == someContent, x => new MyTestProjection { SomeContent = x.SomeContent, SomeDate = x.Nested.SomeDate }, PartitionKey); // Assert Assert.True(5 == result.Count, GetTestName()); Assert.True(someContent == result.First().SomeContent, GetTestName()); Assert.True(someDate.Minute == result.First().SomeDate.Minute, GetTestName()); Assert.True(someDate.Second == result.First().SomeDate.Second, GetTestName()); } [Fact] public void ProjectMany() { // Arrange var someContent = GetContent(); var someDate = DateTime.UtcNow; var documents = CreateTestDocuments(5); documents.ForEach(e => { e.SomeContent = someContent; e.Nested.SomeDate = someDate; }); SUT.AddMany(documents); // Act var result = SUT.ProjectMany( x => x.SomeContent == someContent, x => new MyTestProjection { SomeContent = x.SomeContent, SomeDate = x.Nested.SomeDate }, PartitionKey); // Assert Assert.True(5 == result.Count, GetTestName()); Assert.True(someContent == result.First().SomeContent, GetTestName()); Assert.True(someDate.Minute == result.First().SomeDate.Minute, GetTestName()); Assert.True(someDate.Second == result.First().SomeDate.Second, GetTestName()); } #endregion Project #region Max / Min Queries [Fact] public async Task GetByMaxAsync() { // Arrange var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}"; var documents = CreateTestDocuments(5); var i = 1; documents.ForEach(e => { e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++); e.SomeContent = criteria; }); SUT.AddMany(documents); var expectedMax = documents.OrderByDescending(e => e.Nested.SomeDate).First(); // Act var result = await SUT.GetByMaxAsync(e => e.SomeContent == criteria, e => e.Nested.SomeDate, PartitionKey); // Assert Assert.NotNull(result); Assert.Equal(expectedMax.Id, result.Id); } [Fact] public void GetByMax() { // Arrange var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}"; var documents = CreateTestDocuments(5); var i = 1; documents.ForEach(e => { e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++); e.SomeContent = criteria; }); SUT.AddMany(documents); var expectedMax = documents.OrderByDescending(e => e.Nested.SomeDate).First(); // Act var result = SUT.GetByMax(e => e.SomeContent == criteria, e => e.Nested.SomeDate, PartitionKey); // Assert Assert.NotNull(result); Assert.Equal(expectedMax.Id, result.Id); } [Fact] public void GetMaxValue() { // Arrange var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}"; var documents = CreateTestDocuments(5); var i = 1; documents.ForEach(e => { e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++); e.SomeContent = criteria; }); SUT.AddMany(documents); var expectedMax = documents.OrderByDescending(e => e.Nested.SomeDate).First(); // Act var result = SUT.GetMaxValue(e => e.SomeContent == criteria, e => e.Nested.SomeDate, PartitionKey); // Assert Assert.False(result == default(DateTime)); Assert.Equal(expectedMax.Nested.SomeDate.Date, result.Date); } [Fact] public async Task GetMaxValueAsync() { // Arrange var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}"; var documents = CreateTestDocuments(5); var i = 1; documents.ForEach(e => { e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++); e.SomeContent = criteria; }); SUT.AddMany(documents); var expectedMax = documents.OrderByDescending(e => e.Nested.SomeDate).First(); // Act var result = await SUT.GetMaxValueAsync(e => e.SomeContent == criteria, e => e.Nested.SomeDate, PartitionKey); // Assert Assert.False(result == default(DateTime)); Assert.Equal(expectedMax.Nested.SomeDate.Date, result.Date); } [Fact] public async Task GetByMinAsync() { // Arrange var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}"; var documents = CreateTestDocuments(5); var i = 1; documents.ForEach(e => { e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++); e.SomeContent = criteria; }); SUT.AddMany(documents); var expectedMin = documents.OrderBy(e => e.Nested.SomeDate).First(); // Act var result = await SUT.GetByMinAsync(e => e.SomeContent == criteria, e => e.Nested.SomeDate, PartitionKey); // Assert Assert.NotNull(result); Assert.Equal(expectedMin.Id, result.Id); } [Fact] public void GetByMin() { // Arrange var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}"; var documents = CreateTestDocuments(5); var i = 1; documents.ForEach(e => { e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++); e.SomeContent = criteria; }); SUT.AddMany(documents); var expectedMin = documents.OrderBy(e => e.Nested.SomeDate).First(); // Act var result = SUT.GetByMin(e => e.SomeContent == criteria, e => e.Nested.SomeDate, PartitionKey); // Assert Assert.NotNull(result); Assert.Equal(expectedMin.Id, result.Id); } [Fact] public void GetMinValue() { // Arrange var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}"; var documents = CreateTestDocuments(5); var i = 1; documents.ForEach(e => { e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++); e.SomeContent = criteria; }); SUT.AddMany(documents); var expectedMin = documents.OrderBy(e => e.Nested.SomeDate).First(); // Act var result = SUT.GetMinValue< T, TKey, DateTime >(e => e.SomeContent == criteria, e => e.Nested.SomeDate, PartitionKey); // Assert Assert.True(result != default(DateTime)); Assert.Equal(expectedMin.Nested.SomeDate.Date, result.Date); } [Fact] public async Task GetMinValueAsync() { // Arrange var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}"; var documents = CreateTestDocuments(5); var i = 1; documents.ForEach(e => { e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++); e.SomeContent = criteria; }); SUT.AddMany(documents); var expectedMin = documents.OrderBy(e => e.Nested.SomeDate).First(); // Act var result = await SUT.GetMinValueAsync< T, TKey, DateTime >(e => e.SomeContent == criteria, e => e.Nested.SomeDate, PartitionKey); // Assert Assert.True(result != default(DateTime)); Assert.Equal(expectedMin.Nested.SomeDate.Date, result.Date); } #endregion Max / Min Queries #region Index Management static SemaphoreSlim textIndexSemaphore = new SemaphoreSlim(1, 1); [Fact] public async Task CreateTextIndexNoOptionAsync() { // Arrange const string expectedIndexName = "SomeContent_text"; // Act await textIndexSemaphore.WaitAsync(); try { var result = await SUT.CreateTextIndexAsync(x => x.SomeContent, null, PartitionKey); // Assert var listOfIndexNames = await SUT.GetIndexesNamesAsync(PartitionKey); Assert.Contains(expectedIndexName, listOfIndexNames); // Cleanup await SUT.DropIndexAsync(expectedIndexName, PartitionKey); } finally { textIndexSemaphore.Release(); } } [Fact] public async Task CreateTextIndexWithOptionAsync() { // Arrange string expectedIndexName = $"{Guid.NewGuid()}"; var option = new IndexCreationOptions { Name = expectedIndexName }; await textIndexSemaphore.WaitAsync(); try { // Act var result = await SUT.CreateTextIndexAsync(x => x.Version, option, PartitionKey); // Assert var listOfIndexNames = await SUT.GetIndexesNamesAsync(PartitionKey); Assert.Contains(expectedIndexName, listOfIndexNames); // Cleanup await SUT.DropIndexAsync(expectedIndexName, PartitionKey); } finally { textIndexSemaphore.Release(); } } [Fact] public async Task CreateAscendingIndexAsync() { // Arrange const string expectedIndexName = "SomeContent_1"; // Act var result = await SUT.CreateAscendingIndexAsync(x => x.SomeContent, null, PartitionKey); // Assert var listOfIndexNames = await SUT.GetIndexesNamesAsync(PartitionKey); Assert.Contains(expectedIndexName, listOfIndexNames); // Cleanup await SUT.DropIndexAsync(expectedIndexName, PartitionKey); } [Fact] public async Task CreateDescendingIndexAsync() { // Arrange const string expectedIndexName = "SomeContent_-1"; // Act var result = await SUT.CreateDescendingIndexAsync(x => x.SomeContent, null, PartitionKey); // Assert var listOfIndexNames = await SUT.GetIndexesNamesAsync(PartitionKey); Assert.Contains(expectedIndexName, listOfIndexNames); // Cleanup await SUT.DropIndexAsync(expectedIndexName, PartitionKey); } [Fact] public async Task CreateHashedIndexAsync() { // Arrange const string expectedIndexName = "SomeContent_hashed"; // Act var result = await SUT.CreateHashedIndexAsync(x => x.SomeContent, null, PartitionKey); // Assert var listOfIndexNames = await SUT.GetIndexesNamesAsync(PartitionKey); Assert.Contains(expectedIndexName, listOfIndexNames); // Cleanup await SUT.DropIndexAsync(expectedIndexName, PartitionKey); } #endregion Index Management #region Test Utils [MethodImpl(MethodImplOptions.NoInlining)] private string GetCurrentMethod() { StackTrace st = new StackTrace(); StackFrame sf = st.GetFrame(1); return sf.GetMethod().Name; } [MethodImpl(MethodImplOptions.NoInlining)] private string GetParentMethod() { StackTrace st = new StackTrace(); StackFrame sf = st.GetFrame(2); var method = sf.GetMethod().DeclaringType.Name; return method; } private string GetTestName() { return $"{TestClassName}{PartitionKey}.{GetParentMethod()}"; } private string GetContent() { return $"{TestClassName}{PartitionKey}.{Guid.NewGuid()}.{GetParentMethod()}"; } private void Cleanup() { // We drop the collection at the end of each test session. if (!string.IsNullOrEmpty(PartitionKey)) { SUT.DropTestCollection(PartitionKey); } else { SUT.DropTestCollection(); } } #endregion Test Utils } }