Files
2026-04-20 14:47:24 -05:00

372 lines
19 KiB
C#

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LCU.API.Collections.RepoApi.DataAccess;
using LCU.API.Collections.RepoApi.Domain;
using LCU.API.Collections.RepoApi.Domain.Extensions;
using LCU.API.Collections.RepoApi.Exceptions;
using LCU.API.Collections.RepoApi.Models;
using LCU.API.Collections.RepoApi.Services;
using LCU.API.Collections.RepoApi.Services.Producer;
using LCU.API.Collections.RepoApiTests.Domain;
using LCU.Shared.Collections.RepoApiLib.Models;
using LCU.Shared.Collections.RepoApiLib.Models.Producer;
using LCU.Shared.Collections.RepoApiLib.Models.Settings;
using Moq;
using Xunit;
namespace LCU.API.Collections.RepoApiTests.Services.Processor
{
public class RepoAccountProcessorIntegrationTest
{
private readonly RepoAccountProcessor _repoAccountProcessor;
private readonly IRepoAccountProcessorService _repoAccountProcessorService;
private readonly Mock<IAccountAlertCheckService> _mockAccountAlertCheckService;
private readonly Mock<ISettingsService> _mockSettingsService;
private readonly Mock<IRepoAccountService> _mockRepoAccountService;
private readonly Mock<ICollectionsDao> _mockCollectionsDao;
private readonly Mock<ICoreDao> _mockCoreDao;
private readonly Mock<IRepoLetterService> _mockRepoLetterService;
private readonly Mock<IEmailer> _mockEmailer;
private readonly Mock<IAuctionAssignmentService> _mockAuctionAssignmentService;
private readonly Mock<IEventAlertService> _mockEventAlertService;
private readonly Mock<IRepoCompanySelectionService> _mockRepoCompanySelectionService;
public RepoAccountProcessorIntegrationTest()
{
_mockAccountAlertCheckService = new Mock<IAccountAlertCheckService>();
_mockSettingsService = new Mock<ISettingsService>();
_mockRepoAccountService = new Mock<IRepoAccountService>();
_mockCollectionsDao = new Mock<ICollectionsDao>();
_mockCoreDao = new Mock<ICoreDao>();
_mockEmailer = new Mock<IEmailer>();
_mockAuctionAssignmentService = new Mock<IAuctionAssignmentService>();
_mockRepoLetterService = new Mock<IRepoLetterService>();
_mockEventAlertService = new Mock<IEventAlertService>();
_mockRepoCompanySelectionService = new Mock<IRepoCompanySelectionService>();
var repoSettings = DbContextFromJson.GetTestObjectFromFile<Settings>("Services/Processor/repoSettings.json");
_mockSettingsService.Setup(x => x.GetCachedRepoSettingsAsync()).ReturnsAsync(repoSettings);
_repoAccountProcessorService = new RepoAccountProcessorService( _mockCoreDao.Object,
new RedemptionExpiredDateCalculator(), _mockAccountAlertCheckService.Object,
_mockEventAlertService.Object, _mockRepoCompanySelectionService.Object);
_repoAccountProcessor = new RepoAccountProcessor(
_repoAccountProcessorService, _mockAccountAlertCheckService.Object, _mockCollectionsDao.Object,
_mockEmailer.Object, _mockSettingsService.Object, _mockRepoAccountService.Object,
_mockRepoLetterService.Object, _mockCoreDao.Object, _mockAuctionAssignmentService.Object);
// _mockRepoAccountProcessorService.Setup(mock => mock.TryUpdateCollateralRetitleDate(It.IsAny<RepoAccount>(), It.IsAny<TemenosCase>()));
}
[Fact]
public async Task Basic_Construct_Test()
{
Assert.NotNull(_repoAccountProcessor);
await Assert.ThrowsAsync<IneligibleAccountException>(() => { return _repoAccountProcessor.HandleAccount(null); });
}
/**
* Use this test to make more tests when things go wrong, you can dump raw JSON files from the sources into the test
* and make sure you get expected results. Remember to remove member's PII.
*/
[Fact]
public async Task Should_Create_Account()
{
var testInput = DbContextFromJson.GetTestObjectFromFile<ProcessorTestInput>("Services/Processor/newAccount.json");
Assert.NotNull(testInput);
_mockCollectionsDao.Setup(cd => cd.RetrieveAccountAsync(It.IsAny<string>())).ReturnsAsync(testInput.TemenosAccount);
_mockRepoAccountService.Setup(ras => ras.GetNewestOpenAccount(It.IsAny<string>()))
.ReturnsAsync((RepoAccount) null);
_mockCoreDao.Setup(cd => cd.RetrieveLoanAsync(It.IsAny<string>())).ReturnsAsync(testInput.LoanDetail);
_mockCoreDao.Setup(cd => cd.RetrieveMemberAsync(It.IsAny<string>())).ReturnsAsync(testInput.MemberDetail);
_mockCoreDao.Setup(cd => cd.RetrieveTransactionsAsync(It.IsAny<string>())).ReturnsAsync(testInput.CoreTransactions);
_mockCoreDao.Setup(cd => cd.RetrieveCollateralAsync(It.IsAny<string>())).ReturnsAsync(testInput.CollateralDetails);
_mockRepoLetterService.Setup(x => x.ListByAccountIdAsync(It.IsAny<int>())).ReturnsAsync(
RepoLetterService.ProcessLetters(testInput.TemenosHistory, testInput.RepoLetters));
_mockAuctionAssignmentService.Setup(x => x.GetListByIdsAsync(It.IsAny<IReadOnlyCollection<int>>()))
.ReturnsAsync(new List<AuctionAssignment>());
var result = await _repoAccountProcessor.HandleAccount(new ProcessingItem()
{
AccountNo = "6466120143"
});
Assert.Equal(RepoProcessingResult.Created, result);
}
[Fact]
public void Should_Select_Correct_Case()
{
/**
* Given an account with three cases, choose the correct one:
* 1. Wrong case type
* 2. Ineligible case stage (repoStatus)
* 3. Eligible case with valid stage/status.
*/
var testInput = DbContextFromJson.GetTestObjectFromFile<ProcessorTestInput>("Services/Processor/selectCorrectCase.json");
Assert.NotNull(testInput);
var selectedCase = testInput.TemenosAccount.FindRecoveryCaseOrDefault(0);
Assert.Equal( 342, selectedCase.CaseId);
selectedCase = testInput.TemenosAccount.FindRecoveryCaseOrDefault(25);
Assert.Equal( 25, selectedCase.CaseId);
}
[Fact]
public async Task Should_Not_Create_Ineligible_Account_Temenos_Event()
{
// Temenos Events will specify a case id.
var testInput = DbContextFromJson.GetTestObjectFromFile<ProcessorTestInput>("Services/Processor/ineligibleAccount.json");
Assert.NotNull(testInput);
_mockCollectionsDao.Setup(cd => cd.RetrieveAccountAsync(It.IsAny<string>())).ReturnsAsync(testInput.TemenosAccount);
_mockRepoAccountService.Setup(ras => ras.GetNewestOpenAccount(It.IsAny<string>()))
.ReturnsAsync((RepoAccount) null);
_mockCoreDao.Setup(cd => cd.RetrieveLoanAsync(It.IsAny<string>())).ReturnsAsync(testInput.LoanDetail);
_mockCoreDao.Setup(cd => cd.RetrieveMemberAsync(It.IsAny<string>())).ReturnsAsync(testInput.MemberDetail);
_mockCoreDao.Setup(cd => cd.RetrieveTransactionsAsync(It.IsAny<string>())).ReturnsAsync(testInput.CoreTransactions);
_mockCoreDao.Setup(cd => cd.RetrieveCollateralAsync(It.IsAny<string>())).ReturnsAsync(testInput.CollateralDetails);
_mockRepoLetterService.Setup(x => x.ListByAccountIdAsync(It.IsAny<int>())).ReturnsAsync(
RepoLetterService.ProcessLetters(testInput.TemenosHistory, testInput.RepoLetters));
_mockAuctionAssignmentService.Setup(x => x.GetListByIdsAsync(It.IsAny<IReadOnlyCollection<int>>()))
.ReturnsAsync(new List<AuctionAssignment>());
var result = await _repoAccountProcessor.HandleAccount(new ProcessingItem()
{
AccountNo = "6466120143",
CaseId = "306"
});
Assert.Equal(RepoProcessingResult.Ineligible, result);
}
[Fact]
public async Task Should_Update_Retitled_And_Redemption_Expired_Account()
{
RepoAccount resultAccount = null;
var testInput = DbContextFromJson.GetTestObjectFromFile<ProcessorTestInput>("Services/Processor/update-retitle-redemption-exp.json");
Assert.NotNull(testInput);
_mockCollectionsDao.Setup(cd => cd.RetrieveAccountAsync(It.IsAny<string>())).ReturnsAsync(testInput.TemenosAccount);
_mockRepoAccountService.Setup(ras => ras.GetNewestOpenAccount(It.IsAny<string>()))
.ReturnsAsync(testInput.RepoAccount);
_mockRepoAccountService.Setup(x => x.UpdateAsync(It.IsAny<RepoAccount>(), It.IsAny<AppUser>()))
.ReturnsAsync((RepoAccount inAccount, AppUser inUser) => {
resultAccount = inAccount;
return inAccount;
});
_mockCoreDao.Setup(cd => cd.RetrieveLoanAsync(It.IsAny<string>())).ReturnsAsync(testInput.LoanDetail);
_mockCoreDao.Setup(cd => cd.RetrieveMemberAsync(It.IsAny<string>())).ReturnsAsync(testInput.MemberDetail);
_mockCoreDao.Setup(cd => cd.RetrieveTransactionsAsync(It.IsAny<string>())).ReturnsAsync(testInput.CoreTransactions);
_mockRepoLetterService.Setup(x => x.ListByAccountIdAsync(It.IsAny<int>())).ReturnsAsync(
RepoLetterService.ProcessLetters(testInput.TemenosHistory, testInput.RepoLetters));
_mockAuctionAssignmentService.Setup(x => x.GetListByIdsAsync(It.IsAny<IReadOnlyCollection<int>>()))
.ReturnsAsync(new List<AuctionAssignment>());
// Pre-Assert.
Assert.Null(resultAccount);
Assert.Null(testInput.RepoAccount.RedemptionExpiredDate);
Assert.NotNull(testInput.TemenosAccount.Cases.First().RedemptionExpiredDateWi);
var existingSelections = testInput.RepoAccount.Collaterals.First();
Assert.Null(existingSelections.RetitledInLandmarkName);
Assert.NotEmpty(existingSelections.RepoCompanySelections);
Assert.Collection(existingSelections.RepoCompanySelections,
item =>
{
Assert.Equal(5, item.RepoCompanyId);
Assert.NotNull(item.DateRepoed);
});
// Run
var result = await _repoAccountProcessor.HandleAccount(new ProcessingItem()
{
AccountNo = "7584700143"
});
// Post-Assert
Assert.Equal(RepoProcessingResult.Updated, result);
Assert.NotNull(resultAccount);
Assert.NotNull(resultAccount.RedemptionExpiredDate);
var newSelections = resultAccount.Collaterals.First();
Assert.NotNull(newSelections.RetitledInLandmarkName);
Assert.Collection(newSelections.RepoCompanySelections,
item =>
{
Assert.Equal(5, item.RepoCompanyId);
Assert.NotNull(item.DateRepoed);
}
);
}
[Fact]
public async Task Should_Update_WrittenOff_And_RepoSelection_Account()
{
RepoAccount resultAccount = null;
var testInput = DbContextFromJson.GetTestObjectFromFile<ProcessorTestInput>("Services/Processor/written-off-account.json");
Assert.NotNull(testInput);
_mockCollectionsDao.Setup(cd => cd.RetrieveAccountAsync(It.IsAny<string>())).ReturnsAsync(testInput.TemenosAccount);
_mockRepoAccountService.Setup(ras => ras.GetNewestOpenAccount(It.IsAny<string>()))
.ReturnsAsync(testInput.RepoAccount);
_mockRepoAccountService.Setup(x => x.UpdateAsync(It.IsAny<RepoAccount>(), It.IsAny<AppUser>()))
.ReturnsAsync((RepoAccount inAccount, AppUser inUser) => {
resultAccount = inAccount;
return inAccount;
});
_mockCoreDao.Setup(cd => cd.RetrieveLoanAsync(It.IsAny<string>())).ReturnsAsync(testInput.LoanDetail);
_mockCoreDao.Setup(cd => cd.RetrieveMemberAsync(It.IsAny<string>())).ReturnsAsync(testInput.MemberDetail);
_mockCoreDao.Setup(cd => cd.RetrieveTransactionsAsync(It.IsAny<string>())).ReturnsAsync(testInput.CoreTransactions);
_mockRepoLetterService.Setup(x => x.ListByAccountIdAsync(It.IsAny<int>())).ReturnsAsync(
RepoLetterService.ProcessLetters(testInput.TemenosHistory, testInput.RepoLetters));
_mockAuctionAssignmentService.Setup(x => x.GetListByIdsAsync(It.IsAny<IReadOnlyCollection<int>>()))
.ReturnsAsync(new List<AuctionAssignment>());
// Pre-Assert.
Assert.Null(resultAccount);
Assert.Null(testInput.RepoAccount.ReferenceStatus);
Assert.Null(testInput.RepoAccount.WrittenOffDate);
var existingSelections = testInput.RepoAccount.Collaterals.First();
Assert.NotEmpty(existingSelections.RepoCompanySelections);
Assert.Collection(existingSelections.RepoCompanySelections,
item =>
{
Assert.Equal(4, item.RepoCompanyId);
Assert.Null(item.DateRepoed);
},
item =>
{
Assert.Equal(13, item.RepoCompanyId);
Assert.Null(item.DateRepoed);
});
// Run
var result = await _repoAccountProcessor.HandleAccount(new ProcessingItem()
{
AccountNo = "5730350143"
});
// Post-Assert
Assert.Equal(RepoProcessingResult.Updated, result);
Assert.NotNull(resultAccount);
Assert.Equal("Written Off", resultAccount.ReferenceStatus);
Assert.NotNull(resultAccount.WrittenOffDate);
var newSelections = resultAccount.Collaterals.First();
Assert.Collection(newSelections.RepoCompanySelections,
item =>
{
Assert.Equal(4, item.RepoCompanyId);
Assert.Null(item.DateRepoed);
},
item =>
{
Assert.Equal(13, item.RepoCompanyId);
Assert.NotNull(item.DateRepoed);
},
item =>
{
Assert.Equal(7, item.RepoCompanyId);
Assert.Null(item.DateRepoed);
}
);
}
[Fact]
public async Task Should_Update_WrittenOff_And_RepoSelection_Account2()
{
RepoAccount resultAccount = null;
var testInput = DbContextFromJson.GetTestObjectFromFile<ProcessorTestInput>("Services/Processor/written-off-account-2.json");
Assert.NotNull(testInput);
_mockCollectionsDao.Setup(cd => cd.RetrieveAccountAsync(It.IsAny<string>())).ReturnsAsync(testInput.TemenosAccount);
_mockRepoAccountService.Setup(ras => ras.GetNewestOpenAccount(It.IsAny<string>()))
.ReturnsAsync(testInput.RepoAccount);
_mockRepoAccountService.Setup(x => x.UpdateAsync(It.IsAny<RepoAccount>(), It.IsAny<AppUser>()))
.ReturnsAsync((RepoAccount inAccount, AppUser inUser) => {
resultAccount = inAccount;
return inAccount;
});
_mockCoreDao.Setup(cd => cd.RetrieveLoanAsync(It.IsAny<string>())).ReturnsAsync(testInput.LoanDetail);
_mockCoreDao.Setup(cd => cd.RetrieveMemberAsync(It.IsAny<string>())).ReturnsAsync(testInput.MemberDetail);
_mockCoreDao.Setup(cd => cd.RetrieveTransactionsAsync(It.IsAny<string>())).ReturnsAsync(testInput.CoreTransactions);
_mockRepoLetterService.Setup(x => x.ListByAccountIdAsync(It.IsAny<int>())).ReturnsAsync(
RepoLetterService.ProcessLetters(testInput.TemenosHistory, testInput.RepoLetters));
_mockAuctionAssignmentService.Setup(x => x.GetListByIdsAsync(It.IsAny<IReadOnlyCollection<int>>()))
.ReturnsAsync(new List<AuctionAssignment>());
// Pre-Assert.
Assert.Null(resultAccount);
Assert.Equal("Written Off", testInput.RepoAccount.ReferenceStatus);
Assert.Null(testInput.RepoAccount.WrittenOffDate);
var existingSelections = testInput.RepoAccount.Collaterals.First();
Assert.NotEmpty(existingSelections.RepoCompanySelections);
Assert.Collection(existingSelections.RepoCompanySelections,
item =>
{
Assert.Equal(11, item.RepoCompanyId);
Assert.Null(item.DateRepoed);
},
item =>
{
Assert.Equal(11, item.RepoCompanyId);
Assert.NotNull(item.DateRepoed);
},
item =>
{
Assert.Equal(1, item.RepoCompanyId);
Assert.NotNull(item.DateRepoed);
},
item =>
{
Assert.Equal(5, item.RepoCompanyId);
Assert.NotNull(item.DateRepoed);
},
item =>
{
Assert.Equal(13, item.RepoCompanyId);
Assert.NotNull(item.DateRepoed);
},
item =>
{
Assert.Equal(13, item.RepoCompanyId);
Assert.Null(item.DateRepoed);
});
// Run
var result = await _repoAccountProcessor.HandleAccount(new ProcessingItem()
{
AccountNo = "7115520143"
});
// Post-Assert
Assert.Equal(RepoProcessingResult.Updated, result);
Assert.NotNull(resultAccount);
Assert.Equal("Written Off", resultAccount.ReferenceStatus);
Assert.NotNull(resultAccount.WrittenOffDate);
var newSelections = resultAccount.Collaterals.First();
Assert.Collection(existingSelections.RepoCompanySelections,
item =>
{
Assert.Equal(11, item.RepoCompanyId);
Assert.Null(item.DateRepoed);
},
item =>
{
Assert.Equal(11, item.RepoCompanyId);
Assert.NotNull(item.DateRepoed);
},
item =>
{
Assert.Equal(1, item.RepoCompanyId);
Assert.NotNull(item.DateRepoed);
},
item =>
{
Assert.Equal(5, item.RepoCompanyId);
Assert.NotNull(item.DateRepoed);
},
item =>
{
Assert.Equal(13, item.RepoCompanyId);
Assert.NotNull(item.DateRepoed);
},
item =>
{
Assert.Equal(13, item.RepoCompanyId);
Assert.Null(item.DateRepoed);
});
}
}
}