Various fixes and additions all over the tree

Add a method to obtain all active recurring transactions. Add and adjust
unit and integration tests.
This commit is contained in:
2019-03-24 23:20:02 +01:00
parent d6572e26f1
commit f9b448f24e
15 changed files with 143 additions and 76 deletions

View File

@@ -29,16 +29,6 @@ public class AccountController {
return this.accountService.getAll(); return this.accountService.getAll();
} }
@RequestMapping("getAccountTypes")
public Iterable<String> getAccountTypes() {
return this.accountService.getAccountTypes();
}
@RequestMapping("getAccountStatus")
public Iterable<String> getAccountStatus() {
return this.accountService.getAccountStatus();
}
@RequestMapping("createAccount") @RequestMapping("createAccount")
public ResponseEntity createAccount(String key, String type) { public ResponseEntity createAccount(String key, String type) {
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {

View File

@@ -26,6 +26,11 @@ public class RecurringTransactionController {
return this.recurringTransactionService.getAll(); return this.recurringTransactionService.getAll();
} }
@RequestMapping("getAllActive")
public Iterable<RecurringTransaction> getAllActive() {
return this.recurringTransactionService.getAllActive();
}
@RequestMapping("getAllForAccount") @RequestMapping("getAllForAccount")
public Iterable<RecurringTransaction> getAllForAccount(String accountKey) { public Iterable<RecurringTransaction> getAllForAccount(String accountKey) {
return this.recurringTransactionService.getAllForAccount(accountKey); return this.recurringTransactionService.getAllForAccount(accountKey);

View File

@@ -6,7 +6,11 @@ import org.springframework.data.repository.CrudRepository;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
@Transactional(propagation = Propagation.REQUIRED) @Transactional(propagation = Propagation.REQUIRED)
public interface RecurringTransactionRepository extends CrudRepository<RecurringTransaction, Long> { public interface RecurringTransactionRepository extends CrudRepository<RecurringTransaction, Long> {
Iterable<RecurringTransaction> findRecurringTransactionsByFromAccountOrToAccount(Account fromAccount, Account toAccount); Iterable<RecurringTransaction> findRecurringTransactionsByFromAccountOrToAccount(Account fromAccount, Account toAccount);
Iterable<RecurringTransaction> findByLastOccurrenceIsNullOrLastOccurrenceGreaterThanEqual(LocalDate lastOccurrence);
} }

View File

@@ -40,20 +40,6 @@ public class AccountService {
return this.accountRepository.findAll(); return this.accountRepository.findAll();
} }
/**
* @return all possible account types as specified by the {@link AccountType} enumeration, never <code>null</code>
*/
public Iterable<String> getAccountTypes() {
return Arrays.stream(AccountType.values()).map(AccountType::name).collect(Collectors.toList());
}
/**
* @return all possible account status as specified by the {@link AccountStatus} enumeration, never <code>null</code>
*/
public Iterable<String> getAccountStatus() {
return Arrays.stream(AccountStatus.values()).map(AccountStatus::name).collect(Collectors.toList());
}
/** /**
* This method saves the given account. It either updates the account if it already exists or inserts * This method saves the given account. It either updates the account if it already exists or inserts
* it if it's new. * it if it's new.

View File

@@ -47,6 +47,11 @@ public class RecurringTransactionService {
return this.recurringTransactionRepository.findAll(); return this.recurringTransactionRepository.findAll();
} }
public Iterable<RecurringTransaction> getAllActive() {
return this.recurringTransactionRepository
.findByLastOccurrenceIsNullOrLastOccurrenceGreaterThanEqual(LocalDate.now());
}
public Iterable<RecurringTransaction> getAllForAccount(String accountKey) { public Iterable<RecurringTransaction> getAllForAccount(String accountKey) {
final Account account = this.accountService.getAccountByKey(accountKey); final Account account = this.accountService.getAccountByKey(accountKey);
@@ -73,8 +78,8 @@ public class RecurringTransactionService {
// Visible for unit tests // Visible for unit tests
/* package */ Iterable<RecurringTransaction> getAllDueToday(LocalDate now) { /* package */ Iterable<RecurringTransaction> getAllDueToday(LocalDate now) {
// TODO filter for lastOccurrence not in the past final Iterable<RecurringTransaction> allRecurringTransactions = this.recurringTransactionRepository
final Iterable<RecurringTransaction> allRecurringTransactions = this.recurringTransactionRepository.findAll(); .findByLastOccurrenceIsNullOrLastOccurrenceGreaterThanEqual(now);
//@formatter:off //@formatter:off
return IterableUtils.toList(allRecurringTransactions).stream() return IterableUtils.toList(allRecurringTransactions).stream()
@@ -332,19 +337,19 @@ public class RecurringTransactionService {
response = ResponseReason.MISSING_AMOUNT; response = ResponseReason.MISSING_AMOUNT;
} else if (amount == 0L) { } else if (amount == 0L) {
response = ResponseReason.AMOUNT_ZERO; response = ResponseReason.AMOUNT_ZERO;
} else if (holidayWeekendType == null) { } else if (StringUtils.isEmpty(holidayWeekendType)) {
response = ResponseReason.MISSING_HOLIDAY_WEEKEND_TYPE; response = ResponseReason.MISSING_HOLIDAY_WEEKEND_TYPE;
} else if (!HolidayWeekendType.isValidType(holidayWeekendType)) { } else if (!HolidayWeekendType.isValidType(holidayWeekendType)) {
response = ResponseReason.INVALID_HOLIDAY_WEEKEND_TYPE; response = ResponseReason.INVALID_HOLIDAY_WEEKEND_TYPE;
} else if (intervalType == null) { } else if (StringUtils.isEmpty(intervalType)) {
response = ResponseReason.MISSING_INTERVAL_TYPE; response = ResponseReason.MISSING_INTERVAL_TYPE;
} else if (!IntervalType.isValidType(intervalType)) { } else if (!IntervalType.isValidType(intervalType)) {
response = ResponseReason.INVALID_INTERVAL_TYPE; response = ResponseReason.INVALID_INTERVAL_TYPE;
} else if (firstOccurrence == null) { } else if (StringUtils.isEmpty(firstOccurrence)) {
response = ResponseReason.MISSING_FIRST_OCCURRENCE; response = ResponseReason.MISSING_FIRST_OCCURRENCE;
} }
if (response == null && firstOccurrence != null) { if (response == null && StringUtils.isNotEmpty(firstOccurrence)) {
try { try {
LocalDate.parse(firstOccurrence, DateTimeFormatter.ofPattern(this.financerConfig.getDateFormat())); LocalDate.parse(firstOccurrence, DateTimeFormatter.ofPattern(this.financerConfig.getDateFormat()));
} catch (DateTimeParseException e) { } catch (DateTimeParseException e) {
@@ -352,7 +357,7 @@ public class RecurringTransactionService {
} }
} }
if (response == null && lastOccurrence != null) { if (response == null && StringUtils.isNotEmpty(lastOccurrence)) {
try { try {
LocalDate.parse(lastOccurrence, DateTimeFormatter.ofPattern(this.financerConfig.getDateFormat())); LocalDate.parse(lastOccurrence, DateTimeFormatter.ofPattern(this.financerConfig.getDateFormat()));
} catch (DateTimeParseException e) { } catch (DateTimeParseException e) {
@@ -407,8 +412,7 @@ public class RecurringTransactionService {
try { try {
this.recurringTransactionRepository.deleteById(Long.valueOf(recurringTransactionId)); this.recurringTransactionRepository.deleteById(Long.valueOf(recurringTransactionId));
} } catch (Exception e) {
catch (Exception e) {
LOGGER.error("Could not delete recurring transaction!", e); LOGGER.error("Could not delete recurring transaction!", e);
response = ResponseReason.UNKNOWN_ERROR; response = ResponseReason.UNKNOWN_ERROR;

View File

@@ -4,8 +4,10 @@ import de.financer.ResponseReason;
import de.financer.config.FinancerConfig; import de.financer.config.FinancerConfig;
import de.financer.dba.TransactionRepository; import de.financer.dba.TransactionRepository;
import de.financer.model.Account; import de.financer.model.Account;
import de.financer.model.AccountType;
import de.financer.model.RecurringTransaction; import de.financer.model.RecurringTransaction;
import de.financer.model.Transaction; import de.financer.model.Transaction;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils; import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -87,8 +89,17 @@ public class TransactionService {
fromAccount.setCurrentBalance(fromAccount.getCurrentBalance() + (this.ruleService fromAccount.setCurrentBalance(fromAccount.getCurrentBalance() + (this.ruleService
.getMultiplierFromAccount(fromAccount) * amount)); .getMultiplierFromAccount(fromAccount) * amount));
toAccount.setCurrentBalance(toAccount.getCurrentBalance() + (this.ruleService
.getMultiplierToAccount(toAccount) * amount)); // Special case: if we do the initial bookings, and the booking is to introduce a liability,
// the balance of the liability account must increase
if (AccountType.START.equals(fromAccount.getType()) && AccountType.LIABILITY.equals(toAccount.getType())) {
toAccount.setCurrentBalance(toAccount.getCurrentBalance() + (this.ruleService
.getMultiplierToAccount(toAccount) * amount * -1));
}
else {
toAccount.setCurrentBalance(toAccount.getCurrentBalance() + (this.ruleService
.getMultiplierToAccount(toAccount) * amount));
}
this.transactionRepository.save(transaction); this.transactionRepository.save(transaction);
@@ -158,9 +169,9 @@ public class TransactionService {
response = ResponseReason.MISSING_AMOUNT; response = ResponseReason.MISSING_AMOUNT;
} else if (amount == 0L) { } else if (amount == 0L) {
response = ResponseReason.AMOUNT_ZERO; response = ResponseReason.AMOUNT_ZERO;
} else if (date == null) { } else if (StringUtils.isEmpty(date)) {
response = ResponseReason.MISSING_DATE; response = ResponseReason.MISSING_DATE;
} else if (date != null) { } else if (StringUtils.isNotEmpty(date)) {
try { try {
LocalDate.parse(date, DateTimeFormatter.ofPattern(this.financerConfig.getDateFormat())); LocalDate.parse(date, DateTimeFormatter.ofPattern(this.financerConfig.getDateFormat()));
} catch (DateTimeParseException e) { } catch (DateTimeParseException e) {

View File

@@ -6,6 +6,7 @@
spring.profiles.active=@activeProfiles@ spring.profiles.active=@activeProfiles@
server.servlet.context-path=/financer-server server.servlet.context-path=/financer-server
server.port=8089
spring.jpa.hibernate.ddl-auto=validate spring.jpa.hibernate.ddl-auto=validate

View File

@@ -54,6 +54,6 @@ public class RecurringTransactionService_createRecurringTransactionIntegrationTe
final List<RecurringTransaction> allRecurringTransaction = this.objectMapper final List<RecurringTransaction> allRecurringTransaction = this.objectMapper
.readValue(mvcResult.getResponse().getContentAsByteArray(), new TypeReference<List<RecurringTransaction>>() {}); .readValue(mvcResult.getResponse().getContentAsByteArray(), new TypeReference<List<RecurringTransaction>>() {});
Assert.assertEquals(3, allRecurringTransaction.size()); Assert.assertEquals(4, allRecurringTransaction.size());
} }
} }

View File

@@ -0,0 +1,49 @@
package de.financer.controller.integration;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.financer.FinancerApplication;
import de.financer.model.RecurringTransaction;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import java.util.List;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = FinancerApplication.class)
@AutoConfigureMockMvc
@TestPropertySource(
locations = "classpath:application-integrationtest.properties")
public class RecurringTransactionService_getAllActiveIntegrationTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Test
public void test_getAll() throws Exception {
final MvcResult mvcResult = this.mockMvc
.perform(get("/recurringTransactions/getAllActive").contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andReturn();
final List<RecurringTransaction> allRecurringTransactions = this.objectMapper
.readValue(mvcResult.getResponse().getContentAsByteArray(), new TypeReference<List<RecurringTransaction>>() {});
Assert.assertEquals(3, allRecurringTransactions.size());
}
}

View File

@@ -43,7 +43,7 @@ public class RecurringTransactionService_getAllIntegrationTest {
final List<RecurringTransaction> allRecurringTransactions = this.objectMapper final List<RecurringTransaction> allRecurringTransactions = this.objectMapper
.readValue(mvcResult.getResponse().getContentAsByteArray(), new TypeReference<List<RecurringTransaction>>() {}); .readValue(mvcResult.getResponse().getContentAsByteArray(), new TypeReference<List<RecurringTransaction>>() {});
Assert.assertEquals(3, allRecurringTransactions.size()); Assert.assertEquals(4, allRecurringTransactions.size());
} }
} }

View File

@@ -19,15 +19,15 @@ import java.time.Period;
import java.util.Collections; import java.util.Collections;
/** /**
* This class contains tests for the {@link RecurringTransactionService}, specifically for * This class contains tests for the {@link RecurringTransactionService}, specifically for {@link RecurringTransaction}s
* {@link RecurringTransaction}s that have {@link IntervalType#DAILY} and {@link HolidayWeekendType#NEXT_WORKDAY}. * that have {@link IntervalType#DAILY} and {@link HolidayWeekendType#NEXT_WORKDAY}. Due to these restrictions this
* Due to these restrictions this class does not contain any tests for recurring transactions due in the close past * class does not contain any tests for recurring transactions due in the close past that have been deferred, because
* that have been deferred, because recurring transactions with interval type daily get executed on the next workday * recurring transactions with interval type daily get executed on the next workday anyway, regardless whether they have
* anyway, regardless whether they have been deferred. This means that some executions of a recurring transaction with * been deferred. This means that some executions of a recurring transaction with daily/next workday get ignored if they
* daily/next workday get ignored if they are on a holiday or a weekend day - they do <b>not</b> get executed multiple * are on a holiday or a weekend day - they do <b>not</b> get executed multiple times on the next workday. While this is
* times on the next workday. While this is somehow unfortunate it is <b>not</b> in the current requirements and * somehow unfortunate it is <b>not</b> in the current requirements and therefore left out for the sake of simplicity.
* therefore left out for the sake of simplicity. If such a behavior is required daily/same day should do the trick, * If such a behavior is required daily/same day should do the trick, even though with slightly different semantics
* even though with slightly different semantics (execution even on holidays or weekends). * (execution even on holidays or weekends).
*/ */
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class RecurringTransactionService_getAllDueToday_DAILY_NEXT_WORKDAYTest { public class RecurringTransactionService_getAllDueToday_DAILY_NEXT_WORKDAYTest {
@@ -53,7 +53,9 @@ public class RecurringTransactionService_getAllDueToday_DAILY_NEXT_WORKDAYTest {
public void test_getAllDueToday_dueToday() { public void test_getAllDueToday_dueToday() {
// Arrange // Arrange
// Implicitly: ruleService.isHoliday().return(false) and ruleService.isWeekend().return(false) // Implicitly: ruleService.isHoliday().return(false) and ruleService.isWeekend().return(false)
Mockito.when(this.recurringTransactionRepository.findAll()).thenReturn(Collections.singletonList(createRecurringTransaction(-3))); Mockito.when(this.recurringTransactionRepository
.findByLastOccurrenceIsNullOrLastOccurrenceGreaterThanEqual(Mockito.any()))
.thenReturn(Collections.singletonList(createRecurringTransaction(-3)));
final LocalDate now = LocalDate.now(); final LocalDate now = LocalDate.now();
// Act // Act
@@ -71,7 +73,9 @@ public class RecurringTransactionService_getAllDueToday_DAILY_NEXT_WORKDAYTest {
public void test_getAllDueToday_dueToday_holiday() { public void test_getAllDueToday_dueToday_holiday() {
// Arrange // Arrange
// Implicitly: ruleService.isWeekend().return(false) // Implicitly: ruleService.isWeekend().return(false)
Mockito.when(this.recurringTransactionRepository.findAll()).thenReturn(Collections.singletonList(createRecurringTransaction(0))); Mockito.when(this.recurringTransactionRepository
.findByLastOccurrenceIsNullOrLastOccurrenceGreaterThanEqual(Mockito.any()))
.thenReturn(Collections.singletonList(createRecurringTransaction(0)));
// Today is a holiday, but yesterday was not // Today is a holiday, but yesterday was not
Mockito.when(this.ruleService.isHoliday(Mockito.any())).thenReturn(Boolean.TRUE, Boolean.FALSE); Mockito.when(this.ruleService.isHoliday(Mockito.any())).thenReturn(Boolean.TRUE, Boolean.FALSE);
final LocalDate now = LocalDate.now(); final LocalDate now = LocalDate.now();
@@ -91,7 +95,9 @@ public class RecurringTransactionService_getAllDueToday_DAILY_NEXT_WORKDAYTest {
public void test_getAllDueToday_dueToday_weekend() { public void test_getAllDueToday_dueToday_weekend() {
// Arrange // Arrange
// Implicitly: ruleService.isHoliday().return(false) // Implicitly: ruleService.isHoliday().return(false)
Mockito.when(this.recurringTransactionRepository.findAll()).thenReturn(Collections.singletonList(createRecurringTransaction(0))); Mockito.when(this.recurringTransactionRepository
.findByLastOccurrenceIsNullOrLastOccurrenceGreaterThanEqual(Mockito.any()))
.thenReturn(Collections.singletonList(createRecurringTransaction(0)));
// Today is a weekend day, but yesterday was not // Today is a weekend day, but yesterday was not
Mockito.when(this.ruleService.isWeekend(Mockito.any())).thenReturn(Boolean.TRUE, Boolean.FALSE); Mockito.when(this.ruleService.isWeekend(Mockito.any())).thenReturn(Boolean.TRUE, Boolean.FALSE);
final LocalDate now = LocalDate.now(); final LocalDate now = LocalDate.now();
@@ -111,7 +117,9 @@ public class RecurringTransactionService_getAllDueToday_DAILY_NEXT_WORKDAYTest {
public void test_getAllDueToday_dueToday_tomorrow() { public void test_getAllDueToday_dueToday_tomorrow() {
// Arrange // Arrange
// Implicitly: ruleService.isHoliday().return(false) and ruleService.isWeekend().return(false) // Implicitly: ruleService.isHoliday().return(false) and ruleService.isWeekend().return(false)
Mockito.when(this.recurringTransactionRepository.findAll()).thenReturn(Collections.singletonList(createRecurringTransaction(1))); Mockito.when(this.recurringTransactionRepository
.findByLastOccurrenceIsNullOrLastOccurrenceGreaterThanEqual(Mockito.any()))
.thenReturn(Collections.singletonList(createRecurringTransaction(1)));
final LocalDate now = LocalDate.now(); final LocalDate now = LocalDate.now();
// Act // Act

View File

@@ -35,14 +35,15 @@ public class RecurringTransactionService_getAllDueToday_MONTHLY_NEXT_WORKDAYTest
} }
/** /**
* This method tests whether a recurring transaction with firstOccurrence = one month and one day ago * This method tests whether a recurring transaction with firstOccurrence = one month and one day ago (and thus was
* (and thus was actually due yesterday), intervalType = monthly and holidayWeekendType = next_workday is due today, * actually due yesterday), intervalType = monthly and holidayWeekendType = next_workday is due today, if yesterday
* if yesterday was a holiday but today is not * was a holiday but today is not
*/ */
@Test @Test
public void test_getAllDueToday_duePast_holiday() { public void test_getAllDueToday_duePast_holiday() {
// Arrange // Arrange
Mockito.when(this.recurringTransactionRepository.findAll()) Mockito.when(this.recurringTransactionRepository
.findByLastOccurrenceIsNullOrLastOccurrenceGreaterThanEqual(Mockito.any()))
.thenReturn(Collections.singletonList(createRecurringTransaction(-1))); .thenReturn(Collections.singletonList(createRecurringTransaction(-1)));
// Today is not a holiday but yesterday was // Today is not a holiday but yesterday was
Mockito.when(this.ruleService.isHoliday(Mockito.any())).thenReturn(Boolean.FALSE, Boolean.TRUE); Mockito.when(this.ruleService.isHoliday(Mockito.any())).thenReturn(Boolean.FALSE, Boolean.TRUE);
@@ -56,9 +57,9 @@ public class RecurringTransactionService_getAllDueToday_MONTHLY_NEXT_WORKDAYTest
} }
/** /**
* This method tests whether a recurring transaction with firstOccurrence = last friday one month ago * This method tests whether a recurring transaction with firstOccurrence = last friday one month ago (and thus was
* (and thus was actually due last friday), intervalType = monthly and holidayWeekendType = next_workday is due * actually due last friday), intervalType = monthly and holidayWeekendType = next_workday is due today (monday), if
* today (monday), if friday was holiday * friday was holiday
*/ */
@Test @Test
public void test_getAllDueToday_duePast_weekend_friday_holiday() { public void test_getAllDueToday_duePast_weekend_friday_holiday() {
@@ -79,7 +80,8 @@ public class RecurringTransactionService_getAllDueToday_MONTHLY_NEXT_WORKDAYTest
final LocalDate now = LocalDate.now(); final LocalDate now = LocalDate.now();
final LocalDate monday = now.minusDays(now.getDayOfWeek().getValue() - 1); final LocalDate monday = now.minusDays(now.getDayOfWeek().getValue() - 1);
// The transaction occurs on a friday // The transaction occurs on a friday
Mockito.when(this.recurringTransactionRepository.findAll()) Mockito.when(this.recurringTransactionRepository
.findByLastOccurrenceIsNullOrLastOccurrenceGreaterThanEqual(Mockito.any()))
.thenReturn(Collections.singletonList(createRecurringTransaction(-(now.getDayOfWeek().getValue() + 2)))); .thenReturn(Collections.singletonList(createRecurringTransaction(-(now.getDayOfWeek().getValue() + 2))));
// First False for the dueToday check, 2x True for actual weekend, second False for Friday // First False for the dueToday check, 2x True for actual weekend, second False for Friday
Mockito.when(this.ruleService.isWeekend(Mockito.any())) Mockito.when(this.ruleService.isWeekend(Mockito.any()))
@@ -96,9 +98,9 @@ public class RecurringTransactionService_getAllDueToday_MONTHLY_NEXT_WORKDAYTest
} }
/** /**
* This method tests whether a recurring transaction with firstOccurrence = last sunday a month ago * This method tests whether a recurring transaction with firstOccurrence = last sunday a month ago (and thus was
* (and thus was actually due last sunday/yesterday), intervalType = monthly and holidayWeekendType = next_workday * actually due last sunday/yesterday), intervalType = monthly and holidayWeekendType = next_workday is due today
* is due today (monday) * (monday)
*/ */
@Test @Test
public void test_getAllDueToday_duePast_weekend_sunday() { public void test_getAllDueToday_duePast_weekend_sunday() {
@@ -106,7 +108,8 @@ public class RecurringTransactionService_getAllDueToday_MONTHLY_NEXT_WORKDAYTest
final LocalDate now = LocalDate.now(); final LocalDate now = LocalDate.now();
final LocalDate monday = now.minusDays(now.getDayOfWeek().getValue() - 1); final LocalDate monday = now.minusDays(now.getDayOfWeek().getValue() - 1);
// The transaction occurs on a sunday // The transaction occurs on a sunday
Mockito.when(this.recurringTransactionRepository.findAll()) Mockito.when(this.recurringTransactionRepository
.findByLastOccurrenceIsNullOrLastOccurrenceGreaterThanEqual(Mockito.any()))
.thenReturn(Collections.singletonList(createRecurringTransaction(-now.getDayOfWeek().getValue()))); .thenReturn(Collections.singletonList(createRecurringTransaction(-now.getDayOfWeek().getValue())));
// First False for the dueToday check, 2x True for actual weekend, second False for Friday // First False for the dueToday check, 2x True for actual weekend, second False for Friday
Mockito.when(this.ruleService.isWeekend(Mockito.any())) Mockito.when(this.ruleService.isWeekend(Mockito.any()))
@@ -120,9 +123,9 @@ public class RecurringTransactionService_getAllDueToday_MONTHLY_NEXT_WORKDAYTest
} }
/** /**
* This method tests whether a recurring transaction with firstOccurrence = saturday a month ago * This method tests whether a recurring transaction with firstOccurrence = saturday a month ago (and thus was
* (and thus was actually due last saturday/two days ago), intervalType = monthly and * actually due last saturday/two days ago), intervalType = monthly and holidayWeekendType = next_workday is due
* holidayWeekendType = next_workday is due today (monday) * today (monday)
*/ */
@Test @Test
public void test_getAllDueToday_duePast_weekend_saturday() { public void test_getAllDueToday_duePast_weekend_saturday() {
@@ -130,7 +133,8 @@ public class RecurringTransactionService_getAllDueToday_MONTHLY_NEXT_WORKDAYTest
final LocalDate now = LocalDate.now(); final LocalDate now = LocalDate.now();
final LocalDate monday = now.minusDays(now.getDayOfWeek().getValue() - 1); final LocalDate monday = now.minusDays(now.getDayOfWeek().getValue() - 1);
// The transaction occurs on a saturday // The transaction occurs on a saturday
Mockito.when(this.recurringTransactionRepository.findAll()) Mockito.when(this.recurringTransactionRepository
.findByLastOccurrenceIsNullOrLastOccurrenceGreaterThanEqual(Mockito.any()))
.thenReturn(Collections.singletonList(createRecurringTransaction(-(now.getDayOfWeek().getValue() + 1)))); .thenReturn(Collections.singletonList(createRecurringTransaction(-(now.getDayOfWeek().getValue() + 1))));
// First False for the dueToday check, 2x True for actual weekend, second False for Friday // First False for the dueToday check, 2x True for actual weekend, second False for Friday
Mockito.when(this.ruleService.isWeekend(Mockito.any())) Mockito.when(this.ruleService.isWeekend(Mockito.any()))

View File

@@ -35,14 +35,15 @@ public class RecurringTransactionService_getAllDueToday_MONTHLY_PREVIOUS_WORKDAY
} }
/** /**
* This method tests whether a recurring transaction with firstOccurrence = one month plus one day (and thus * This method tests whether a recurring transaction with firstOccurrence = one month plus one day (and thus will
* will actually be due tomorrow), intervalType = monthly and holidayWeekendType = previous_workday is due today, if * actually be due tomorrow), intervalType = monthly and holidayWeekendType = previous_workday is due today, if
* tomorrow will be a holiday but today is not * tomorrow will be a holiday but today is not
*/ */
@Test @Test
public void test_getAllDueToday_dueFuture_holiday() { public void test_getAllDueToday_dueFuture_holiday() {
// Arrange // Arrange
Mockito.when(this.recurringTransactionRepository.findAll()) Mockito.when(this.recurringTransactionRepository
.findByLastOccurrenceIsNullOrLastOccurrenceGreaterThanEqual(Mockito.any()))
.thenReturn(Collections.singletonList(createRecurringTransaction(1))); .thenReturn(Collections.singletonList(createRecurringTransaction(1)));
// Today is not a holiday but tomorrow is // Today is not a holiday but tomorrow is
Mockito.when(this.ruleService.isHoliday(Mockito.any())).thenReturn(Boolean.FALSE, Boolean.TRUE); Mockito.when(this.ruleService.isHoliday(Mockito.any())).thenReturn(Boolean.FALSE, Boolean.TRUE);

View File

@@ -35,14 +35,15 @@ public class RecurringTransactionService_getAllDueToday_MONTHLY_SAME_DAYTest {
} }
/** /**
* This method tests whether a recurring transaction with firstOccurrence = one month and one day ago * This method tests whether a recurring transaction with firstOccurrence = one month and one day ago (and thus was
* (and thus was actually due yesterday), intervalType = monthly and holidayWeekendType = same_day is not due today, * actually due yesterday), intervalType = monthly and holidayWeekendType = same_day is not due today, if yesterday
* if yesterday was a holiday but today is not * was a holiday but today is not
*/ */
@Test @Test
public void test_getAllDueToday_duePast_holiday() { public void test_getAllDueToday_duePast_holiday() {
// Arrange // Arrange
Mockito.when(this.recurringTransactionRepository.findAll()) Mockito.when(this.recurringTransactionRepository
.findByLastOccurrenceIsNullOrLastOccurrenceGreaterThanEqual(Mockito.any()))
.thenReturn(Collections.singletonList(createRecurringTransaction(-1))); .thenReturn(Collections.singletonList(createRecurringTransaction(-1)));
// Today is not a holiday but yesterday was // Today is not a holiday but yesterday was
Mockito.when(this.ruleService.isHoliday(Mockito.any())).thenReturn(Boolean.FALSE, Boolean.TRUE); Mockito.when(this.ruleService.isHoliday(Mockito.any())).thenReturn(Boolean.FALSE, Boolean.TRUE);

View File

@@ -7,4 +7,7 @@ INSERT INTO recurring_transaction (from_account_id, to_account_id, description,
VALUES ((SELECT ID FROM account WHERE "key" = 'accounts.income'), (SELECT ID FROM account WHERE "key" = 'accounts.checkaccount'), 'Pay', 250000, 'MONTHLY', '2019-01-15', 'NEXT_WORKDAY'); VALUES ((SELECT ID FROM account WHERE "key" = 'accounts.income'), (SELECT ID FROM account WHERE "key" = 'accounts.checkaccount'), 'Pay', 250000, 'MONTHLY', '2019-01-15', 'NEXT_WORKDAY');
INSERT INTO recurring_transaction (from_account_id, to_account_id, description, amount, interval_type, first_occurrence, holiday_weekend_type) INSERT INTO recurring_transaction (from_account_id, to_account_id, description, amount, interval_type, first_occurrence, holiday_weekend_type)
VALUES ((SELECT ID FROM account WHERE "key" = 'accounts.cash'), (SELECT ID FROM account WHERE "key" = 'accounts.convenience'), 'Pretzel', 170, 'DAILY', '2019-02-20', 'SAME_DAY'); VALUES ((SELECT ID FROM account WHERE "key" = 'accounts.cash'), (SELECT ID FROM account WHERE "key" = 'accounts.convenience'), 'Pretzel', 170, 'DAILY', '2019-02-20', 'SAME_DAY');
INSERT INTO recurring_transaction (from_account_id, to_account_id, description, amount, interval_type, first_occurrence, last_occurrence, holiday_weekend_type)
VALUES ((SELECT ID FROM account WHERE "key" = 'accounts.cash'), (SELECT ID FROM account WHERE "key" = 'accounts.foodexternal'), 'McDonalds Happy Meal', 399, 'WEEKLY', '2019-02-20', '2019-03-20', 'SAME_DAY');