using FluentAssertions; using FluentValidation; using Microsoft.EntityFrameworkCore; using Moq; using ReserveManagementSystemApi.Models; using ReserveManagementSystemApi.ServiceClients; using ReserveManagementSystemApi.Services; using ReserveManagementSystemLib.Models; using ReserveManagementSystemLib.Persistence; using ReserveManagementSystemLib.Repositories; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using TechTalk.SpecFlow; using TechTalk.SpecFlow.Assist; using TechTalk.SpecFlow.Assist.ValueRetrievers; using Xunit; namespace ReserveManagementSystemApi.Tests.ServiceTests { [Binding] public sealed class LoanServiceSteps { // For additional details on SpecFlow step definitions see https://go.specflow.org/doc-stepdef private readonly ScenarioContext _scenarioContext; private LoanService _loanService; private AppDbContext _appDbContext; private IEnumerable _loansResult; private List _loansToSave; private Loan _loanResult; private Exception _exception; private LoanFilter _loanFilter; private List _memberResult; private List _loanNumberResult; private List _applicationIdResult; PaginatedListResponse _pagedListResponse = new PaginatedListResponse(); private IEnumerable _closedLoans; private IEnumerable _loansInSystem; private IEnumerable _loansNotInSystem; private Mock _mockLoanRepo = new Mock(); private Mock _mockAuditHistRepo = new Mock(); public LoanServiceSteps(ScenarioContext scenarioContext) { _scenarioContext = scenarioContext; } [BeforeScenario] public void CreateDatabase() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .Options; _appDbContext = new AppDbContext(options); _loanService = new LoanService(new LoanRepository(_appDbContext), new LoanTypeRepository(_appDbContext), new AuditHistoryService(_mockAuditHistRepo.Object), new Mock().Object); } [AfterScenario] public void Dispose() { _appDbContext.Database.EnsureDeleted(); _appDbContext.Dispose(); } [Given(@"the Loan table has the following loans")] public void GivenTheLoanTableHasTheFollowingLoans(Table table) { var loans = table.CreateSet(); _appDbContext.Loans.AddRange(loans); _appDbContext.SaveChanges(); } [Given(@"I have these loans to save")] public void GivenIHaveThisLoanToSave(Table table) { _loansToSave = table.CreateSet().ToList(); } [Given(@"a loan filter that looks like")] public void GivenALoanFilterThatLooksLike(Table table) { _loanFilter = table.CreateInstance(); } [Then(@"the first loan from the loan service has ImportId (.*)")] public void ThenTheFirstLoanFromTheLoanServiceHasImportId(int importId) { Assert.Equal(importId, _loansResult.First().ImportId); } [Given(@"the Loan Repository throws an exception in ListAll")] public void GivenTheLoanRepositoryThrowsAnExceptionInListAll() { _mockLoanRepo.Setup(a => a.GetAll()).Throws(new Exception()); _loanService = new LoanService(_mockLoanRepo.Object, new LoanTypeRepository(_appDbContext), new AuditHistoryService(_mockAuditHistRepo.Object), new Mock().Object); } [Given(@"the Loan Repository throws an exception in FindByIdAsync")] public void GivenTheLoanRepositoryThrowsAnExceptionInFindByIdAsync() { _mockLoanRepo.Setup(a => a.FindByIdAsync(It.IsAny())).Throws(new Exception()); _loanService = new LoanService(_mockLoanRepo.Object, new LoanTypeRepository(_appDbContext), new AuditHistoryService(_mockAuditHistRepo.Object), new Mock().Object); } [Given(@"the Loan Repository throws an exception in UpdateAsync")] public void GivenTheLoanRepositoryThrowsAnExceptionInAdd() { _mockLoanRepo.Setup(a => a.UpdateAsync(It.IsAny>())).Throws(new Exception()); _loanService = new LoanService(_mockLoanRepo.Object, new LoanTypeRepository(_appDbContext), new AuditHistoryService(_mockAuditHistRepo.Object), new Mock().Object); } [Given(@"loan types that look like")] public void GivenLoanTypesThatLookLike(Table table) { var loanTypes = table.CreateSet().ToList(); _appDbContext.LoanTypes.AddRange(loanTypes); _appDbContext.SaveChanges(); } [Given(@"I have these loans to save with chargebacks")] public void GivenIHaveTheseLoansToSaveWithChargebacks(Table table) { _closedLoans = table.CreateSet().ToList(); } [Given(@"the dealer table has these dealers")] public void GivenTheDealerTableHasTheseDealers(Table table) { var dealers = table.CreateSet().ToList(); _appDbContext.Dealers.AddRange(dealers); _appDbContext.SaveChanges(); } [When(@"I save the loans with chargebacks")] public async void WhenISaveTheLoansWithChargebacks() { try { var result = await _loanService.SaveWithChargebackAsync(_closedLoans.ToList()); } catch (Exception ex) { _exception = ex; } } [When(@"I get the list of all loans with the loan service")] public async void WhenIGetTheListOfAllLoansWithTheLoanService() { try { _loansResult = await _loanService.GetAllAsync(); } catch (Exception ex) { _exception = ex; } } [When(@"I get the list of all loans with the loan service with the mock loan repo")] public async void WhenIGetTheListOfAllLoansWithTheLoanServiceWithTheMockLoanRepo() { try { _loansResult = await _loanService.GetAllAsync(); } catch (Exception ex) { _exception = ex; } } [When(@"I get the list of the filtered loans with the loan service")] public async void WhenIGetTheListOfTheFilteredLoansWithTheLoanService() { try { _pagedListResponse = await _loanService.GetFilteredAsync(_loanFilter); _loansResult = _pagedListResponse.LoanList; } catch (Exception ex) { _exception = ex; } } [When(@"I get the list of paged loans")] public async void WhenIGetTheListOfPagedLoans() { try { _pagedListResponse = await _loanService.GetFilteredAsync(_loanFilter); _loansResult = _pagedListResponse.LoanList; } catch (Exception ex) { _exception = ex; } } [Then(@"the result from the loan service should have (.*) pages")] public void ThenTheResultFromTheLoanServiceShouldHavePages(int pageCount) { Assert.Equal(pageCount, _pagedListResponse.TotalPages); } [Then(@"the result from the loan service should have (.*) records")] public void ThenTheResultFromTheLoanServiceShouldHaveRecords(int recordCount) { Assert.Equal(recordCount, _pagedListResponse.LoanList.Count()); } [Then(@"the result from the loan service should have (.*) total items")] public void ThenTheResultFromTheLoanServiceShouldHaveTotalItems(int recordCount) { Assert.Equal(recordCount, _pagedListResponse.TotalItems); } [Then(@"the first result from the loan service should have loanid (.*)")] public void ThenTheFirstResultFromTheLoanServiceShouldHaveLoanId(int loanId) { Assert.Equal(loanId, _pagedListResponse.LoanList.First().LoanId); } //have to rethink this if we get rid of the other one [When(@"I save the loan with the reserve")] public async void WhenISaveTheLoan() { try { await _loanService.SaveLoansAsync(_loansToSave); } catch (Exception ex) { _exception = ex; } } [When(@"I save the loan with the reserve with the mock loan repo")] public async void WhenISaveTheLoanWithTheReserveWithTheMockLoanRepo() { try { await _loanService.SaveLoansAsync(_loansToSave); } catch (Exception ex) { _exception = ex; } } [Then(@"the result from the loan service has previous page should be (.*)")] public void ThenTheResultFromTheLoanServiceHasPreviousPageShouldBe(bool hasPreviousPage) { Assert.Equal(hasPreviousPage, _pagedListResponse.HasPreviousPage); } [Then(@"the result from the loan service has next page should be (.*)")] public void ThenTheResultFromTheLoanServiceHasNextPageShouldBe(bool hasNextPage) { Assert.Equal(hasNextPage, _pagedListResponse.HasNextPage); } [Then (@"the result from the loan service first page should be (.*)")] public void ThenTheResultFromTheLoanServiceFirstPageShouldBe(int firstPage) { Assert.Equal(firstPage, _pagedListResponse.FirstPage); } [Then(@"the result from the loan service last page should be (.*)")] public void ThenTheResultFromTheLoanServiceLastPageShouldBe(int lastPage) { Assert.Equal(lastPage, _pagedListResponse.LastPage); } [When(@"I get the loan with the loanId (.*) from the loan service")] public async void WhenIGetTheLoanWithTheLoanIdFromTheLoanService(int loanId) { try { _loanResult = await _loanService.GetByIdAsync(loanId); } catch (Exception ex) { _exception = ex; } } [When(@"I get the loan with the loanId (.*) from the loan service using the Mock Loan Repo")] public async void WhenIGetTheLoanWithTheLoanIdFromTheLoanServiceUsingTheMockLoanRepo(int loanId) { try { _loanResult = await _loanService.GetByIdAsync(loanId); } catch (Exception ex) { _exception = ex; } } [When(@"I get the list of members with search string ""(.*)""")] public async void WhenIGetTheListOfMembersWithSearchString(string searchString) { _memberResult = await _loanService.SearchMembers(searchString); } [When(@"I get the list of loan numbers with search string ""(.*)""")] public async void WhenIGetTheListOfLoanNumbersWithSearchString(string searchString) { _loanNumberResult = await _loanService.SearchLoanNumbers(searchString); } [When(@"I get the list of application ids with search string ""(.*)""")] public async void WhenIGetTheListOfApplicationIdsWithSearchString(string searchString) { _applicationIdResult = await _loanService.SearchApplicationIds(searchString); } [Then(@"the result from the loan service should have (.*) loans")] public void ThenTheResultFromTheLoanServiceShouldHaveLoans(int loanCount) { Assert.Equal(loanCount, _loansResult.Count()); } [Then(@"the list of members returned is in this order")] public void ThenTheListOfMembersReturnedIsInThisOrder(Table table) { var expectedMemberNumbers = table.Rows.Select(x => x[0]).ToList(); _memberResult.Should().BeEquivalentTo(expectedMemberNumbers).And.ContainInOrder(expectedMemberNumbers); } [Then(@"the list of loan numbers looks like")] public void ThenTheListOfLoanNumbersLooksLike(Table table) { var expectedLoanNumbers = table.Rows.Select(x => x[0]).ToList(); _loanNumberResult.Should().BeEquivalentTo(expectedLoanNumbers).And.ContainInOrder(expectedLoanNumbers); } [Then(@"the list of application ids looks like")] public void ThenTheListOfApplicationIdsLooksLike(Table table) { var expectedApplicationIds = table.Rows.Select(x => x[0]).ToList(); _applicationIdResult.Should().BeEquivalentTo(expectedApplicationIds).And.ContainInOrder(expectedApplicationIds); } [Then(@"the loans from the loan service look like")] public async void ThenTheLoanFromTheLoanServiceLooksLike(Table table) { var actualLoans = (await _loanService.GetAllAsync()).ToList(); table.CompareToSet(actualLoans); } [Then(@"the first loan from the loan service has LoanId (.*)")] public void ThenTheFirstLoanFromTheLoanServiceHasLoanId(int loanId) { Assert.Equal(loanId, _loansResult.First().LoanId); } [Then(@"the loan ids from the loan service look like")] public void ThenTheLoanIdsFromTheLoanServiceLookLike(Table table) { var expectedLoanIds = table.CreateSet().ToList(); _loansResult.Select(x => x.LoanId).Should().BeEquivalentTo(expectedLoanIds).And.ContainInOrder(expectedLoanIds); } [Then(@"the loan ids from the loan service look like ""(.*)""")] public void ThenTheLoanIdsFromTheLoanServiceLookLike(string listOfIds) { var expected = listOfIds.Split(',').Select(x => int.Parse(x)).ToList(); _loansResult.Select(x => x.LoanId).Should().BeEquivalentTo(expected); } [Then(@"the loan with LoanId (.*) has dealer name ""(.*)""")] public void ThenTheLoanWithLoanIdHasDealerName(int loanId, string dealerName) { Assert.Equal(dealerName, _loansResult.First(x => x.LoanId == loanId).Dealer.Name); } [Then(@"the Loan Service throws an exception with the message ""(.*)""")] public void ThenTheLoanServiceThrowsAnExceptionWithTheMessage(string message) { Assert.NotNull(_exception); Assert.Equal(message, _exception.Message); } [Then(@"the loan from the loan service has LoanId (.*)")] public void ThenTheLoanFromTheLoanServiceHasLoanId(int loanId) { Assert.Equal(loanId, _loanResult.LoanId); } [Then(@"the loan from the loan service has dealer name ""(.*)""")] public void ThenTheLoanFromTheLoanServiceHasDealerName(string dealerName) { Assert.Equal(dealerName, _loanResult.Dealer.Name); } [Then(@"the flat fee result for MemberNumber (.*) should be (.*)")] public void ThenTheReserveAmountResultShouldBe(string member, bool feePaid) { Assert.Equal(feePaid, _loansResult.FirstOrDefault(x => x.MemberNumber == member).FlatFeePaid); } [Then(@"the loan from the loan service has LoanType.LoanComment ""(.*)""")] public void ThenTheLoanFromTheLoanServiceHasLoanTypeDescription(string description) { Assert.Equal(description, _loanResult.LoanType?.LoanComment ?? string.Empty); } [Then(@"the loans in the system look like")] public void ThenTheLoansInTheSystemLookLike(Table table) { table.CompareToSet(_loansInSystem); } [Then(@"the loans not in the system look like")] public void ThenTheLoansNotInTheSystemLookLike(Table table) { table.CompareToSet(_loansNotInSystem); } [Then(@"the loans in the loan table will look like")] public void ThenTheLoansInTheLoanTableWillLookLike(Table table) { table.CompareToSet(_loansResult); } } }