using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using LCU.API.Collections.CollectionsApiLib.Models; using LCU.API.Collections.RepoApi.DataAccess; using LCU.API.Collections.RepoApi.Domain.Processing; using LCU.API.Collections.RepoApi.Exceptions; using LCU.API.Collections.RepoApi.Services; using LCU.API.Collections.RepoApi.Services.Producer; using LCU.Shared.Collections.RepoApiLib.Models; using LCU.Shared.Collections.RepoApiLib.Models.Consumer; using LCU.Shared.Collections.RepoApiLib.Models.Producer; using LCU.Shared.Collections.RepoApiLib.Models.Settings; using Moq; using Xunit; using Xunit.Sdk; namespace LCU.API.Collections.RepoApiTests.Services.Processor { public class RepoAccountProcessorServiceTest { private readonly Mock _mockCoreDao; private readonly RepoAccountProcessorService _repoAccountProcessorService; private readonly RepoAccount originalRepoAccount; private readonly TemenosAccount recoveryAccount; private readonly TemenosCase recoveryCase; private readonly LoanDetail loanDetail; private readonly Mock mockRedemptionExpiredDateCalculator; private readonly Mock mockAccountAlertCheckService; private readonly Settings settings; private readonly Mock _mockEventAlertService; private readonly Mock _mockRepoCompanySelectionService; public RepoAccountProcessorServiceTest() { settings = new Settings() { AllowedStatusChanges = new List() { new AllowedStatusChange() { ID = 1, CurrentStatus = "O4R", AllowedChangeStatus = "REPO" }, new AllowedStatusChange() { ID = 2, CurrentStatus = "RECA", AllowedChangeStatus = "O4R" } } }; mockAccountAlertCheckService = new Mock(); mockRedemptionExpiredDateCalculator = new Mock(); _mockEventAlertService = new Mock(); _mockCoreDao = new Mock(); _mockRepoCompanySelectionService = new Mock(); mockRedemptionExpiredDateCalculator.Setup(x => x.CalculateAsync(It.IsAny(), It.IsAny>())) .Returns(DateTime.Parse("2015-05-09")); _repoAccountProcessorService = new RepoAccountProcessorService(_mockCoreDao.Object, mockRedemptionExpiredDateCalculator.Object, mockAccountAlertCheckService.Object, _mockEventAlertService.Object, _mockRepoCompanySelectionService.Object); originalRepoAccount = new RepoAccount() { RepoId = 100, AccountNo = "123456-789", AccountTypeCode = "LP1", OrigAccountTypeCode = "LP1", Balance = 100, Bankruptcy = "No", Borrowers = new List() { new Borrower() { RepoId = 100, IndividualId = "1200", IndividualName = "John Tester", OwnershipType = 6 } }, Branch = 5656, Collaterals = new List() { new Collateral() { RepoId = 100, Vin = "123", CollateralId = 101, RepoCompanySelections = new List() { new RepoCompanySelection() { RepoType = RepoType.Involuntary } } } }, Collector = "Diana", LoanNo = 123, MemberNo = 1000, PrimaryIndividualId = "1200", Status = "O4R", SubStatus = "SUB", ReferenceId = 997, SixtyPlusCollectorId = 12345, SixtyPlusCollector = new SixtyPlusCollector() { SixtyPlusCollectorId = 12345, SixtyPlusCollectorName = "Sixty Plus" } }; recoveryAccount = new TemenosAccount() { AccountNumber = "123456-789", AccountTypeId = 1008, AccountType = new RepoAccountType() { Id = 1008, Code = "LP2", Description = "Something" }, AccountStatus = "Open", AccountId = 5, Branch = "54", DateFirstDelinquent = "11/5/2018 12:00:00 AM", DateLastPaid = "11/4/2018 12:00:00 AM", // UserStatusCode1 = "REPO", // CustomerNo = "1234" }; recoveryCase = new TemenosCase() { CaseId = 997, RepoStatus = RepoStatus.O4R, CreatedDate = DateTime.Today, TitleOrdered = true, TitleOrderedDate = DateTime.Parse("8/12/2020 12:00:00 AM") }; loanDetail = new LoanDetail() { Status = "OpenOrSomething" }; } [Fact] public void Basic_Construct_Test() { Assert.NotNull(_repoAccountProcessorService); } [Fact] public void Status_Compare_Test() { Assert.NotNull(_repoAccountProcessorService); RepoAccount account1 = new RepoAccount() { Status = "O4R" }; RepoAccount account2 = new RepoAccount() { Status = "REPO" }; RepoAccount account3 = new RepoAccount(); Assert.True(_repoAccountProcessorService.IsStatusMatch(account1, " O4r ")); Assert.True(_repoAccountProcessorService.IsStatusMatch(account1, " O4R")); Assert.True(_repoAccountProcessorService.IsStatusMatch(account1, "O4r ")); Assert.True(_repoAccountProcessorService.IsStatusMatch(account2, " repo ")); Assert.False(_repoAccountProcessorService.IsStatusMatch(account1, null)); Assert.False(_repoAccountProcessorService.IsStatusMatch(account1, "repo")); Assert.False(_repoAccountProcessorService.IsStatusMatch(account2, null)); Assert.False(_repoAccountProcessorService.IsStatusMatch(account3, " repo ")); } [Fact] public void Convert_Borrower_Type_Test() { Assert.NotNull(_repoAccountProcessorService); Assert.Equal(OwnershipType.Borrower, _repoAccountProcessorService.ConvertBorrowerType(" BORROWER ")); Assert.Equal(OwnershipType.Borrower, _repoAccountProcessorService.ConvertBorrowerType("borrower ")); Assert.Equal(OwnershipType.Borrower, _repoAccountProcessorService.ConvertBorrowerType(" borRower")); Assert.Equal(OwnershipType.Coborrower, _repoAccountProcessorService.ConvertBorrowerType(" CO-BORROWER ")); Assert.Equal(OwnershipType.Coborrower, _repoAccountProcessorService.ConvertBorrowerType("co-borrower ")); Assert.Equal(OwnershipType.Coborrower, _repoAccountProcessorService.ConvertBorrowerType(" co-borRower")); Assert.Equal(OwnershipType.Other, _repoAccountProcessorService.ConvertBorrowerType(" COBORROWER ")); Assert.Equal(OwnershipType.Other, _repoAccountProcessorService.ConvertBorrowerType("asdfasdf ")); Assert.Equal(OwnershipType.Other, _repoAccountProcessorService.ConvertBorrowerType(null)); } [Fact] public void Create_Repo_Account_Ok() { var temenosAccount = new TemenosAccount() { AccountIdentifier = "323232789", AccountType = new RepoAccountType() { Id = 1007, Code = "LP2", Description = "test" }, AccountId = 5, Branch = "54", Balance = (decimal)71234.33, AccountTypeId = 1007, AccountStatus = "Open", DateFirstDelinquent = "11/5/2018 12:00:00 AM", DateLastPaid = "11/5/2018 12:00:00 AM" }; var temenosCase = new TemenosCase() { CaseId = 12345, RepoStatus = RepoStatus.O4R, CreatedDate = DateTime.Today, TitleOrdered = true, TitleOrderedDate = DateTime.Parse("8/12/2020 12:00:00 AM") }; var loanDetail = new LoanDetail() { Balance = 1000, AccountType = 5, IndividualId = new int[] { 1000, 1001 }, Borrowers = new List() { new LoanOwner() { IndividualId = 12345, Name = "xxx Borrower", Type = "Borrower" } }, NextDueDate = DateTime.Today }; _mockCoreDao.Setup(service => service.RetrieveCollateralAsync(It.IsAny())) .ReturnsAsync( new List() { new CollateralDetail() { CollateralId = 1000, CurrentValue = 2000, Description = "xxx description" } } ); _mockCoreDao.Setup(service => service.RetrieveMemberAsync(It.IsAny())) .ReturnsAsync( new MemberDetail() { MemberId = 8675309 } ); var result = _repoAccountProcessorService.CreateRepoAccount(temenosAccount, temenosCase, loanDetail); Assert.Equal(temenosAccount.AccountIdentifier, result.AccountNo); Assert.Equal(temenosAccount.Balance, result.Balance); // Q1. Confirm with business not to use loan balance? Assert.NotNull(result.Borrowers); Assert.NotNull(result.Collaterals); Assert.NotNull(result.AccountLastProcessed); Assert.Equal("xxx Borrower", result.Borrowers.First().IndividualName); Assert.Equal("xxx description", result.Collaterals.First().Description); Assert.Equal(temenosAccount.AccountId, result.ReferenceId); Assert.Equal(temenosCase.CaseId, result.ReferenceCaseId); Assert.Equal(temenosAccount.AccountType.Code, result.AccountTypeCode); Assert.Equal(temenosAccount.AccountType.Code, result.OrigAccountTypeCode); Assert.Equal(temenosAccount.AccountStatus, result.ReferenceStatus); } [Fact] public void Create_Repo_Account_No_Collateral() { var loanDetail = new LoanDetail() { Balance = 1000, AccountType = 5, IndividualId = new int[] { 1000, 1001 } }; _mockCoreDao.Setup(service => service.RetrieveCollateralAsync(It.IsAny())) .ReturnsAsync(new List() { }); Assert.Throws(() => _repoAccountProcessorService.CreateRepoAccount(recoveryAccount, recoveryCase, loanDetail)); } [Fact] public void Create_Repo_Account_No_Borrower() { var loanDetail = new LoanDetail() { Balance = 1000, AccountType = 5, IndividualId = new int[] { 1000, 1001 } }; _mockCoreDao.Setup(service => service.RetrieveCollateralAsync(It.IsAny())) .ReturnsAsync(new List() { new CollateralDetail() { CollateralId = 1000, CurrentValue = 2000 } }); Assert.Throws(() => _repoAccountProcessorService.CreateRepoAccount(recoveryAccount, recoveryCase, loanDetail)); } [Fact] public void Create_Repo_Account_Bad_DateTime() { var temenosAccount = recoveryAccount; temenosAccount.DateFirstDelinquent = null; var loanDetail = new LoanDetail() { Balance = 1000, AccountType = 5, IndividualId = new int[] { 1000, 1001 }, Borrowers = new List() { new LoanOwner() { IndividualId = 12345, Name = "John Borrower", Type = "Borrower" } } }; _mockCoreDao.Setup(service => service.RetrieveCollateralAsync(It.IsAny())) .ReturnsAsync( new List() { new CollateralDetail() { CollateralId = 1000, CurrentValue = 2000 } }); Assert.ThrowsAny(() => _repoAccountProcessorService.CreateRepoAccount(temenosAccount, recoveryCase, loanDetail)); } [Fact] public void Construct_Collateral_OK() { List collateralDetail = new List() { new CollateralDetail() { Other = new OtherCollateral() { MiscellaneousInformation = "VINVINVINVINVIN" }, Vehicle = new Vehicle() { VIN = "VINVINVINVINVINVIN" } } }; RepoAccount repoAccount = new RepoAccount() { }; var results = _repoAccountProcessorService.ConstructCollateralFromDetails(collateralDetail); Assert.NotNull(results); Assert.NotEmpty(results); } [Fact] public void Construct_Collateral_Empty_List() { List collateralDetail = new List() { }; RepoAccount repoAccount = new RepoAccount() { }; var results = _repoAccountProcessorService.ConstructCollateralFromDetails(collateralDetail); Assert.NotNull(results); Assert.Empty(results); } [Fact] public void Merge_Everything_Ok() { var slip = new RepoAccountProcessingSlip() { RecoveryAccount = recoveryAccount, ExistingRepoAccount = originalRepoAccount, RecoveryCase = recoveryCase, CurrentSettings = settings, Letters = new List(), Loan = loanDetail, RequestedBy = new ProcessingItem() { AccountNo = recoveryAccount.AccountIdentifier, QueuedBy = "Tester" } }; slip.AssertReadyForFullProcessing(); var result = _repoAccountProcessorService.UpdateRepoAccountFromParts(slip); Assert.Equal(originalRepoAccount.AccountNo, result.AccountNo); Assert.Equal(originalRepoAccount.RepoId, result.RepoId); Assert.Equal(originalRepoAccount.Borrowers, result.Borrowers); Assert.Equal(originalRepoAccount.Collaterals, result.Collaterals); Assert.Equal(originalRepoAccount.OrigAccountTypeCode, result.OrigAccountTypeCode); Assert.NotEqual(originalRepoAccount.SixtyPlusCollector, result.SixtyPlusCollector); Assert.NotEqual(originalRepoAccount.AccountTypeCode, result.AccountTypeCode); } [Fact] public void UpdateRepoAccountFromParts_Updates_Repo_Status_Ok() { originalRepoAccount.Status = "O4R"; recoveryCase.RepoStatus = RepoStatus.REPO; var slip = new RepoAccountProcessingSlip() { RecoveryAccount = recoveryAccount, ExistingRepoAccount = originalRepoAccount, RecoveryCase = recoveryCase, CurrentSettings = settings, Letters = new List(), Loan = loanDetail, RequestedBy = new ProcessingItem() { AccountNo = recoveryAccount.AccountIdentifier, QueuedBy = "Tester" } }; slip.AssertReadyForFullProcessing(); var updatedRepoAccount = _repoAccountProcessorService.UpdateRepoAccountFromParts(slip); Assert.Equal("REPO", updatedRepoAccount.Status); _repoAccountProcessorService.CheckForRejectedStatusChange(originalRepoAccount, updatedRepoAccount, settings); Assert.Equal("REPO", updatedRepoAccount.Status); Assert.Null(updatedRepoAccount.Collaterals.First().RepoCompanySelections.First().DateRepoed); } [Fact] public void UpdateRepoAccountFromParts_Updates_O4R_Status_Ok() { originalRepoAccount.Status = "RECA"; recoveryCase.RepoStatus = RepoStatus.O4R; var slip = new RepoAccountProcessingSlip() { RecoveryAccount = recoveryAccount, ExistingRepoAccount = originalRepoAccount, RecoveryCase = recoveryCase, CurrentSettings = settings, Letters = new List(), Loan = loanDetail, RequestedBy = new ProcessingItem() { AccountNo = recoveryAccount.AccountIdentifier, QueuedBy = "Tester" } }; slip.AssertReadyForFullProcessing(); var updatedRepoAccount = _repoAccountProcessorService.UpdateRepoAccountFromParts(slip); Assert.Equal("O4R", updatedRepoAccount.Status); _repoAccountProcessorService.CheckForRejectedStatusChange(originalRepoAccount, updatedRepoAccount, settings); Assert.Equal("O4R", updatedRepoAccount.Status); } [Fact] public void UpdateRepoAccountFromParts_Updates_SixtyPlusCollector_Ok() { var SixtyPlus = new Dictionary() { {"SixtyPlus User Assigned", "67890" } }; recoveryAccount.CustomFieldMap = SixtyPlus; var slip = new RepoAccountProcessingSlip() { RecoveryAccount = recoveryAccount, ExistingRepoAccount = originalRepoAccount, RecoveryCase = recoveryCase, CurrentSettings = settings, Letters = new List(), Loan = loanDetail, RequestedBy = new ProcessingItem() { AccountNo = recoveryAccount.AccountIdentifier, QueuedBy = "Tester" } }; slip.AssertReadyForFullProcessing(); var updatedRepoAccount = _repoAccountProcessorService.UpdateRepoAccountFromParts(slip); Assert.Equal(67890, updatedRepoAccount.SixtyPlusCollectorId); } [Fact] public void UpdateRepoAccountFromParts_Updates_SixtyPlusCollector_Null() { var SixtyPlus = new Dictionary() { {"SixtyPlus User Assigned", "" } }; recoveryAccount.CustomFieldMap = SixtyPlus; var slip = new RepoAccountProcessingSlip() { RecoveryAccount = recoveryAccount, ExistingRepoAccount = originalRepoAccount, RecoveryCase = recoveryCase, CurrentSettings = settings, Letters = new List(), Loan = loanDetail, RequestedBy = new ProcessingItem() { AccountNo = recoveryAccount.AccountIdentifier, QueuedBy = "Tester" } }; slip.AssertReadyForFullProcessing(); var updatedRepoAccount = _repoAccountProcessorService.UpdateRepoAccountFromParts(slip); Assert.Null(updatedRepoAccount.SixtyPlusCollectorId); } [Fact] public void UpdateRepoAccountFromParts_DontThrow_Null_LastPaymentDate() { originalRepoAccount.Status = "RECA"; recoveryAccount.DateLastPaid = null; recoveryCase.RepoStatus = RepoStatus.O4R; var slip = new RepoAccountProcessingSlip() { RecoveryAccount = recoveryAccount, ExistingRepoAccount = originalRepoAccount, RecoveryCase = recoveryCase, CurrentSettings = settings, Letters = new List(), Loan = loanDetail, RequestedBy = new ProcessingItem() { AccountNo = recoveryAccount.AccountIdentifier, QueuedBy = "Tester" } }; slip.AssertReadyForFullProcessing(); var updatedRepoAccount = _repoAccountProcessorService.UpdateRepoAccountFromParts(slip); Assert.Null(updatedRepoAccount.LastPaymentDate); } [Fact] public void UpdateRepoAccountFromParts_DontThrow_Bad_LastPaymentDate() { originalRepoAccount.Status = "RECA"; recoveryAccount.DateLastPaid = "NotADate"; recoveryCase.RepoStatus = RepoStatus.O4R; var slip = new RepoAccountProcessingSlip() { RecoveryAccount = recoveryAccount, ExistingRepoAccount = originalRepoAccount, RecoveryCase = recoveryCase, CurrentSettings = settings, Letters = new List(), Loan = loanDetail, RequestedBy = new ProcessingItem() { AccountNo = recoveryAccount.AccountIdentifier, QueuedBy = "Tester" } }; slip.AssertReadyForFullProcessing(); var updatedRepoAccount = _repoAccountProcessorService.UpdateRepoAccountFromParts(slip); Assert.Null(updatedRepoAccount.LastPaymentDate); } [Fact] public void Check_Status_Reject_REJECT() { originalRepoAccount.Status = "RECA"; // RECA can't go to REPO recoveryCase.RepoStatus = RepoStatus.REPO; var slip = new RepoAccountProcessingSlip() { RecoveryAccount = recoveryAccount, ExistingRepoAccount = originalRepoAccount, RecoveryCase = recoveryCase, CurrentSettings = settings, Letters = new List(), Loan = loanDetail, RequestedBy = new ProcessingItem() { AccountNo = recoveryAccount.AccountIdentifier, QueuedBy = "Tester" } }; slip.AssertReadyForFullProcessing(); var updatedRepoAccount = _repoAccountProcessorService.UpdateRepoAccountFromParts(slip); Assert.Equal("REPO", updatedRepoAccount.Status); _repoAccountProcessorService.CheckForRejectedStatusChange(originalRepoAccount, updatedRepoAccount, settings); // Should have been reverted Assert.Equal("RECA", updatedRepoAccount.Status); mockAccountAlertCheckService.Verify(x => x.ManualAlert(It.IsAny()), Times.Once); } [Fact] public void Check_Status_Reject_ACCEPT() { originalRepoAccount.Status = "RECA"; // RECA can go to 04R recoveryCase.RepoStatus = RepoStatus.O4R; var slip = new RepoAccountProcessingSlip() { RecoveryAccount = recoveryAccount, ExistingRepoAccount = originalRepoAccount, RecoveryCase = recoveryCase, CurrentSettings = settings, Letters = new List(), Loan = loanDetail, RequestedBy = new ProcessingItem() { AccountNo = recoveryAccount.AccountIdentifier, QueuedBy = "Tester" } }; slip.AssertReadyForFullProcessing(); var updatedRepoAccount = _repoAccountProcessorService.UpdateRepoAccountFromParts(slip); Assert.Equal("O4R", updatedRepoAccount.Status); _repoAccountProcessorService.CheckForRejectedStatusChange(originalRepoAccount, updatedRepoAccount, settings); // Should have been accepted Assert.Equal("O4R", updatedRepoAccount.Status); mockAccountAlertCheckService.Verify(x => x.ManualAlert(It.IsAny()), Times.Never); } [Fact] public void Update_Redemption_Expired_Date_Ok() { originalRepoAccount.Status = "O4R"; recoveryCase.RepoStatus = RepoStatus.REPO; var slip = new RepoAccountProcessingSlip() { RecoveryAccount = recoveryAccount, ExistingRepoAccount = originalRepoAccount, RecoveryCase = recoveryCase, CurrentSettings = settings, Loan = loanDetail, Letters = new List(), RequestedBy = new ProcessingItem() { AccountNo = recoveryAccount.AccountIdentifier, QueuedBy = "Tester" } }; slip.AssertReadyForFullProcessing(); var updatedRepoAccount = _repoAccountProcessorService.UpdateRepoAccountFromParts(slip); Assert.Equal("REPO", updatedRepoAccount.Status); _repoAccountProcessorService.CheckForRejectedStatusChange(originalRepoAccount, updatedRepoAccount, settings); Assert.Equal("REPO", updatedRepoAccount.Status); Assert.Equal(DateTime.Parse("2015-05-09"), updatedRepoAccount.RedemptionExpiredDate); } [Fact] public void Status_CoMpARe_Test() { Assert.NotNull(_repoAccountProcessorService); var repoAccount = new RepoAccount() { Status = "o4r" }; Assert.False(_repoAccountProcessorService.IsStatusMatch(null, "repo")); Assert.False(_repoAccountProcessorService.IsStatusMatch(repoAccount, "repo")); Assert.False(_repoAccountProcessorService.IsStatusMatch(repoAccount, "Repo")); Assert.True(_repoAccountProcessorService.IsStatusMatch(repoAccount, "o4r")); Assert.True(_repoAccountProcessorService.IsStatusMatch(repoAccount, "O4r")); Assert.True(_repoAccountProcessorService.IsStatusMatch(repoAccount, "O4r ")); Assert.True(_repoAccountProcessorService.IsStatusMatch(repoAccount, " o4R ")); } [Fact] public void UpdateRepo_From_REDEM_Test() { Assert.NotNull(_repoAccountProcessorService); var temenosAccount = new TemenosAccount() { AccountNumber = "123456-789", DateFirstDelinquent = "11/5/2018 12:00:00 AM", DateLastPaid = "11/4/2018 12:00:00 AM", AccountTypeId = 1007, AccountType = new RepoAccountType() { Id = 1007, Code = "LP1", Description = "Testlp1" } }; var temenosCase = new TemenosCase() { RepoStatus = RepoStatus.REDEEMED }; var repoAccount = new RepoAccount() { RepoId = 1, Status = "o4r", AccountNo = "123456-999", Collaterals = new List() { new Collateral() { RepoId = 1, RepoCompanySelections = new List() { new RepoCompanySelection() { DateTimeCreated = DateTime.Now.Subtract(TimeSpan.FromDays(7)), RepoType = RepoType.Involuntary, CollateralId = 1, Id = 1, RepoCompanyId = 4, RepoCompanyAssignmentDate = DateTime.Now.Subtract(TimeSpan.FromDays(7)) } } } } }; var slip = new RepoAccountProcessingSlip() { RecoveryAccount = temenosAccount, ExistingRepoAccount = repoAccount, RecoveryCase = temenosCase, Loan = loanDetail, CurrentSettings = settings, Letters = new List(), RequestedBy = new ProcessingItem() { AccountNo = recoveryAccount.AccountIdentifier, QueuedBy = "Tester" } }; slip.AssertReadyForFullProcessing(); var result = _repoAccountProcessorService.UpdateRepoAccountFromParts(slip); Assert.Equal("REDEEMED", result.Status); Assert.Equal("123456-999", result.AccountNo); } [Fact] public void Update_With_REPO_Status_Four_Days_Does_Not_Close_Account() { Assert.NotNull(_repoAccountProcessorService); var repo = new RepoAccount() { RepoId = 5, AccountNo = "1234567-98", Status = "REPO", RepoStatusChanges = new List { new RepoStatusChange { StatusFrom = "O4R", StatusTo = "REPO", ChangedDate = DateTime.Now.AddDays(-4) } } }; _repoAccountProcessorService.UpdateRepoAccountDateClosed(repo); _mockEventAlertService.Verify(x => x.MarkAllAsRead(It.IsAny()), Times.Never()); Assert.Null(repo.DateClosed); } [Fact] public void Update_With_PSKP_Status_Four_Days_Closes_Account() { Assert.NotNull(_repoAccountProcessorService); var repo = new RepoAccount() { RepoId = 5, AccountNo = "1234567-98", Status = "PSKP", RepoStatusChanges = new List { new RepoStatusChange { StatusFrom = "O4R", StatusTo = "PSKP", ChangedDate = DateTime.Now.AddDays(-4) } } }; _repoAccountProcessorService.UpdateRepoAccountDateClosed(repo); _mockEventAlertService.Verify(x => x.MarkAllAsRead(It.IsAny()), Times.Once()); Assert.NotNull(repo.DateClosed); } [Fact] public void Update_With_REDEEMED_Status_Four_Days_Closes_Account() { Assert.NotNull(_repoAccountProcessorService); var repo = new RepoAccount() { RepoId = 5, AccountNo = "1234567-98", Status = "REDEEMED", RepoStatusChanges = new List { new RepoStatusChange { StatusFrom = "REPO", StatusTo = "REDEEMED", ChangedDate = DateTime.Now.AddDays(-4) } } }; _repoAccountProcessorService.UpdateRepoAccountDateClosed(repo); _mockEventAlertService.Verify(x => x.MarkAllAsRead(It.IsAny()), Times.Once()); Assert.NotNull(repo.DateClosed); } [Fact] public void Update_With_REDEEMED_Three_Days_Does_Not_Force_Close_Account() { Assert.NotNull(_repoAccountProcessorService); var repo = new RepoAccount() { RepoId = 5, AccountNo = "1234567-98", Status = "REDEEMED", RepoStatusChanges = new List { new RepoStatusChange { StatusFrom = "REPO", StatusTo = "REDEEMED", ChangedDate = DateTime.Now.AddDays(-3) } } }; _repoAccountProcessorService.UpdateRepoAccountDateClosed(repo); _mockEventAlertService.Verify(x => x.MarkAllAsRead(It.IsAny()), Times.Never()); Assert.Null(repo.DateClosed); } [Fact] public void TryUpdateCollateralRetitleDate_OK() { var ogAccount = originalRepoAccount; _repoAccountProcessorService.TryUpdateCollateralRetitleDate(ogAccount, recoveryCase); Assert.All(ogAccount.Collaterals, collateral => { Assert.Equal(DateTime.Parse("8/12/2020 12:00:00 AM"), collateral.RetitledInLandmarkName); Assert.Equal(new DateTime(637327872000000000), collateral.RetitledInLandmarkName); }); } [Fact] public void TryUpdateCollateralRetitleDate_MissingFields() { var ogAccount = originalRepoAccount; var temenosCase = new TemenosCase() { CaseId = 997, RepoStatus = RepoStatus.O4R, CreatedDate = DateTime.Today, }; _repoAccountProcessorService.TryUpdateCollateralRetitleDate(ogAccount, temenosCase); Assert.All(ogAccount.Collaterals, collateral => { Assert.Null(collateral.RetitledInLandmarkName); }); } [Fact] public void TryUpdateCollateralRetitleDate_NullDate() { var ogAccount = originalRepoAccount; var temenoseCase = recoveryCase; temenoseCase.TitleOrdered = true; temenoseCase.TitleOrderedDate = null; _repoAccountProcessorService.TryUpdateCollateralRetitleDate(ogAccount, temenoseCase); Assert.All(ogAccount.Collaterals, collateral => { Assert.Null(collateral.RetitledInLandmarkName); }); } [Fact] public void TryUpdateCollateralRetitleDate_TitleOrderedFalse() { var ogAccount = originalRepoAccount; var temenosCase = recoveryCase; temenosCase.TitleOrdered = false; _repoAccountProcessorService.TryUpdateCollateralRetitleDate(ogAccount, temenosCase); Assert.All(ogAccount.Collaterals, collateral => { Assert.Null(collateral.RetitledInLandmarkName); }); } [Fact] public void MapRepoAgentIdToRepoCompanyId_OK() { var repoCompanies = new List(); repoCompanies.Add(new RepoCompany() { ID = 5, ReferenceId = 555 }); repoCompanies.Add(new RepoCompany() { ID = 3, ReferenceId = 333 }); Assert.Equal(5, _repoAccountProcessorService.MapRepoAgentIdToRepoCompanyId("555", repoCompanies)); Assert.Equal(3, _repoAccountProcessorService.MapRepoAgentIdToRepoCompanyId("333", repoCompanies)); } [Fact] public void MapRepoAgentIdToRepoCompanyId_Returns_Null_If_No_Map() { var repoCompanies = new List(); repoCompanies.Add(new RepoCompany() { ID = 5, ReferenceId = 555 }); repoCompanies.Add(new RepoCompany() { ID = 3, ReferenceId = 333 }); Assert.Throws(() => { _repoAccountProcessorService.MapRepoAgentIdToRepoCompanyId("777", new List()); }); } [Fact] public void MapRepoAgentIdToRepoCompanyId_Throws_If_Empty_List() { Assert.Throws(() => { _repoAccountProcessorService.MapRepoAgentIdToRepoCompanyId("777", new List()); }); } [Fact] public void CreateNewRepoCompanyAssignment_OK() { var collateral = new Collateral() { CollateralId = 4, RepoCompanySelections = new List() }; var temenosCase = new TemenosCase() { RepoAgentId = "555", RepoType = RepoType.Voluntary, DateRepossessed = DateTime.Parse("2020-02-10"), DateRepoAssigned = DateTime.Parse("2015-02-10") }; var results = _repoAccountProcessorService.CreateNewRepoCompanyAssignment(collateral, temenosCase, 123); Assert.NotNull(results); Assert.Equal(4, results.CollateralId); Assert.Equal(RepoType.Voluntary, results.RepoType); Assert.Equal(DateTime.Parse("2020-02-10"), results.DateRepoed); Assert.Equal(DateTime.Parse("2015-02-10"), results.RepoCompanyAssignmentDate); } [Fact] public void CreateNewRepoCompanyAssignment_No_DateReposessed() { var collateral = new Collateral() { CollateralId = 4, RepoCompanySelections = new List() }; var temenosCase = new TemenosCase() { RepoAgentId = "555", RepoType = RepoType.Voluntary, DateRepossessed = null, DateRepoAssigned = DateTime.Parse("2015-02-10") }; var results = _repoAccountProcessorService.CreateNewRepoCompanyAssignment(collateral, temenosCase, 123); Assert.NotNull(results); Assert.Equal(4, results.CollateralId); Assert.Equal(RepoType.Voluntary, results.RepoType); Assert.Null(results.DateRepoed); Assert.Equal(DateTime.Parse("2015-02-10"), results.RepoCompanyAssignmentDate); } [Fact] public void CreateNewRepoCompanyAssignment_Defaults_Null_RepoType() { var collateral = new Collateral() { CollateralId = 4, RepoCompanySelections = new List() }; var temenosCase = new TemenosCase() { RepoAgentId = "555", RepoType = null, DateRepossessed = null, DateRepoAssigned = DateTime.Parse("2015-02-10") }; var results = _repoAccountProcessorService.CreateNewRepoCompanyAssignment(collateral, temenosCase, 123); Assert.NotNull(results); Assert.Equal(4, results.CollateralId); Assert.Equal(RepoType.Unknown, results.RepoType); Assert.Null(results.DateRepoed); Assert.Equal(DateTime.Parse("2015-02-10"), results.RepoCompanyAssignmentDate); } [Fact] public void TryUpdateOrCreateRepoCompanyAssignment_OK_No_Existing_Assignment_TemenosHasData() { var temenosCase = new TemenosCase() { RepoAgentId = "333", DateRepossessed = null, RepoType = RepoType.Voluntary, DateRepoAssigned = DateTime.Parse("2015-02-10") }; ICollection collaterals = new[] { new Collateral() { CollateralId = 0, RepoCompanySelections = new List() }, new Collateral() { CollateralId = 1, RepoCompanySelections = new List() } }; var settings = new Settings() { RepoCompanies = new RepoCompany[] { new RepoCompany { ID = 3, ReferenceId = 333 }, new RepoCompany { ID = 5, ReferenceId = 555 } } }; var repoAccount = new RepoAccount() { Collaterals = collaterals }; _repoAccountProcessorService.TryUpdateOrCreateRepoCompanyAssignment(repoAccount, temenosCase, settings); Assert.All(repoAccount.Collaterals, collateral => { Assert.Single(collateral.RepoCompanySelections); }); } [Fact] public void TryUpdateOrCreateRepoCompanyAssignment_OK_No_Existing_Assignment_NoTemenosData() { var temenosCase = new TemenosCase() { }; ICollection collaterals = new[] { new Collateral() { CollateralId = 0, RepoCompanySelections = new List() }, new Collateral() { CollateralId = 1, RepoCompanySelections = new List() } }; var settings = new Settings() { RepoCompanies = new RepoCompany[] { new RepoCompany { ID = 3, ReferenceId = 333 }, new RepoCompany { ID = 5, ReferenceId = 555 } } }; var repoAccount = new RepoAccount() { Collaterals = collaterals }; _repoAccountProcessorService.TryUpdateOrCreateRepoCompanyAssignment(repoAccount, temenosCase, settings); Assert.All(repoAccount.Collaterals, collateral => { Assert.Empty(collateral.RepoCompanySelections); }); } [Fact] public void TryUpdateOrCreateRepoCompanyAssignment_NoUpdateWhenDataSame() { var temenosCase = new TemenosCase() { RepoAgentId = "333", DateRepossessed = null, RepoType = RepoType.Voluntary, DateRepoAssigned = DateTime.Parse("2015-02-10") }; var companyForCollateral = new RepoCompanySelection() { RepoType = RepoType.Voluntary, RepoCompanyId = 3, DateRepoed = null, RepoCompanyAssignmentDate = DateTime.Parse("2015-02-10") }; ICollection collaterals = new[] { new Collateral() { CollateralId = 0, RepoCompanySelections = new List { companyForCollateral } } }; var settings = new Settings() { RepoCompanies = new RepoCompany[] { new RepoCompany { ID = 3, ReferenceId = 333 }, new RepoCompany { ID = 5, ReferenceId = 555 } } }; var repoAccount = new RepoAccount() { Collaterals = collaterals }; _repoAccountProcessorService.TryUpdateOrCreateRepoCompanyAssignment(repoAccount, temenosCase, settings); Assert.All(repoAccount.Collaterals, collateral => { var repoCompany = collateral.RepoCompanySelections.Single(); Assert.Equal(companyForCollateral, repoCompany); }); } [Fact] public void TryUpdateOrCreateRepoCompanyAssignment_Update_Ok() { var temenosCase = new TemenosCase() { RepoAgentId = "333", DateRepossessed = DateTime.Parse("2020-02-10"), RepoType = RepoType.Voluntary, DateRepoAssigned = DateTime.Parse("2015-02-10"), }; var companyForCollateral = new RepoCompanySelection() { RepoType = RepoType.Voluntary, RepoCompanyId = 3, DateRepoed = null, RepoCompanyAssignmentDate = DateTime.Parse("2015-02-10") }; ICollection collaterals = new[] { new Collateral() { CollateralId = 0, RepoCompanySelections = new List { companyForCollateral } } }; var settings = new Settings() { RepoCompanies = new RepoCompany[] { new RepoCompany { ID = 3, ReferenceId = 333 }, new RepoCompany { ID = 5, ReferenceId = 555 } } }; var repoAccount = new RepoAccount() { Collaterals = collaterals }; _repoAccountProcessorService.TryUpdateOrCreateRepoCompanyAssignment(repoAccount, temenosCase, settings); Assert.All(repoAccount.Collaterals, collateral => { var repoCompany = collateral.RepoCompanySelections.Single(); Assert.Equal(DateTime.Parse("2020-02-10"), repoCompany.DateRepoed); }); } [Fact] public void TryUpdateOrCreateRepoCompanyAssignment_Missing_RepoCompanyAssignmentDate() { var temenosCase = new TemenosCase() { RepoAgentId = "333", DateRepossessed = DateTime.Parse("2020-02-10"), RepoType = RepoType.Voluntary, DateRepoAssigned = null, }; var companyForCollateral = new RepoCompanySelection() { RepoType = RepoType.Voluntary, RepoCompanyId = 3, DateRepoed = null, RepoCompanyAssignmentDate = null }; ICollection collaterals = new[] { new Collateral() { CollateralId = 0, RepoCompanySelections = new List { companyForCollateral } } }; var settings = new Settings() { RepoCompanies = new RepoCompany[] { new RepoCompany { ID = 3, ReferenceId = 333 }, new RepoCompany { ID = 5, ReferenceId = 555 } } }; var repoAccount = new RepoAccount() { Collaterals = collaterals }; Assert.Throws(() => _repoAccountProcessorService.TryUpdateOrCreateRepoCompanyAssignment(repoAccount, temenosCase, settings)); } [Fact] public void TryUpdateOrCreateRepoCompanyAssignment_Handles_RepoAgentID_Empty_String() { var temenosCase = new TemenosCase() { RepoAgentId = "", DateRepossessed = DateTime.Parse("2020-02-10"), RepoType = RepoType.Voluntary, DateRepoAssigned = DateTime.Parse("2015-02-10"), }; var companyForCollateral = new RepoCompanySelection() { RepoType = RepoType.Voluntary, RepoCompanyId = 3, DateRepoed = null, RepoCompanyAssignmentDate = DateTime.Parse("2015-02-10") }; ICollection collaterals = new[] { new Collateral() { CollateralId = 0, RepoCompanySelections = new List { companyForCollateral } } }; var settings = new Settings() { RepoCompanies = new RepoCompany[] { new RepoCompany { ID = 3, ReferenceId = 333 }, new RepoCompany { ID = 5, ReferenceId = 555 } } }; var repoAccount = new RepoAccount() { Collaterals = collaterals }; _repoAccountProcessorService.TryUpdateOrCreateRepoCompanyAssignment(repoAccount, temenosCase, settings); Assert.All((repoAccount.Collaterals), (collateral => { Assert.Equal(2, collateral.RepoCompanySelections.Count); Assert.Contains(collateral.RepoCompanySelections, selection => selection.DateRepoed == DateTime.Today || selection.DateRepoed == DateTime.Parse("2020-02-10")); })); } [Fact] public void TryUpdateOrCreateRepoCompanyAssignment_Create_OK() { var temenosCase = new TemenosCase() { RepoAgentId = "555", DateRepossessed = null, RepoType = RepoType.Skip, DateRepoAssigned = DateTime.Parse("2015-02-10"), }; var companyForCollateral = new RepoCompanySelection() { RepoType = RepoType.Voluntary, RepoCompanyId = 3, DateRepoed = null, RepoCompanyAssignmentDate = DateTime.Parse("2015-02-10") }; ICollection collaterals = new[] { new Collateral() { CollateralId = 0, RepoCompanySelections = new List { companyForCollateral } } }; var settings = new Settings() { RepoCompanies = new RepoCompany[] { new RepoCompany { ID = 3, ReferenceId = 333 }, new RepoCompany { ID = 5, ReferenceId = 555 } } }; var repoAccount = new RepoAccount() { Collaterals = collaterals }; _repoAccountProcessorService.TryUpdateOrCreateRepoCompanyAssignment(repoAccount, temenosCase, settings); Assert.All(repoAccount.Collaterals, collateral => { Assert.Equal(2, collateral.RepoCompanySelections.Count); Assert.Equal(5, collateral.RepoCompanySelections.OrderByDescending(x => x.DateTimeCreated).First().RepoCompanyId); Assert.Equal(3, collateral.RepoCompanySelections.OrderByDescending(x => x.DateTimeCreated).ToList()[1] .RepoCompanyId); //SHOULD MARK PREVIOUS MOST RECENT ENTRY WITH A DateRepoed! Assert.NotNull(collateral.RepoCompanySelections.OrderByDescending(x => x.DateTimeCreated).ToList()[1] .DateRepoed); Assert.NotNull(collateral.RepoCompanySelections.OrderByDescending(x => x.DateTimeCreated).ToList()[1] .RepoCompanyAssignmentDate); }); } [Fact] public void TryUpdateOrCreateRepoCompanyAssignment_Create_OK_Missing_BOTH_Dates() { var temenosCase = new TemenosCase() { RepoAgentId = "555", DateRepossessed = null, RepoType = RepoType.Skip, DateRepoAssigned = DateTime.Parse("2015-02-10"), }; // So, both DateRepoed and RepoCompanyAssignmentDate are null. GJF 256 rows like this in prod. var companyForCollateral = new RepoCompanySelection() { RepoType = RepoType.Voluntary, RepoCompanyId = 3, DateRepoed = null, RepoCompanyAssignmentDate = null, DateTimeCreated = DateTime.Parse("2015-02-10"), }; ICollection collaterals = new[] { new Collateral() { CollateralId = 0, RepoCompanySelections = new List { companyForCollateral } } }; var settings = new Settings() { RepoCompanies = new RepoCompany[] { new RepoCompany { ID = 3, ReferenceId = 333 }, new RepoCompany { ID = 5, ReferenceId = 555 } } }; var repoAccount = new RepoAccount() { Collaterals = collaterals }; _repoAccountProcessorService.TryUpdateOrCreateRepoCompanyAssignment(repoAccount, temenosCase, settings); Assert.All(repoAccount.Collaterals, collateral => { Assert.Equal(2, collateral.RepoCompanySelections.Count); Assert.Equal(5, collateral.RepoCompanySelections.OrderByDescending(x => x.DateTimeCreated).First().RepoCompanyId); Assert.Equal(3, collateral.RepoCompanySelections.OrderByDescending(x => x.DateTimeCreated).ToList()[1] .RepoCompanyId); //SHOULD MARK PREVIOUS MOST RECENT ENTRY WITH A DateRepoed! Assert.NotNull(collateral.RepoCompanySelections.OrderByDescending(x => x.DateTimeCreated).ToList()[1] .DateRepoed); Assert.NotNull(collateral.RepoCompanySelections.OrderByDescending(x => x.DateTimeCreated).ToList()[1] .RepoCompanyAssignmentDate); }); } [Fact] public void UpdateOrCreateRepoCompanyAssignment_Update_Ok() { var temenosCase = new TemenosCase() { RepoAgentId = "333", DateRepossessed = DateTime.Parse("2020-02-10"), RepoType = RepoType.Involuntary, DateRepoAssigned = DateTime.Parse("2018-02-10"), }; var companyForCollateral = new RepoCompanySelection() { RepoType = RepoType.Voluntary, RepoCompanyId = 3, DateRepoed = null, RepoCompanyAssignmentDate = DateTime.Parse("2015-02-10") }; var collateral = new Collateral() { CollateralId = 0, RepoCompanySelections = new List { companyForCollateral } }; var updates = _repoAccountProcessorService.UpdateOrCreateRepoCompanyAssignment(collateral, companyForCollateral, temenosCase, 3); Assert.Equal(2, updates.Count); updates = updates.OrderByDescending(x => x.DateRepoed).ToList(); Assert.Equal(temenosCase.RepoType, updates[1].RepoType); Assert.Equal(temenosCase.DateRepoAssigned, updates[1].RepoCompanyAssignmentDate); Assert.Equal(temenosCase.DateRepossessed, updates[1].DateRepoed); Assert.Equal(companyForCollateral.RepoType, updates[0].RepoType); Assert.Equal(companyForCollateral.RepoCompanyAssignmentDate, updates[0].RepoCompanyAssignmentDate); Assert.Contains(DateTime.Today.ToShortDateString().ToString(CultureInfo.InvariantCulture), updates[0].DateRepoed.ToString()); Assert.Equal(updates[0], collateral.RepoCompanySelections.OrderByDescending(x => x.DateRepoed).ToList()[0]); } [Fact] public void UpdateOrCreateRepoCompanyAssignment_No_Update_Ok() { var temenosCase = new TemenosCase() { RepoAgentId = "333", DateRepossessed = DateTime.Parse("12-31-2021"), RepoType = RepoType.Voluntary, DateRepoAssigned = DateTime.Parse("2015-02-10") }; var companyForCollateral = new RepoCompanySelection() { RepoType = RepoType.Voluntary, RepoCompanyId = 3, DateRepoed = null, RepoCompanyAssignmentDate = DateTime.Parse("2015-02-10") }; var collateral = new Collateral() { CollateralId = 0, RepoCompanySelections = new List { companyForCollateral } }; var updates = _repoAccountProcessorService.UpdateOrCreateRepoCompanyAssignment(collateral, companyForCollateral, temenosCase, 3); Assert.Single(updates); Assert.Equal(DateTime.Parse("12-31-2021"), updates.Single().DateRepoed); Assert.Equal(collateral.RepoCompanySelections, updates); } [Fact] public void UpdateOrCreateRepoCompanyAssignment_No_Selections_New_Data() { var temenosCase = new TemenosCase() { RepoAgentId = "333", DateRepossessed = DateTime.Parse("12-31-2021"), RepoType = RepoType.Voluntary, DateRepoAssigned = DateTime.Parse("2015-02-10") }; var collateral = new Collateral() { CollateralId = 0, RepoCompanySelections = new List() }; var updates = _repoAccountProcessorService.UpdateOrCreateRepoCompanyAssignment(collateral, null, temenosCase, 3); Assert.Single(updates); Assert.Single(collateral.RepoCompanySelections); Assert.Equal(updates, collateral.RepoCompanySelections); Assert.Equal(3, updates.Single().RepoCompanyId); Assert.Equal(DateTime.Parse("12-31-2021"), updates.Single().DateRepoed); Assert.Equal(DateTime.Parse("2015-02-10"), updates.Single().RepoCompanyAssignmentDate); Assert.Equal(RepoType.Voluntary, updates.Single().RepoType); } [Fact] public void UpdateOrCreateRepoCompanyAssignment_No_Selections_No_Fields() { var temenosCase = new TemenosCase(); var collateral = new Collateral() { CollateralId = 0, RepoCompanySelections = new List() }; var updates = _repoAccountProcessorService.UpdateOrCreateRepoCompanyAssignment(collateral, null, temenosCase, null); Assert.Empty(updates); Assert.Empty(collateral.RepoCompanySelections); } [Fact] public void GetDateTimeFromString_Ok() { var dateString = "2015-02-10"; var result = _repoAccountProcessorService.GetDateTimeFromString(dateString); Assert.True(result.IsSuccess); Assert.Equal(new DateTime(2015, 02, 10), result.Value); Assert.Null(result.ErrorMessage); dateString = ""; result = _repoAccountProcessorService.GetDateTimeFromString(dateString); Assert.False(result.IsSuccess); Assert.Null(result.Value); Assert.Equal("Cannot Parse Empty Date String", result.ErrorMessage); dateString = "¯\\_(ツ)_/¯"; result = _repoAccountProcessorService.GetDateTimeFromString(dateString); Assert.False(result.IsSuccess); Assert.Null(result.Value); Assert.Equal("There was an Exception when processing the date string: ¯\\_(ツ)_/¯", result.ErrorMessage); } } }