| /* |
| * Copyright 2017 The Mifos Initiative. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package io.mifos.portfolio; |
| |
| import com.google.gson.Gson; |
| import io.mifos.core.api.util.NotFoundException; |
| import io.mifos.core.test.domain.TimeStampChecker; |
| import io.mifos.individuallending.api.v1.domain.caseinstance.CaseParameters; |
| import io.mifos.individuallending.api.v1.domain.caseinstance.CreditWorthinessFactor; |
| import io.mifos.individuallending.api.v1.domain.caseinstance.CreditWorthinessSnapshot; |
| import io.mifos.individuallending.api.v1.domain.product.AccountDesignators; |
| import io.mifos.portfolio.api.v1.domain.AccountAssignment; |
| import io.mifos.portfolio.api.v1.domain.Case; |
| import io.mifos.portfolio.api.v1.domain.CasePage; |
| import io.mifos.portfolio.api.v1.domain.Product; |
| import io.mifos.portfolio.api.v1.events.CaseEvent; |
| import io.mifos.portfolio.api.v1.events.EventConstants; |
| import org.junit.Assert; |
| import org.junit.Test; |
| import org.mockito.Mockito; |
| |
| import java.math.BigDecimal; |
| import java.util.*; |
| import java.util.concurrent.TimeUnit; |
| import java.util.stream.Collectors; |
| import java.util.stream.Stream; |
| |
| /** |
| * @author Myrle Krantz |
| */ |
| public class TestCases extends AbstractPortfolioTest { |
| |
| public TestCases() { } |
| |
| @Test |
| public void shouldFailToCreateCaseForNonexistentProduct() throws InterruptedException { |
| try { |
| final String productIdentifier = "nonexistantProduct"; |
| final Case caseInstance = Fixture.getTestCase(productIdentifier); |
| |
| portfolioManager.createCase(productIdentifier, caseInstance); |
| Assert.fail("Should fail because product doesn't exist."); |
| |
| portfolioManager.getCase(productIdentifier, caseInstance.getIdentifier()); |
| Assert.fail("Should fail because product doesn't exist."); |
| } |
| catch (final NotFoundException ignored) { |
| } |
| } |
| |
| @Test(expected = IllegalArgumentException.class) |
| public void shouldFailToCreateCaseWithInterestOutOfRange() throws InterruptedException { |
| final Product product = createAndEnableProduct(); |
| |
| createAdjustedCase(product.getIdentifier(), x -> x.setInterest(BigDecimal.valueOf(13_0000, 4))); |
| } |
| |
| @Test |
| public void shouldCreateCase() throws InterruptedException { |
| final Product product = createAndEnableProduct(); |
| |
| final TimeStampChecker timeStampChecker = TimeStampChecker.roughlyNow(); |
| final Case caseInstance = createCase(product.getIdentifier()); |
| |
| final Case caseAsSaved = portfolioManager.getCase(product.getIdentifier(), caseInstance.getIdentifier()); |
| |
| Assert.assertEquals(caseInstance, caseAsSaved); |
| Assert.assertEquals(caseAsSaved.getCreatedBy(), TEST_USER); |
| timeStampChecker.assertCorrect(caseAsSaved.getCreatedOn()); |
| Assert.assertEquals(caseAsSaved.getLastModifiedBy(), TEST_USER); |
| timeStampChecker.assertCorrect(caseAsSaved.getLastModifiedOn()); |
| Assert.assertEquals(Case.State.CREATED.name(), caseAsSaved.getCurrentState()); |
| } |
| |
| @Test |
| public void shouldChangeCase() throws InterruptedException { |
| final Product product = createAndEnableProduct(); |
| |
| final CaseParameters newCaseParameters = Fixture.createAdjustedCaseParameters(x -> {}); |
| final String originalParameters = new Gson().toJson(newCaseParameters); |
| final Case caseInstance = createAdjustedCase(product.getIdentifier(), x -> x.setParameters(originalParameters)); |
| |
| final Set<AccountAssignment> accountAssignments = new HashSet<>(); |
| accountAssignments.add(new AccountAssignment(AccountDesignators.CUSTOMER_LOAN_GROUP, "002-011")); |
| accountAssignments.add(new AccountAssignment(AccountDesignators.ENTRY, "002-012")); |
| caseInstance.setAccountAssignments(accountAssignments); |
| |
| newCaseParameters.setMaximumBalance(Fixture.fixScale(BigDecimal.TEN)); |
| newCaseParameters.getPaymentCycle().setAlignmentDay(1); |
| newCaseParameters.getPaymentCycle().setAlignmentWeek(2); |
| |
| newCaseParameters.setCreditWorthinessSnapshots(Collections.emptyList()); |
| |
| final String changedParameters = new Gson().toJson(newCaseParameters); |
| caseInstance.setParameters(changedParameters); |
| |
| TimeUnit.SECONDS.sleep(2); |
| |
| final TimeStampChecker timeStampChecker = TimeStampChecker.roughlyNow(); |
| |
| portfolioManager.changeCase(product.getIdentifier(), caseInstance.getIdentifier(), caseInstance); |
| Assert.assertTrue(this.eventRecorder.wait(EventConstants.PUT_CASE, |
| new CaseEvent(product.getIdentifier(), caseInstance.getIdentifier()))); |
| |
| final Case caseAsSaved = portfolioManager.getCase(product.getIdentifier(), caseInstance.getIdentifier()); |
| |
| Assert.assertEquals(caseInstance, caseAsSaved); |
| Assert.assertEquals(TEST_USER, caseAsSaved.getLastModifiedBy()); |
| timeStampChecker.assertCorrect(caseAsSaved.getLastModifiedOn()); |
| Assert.assertEquals(Case.State.CREATED.name(), caseAsSaved.getCurrentState()); |
| } |
| |
| @Test |
| public void shouldRemoveCosigner() throws InterruptedException { |
| final Product product = createAndEnableProduct(); |
| |
| final CaseParameters caseParameters = Fixture.createAdjustedCaseParameters(x -> {}); |
| final String caseParametersAsString = new Gson().toJson(caseParameters); |
| final Case caseInstance = createAdjustedCase(product.getIdentifier(), x -> x.setParameters(caseParametersAsString)); |
| |
| caseParameters.setCreditWorthinessSnapshots(Collections.singletonList(caseParameters.getCreditWorthinessSnapshots().get(0))); |
| final String changedParameters = new Gson().toJson(caseParameters); |
| caseInstance.setParameters(changedParameters); |
| |
| portfolioManager.changeCase(product.getIdentifier(), caseInstance.getIdentifier(), caseInstance); |
| Assert.assertTrue(this.eventRecorder.wait(EventConstants.PUT_CASE, |
| new CaseEvent(product.getIdentifier(), caseInstance.getIdentifier()))); |
| |
| final Case caseAsSaved = portfolioManager.getCase(product.getIdentifier(), caseInstance.getIdentifier()); |
| |
| Assert.assertEquals(caseInstance, caseAsSaved); |
| } |
| |
| @Test |
| public void shouldAddDebt() throws InterruptedException { |
| final Product product = createAndEnableProduct(); |
| |
| final CaseParameters caseParameters = Fixture.createAdjustedCaseParameters(x -> {}); |
| final String caseParametersAsString = new Gson().toJson(caseParameters); |
| final Case caseInstance = createAdjustedCase(product.getIdentifier(), x -> x.setParameters(caseParametersAsString)); |
| |
| final List<CreditWorthinessFactor> debts = caseParameters.getCreditWorthinessSnapshots().get(0).getDebts(); |
| final ArrayList<CreditWorthinessFactor> newDebts = new ArrayList<>(); |
| newDebts.addAll(debts); |
| newDebts.add(new CreditWorthinessFactor("boop", BigDecimal.valueOf(5, Fixture.MINOR_CURRENCY_UNIT_DIGITS))); |
| caseParameters.getCreditWorthinessSnapshots().get(0).setDebts(newDebts); |
| final String changedParameters = new Gson().toJson(caseParameters); |
| caseInstance.setParameters(changedParameters); |
| |
| portfolioManager.changeCase(product.getIdentifier(), caseInstance.getIdentifier(), caseInstance); |
| Assert.assertTrue(this.eventRecorder.wait(EventConstants.PUT_CASE, |
| new CaseEvent(product.getIdentifier(), caseInstance.getIdentifier()))); |
| |
| final Case caseAsSaved = portfolioManager.getCase(product.getIdentifier(), caseInstance.getIdentifier()); |
| |
| Assert.assertEquals(caseInstance, caseAsSaved); |
| } |
| |
| @Test |
| public void shouldRemoveCaseAccountAssignments() throws InterruptedException { |
| final Product product = createAndEnableProduct(); |
| |
| final Case caseInstance = createCase(product.getIdentifier()); |
| caseInstance.setAccountAssignments(Collections.emptySet()); |
| |
| portfolioManager.changeCase(product.getIdentifier(), caseInstance.getIdentifier(), caseInstance); |
| Assert.assertTrue(this.eventRecorder.wait(EventConstants.PUT_CASE, |
| new CaseEvent(product.getIdentifier(), caseInstance.getIdentifier()))); |
| |
| final Case caseAsSaved = portfolioManager.getCase(product.getIdentifier(), caseInstance.getIdentifier()); |
| Assert.assertEquals(caseInstance, caseAsSaved); |
| Assert.assertTrue(caseInstance.getAccountAssignments().isEmpty()); |
| } |
| |
| @Test |
| public void shouldCreateCosignerWithoutDetails() throws InterruptedException { |
| final Product product = createAndEnableProduct(); |
| |
| final CaseParameters caseParameters = Fixture.createAdjustedCaseParameters(x -> { |
| final CreditWorthinessSnapshot bob = new CreditWorthinessSnapshot("bob"); |
| bob.setDebts(Collections.emptyList()); |
| bob.setAssets(Collections.emptyList()); |
| bob.setIncomeSources(Collections.emptyList()); |
| x.getCreditWorthinessSnapshots().add(bob); |
| }); |
| final String caseParametersAsString = new Gson().toJson(caseParameters); |
| final Case caseInstance = createAdjustedCase(product.getIdentifier(), x -> x.setParameters(caseParametersAsString)); |
| |
| final Case caseAsSaved = portfolioManager.getCase(product.getIdentifier(), caseInstance.getIdentifier()); |
| |
| Assert.assertEquals(caseInstance, caseAsSaved); |
| } |
| |
| @Test |
| public void shouldThrowWhenCustomerNotInGoodStanding() throws InterruptedException { |
| Mockito.doReturn(false).when(customerManager).isCustomerInGoodStanding("don"); |
| |
| final Product product = createProduct(); |
| |
| final CaseParameters newCaseParameters = Fixture.createAdjustedCaseParameters(x -> x.setCustomerIdentifier("don")); |
| final String originalParameters = new Gson().toJson(newCaseParameters); |
| |
| try { |
| createAdjustedCase(product.getIdentifier(), x -> x.setParameters(originalParameters)); |
| Assert.fail("This should cause an illegal argument exception because Don is not a customer in good standing."); |
| } |
| catch (final IllegalArgumentException ignored){ |
| } |
| } |
| |
| @Test |
| public void shouldThrowWhenProductNotActivated() throws InterruptedException { |
| final Product product = createProduct(); |
| |
| try { |
| createCase(product.getIdentifier()); |
| Assert.fail("This should cause an illegal argument exception."); |
| } |
| catch (final IllegalArgumentException ignored){ |
| } |
| |
| portfolioManager.enableProduct(product.getIdentifier(), true); |
| Assert.assertTrue(this.eventRecorder.wait(EventConstants.PUT_PRODUCT_ENABLE, product.getIdentifier())); |
| |
| try { |
| final Case caseInstance = createCase(product.getIdentifier()); |
| Assert.assertTrue(this.eventRecorder.wait(EventConstants.POST_CASE, |
| new CaseEvent(product.getIdentifier(), caseInstance.getIdentifier()))); |
| } |
| catch (final IllegalArgumentException ignored){ |
| Assert.fail("This should *not* cause an illegal argument exception."); |
| } |
| |
| portfolioManager.enableProduct(product.getIdentifier(), false); |
| Assert.assertTrue(this.eventRecorder.wait(EventConstants.PUT_PRODUCT_ENABLE, product.getIdentifier())); |
| try { |
| createCase(product.getIdentifier()); |
| Assert.fail("This should cause an illegal argument exception."); |
| } |
| catch (final IllegalArgumentException ignored){ |
| } |
| } |
| |
| @Test |
| public void shouldListAndPageCases() throws InterruptedException { |
| final Product product = createAndEnableProduct(); |
| |
| final Set<String> expectedCaseIdentifiers = new HashSet<>(); |
| |
| for (int i = 0; i < 20; i++) { |
| final Case caseInstance = createCase(product.getIdentifier()); |
| expectedCaseIdentifiers.add(caseInstance.getIdentifier()); |
| } |
| |
| final CasePage casePage1 = portfolioManager.getAllCasesForProduct(product.getIdentifier(), false, 0, 10); |
| Assert.assertEquals(casePage1.getTotalElements(), Long.valueOf(20L)); |
| Assert.assertEquals(casePage1.getElements().size(), 10); |
| Assert.assertEquals(casePage1.getTotalPages(), Integer.valueOf(2)); |
| |
| final CasePage casePage2 = portfolioManager.getAllCasesForProduct(product.getIdentifier(), false, 1, 10); |
| Assert.assertEquals(casePage2.getTotalElements(), Long.valueOf(20L)); |
| Assert.assertEquals(casePage2.getElements().size(), 10); |
| Assert.assertEquals(casePage2.getTotalPages(), Integer.valueOf(2)); |
| |
| final Set<String> returnedCaseIdentifiers = Stream.concat( |
| casePage1.getElements().stream().map(Case::getIdentifier), |
| casePage2.getElements().stream().map(Case::getIdentifier)) |
| .collect(Collectors.toSet()); |
| |
| Assert.assertEquals(expectedCaseIdentifiers, returnedCaseIdentifiers); |
| } |
| } |