InvestmentSizeRecommender implements BiFunction<Loan, SessionInfo, Money> { @Override public Money apply(final Loan loan, final SessionInfo sessionInfo) { final int id = loan.getId(); final Money[] recommended = getInvestmentBounds(strategy, loan, sessionInfo); final Money minimumRecommendation = recommended[0]; final Money maximumRecommendation = recommended[1]; LOGGER.debug("Recommended investment range for loan #{} is <{}; {}>.", id, minimumRecommendation, maximumRecommendation); final Money loanRemaining = loan.getNonReservedRemainingInvestment(); final Money zero = loanRemaining.getZero(); if (minimumRecommendation.compareTo(loanRemaining) > 0) { LOGGER.debug("Not recommending loan #{} due to minimum over remaining.", id); return zero; } final Money recommendedAmount = maximumRecommendation.min(loanRemaining); final Money r = roundToNearestIncrement(recommendedAmount, sessionInfo.getInvestmentStep()); if (r.compareTo(minimumRecommendation) < 0) { LOGGER.debug("Not recommending loan #{} due to recommendation below minimum.", id); return zero; } else { LOGGER.debug("Final recommendation for loan #{} is {}.", id, r); return r; } } InvestmentSizeRecommender(final ParsedStrategy strategy); @Override Money apply(final Loan loan, final SessionInfo sessionInfo);  }
@Test void withSpecificRating() { final ParsedStrategy s = getStrategy(); final InvestmentSizeRecommender r = new InvestmentSizeRecommender(s); final Loan loan = mockLoan(50_000); final Money actualInvestment = r.apply(loan, mockSessionInfo()); assertThat(actualInvestment).isEqualTo(Money.from(400)); }
@Test void byDefault() { final ParsedStrategy s = getStrategy(); final Loan l = mockLoan(100_000); final InvestmentSizeRecommender r = new InvestmentSizeRecommender(s); final Money actualInvestment = r.apply(l, mockSessionInfo()); assertThat(actualInvestment).isEqualTo(Money.from(MAXIMUM_INVESTMENT)); }
@Test void nothingMoreToInvest() { final SessionInfo sessionInfo = mockSessionInfo(); final ParsedStrategy s = getStrategy(); final Loan l = mockLoan(sessionInfo.getMinimumInvestmentAmount() .getValue() .intValue() - 1); final InvestmentSizeRecommender r = new InvestmentSizeRecommender(s); final Money actualInvestment = r.apply(l, sessionInfo); assertThat(actualInvestment).isEqualTo(Money.ZERO); }
@Test void minimumOverRemaining() { final SessionInfo sessionInfo = mockSessionInfo(); final Money minimumInvestment = sessionInfo.getMinimumInvestmentAmount(); final Loan l = mockLoan(minimumInvestment.getValue() .intValue() - 1); final ParsedStrategy s = mock(ParsedStrategy.class); when(s.getMinimumInvestmentSize(eq(l.getRating()))).thenReturn(minimumInvestment); when(s.getMaximumInvestmentSize(eq(l.getRating()))).thenReturn(minimumInvestment.add(minimumInvestment)); when(s.getMaximumInvestmentShareInPercent()).thenReturn(100); final InvestmentSizeRecommender r = new InvestmentSizeRecommender(s); assertThat(r.apply(l, sessionInfo)).isEqualTo(Money.ZERO); }
@Test void recommendationRoundedUnderMinimum() { final SessionInfo sessionInfo = mockSessionInfo(); final Money minimumInvestment = sessionInfo.getMinimumInvestmentAmount(); final Loan l = mockLoan(minimumInvestment.getValue() .intValue() - 1); final ParsedStrategy s = mock(ParsedStrategy.class); when(s.getMinimumInvestmentSize(eq(l.getRating()))).thenReturn( minimumInvestment.subtract(1)); when(s.getMaximumInvestmentSize(eq(l.getRating()))) .thenReturn(minimumInvestment); when(s.getMaximumInvestmentShareInPercent()).thenReturn(100); final InvestmentSizeRecommender r = new InvestmentSizeRecommender(s); assertThat(r.apply(l, sessionInfo)).isEqualTo(Money.ZERO); }