package de.asideas.crowdsource.domain.model; import de.asideas.crowdsource.presentation.FinancingRound; import de.asideas.crowdsource.presentation.Pledge; import org.exparity.hamcrest.date.DateMatchers; import org.joda.time.DateTime; import org.junit.Test; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; public class FinancingRoundEntityTest { @Test public void budgetPerUserClearRounding() { assertThat(newFinancingRound(100, 10).getBudgetPerUser(), is(10)); } @Test public void budgetPerUserNonClearRounding() { assertThat(newFinancingRound(109, 10).getBudgetPerUser(), is(10)); } @Test public void newFinancingRoundCorrectlyInitialized() { final int countUsers = 10; final FinancingRound creationCmd = new FinancingRound(); creationCmd.setBudget(1000); creationCmd.setEndDate(new DateTime(0L)); creationCmd.setId("test_id"); final FinancingRoundEntity res = FinancingRoundEntity.newFinancingRound(creationCmd, countUsers); assertThat(res.getId(), is(nullValue())); assertThat(res.getBudgetPerUser(), is(100)); assertThat(res.getBudget(), is(creationCmd.getBudget())); assertThat(res.getEndDate(), is(creationCmd.getEndDate())); assertThat(res.getStartDate().toDate(), DateMatchers.sameSecond(new Date())); assertThat(res.getUserCount(), is(countUsers)); } @Test public void active_shouldReturnTrueWhenEndDateInFuture() throws Exception { FinancingRoundEntity round = newFinancingRound(100, 10, new DateTime().plusDays(1)); round.setStartDate(new DateTime().minusDays(1)); assertThat(round.active(), is(true)); } @Test public void active_shouldReturnFalseWhenStartDateAndEndDateInFuture() throws Exception { FinancingRoundEntity round = newFinancingRound(100, 10, new DateTime().plusDays(2)); round.setStartDate(new DateTime().plusDays(1)); assertThat(round.active(), is(false)); } @Test public void active_shouldReturnFalseWhenEndDateInPast() throws Exception { FinancingRoundEntity round = newFinancingRound(100, 10, new DateTime().minusDays(1)); round.setStartDate(new DateTime().minusDays(2)); assertThat(round.active(), is(false)); } @Test public void active_shouldReturnFalseWhenStartDateInFuture() throws Exception { FinancingRoundEntity round = newFinancingRound(100, 10, new DateTime().plusDays(2)); round.setStartDate(new DateTime().plusDays(1)); assertThat(round.active(), is(false)); } @Test public void terminated_shouldReturnTrueWhenEndDateInPast() { FinancingRoundEntity round = newFinancingRound(100, 10, new DateTime().minusDays(1)); round.setStartDate(new DateTime().minusDays(2)); assertThat(round.terminated(), is(true)); } @Test public void terminated_shouldReturnFalseWhenStillActive() { FinancingRoundEntity round = newFinancingRound(100, 10, new DateTime().plusDays(1)); round.setStartDate(new DateTime().minusDays(1)); assertThat(round.terminated(), is(false)); } @Test public void terminated_shouldReturnFalseWhenNotYetStarted() { FinancingRoundEntity round = newFinancingRound(100, 10, new DateTime().plusDays(2)); round.setStartDate(new DateTime().plusDays(1)); assertThat(round.terminated(), is(false)); } @Test public void terminationPostProcessingRequiredNow_shouldReturnTrueWhenTerminated() throws Exception { final FinancingRoundEntity financingRound = newFinancingRound(100, 10, new DateTime().minusHours(1)); assertThat(financingRound.terminationPostProcessingRequiredNow(), is(true)); } @Test public void terminationPostProcessingRequiredNow_shouldReturnFalseWhenTerminatedButAlreadyProcessed() throws Exception { final FinancingRoundEntity financingRound = newFinancingRound(100, 10, new DateTime().minusHours(1)); financingRound.setTerminationPostProcessingDone(true); assertThat(financingRound.terminationPostProcessingRequiredNow(), is(false)); } @Test public void terminationPostProcessingRequiredNow_shouldReturnFalseWhenActiveButAlreadyProcessed() throws Exception { final FinancingRoundEntity financingRound = newFinancingRound(100, 10, new DateTime().plusDays(1)); financingRound.setTerminationPostProcessingDone(true); assertThat(financingRound.terminationPostProcessingRequiredNow(), is(false)); } @Test public void initPostRoundBudget() throws Exception { final FinancingRoundEntity financingRound = newFinancingRound(1000, 10, new DateTime().minusHours(1)); financingRound.initPostRoundBudget(17); assertThat(financingRound.getPostRoundBudget(), is(983)); } @Test(expected = IllegalStateException.class) public void initPostRoundBudget_shouldThrowExceptionOnNotTerminatedRound() throws Exception { final FinancingRoundEntity financingRound = newFinancingRound(1000, 10, new DateTime().plusDays(2)); financingRound.setStartDate(new DateTime().plusDays(1)); financingRound.initPostRoundBudget(17); } @Test(expected = IllegalStateException.class) public void initPostRoundBudget_shouldThrowExceptionWhenAlreadyInitialized() throws Exception { final FinancingRoundEntity financingRound = newFinancingRound(1000, 10, new DateTime().plusDays(2)); financingRound.setPostRoundBudget(0); financingRound.initPostRoundBudget(17); } @Test public void postRoundPledgableBudgetRemaining() throws Exception { FinancingRoundEntity round = newFinancingRound(1000, 12, new DateTime().minusDays(2)); round.setPostRoundBudget(400); round.setTerminationPostProcessingDone(true); assertThat(round.postRoundPledgableBudgetRemaining(preparePostRoundPledges(round)), is(400 - (1 + 2 + 3 + 4 + 5))); } @Test public void postRoundPledgableBudgetRemaining_returnsZeroOnNonTerminatedRound() throws Exception { FinancingRoundEntity round = newFinancingRound(1000, 12, new DateTime().minusDays(2)); round.setTerminationPostProcessingDone(false); assertThat(round.postRoundPledgableBudgetRemaining(preparePostRoundPledges(round)), is(0)); } @Test public void postRoundPledgableBudgetRemaining_shouldReturnPostRoundBudgetOnNullOrEmptyPledges() throws Exception { FinancingRoundEntity round = newFinancingRound(1000, 12, new DateTime().minusDays(2)); round.setPostRoundBudget(400); round.setTerminationPostProcessingDone(true); assertThat(round.postRoundPledgableBudgetRemaining(null), is(400)); assertThat(round.postRoundPledgableBudgetRemaining(Collections.emptyList()), is(400)); } @Test(expected = IllegalArgumentException.class) public void postRoundPledgableBudgetRemaining_shouldThrowExIfPledgesFromActiveStateSupplied() throws Exception { FinancingRoundEntity round = newFinancingRound(1000, 12, new DateTime().minusDays(2)); round.setStartDate(new DateTime().minusDays(4)); round.setPostRoundBudget(400); round.setTerminationPostProcessingDone(true); List<PledgeEntity> pledges = preparePostRoundPledges(round); PledgeEntity malicousPledge = new PledgeEntity(new ProjectEntity(), null, new Pledge(1), round); malicousPledge.setCreatedDate(round.getStartDate().plusMinutes(10)); pledges.add(3, malicousPledge); round.postRoundPledgableBudgetRemaining(pledges); } private FinancingRoundEntity newFinancingRound(int budget, int countUsers) { return newFinancingRound(budget, countUsers, new DateTime().plusDays(1)); } private FinancingRoundEntity newFinancingRound(int budget, int countUsers, DateTime endDate) { final FinancingRound cmd = new FinancingRound(); cmd.setBudget(budget); cmd.setEndDate(endDate); return FinancingRoundEntity.newFinancingRound(cmd, countUsers); } private List<PledgeEntity> preparePostRoundPledges(FinancingRoundEntity financingRound) { List<PledgeEntity> res = new ArrayList<>(); PledgeEntity pledge; ProjectEntity projectEntity; for (int i = 1; i < 6; i++) { projectEntity = new ProjectEntity(); projectEntity.setId("test_project_id_" + i); pledge = new PledgeEntity(projectEntity, null, new Pledge(i), financingRound); pledge.setCreatedDate(financingRound.getEndDate().plusHours(2 * i)); res.add(pledge); } return res; } }