using MongoDbGenericRepository.Models; using NUnit.Framework; using System; using System.Collections.Generic; using System.Configuration; using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; using System.Threading.Tasks; using NUnit.Framework.Legacy; namespace IntegrationTests.Infrastructure { [TestFixture] public abstract class MongoDbTKeyDocumentTestBase where T: TestDoc, new() where TKey : IEquatable { public T CreateTestDocument() { return new T(); } public abstract string GetClassName(); public List CreateTestDocuments(int numberOfDocumentsToCreate) { var docs = new List(); for (var i = 0; i < numberOfDocumentsToCreate; i++) { docs.Add(new T()); } return docs; } /// /// 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; } public MongoDbTKeyDocumentTestBase() { var type = CreateTestDocument(); DocumentTypeName = type.GetType().FullName; if (type is IPartitionedDocument) { PartitionKey = ((IPartitionedDocument)type).PartitionKey; } TestClassName = GetClassName(); } [OneTimeSetUp] public void Init() { SUT = new TestRepository("mongodb://test:Test123!@10.0.3.4:27017", "MongoDbTests"); } [OneTimeTearDown] public void Cleanup() { // We drop the collection at the end of each test session. if (!string.IsNullOrEmpty(PartitionKey)) { SUT.DropTestCollection(PartitionKey); } else { SUT.DropTestCollection(); } } #region Add [Test] 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.That(count, Is.EqualTo(1), GetTestName()); } [Test] 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.That(count, Is.EqualTo(1), GetTestName()); } [Test] 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.That(count, Is.EqualTo(2), GetTestName()); } [Test] 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.That(count, Is.EqualTo(2), GetTestName()); } #endregion Add #region Read [Test] public async Task GetByIdAsync() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = await SUT.GetByIdAsync(document.Id, PartitionKey); // Assert ClassicAssert.IsNotNull(result, GetTestName()); } [Test] public void GetById() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = SUT.GetById(document.Id, PartitionKey); // Assert ClassicAssert.IsNotNull(result, GetTestName()); } [Test] 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 ClassicAssert.IsNotNull(result, GetTestName()); } [Test] public void GetOne() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = SUT.GetOne(x => x.Id.Equals(document.Id), PartitionKey); // Assert ClassicAssert.IsNotNull(result, GetTestName()); } [Test] 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.CountDocuments(); // Assert Assert.That(count, Is.EqualTo(1), GetTestName()); } [Test] 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.That(result, Is.EqualTo(true), GetTestName()); } [Test] 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.That(result, Is.EqualTo(false), GetTestName()); } [Test] public void AnyReturnsTrue() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = SUT.Any(x => x.Id.Equals(document.Id), PartitionKey); // Assert Assert.That(result, Is.EqualTo(true), GetTestName()); } [Test] public void AnyReturnsFalse() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = SUT.Any(x => x.Id.Equals(document.Init()), PartitionKey); // Assert Assert.That(result, Is.EqualTo(false), GetTestName()); } [Test] 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.That(result.Count, Is.EqualTo(5), GetTestName()); } [Test] 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.That(result.Count, Is.EqualTo(5), GetTestName()); } [Test] 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.That(result, Is.EqualTo(5), GetTestName()); } [Test] 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.That(result, Is.EqualTo(5), GetTestName()); } #endregion Read #region Update [Test] public void UpdateOne() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); var content = GetContent(); document.SomeContent = content; // Act var result = SUT.UpdateOne(document); // Assert Assert.That(result, Is.True); var updatedDocument = SUT.GetById(document.Id, PartitionKey); ClassicAssert.IsNotNull(updatedDocument, GetTestName()); Assert.That(updatedDocument.SomeContent, Is.EqualTo(content), GetTestName()); } [Test] 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.That(result, Is.True); var updatedDocument = SUT.GetById(document.Id, PartitionKey); ClassicAssert.IsNotNull(updatedDocument, GetTestName()); Assert.That(updatedDocument.SomeContent, Is.EqualTo(content), GetTestName()); } [Test] public void UpdateOneField() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); var content = GetContent(); // Act var result = SUT.UpdateOne(document, x => x.SomeContent, content); // Assert ClassicAssert.IsTrue(result, GetTestName()); var updatedDocument = SUT.GetById(document.Id, PartitionKey); ClassicAssert.IsNotNull(updatedDocument, GetTestName()); Assert.That(updatedDocument.SomeContent, Is.EqualTo(content), GetTestName()); } [Test] 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 ClassicAssert.IsTrue(result, GetTestName()); var updatedDocument = SUT.GetById(document.Id, PartitionKey); ClassicAssert.IsNotNull(updatedDocument, GetTestName()); Assert.That(updatedDocument.SomeContent, Is.EqualTo(content), GetTestName()); } [Test] 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 ClassicAssert.IsTrue(result, GetTestName()); var updatedDocument = SUT.GetById(document.Id, PartitionKey); ClassicAssert.IsNotNull(updatedDocument, GetTestName()); Assert.That(updatedDocument.SomeContent, Is.EqualTo(content), GetTestName()); } [Test] 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 ClassicAssert.IsTrue(result, GetTestName()); var updatedDocument = SUT.GetById(document.Id, PartitionKey); ClassicAssert.IsNotNull(updatedDocument, GetTestName()); Assert.That(updatedDocument.SomeContent, Is.EqualTo(content), GetTestName()); } [Test] 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 ClassicAssert.IsTrue(result); var updatedDocument = SUT.GetById(document.Id, PartitionKey); ClassicAssert.IsNotNull(updatedDocument); Assert.That(updatedDocument.Children[0].Type, Is.EqualTo(childrenToAdd[0].Type), GetTestName()); Assert.That(updatedDocument.Children[0].Value, Is.EqualTo(childrenToAdd[0].Value), GetTestName()); Assert.That(updatedDocument.Children[1].Type, Is.EqualTo(childrenToAdd[1].Type), GetTestName()); Assert.That(updatedDocument.Children[1].Value, Is.EqualTo(childrenToAdd[1].Value), GetTestName()); } [Test] 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 ClassicAssert.IsTrue(result); var updatedDocument = SUT.GetById(document.Id, PartitionKey); ClassicAssert.IsNotNull(updatedDocument); Assert.That(updatedDocument.Children[0].Type, Is.EqualTo(childrenToAdd[0].Type), GetTestName()); Assert.That(updatedDocument.Children[0].Value, Is.EqualTo(childrenToAdd[0].Value), GetTestName()); Assert.That(updatedDocument.Children[1].Type, Is.EqualTo(childrenToAdd[1].Type), GetTestName()); Assert.That(updatedDocument.Children[1].Value, Is.EqualTo(childrenToAdd[1].Value), GetTestName()); } #endregion Update #region Delete [Test] public void DeleteOne() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = SUT.DeleteOne(document); // Assert Assert.That(result, Is.EqualTo(1)); ClassicAssert.IsFalse(SUT.Any(e => e.Id.Equals(document.Id), PartitionKey), GetTestName()); } [Test] public void DeleteOneLinq() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = SUT.DeleteOne(e => e.Id.Equals(document.Id), PartitionKey); // Assert Assert.That(result, Is.EqualTo(1)); ClassicAssert.IsFalse(SUT.Any(e => e.Id.Equals(document.Id), PartitionKey), GetTestName()); } [Test] public async Task DeleteOneAsync() { // Arrange var document = CreateTestDocument(); SUT.AddOne(document); // Act var result = await SUT.DeleteOneAsync(document); // Assert Assert.That(result, Is.EqualTo(1)); ClassicAssert.IsFalse(SUT.Any(e => e.Id.Equals(document.Id), PartitionKey), GetTestName()); } [Test] 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.That(result, Is.EqualTo(1)); ClassicAssert.IsFalse(SUT.Any(e => e.Id.Equals(document.Id), PartitionKey), GetTestName()); } [Test] 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.That(result, Is.EqualTo(5)); ClassicAssert.IsFalse(SUT.Any(e => e.SomeContent == criteria, PartitionKey), GetTestName()); } [Test] public async Task DeleteManyAsync() { // Arrange var criteria = $"{GetTestName()}.{DocumentTypeName}"; var documents = CreateTestDocuments(5); documents.ForEach(e => e.SomeContent = criteria); SUT.AddMany(documents); // Act var result = await SUT.DeleteManyAsync(documents); // Assert Assert.That(result, Is.EqualTo(5)); ClassicAssert.IsFalse(SUT.Any(e => e.SomeContent == criteria, PartitionKey), GetTestName()); } [Test] 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.That(result, Is.EqualTo(5)); ClassicAssert.IsFalse(SUT.Any(e => e.SomeContent == criteria, PartitionKey), GetTestName()); } [Test] public void DeleteMany() { // Arrange var criteria = $"{GetTestName()}.{DocumentTypeName}"; var documents = CreateTestDocuments(5); documents.ForEach(e => e.SomeContent = criteria); SUT.AddMany(documents); // Act var result = SUT.DeleteMany(documents); // Assert Assert.That(result, Is.EqualTo(5)); ClassicAssert.IsFalse(SUT.Any(e => e.SomeContent == criteria, PartitionKey), GetTestName()); } #endregion Delete #region Project [Test] 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 ClassicAssert.IsNotNull(result, GetTestName()); Assert.That(result.SomeContent, Is.EqualTo(someContent), GetTestName()); Assert.That(result.SomeDate.Minute, Is.EqualTo(someDate.Minute), GetTestName()); Assert.That(result.SomeDate.Second, Is.EqualTo(someDate.Second), GetTestName()); } [Test] 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 ClassicAssert.IsNotNull(result, GetTestName()); Assert.That(result.SomeContent, Is.EqualTo(someContent), GetTestName()); Assert.That(result.SomeDate.Minute, Is.EqualTo(someDate.Minute), GetTestName()); Assert.That(result.SomeDate.Second, Is.EqualTo(someDate.Second), GetTestName()); } [Test] 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.That(result.Count, Is.EqualTo(5), GetTestName()); Assert.That(result.First().SomeContent, Is.EqualTo(someContent), GetTestName()); Assert.That(result.First().SomeDate.Minute, Is.EqualTo(someDate.Minute), GetTestName()); Assert.That(result.First().SomeDate.Second, Is.EqualTo(someDate.Second), GetTestName()); } [Test] 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.That(result.Count, Is.EqualTo(5), GetTestName()); Assert.That(result.First().SomeContent, Is.EqualTo(someContent), GetTestName()); Assert.That(result.First().SomeDate.Minute, Is.EqualTo(someDate.Minute), GetTestName()); Assert.That(result.First().SomeDate.Second, Is.EqualTo(someDate.Second), GetTestName()); } #endregion Project #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()}"; } #endregion Test Utils } }