package com.piggymetrics.statistics.service; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.piggymetrics.statistics.domain.*; import com.piggymetrics.statistics.domain.timeseries.DataPoint; import com.piggymetrics.statistics.domain.timeseries.ItemMetric; import com.piggymetrics.statistics.domain.timeseries.StatisticMetric; import com.piggymetrics.statistics.repository.DataPointRepository; import org.junit.Before; import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; import java.time.ZoneId; import java.util.Date; import java.util.List; import java.util.Map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.AdditionalAnswers.returnsFirstArg; import static org.mockito.Mockito.*; import static org.mockito.MockitoAnnotations.initMocks; public class StatisticsServiceImplTest { @InjectMocks private StatisticsServiceImpl statisticsService; @Mock private ExchangeRatesServiceImpl ratesService; @Mock private DataPointRepository repository; @Before public void setup() { initMocks(this); } @Test public void shouldFindDataPointListByAccountName() { final List<DataPoint> list = ImmutableList.of(new DataPoint()); when(repository.findByIdAccount("test")).thenReturn(list); List<DataPoint> result = statisticsService.findByAccountName("test"); assertEquals(list, result); } @Test(expected = IllegalArgumentException.class) public void shouldFailToFindDataPointWhenAccountNameIsNull() { statisticsService.findByAccountName(null); } @Test(expected = IllegalArgumentException.class) public void shouldFailToFindDataPointWhenAccountNameIsEmpty() { statisticsService.findByAccountName(""); } @Test public void shouldSaveDataPoint() { /** * Given */ Item salary = new Item(); salary.setTitle("Salary"); salary.setAmount(new BigDecimal(9100)); salary.setCurrency(Currency.USD); salary.setPeriod(TimePeriod.MONTH); Item grocery = new Item(); grocery.setTitle("Grocery"); grocery.setAmount(new BigDecimal(500)); grocery.setCurrency(Currency.RUB); grocery.setPeriod(TimePeriod.DAY); Item vacation = new Item(); vacation.setTitle("Vacation"); vacation.setAmount(new BigDecimal(3400)); vacation.setCurrency(Currency.EUR); vacation.setPeriod(TimePeriod.YEAR); Saving saving = new Saving(); saving.setAmount(new BigDecimal(1000)); saving.setCurrency(Currency.EUR); saving.setInterest(new BigDecimal(3.2)); saving.setDeposit(true); saving.setCapitalization(false); Account account = new Account(); account.setIncomes(ImmutableList.of(salary)); account.setExpenses(ImmutableList.of(grocery, vacation)); account.setSaving(saving); final Map<Currency, BigDecimal> rates = ImmutableMap.of( Currency.EUR, new BigDecimal("0.8"), Currency.RUB, new BigDecimal("80"), Currency.USD, BigDecimal.ONE ); /** * When */ when(ratesService.convert(any(Currency.class),any(Currency.class),any(BigDecimal.class))) .then(i -> i.getArgumentAt(2, BigDecimal.class) .divide(rates.get(i.getArgumentAt(0, Currency.class)), 4, RoundingMode.HALF_UP)); when(ratesService.getCurrentRates()).thenReturn(rates); when(repository.save(any(DataPoint.class))).then(returnsFirstArg()); DataPoint dataPoint = statisticsService.save("test", account); /** * Then */ final BigDecimal expectedExpensesAmount = new BigDecimal("17.8861"); final BigDecimal expectedIncomesAmount = new BigDecimal("298.9802"); final BigDecimal expectedSavingAmount = new BigDecimal("1250"); final BigDecimal expectedNormalizedSalaryAmount = new BigDecimal("298.9802"); final BigDecimal expectedNormalizedVacationAmount = new BigDecimal("11.6361"); final BigDecimal expectedNormalizedGroceryAmount = new BigDecimal("6.25"); assertEquals(dataPoint.getId().getAccount(), "test"); assertEquals(dataPoint.getId().getDate(), Date.from(LocalDate.now().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant())); assertTrue(expectedExpensesAmount.compareTo(dataPoint.getStatistics().get(StatisticMetric.EXPENSES_AMOUNT)) == 0); assertTrue(expectedIncomesAmount.compareTo(dataPoint.getStatistics().get(StatisticMetric.INCOMES_AMOUNT)) == 0); assertTrue(expectedSavingAmount.compareTo(dataPoint.getStatistics().get(StatisticMetric.SAVING_AMOUNT)) == 0); ItemMetric salaryItemMetric = dataPoint.getIncomes().stream() .filter(i -> i.getTitle().equals(salary.getTitle())) .findFirst().get(); ItemMetric vacationItemMetric = dataPoint.getExpenses().stream() .filter(i -> i.getTitle().equals(vacation.getTitle())) .findFirst().get(); ItemMetric groceryItemMetric = dataPoint.getExpenses().stream() .filter(i -> i.getTitle().equals(grocery.getTitle())) .findFirst().get(); assertTrue(expectedNormalizedSalaryAmount.compareTo(salaryItemMetric.getAmount()) == 0); assertTrue(expectedNormalizedVacationAmount.compareTo(vacationItemMetric.getAmount()) == 0); assertTrue(expectedNormalizedGroceryAmount.compareTo(groceryItemMetric.getAmount()) == 0); assertEquals(rates, dataPoint.getRates()); verify(repository, times(1)).save(dataPoint); } }