Files
2026-04-07 14:21:04 -05:00

177 lines
7.9 KiB
C#

using LCU.API.Internal.LoanRate.Services;
using LCU.API.Internal.LoanRate.Services.LoanRateOperationServices;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.LcuClassPatterns.CrudTests.Utilities;
using LCU.Library.Internal.LoanRateModels.Entities;
using LCU.Library.Internal.LoanRateModels.Responses.Validation;
using LCU.Library.Internal.LoanRateModels.Responses.Validation.RateSheetValidations;
using LCU.Library.Internal.TypeExtensions.ObjectExtensions;
namespace LCU.API.Internal.LoanRateTests.ServiceTests.LoanRateOperationServicesTests;
public class RateValidationServiceTest
{
private readonly RateValidationService _rateValidationService;
private readonly Mock<IRateService> _mockRateService;
public RateValidationServiceTest()
{
_mockRateService = new Mock<IRateService>();
_rateValidationService = new RateValidationService(_mockRateService.Object);
}
[Fact]
public async Task RateValidation_ValidateAsync_Success_AllPass()
{
var rates = FakeRates();
foreach (var rate in rates)
{
var originalRate = FakeNewRate(rate, decimal.ToInt32(rate.Value - new Random().Next(0, 10)), decimal.ToInt32(rate.Value));
var rateHistory = FakeRateHistory(rate,
originalRate,
decimal.ToInt32(rate.Value - new Random().Next(0, 10)),
decimal.ToInt32(rate.Value + new Random().Next(0, 10)));
_mockRateService.Setup(x => x.GetRateHistory(It.IsAny<Rate>())).ReturnsAsync(rateHistory);
_mockRateService.Setup(x => x.GetByIdAsync(It.IsAny<int>())).ReturnsAsync(originalRate);
}
var result = await _rateValidationService.ValidateAsync(rates);
Assert.NotNull(result);
Assert.True(result.All(x => x.Pass));
Assert.True(result.All(x => x.Validations.Count > 0));
_mockRateService.Verify(x => x.GetRateHistory(It.IsAny<Rate>()), Times.Exactly(rates.Count));
_mockRateService.Verify(x => x.GetByIdAsync(It.IsAny<int>()), Times.Exactly(rates.Count));
}
[Fact]
public async Task RateValidation_ValidateAsync_Success_DoesNotPassRange()
{
var rates = FakeRates();
foreach (var rate in rates)
{
var originalRate = FakeNewRate(rate, decimal.ToInt32(rate.Value - new Random().Next(0, 10)), decimal.ToInt32(rate.Value));
var rateHistory = FakeRateHistory(rate,
originalRate,
decimal.ToInt32(rate.Value - new Random().Next(0, 10)),
decimal.ToInt32(rate.Value + new Random().Next(0, 10)));
originalRate.Value += 100;
rate.Value += 100;
_mockRateService.Setup(x => x.GetRateHistory(It.IsAny<Rate>())).ReturnsAsync(rateHistory);
_mockRateService.Setup(x => x.GetByIdAsync(It.IsAny<int>())).ReturnsAsync(originalRate);
}
var result = await _rateValidationService.ValidateAsync(rates);
Assert.NotNull(result);
Assert.False(result.All(x => x.Pass));
Assert.True(result.All(x => x.Validations.Count > 0));
Assert.True(result.All(x => x.Validations.First(y => y.RateSheetValidationType == RateSheetValidationTypes.IsWithinTrendRange).Pass));
Assert.False(result.All(x => x.Validations.First(y => y.RateSheetValidationType == RateSheetValidationTypes.IsWithinRange).Pass));
_mockRateService.Verify(x => x.GetRateHistory(It.IsAny<Rate>()), Times.Exactly(rates.Count));
_mockRateService.Verify(x => x.GetByIdAsync(It.IsAny<int>()), Times.Exactly(rates.Count));
}
[Fact]
public async Task RateValidation_ValidateAsync_Success_DoesNotPassTrend()
{
var rates = FakeRates();
foreach (var rate in rates)
{
var originalRate = FakeNewRate(rate, decimal.ToInt32(rate.Value - new Random().Next(0, 10)), decimal.ToInt32(rate.Value));
var rateHistory = FakeRateHistory(rate,
originalRate,
decimal.ToInt32(rate.Value - new Random().Next(0, 10)),
decimal.ToInt32(rate.Value + new Random().Next(0, 10)));
rateHistory.First().Value += 100;
_mockRateService.Setup(x => x.GetRateHistory(It.IsAny<Rate>())).ReturnsAsync(rateHistory);
_mockRateService.Setup(x => x.GetByIdAsync(It.IsAny<int>())).ReturnsAsync(originalRate);
}
var result = await _rateValidationService.ValidateAsync(rates);
Assert.NotNull(result);
Assert.False(result.All(x => x.Pass));
Assert.True(result.All(x => x.Validations.Count > 0));
Assert.False(result.All(x => x.Validations.First(y => y.RateSheetValidationType == RateSheetValidationTypes.IsWithinTrendRange).Pass));
Assert.True(result.All(x => x.Validations.First(y => y.RateSheetValidationType == RateSheetValidationTypes.IsWithinRange).Pass));
_mockRateService.Verify(x => x.GetRateHistory(It.IsAny<Rate>()), Times.Exactly(rates.Count));
_mockRateService.Verify(x => x.GetByIdAsync(It.IsAny<int>()), Times.Exactly(rates.Count));
}
[Fact]
public async Task RateValidation_ValidateAsync_ThrowsException()
{
var rates = FakeRates();
_mockRateService.Setup(x => x.GetRateHistory(rates[0])).Throws(new Exception("Test")).Verifiable();
await Assert.ThrowsAsync<ServiceException>(async () => await _rateValidationService.ValidateAsync(rates));
_mockRateService.Verify(x => x.GetRateHistory(It.IsAny<Rate>()), Times.Once);
_mockRateService.Verify(x => x.GetByIdAsync(It.IsAny<int>()), Times.Never);
}
private List<Rate> FakeRates(int count = 3)
{
var rates = new List<Rate>();
for (var i = 0; i < count; i++)
{
var startDate = (DateTime)typeof(DateTime).GetRandomValue();
rates.Add(new Rate
{
RateId = (int)typeof(int).GetRandomValue(),
Value = new Random().Next(20, 30),
Row = (string)typeof(string).GetRandomValue(),
Column = (string)typeof(string).GetRandomValue(),
RateStartDate = startDate,
RateEndDate = startDate.AddDays(10),
RateSheetId = (int)typeof(int).GetRandomValue()
});
}
return rates;
}
private Rate FakeNewRate(Rate rate, int minValue = int.MinValue, int maxValue = int.MaxValue)
{
var newRate = rate.DeepCopy();
newRate.RateId = (int)typeof(int).GetRandomValue();
newRate.Value = new Random().Next(minValue, maxValue);
return newRate;
}
private List<Rate> FakeRateHistory(Rate rate, Rate originalRate, int minValue = int.MinValue, int maxValue = int.MaxValue)
{
var rates = new List<Rate>
{
FakeNewRate(rate, minValue, decimal.ToInt32(rate.Value)),
FakeNewRate(rate, minValue, maxValue),
FakeNewRate(rate, decimal.ToInt32(rate.Value), maxValue)
};
var trend = Math.Round(rate.Value / originalRate.Value, 2);
rates[0].RateStartDate = rate.RateStartDate.AddDays(-30);
rates[0].RateEndDate = rate.RateStartDate.AddDays(-20);
rates[1].RateStartDate = rate.RateStartDate.AddDays(-20);
rates[1].RateEndDate = rate.RateStartDate.AddDays(-10);
rates[1].Value = Math.Round(rates[0].Value * (trend + 1), 2);
rates[2].RateStartDate = rate.RateStartDate.AddDays(-10);
rates[2].RateEndDate = rate.RateStartDate;
rates[2].Value = Math.Round(rates[1].Value * (trend - 1), 2);
return rates;
}
}