Files
monorepo/LCU.API.Internal.Document/LCU.API.Internal.DocumentLibTest/Repositories/DocumentInformationRepositoryTest.cs
T
2026-03-13 09:11:35 -05:00

1230 lines
44 KiB
C#

using FluentAssertions;
using LCU.API.Internal.DocumentLib.Containers;
using LCU.API.Internal.DocumentLib.Repositories;
using LCU.API.Internal.DocumentLibTest.TestDataFactories;
using LCU.API.Internal.DocumentLibTest.TestDoubles;
using LCU.Library.DocumentType.Models.Responses;
using LCU.Library.Internal.DocumentIngestorModels.Models.Pagination;
using LCU.Library.Internal.DocumentModels.Requests.Search;
using MongoDB.Driver;
namespace LCU.API.Internal.DocumentLibTest.Repositories;
public class DocumentInformationRepositoryTest : IDisposable
{
private readonly IDocumentInformationRepository _repository;
private readonly FakeMongoCollectionFactory _collectionFactory = new();
public DocumentInformationRepositoryTest()
{
_repository = new DocumentInformationRepository(_collectionFactory);
}
[SetUp]
public async Task SetUp()
{
var collection = _collectionFactory.GetCollection<DocumentInformation>();
await collection.DeleteManyAsync(Builders<DocumentInformation>.Filter.Empty);
}
[Test]
public async Task GetDocumentInformation_NoMatchingId_ReturnsNull()
{
await SearchableDocumentFactory(d => d.CreatedDate = DateTime.Now.AddDays(1));
var actualDocument = await _repository.GetDocumentInformation(Guid.NewGuid());
Assert.Null(actualDocument);
}
[Test]
public async Task SearchDocumentInformation_NameMatchedExactly_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
Name = document.Name
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_NameNotMatched_DoesNotReturnDocument()
{
await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
Name = Guid.NewGuid().ToString()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_TypeMatchedExactly_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
Type = document.Type
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_TypeNotMatched_DoesNotReturnDocument()
{
await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
Type = Guid.NewGuid().ToString()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_ScanStatusMatchedExactly_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
ScanStatus = document.ScanStatus
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_ScanStatusNotMatched_DoesNotReturnDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
ScanStatus = !document.ScanStatus
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_SourceMatchedExactly_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
Source = document.Source
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_SourceNotMatched_DoesNotReturnDocument()
{
await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
Source = Guid.NewGuid().ToString()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_DataSourceMatchedExactly_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
DataSource = document.DataSource
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_DataSourceNotMatched_DoesNotReturnDocument()
{
await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
DataSource = Guid.NewGuid().ToString()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_TraceIdMatchedExactly_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
TraceId = document.TraceId
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_TraceIdNotMatched_DoesNotReturnDocument()
{
await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
TraceId = Guid.NewGuid()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_PersonNumbersEqualsMatchedExactly_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
PersonNumbersEquals = document.PersonNumbers.FirstOrDefault()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_PersonNumbersEqualsNotMatched_DoesNotReturnDocument()
{
await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
PersonNumbersEquals = Guid.NewGuid().ToString()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_PersonNumbersContainsMatchedExactly_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
PersonNumbersContains = document.PersonNumbers
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_PersonNumbersContainsPartiallyMatched_DoesNotReturnDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
PersonNumbersContains = EnumerableDataSeriesFactory.CreateSeries(() => Guid.NewGuid().ToString(), 5).Concat(document.PersonNumbers).ToArray()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_PersonNumbersContainsNotMatched_DoesNotReturnDocument()
{
await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
PersonNumbersContains = EnumerableDataSeriesFactory.CreateSeries(() => Guid.NewGuid().ToString(), 5).ToArray()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_PersonNumbersContainsAnyMatchedExactly_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
PersonNumbersContainsAny = document.PersonNumbers
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_PersonNumbersContainsAnyPartiallyMatched_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
PersonNumbersContainsAny = EnumerableDataSeriesFactory.CreateSeries(() => Guid.NewGuid().ToString(), 5).Concat(document.PersonNumbers).ToArray()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_PersonNumbersContainsAnyNoneMatched_DoesNotReturnDocument()
{
await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
PersonNumbersContainsAny = EnumerableDataSeriesFactory.CreateSeries(() => Guid.NewGuid().ToString(), 5).ToArray()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_OrganizationNumbersEqualsMatchedExactly_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
OrganizationNumbersEquals = document.OrganizationNumbers.FirstOrDefault()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_OrganizationNumbersEqualsNotMatched_DoesNotReturnDocument()
{
await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
OrganizationNumbersEquals = Guid.NewGuid().ToString()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_OrganizationNumbersContainsMatchedExactly_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
OrganizationNumbersContains = new [] { document.OrganizationNumbers.First() }
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_OrganizationNumbersContainsPartiallyMatched_DoesNotReturnDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
OrganizationNumbersContains = EnumerableDataSeriesFactory.CreateSeries(() => Guid.NewGuid().ToString(), 5).Concat(document.OrganizationNumbers).ToArray()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_OrganizationNumbersContainsNotMatched_DoesNotReturnDocument()
{
await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
OrganizationNumbersContains = EnumerableDataSeriesFactory.CreateSeries(() => Guid.NewGuid().ToString(), 5).ToArray()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_OrganizationNumbersContainsAnyMatchedExactly_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
OrganizationNumbersContainsAny = document.OrganizationNumbers
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_OrganizationNumbersContainsAnyPartiallyMatched_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
OrganizationNumbersContainsAny = EnumerableDataSeriesFactory.CreateSeries(() => Guid.NewGuid().ToString(), 5).Concat(document.OrganizationNumbers).ToArray()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_OrganizationNumbersContainsAnyNoneMatched_DoesNotReturnDocument()
{
await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
OrganizationNumbersContainsAny = EnumerableDataSeriesFactory.CreateSeries(() => Guid.NewGuid().ToString(), 5).ToArray()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_AccountNumberEqualsMatchedExactly_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
AccountNumberEquals = document.AccountNumber
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_AccountNumberEqualsNotMatched_DoesNotReturnDocument()
{
await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
AccountNumberEquals = Guid.NewGuid().ToString()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_AccountNumberContainsAnyNumberInFilter_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
AccountNumberContainsAny = EnumerableDataSeriesFactory.CreateSeries(() => Guid.NewGuid().ToString(), 5).Concat(new[]{ document.AccountNumber }).ToArray()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_AccountNumberContainsAnyNumberNotInFilter_DoesNotReturnDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
AccountNumberContainsAny = EnumerableDataSeriesFactory.CreateSeries(() => Guid.NewGuid().ToString(), 5).Concat(document.OrganizationNumbers).ToArray()
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_AttributesEqualsMatchedExactly_ReturnsDocument()
{
var attribute = Guid.NewGuid().ToString();
var value = Guid.NewGuid().ToString();
var document = await SearchableDocumentFactory(d => d.Attributes[attribute] = value);
var filter = new DocumentInformationFilter
{
AttributesEquals = new Dictionary<string, string>
{
[attribute] = value
}
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_AttributesEqualsNotMatched_DoesNotReturnDocument()
{
var attribute = Guid.NewGuid().ToString();
var value = Guid.NewGuid().ToString();
await SearchableDocumentFactory(d => d.Attributes[attribute] = value);
var filter = new DocumentInformationFilter
{
AttributesEquals = new Dictionary<string, string>
{
[attribute] = Guid.NewGuid().ToString()
}
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_AttributesContainsAndAttributeMatchesExactly_ReturnsDocument()
{
var attribute = Guid.NewGuid().ToString();
var value = Guid.NewGuid().ToString();
var document = await SearchableDocumentFactory(d => d.Attributes[attribute] = value);
var filter = new DocumentInformationFilter
{
AttributesContains = new Dictionary<string, string>
{
[attribute] = value
}
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_AttributesContainsAndAttributeMatchesDifferentCase_ReturnsDocument()
{
var attribute = Guid.NewGuid().ToString();
var value = Guid.NewGuid().ToString();
var document = await SearchableDocumentFactory(d => d.Attributes[attribute] = value);
var filter = new DocumentInformationFilter
{
AttributesContains = new Dictionary<string, string>
{
[attribute] = value.ToLower()
}
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_AttributesContainsAndAttributeMatchesOnWordBoundary_ReturnsDocument()
{
var attribute = Guid.NewGuid().ToString();
var value = Guid.NewGuid().ToString();
var document = await SearchableDocumentFactory(d => d.Attributes[attribute] = $"{Guid.NewGuid()} {value},{Guid.NewGuid()}");
var filter = new DocumentInformationFilter
{
AttributesContains = new Dictionary<string, string>
{
[attribute] = value
}
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_AttributesContainsAndAttributeMatchesWithinAnotherWord_DoesNotReturnDocument()
{
var attribute = Guid.NewGuid().ToString();
var value = Guid.NewGuid().ToString();
await SearchableDocumentFactory(d => d.Attributes[attribute] = $"{Guid.NewGuid()}{value}{Guid.NewGuid()}");
var filter = new DocumentInformationFilter
{
AttributesContains = new Dictionary<string, string>
{
[attribute] = value
}
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_AttributeContainsAnyAttributeMatchesExactlyOne_ReturnsDocument()
{
var attribute = Guid.NewGuid().ToString();
var value = Guid.NewGuid().ToString();
var document = await SearchableDocumentFactory(d => d.Attributes[attribute] = value);
var filter = new DocumentInformationFilter
{
AttributesContainsAny = new Dictionary<string, string>
{
[attribute] = $"{Guid.NewGuid()},{value},{Guid.NewGuid()}"
}
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_AttributeContainsAnyAttributeMatchesOneDifferentCase_ReturnsDocument()
{
var attribute = Guid.NewGuid().ToString();
var value = Guid.NewGuid().ToString();
var document = await SearchableDocumentFactory(d => d.Attributes[attribute] = value);
var filter = new DocumentInformationFilter
{
AttributesContainsAny = new Dictionary<string, string>
{
[attribute] = $"{Guid.NewGuid()},{value.ToLower()},{Guid.NewGuid()}"
}
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_AttributeContainsAnyAttributeMatchesNone_DoesNotReturnDocument()
{
var attribute = Guid.NewGuid().ToString();
var value = Guid.NewGuid().ToString();
await SearchableDocumentFactory(d => d.Attributes[attribute] = value);
var filter = new DocumentInformationFilter
{
AttributesContainsAny = new Dictionary<string, string>
{
[attribute] = $"{Guid.NewGuid()},{Guid.NewGuid()},{Guid.NewGuid()}"
}
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_AttributesContainsMatchAndAttributeContainsAnyMatch_ReturnsDocument()
{
var attributeContains = Guid.NewGuid().ToString();
var attributeContainsAny = Guid.NewGuid().ToString();
var value = Guid.NewGuid().ToString();
var document = await SearchableDocumentFactory(d =>
{
d.Attributes[attributeContains] = $"{Guid.NewGuid()},{value},{Guid.NewGuid()}";
d.Attributes[attributeContainsAny] = value;
});
var filter = new DocumentInformationFilter
{
AttributesContains = new Dictionary<string, string>
{
[attributeContains] = value
},
AttributesContainsAny = new Dictionary<string, string>
{
[attributeContainsAny] = $"{Guid.NewGuid()},{value},{Guid.NewGuid()}"
}
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_AttributesContainsMatchAndAttributeContainsAnyNotMatched_DoesNotReturnDocument()
{
var attributeContains = Guid.NewGuid().ToString();
var attributeContainsAny = Guid.NewGuid().ToString();
var value = Guid.NewGuid().ToString();
await SearchableDocumentFactory(d =>
{
d.Attributes[attributeContains] = $"{Guid.NewGuid()},{value},{Guid.NewGuid()}";
d.Attributes[attributeContainsAny] = value;
});
var filter = new DocumentInformationFilter
{
AttributesContains = new Dictionary<string, string>
{
[attributeContains] = value
},
AttributesContainsAny = new Dictionary<string, string>
{
[attributeContainsAny] = $"{Guid.NewGuid()},{Guid.NewGuid()},{Guid.NewGuid()}"
}
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_AttributesContainsNotMatchedAndAttributeContainsAnyMatch_DoesNotReturnDocument()
{
var attributeContains = Guid.NewGuid().ToString();
var attributeContainsAny = Guid.NewGuid().ToString();
var value = Guid.NewGuid().ToString();
await SearchableDocumentFactory(d =>
{
d.Attributes[attributeContains] = $"{Guid.NewGuid()},{value},{Guid.NewGuid()}";
d.Attributes[attributeContainsAny] = value;
});
var filter = new DocumentInformationFilter
{
AttributesContains = new Dictionary<string, string>
{
[attributeContains] = Guid.NewGuid().ToString()
},
AttributesContainsAny = new Dictionary<string, string>
{
[attributeContainsAny] = $"{Guid.NewGuid()},{value},{Guid.NewGuid()}"
}
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_CreatedDateMinimumLessThanCreatedDate_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
CreatedDateMinimum = document.CreatedDate.AddDays(-1)
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_CreatedDateMinimumGreaterThanCreatedDate_DoesNotReturnDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
CreatedDateMinimum = document.CreatedDate.AddDays(1)
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_CreatedDateMaximumGreaterThanCreatedDate_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
CreatedDateMaximum = document.CreatedDate.AddDays(1)
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_CreatedDateMaximumLessThanCreatedDate_DoesNotReturnDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
CreatedDateMaximum = document.CreatedDate.AddDays(-1)
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_UploadDateMinimumLessThanCreatedDate_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
UploadDateMinimum = document.CreatedDate.AddDays(-1)
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_UploadDateMinimumGreaterThanCreatedDate_DoesNotReturnDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
UploadDateMinimum = document.CreatedDate.AddDays(1)
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_UploadDateMaximumGreaterThanCreatedDate_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
UploadDateMaximum = document.CreatedDate.AddDays(1)
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_UploadDateMaximumLessThanCreatedDate_DoesNotReturnDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
UploadDateMaximum = document.CreatedDate.AddDays(-1)
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_LastModifiedMinimumLessThanCreatedDate_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
LastModifiedMinimum = document.CreatedDate.AddDays(-1)
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_LastModifiedMinimumGreaterThanCreatedDate_DoesNotReturnDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
LastModifiedMinimum = document.CreatedDate.AddDays(1)
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_LastModifiedDateMaximumGreaterThanCreatedDate_ReturnsDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
LastModifiedDateMaximum = document.CreatedDate.AddDays(1)
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(1, documents.Count);
documents.Single().Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task SearchDocumentInformation_LastModifiedMaximumLessThanCreatedDate_DoesNotReturnDocument()
{
var document = await SearchableDocumentFactory();
var filter = new DocumentInformationFilter
{
LastModifiedDateMaximum = document.CreatedDate.AddDays(-1)
};
var documents = await _repository.SearchDocumentInformation(filter);
Assert.AreEqual(0, documents.Count);
}
[Test]
public async Task SearchDocumentInformation_Skip_BypassesTheSkippedDocuments()
{
const int skip = 5;
var documents = await Task.WhenAll(EnumerableDataSeriesFactory.CreateSeries(async () => await SearchableDocumentFactory(), skip * 2));
var filter = new DocumentInformationFilter { AccountNumberContainsAny = documents.Select(d => d.AccountNumber).ToArray() };
var searchResult = await _repository.SearchDocumentInformation(filter, skip);
searchResult.Should().HaveSameCount(documents[skip..]);
searchResult.Should().AllSatisfy(r => documents.Should().ContainEquivalentOf(r, d => d.Using(DateTimeComparison.Truncated)));
}
[Test]
public async Task SearchDocumentInformation_Take_OnlyReturnsThatManyDocuments()
{
const int take = 5;
var documents = await Task.WhenAll(EnumerableDataSeriesFactory.CreateSeries(async () => await SearchableDocumentFactory(), take * 2));
var filter = new DocumentInformationFilter { AccountNumberContainsAny = documents.Select(d => d.AccountNumber).ToArray() };
var searchResult = await _repository.SearchDocumentInformation(filter, null, take);
searchResult.Should().HaveCount(take);
searchResult.Should().AllSatisfy(r => documents.Should().ContainEquivalentOf(r, d => d.Using(DateTimeComparison.Truncated)));
}
[Test]
public async Task GetDocumentInformationByBlobId_NoMatchingId_ReturnsNull()
{
await SearchableDocumentFactory();
var actualDocument = await _repository.GetDocumentInformationByBlobId(Guid.NewGuid());
Assert.Null(actualDocument);
}
[Test]
public async Task SaveDocumentInformation_AllCases_InsertsDocumentAndReturnsIt()
{
var document = DocumentInformationFactory.CreateDocumentInformation();
var inserted = await _repository.SaveDocumentInformation(document);
inserted.Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
var found = (await
(await _collectionFactory
.GetCollection<DocumentInformation>()
.FindAsync(d => d.DocumentId == document.DocumentId))
.ToListAsync()
).SingleOrDefault();
inserted.Should().BeEquivalentTo(found, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task UpdateDocumentInformation_DocumentDoesNotExist_ThrowsException()
{
var id = Guid.NewGuid();
var document = DocumentInformationFactory.CreateDocumentInformation();
await _repository.UpdateDocumentInformation(id, document);
var found = await _collectionFactory
.GetCollection<DocumentInformation>()
.CountDocumentsAsync(d => d.DocumentId == id);
Assert.AreEqual(0, found);
}
[Test]
public async Task UpdateDocumentInformation_DocumentExists_FullyReplacesWithNewAndReturnsNew()
{
var existingDocument = await SearchableDocumentFactory();
var updatedDocument = DocumentInformationFactory.CreateDocumentInformation();
updatedDocument.DocumentId = existingDocument.DocumentId;
var updated = await _repository.UpdateDocumentInformation(existingDocument.DocumentId, updatedDocument);
updated.Should().BeEquivalentTo(updatedDocument, d => d.Using(DateTimeComparison.Truncated));
var found = (await
(await _collectionFactory
.GetCollection<DocumentInformation>()
.FindAsync(d => d.DocumentId == existingDocument.DocumentId))
.ToListAsync()
).SingleOrDefault();
updated.Should().BeEquivalentTo(found, d => d.Using(DateTimeComparison.Truncated));
}
[Test]
public async Task RemoveDocumentInformation_DocumentDoesNotExist_ReturnsNull()
{
var removed = await _repository.RemoveDocumentInformation(Guid.NewGuid());
Assert.IsNull(removed);
}
[Test]
public async Task RemoveDocumentInformation_DocumentExists_DeletesAndReturnsDeleted()
{
var document = await SearchableDocumentFactory();
var removed = await _repository.RemoveDocumentInformation(document.DocumentId);
removed.Should().BeEquivalentTo(document, d => d.Using(DateTimeComparison.Truncated));
var found = await _collectionFactory
.GetCollection<DocumentInformation>()
.CountDocumentsAsync(d => d.DocumentId == document.DocumentId);
Assert.AreEqual(0, found);
}
[Test]
public async Task SearchDocumentInformation_SortsDocumentsWithOneSort()
{
var numberOfDocuments = 25;
var documents = await SearchableMultiDocumentFactory(numberOfDocuments);
// Using UploadDate as CreatedDate has AddDays(i % 3) to create duplicates.
// If sorted by just CreatedDate, the order may be different when it is pulled from the collection causing the test to fail
var sort = new List<SortableField>
{
new()
{
Field = "UploadDate",
Position = 0,
IsDescending = true
}
};
// Sort descending on upload date
documents.Sort((a, b) => b.UploadDate.CompareTo(a.UploadDate));
var searchResult = await _repository.SearchDocumentInformation(new DocumentInformationFilter(), null, numberOfDocuments, sort);
documents.Should().BeInDescendingOrder(a => a.UploadDate);
searchResult.Should().BeInDescendingOrder(a => a.UploadDate);
searchResult.Should().BeEquivalentTo(documents, d => d.Using(DateTimeComparison.Truncated).WithStrictOrdering());
}
[Test]
public async Task SearchDocumentInformation_SortsDocumentsWithMultipleSortsAndMaintainsPositionOrder()
{
var numberOfDocuments = 25;
var documents = await SearchableMultiDocumentFactory(numberOfDocuments);
var sort = new List<SortableField>
{
new()
{
Field = "Name",
Position = 2,
IsDescending = false
},
new()
{
Field = "CreatedDate",
Position = 0,
IsDescending = false
},
new()
{
Field = "UploadDate",
Position = 1,
IsDescending = false
}
};
// Sort ascending on created date, then ascending on upload date, then ascending on name
documents = documents.OrderBy(x => x.CreatedDate).ThenBy(x => x.UploadDate).ThenBy(x => x.Name).ToList();
var searchResult = await _repository.SearchDocumentInformation(new DocumentInformationFilter(), null, numberOfDocuments, sort);
searchResult.Should().BeEquivalentTo(documents, d => d.Using(DateTimeComparison.Truncated).WithStrictOrdering());
}
[Test]
public async Task GetDocumentsForCleanup_Success()
{
var documents = new List<DocumentInformation>();
for (var i=0; i < 3; i++)
{
var document = DocumentInformationFactory.CreateDocumentInformation();
document.CreatedDate = document.CreatedDate.AddMonths(i % 3 * -1);
document.UploadDate = document.UploadDate.AddDays(i);
documents.Add(document);
}
documents[1].DocumentBlobId = null;
documents = await SearchableMultiDocumentFactory(documents);
var request = new GetDocumentCleanupRequest
{
DocumentCodeDetailInfos = new List<DocumentCodeDetailsResponse>
{
new()
{
DocumentCode = documents[0].Type,
InternalRetentionMonths = 3
},
new()
{
DocumentCode = documents[1].Type,
InternalRetentionMonths = 1
},
new()
{
DocumentCode = documents[2].Type,
InternalRetentionMonths = 1
}
},
Limit = 10
};
var expectedResults = documents.Where(document =>
{
var docCodeDetail = request.DocumentCodeDetailInfos
.FirstOrDefault(docCodeDetail => document.Type == docCodeDetail.DocumentCode);
return DateTime.Now >= document.CreatedDate.AddMonths(docCodeDetail!.InternalRetentionMonths)
&& document.DocumentBlobId is not null;
}).Select(document => document.DocumentId).ToList();
var result = await _repository.GetDocumentsForCleanup(request);
result.Should().BeEquivalentTo(expectedResults);
}
[Test]
public async Task GetDocumentsForCleanup_Success_NoDocumentsFound()
{
var request = new GetDocumentCleanupRequest
{
DocumentCodeDetailInfos = new List<DocumentCodeDetailsResponse>
{
new()
{
DocumentCode = Guid.NewGuid().ToString(),
InternalRetentionMonths = 3
}
},
Limit = 10
};
var result = await _repository.GetDocumentsForCleanup(request);
Assert.IsEmpty(result);
}
private async Task<DocumentInformation> SearchableDocumentFactory(Action<DocumentInformation>? documentSetup = null)
{
var document = DocumentInformationFactory.CreateDocumentInformation();
documentSetup?.Invoke(document);
var collection = _collectionFactory.GetCollection<DocumentInformation>();
await collection.InsertOneAsync(document);
return document;
}
private async Task<List<DocumentInformation>> SearchableMultiDocumentFactory(int numberOfDocuments = 10, Action<DocumentInformation>? documentSetup = null)
{
var documents = new List<DocumentInformation>();
for(var i = 0; i < numberOfDocuments; i++)
{
var document = DocumentInformationFactory.CreateDocumentInformation();
document.CreatedDate = document.CreatedDate.AddMonths(i % 3 * -1);
document.UploadDate = document.UploadDate.AddDays(i);
documentSetup?.Invoke(document);
documents.Add(document);
}
var collection = _collectionFactory.GetCollection<DocumentInformation>();
await collection.InsertManyAsync(documents);
return documents;
}
private async Task<List<DocumentInformation>> SearchableMultiDocumentFactory(List<DocumentInformation> documents)
{
var collection = _collectionFactory.GetCollection<DocumentInformation>();
await collection.InsertManyAsync(documents);
return documents;
}
public void Dispose()
{
_collectionFactory.Dispose();
}
}