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:
@@ -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()) {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()))
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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');
|
||||||
Reference in New Issue
Block a user