StatisticsServiceImpl implements StatisticsService { @Override public DataPoint save(String accountName, Account account) { Instant instant = LocalDate.now().atStartOfDay() .atZone(ZoneId.systemDefault()).toInstant(); DataPointId pointId = new DataPointId(accountName, Date.from(instant)); Set<ItemMetric> incomes = account.getIncomes().stream() .map(this::createItemMetric) .collect(Collectors.toSet()); Set<ItemMetric> expenses = account.getExpenses().stream() .map(this::createItemMetric) .collect(Collectors.toSet()); Map<StatisticMetric, BigDecimal> statistics = createStatisticMetrics(incomes, expenses, account.getSaving()); DataPoint dataPoint = new DataPoint(); dataPoint.setId(pointId); dataPoint.setIncomes(incomes); dataPoint.setExpenses(expenses); dataPoint.setStatistics(statistics); dataPoint.setRates(ratesService.getCurrentRates()); log.debug("new datapoint has been created: {}", pointId); return repository.save(dataPoint); }  @Override List<DataPoint> findByAccountName(String accountName); @Override DataPoint save(String accountName, Account account);  }
@Test public void shouldSaveDataPoint() { 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(ratesService.convert(any(Currency.class),any(Currency.class),any(BigDecimal.class))) .then(i -> ((BigDecimal)i.getArgument(2)) .divide(rates.get(i.getArgument(0)), 4, RoundingMode.HALF_UP)); when(ratesService.getCurrentRates()).thenReturn(rates); when(repository.save(any(DataPoint.class))).then(returnsFirstArg()); DataPoint dataPoint = statisticsService.save("test", account); 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); }
@Test public void shouldSaveDataPoint() { 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(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); 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); }