Rename root folders

This commit is contained in:
Adi Narayana Raju
2016-02-01 11:00:15 +05:30
parent c5b56dae8f
commit 139e066d3d
2652 changed files with 0 additions and 0 deletions
@@ -0,0 +1,54 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.batch;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.core.UriInfo;
import org.junit.Assert;
import org.junit.Test;
import org.mifosplatform.batch.domain.BatchRequest;
import org.mifosplatform.batch.domain.BatchResponse;
import org.mifosplatform.batch.service.BatchApiService;
import org.mockito.Mockito;
/**
* Runs a unit test for BatchApiResource by mocking the BatchRequest and
* BatchApiService objects.
*
* @author Rishabh Shukla
*/
public class BatchBuilder {
// Verify a non-empty response by BatchApiResource.
@Test
public void batchApiTest() {
// Mock a BatchRequest objects
final BatchRequest batchTest = Mockito.mock(BatchRequest.class);
// Mock a BatchApiService object
final BatchApiService serviceTest = Mockito.mock(BatchApiService.class);
// Mock a UriInfo object
final UriInfo uriInfo = Mockito.mock(UriInfo.class);
final List<BatchRequest> requestList = new ArrayList<>();
requestList.add(batchTest);
// Call the BatchApiService using mocked objects
final List<BatchResponse> result = serviceTest.handleBatchRequestsWithoutEnclosingTransaction(requestList, uriInfo);
// Verifies whether handleBatchRequests() function of BatchApiService
// was called
Mockito.verify(serviceTest).handleBatchRequestsWithoutEnclosingTransaction(requestList, uriInfo);
// Verifies a non-empty response by the BatchApiResource
Assert.assertNotNull(result);
}
}
@@ -0,0 +1,56 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.commands.provider;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.configuration.spring.TestsWithoutDatabaseAndNoJobsConfiguration;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ActiveProfiles("basicauth")
@ContextConfiguration(classes = TestsWithoutDatabaseAndNoJobsConfiguration.class)
public class CommandHandlerProviderTest {
@Autowired
private CommandHandlerProvider commandHandlerProvider;
public CommandHandlerProviderTest() {
super();
}
@Test
public void shouldRegisterHandler() {
try {
final Long testCommandId = 815L;
final NewCommandSourceHandler registeredHandler = this.commandHandlerProvider.getHandler("HUMAN", "UPDATE");
final CommandProcessingResult result =
registeredHandler.processCommand(
JsonCommand.fromExistingCommand(testCommandId, null, null, null, null, null, null, null, null));
Assert.assertEquals(testCommandId, result.commandId());
} catch (UnsupportedCommandException ucex) {
Assert.fail();
}
}
@Test(expected = UnsupportedCommandException.class)
public void shouldThrowUnsupportedCommandException() {
this.commandHandlerProvider.getHandler("WHATEVER", "DOSOMETHING");
}
}
@@ -0,0 +1,26 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.commands.provider;
import org.mifosplatform.commands.annotation.CommandType;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.springframework.stereotype.Component;
@Component
@CommandType(entity = "HUMAN", action = "UPDATE")
public class ValidCommandHandler implements NewCommandSourceHandler {
public ValidCommandHandler() {
super();
}
@Override
public CommandProcessingResult processCommand(JsonCommand command) {
return CommandProcessingResult.commandOnlyResult(command.commandId());
}
}
@@ -0,0 +1,56 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.common;
import com.google.common.base.Preconditions;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.builder.ResponseSpecBuilder;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
/**
* REST integration tests helper. Intended to encapsulate the current
* RestAssured-based implementation as private. May be REST integration tests
* should instead be written using e.g. Spring's TestRestTemplate or Square's
* Retrofit (already used in the Mifos X Android client).
*/
public class RestAssuredFixture {
private final int httpPort;
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
public RestAssuredFixture(int httpPort) {
super();
this.httpPort = httpPort;
Utils.initializeRESTAssured();
RestAssured.port = httpPort;
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
}
public <T> T httpGet(String apiPath, String jsonAttributeToGetBack) {
return Utils.performServerGet(this.requestSpec, this.responseSpec, getApiPath(apiPath), jsonAttributeToGetBack);
}
public <T> T httpGet(String apiPath) {
return httpGet(apiPath, "");
}
private String getApiPath(String apiPath) {
Preconditions.checkArgument(apiPath.startsWith("/"), "trailingApiUrl must start with slash: " + apiPath);
return "/mifosng-provider/api/v1" + apiPath + "?tenantIdentifier=default";
}
protected String getApiUrl(String apiPath) {
return "http://localhost:" + httpPort + getApiPath(apiPath);
}
}
@@ -0,0 +1,121 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.common;
import static com.jayway.restassured.RestAssured.given;
import static com.jayway.restassured.path.json.JsonPath.from;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.Random;
import org.apache.commons.lang.StringUtils;
import org.apache.http.conn.HttpHostConnectException;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.path.json.JsonPath;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
/**
* Util for RestAssured tests. This class here in src/test is copy/pasted :(
* from and identical to the one in src/integrationTest; please keep it in sync.
* The cunning plan is that, now that we have Spring Boot + MariaDB4j,
* eventually do completely away with src/integrationTest and have only
* src/test.. can you help? ;)
*/
@SuppressWarnings("unchecked")
public class Utils {
public static final String TENANT_IDENTIFIER = "tenantIdentifier=default";
private static final String LOGIN_URL = "/mifosng-provider/api/v1/authentication?username=mifos&password=password&" + TENANT_IDENTIFIER;
public static void initializeRESTAssured() {
RestAssured.baseURI = "https://localhost";
RestAssured.port = 8443;
RestAssured.keystore("src/main/resources/keystore.jks", "openmf");
}
public static String loginIntoServerAndGetBase64EncodedAuthenticationKey() {
try {
System.out.println("-----------------------------------LOGIN-----------------------------------------");
final String json = RestAssured.post(LOGIN_URL).asString();
assertThat("Failed to login into mifosx platform", StringUtils.isBlank(json), is(false));
return JsonPath.with(json).get("base64EncodedAuthenticationKey");
} catch (final Exception e) {
if (e instanceof HttpHostConnectException) {
final HttpHostConnectException hh = (HttpHostConnectException) e;
fail("Failed to connect to mifosx platform:" + hh.getMessage());
}
throw new RuntimeException(e);
}
}
public static <T> T performServerGet(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String getURL, final String jsonAttributeToGetBack) {
final String json = given().spec(requestSpec).expect().spec(responseSpec).log().ifError().when().get(getURL).andReturn().asString();
return (T) from(json).get(jsonAttributeToGetBack);
}
public static <T> T performServerPost(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String postURL, final String jsonBodyToSend, final String jsonAttributeToGetBack) {
final String json = given().spec(requestSpec).body(jsonBodyToSend).expect().spec(responseSpec).log().ifError().when().post(postURL)
.andReturn().asString();
if (jsonAttributeToGetBack == null) { return (T) json; }
return (T) from(json).get(jsonAttributeToGetBack);
}
public static <T> T performServerPut(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String putURL, final String jsonBodyToSend, final String jsonAttributeToGetBack) {
final String json = given().spec(requestSpec).body(jsonBodyToSend).expect().spec(responseSpec).log().ifError().when().put(putURL)
.andReturn().asString();
return (T) from(json).get(jsonAttributeToGetBack);
}
public static <T> T performServerDelete(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String deleteURL, final String jsonAttributeToGetBack) {
final String json = given().spec(requestSpec).expect().spec(responseSpec).log().ifError().when().delete(deleteURL).andReturn()
.asString();
return (T) from(json).get(jsonAttributeToGetBack);
}
public static String convertDateToURLFormat(String dateToBeConvert) {
SimpleDateFormat oldFormat = new SimpleDateFormat("dd MMMMMM yyyy", Locale.US);
SimpleDateFormat newFormat = new SimpleDateFormat("yyyy-MM-dd");
String reformattedStr = "";
try {
reformattedStr = newFormat.format(oldFormat.parse(dateToBeConvert));
} catch (final ParseException e) {
e.printStackTrace();
}
return reformattedStr;
}
public static String randomStringGenerator(final String prefix, final int len, final String sourceSetString) {
final int lengthOfSource = sourceSetString.length();
final Random rnd = new Random();
final StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
sb.append((sourceSetString).charAt(rnd.nextInt(lengthOfSource)));
}
return (prefix + (sb.toString()));
}
public static String randomStringGenerator(final String prefix, final int len) {
return randomStringGenerator(prefix, len, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
}
public static String randomNameGenerator(final String prefix, final int lenOfRandomSuffix) {
return randomStringGenerator(prefix, lenOfRandomSuffix);
}
}
@@ -0,0 +1,44 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.infrastructure.configuration.spring;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
/**
* This integration test ensure that the "production" Spring XML configuration
* files (appContext.xml & Co.) are valid. It does not need any database for
* that.
*
* Note: For a simple test like this, contrary to
* AbstractSpringBootWithMariaDB4jIntegrationTest, there is no need to use
* Boot's SpringApplicationConfiguration here, instead the simpler classic Sring
* core ContextConfiguration is sufficient (as long as the
* TestsWithoutDatabaseAndNoJobsConfiguration used extends
* AbstractApplicationConfiguration).
*/
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ActiveProfiles("basicauth")
@ContextConfiguration(classes = TestsWithoutDatabaseAndNoJobsConfiguration.class)
public class SpringConfigurationTest {
/**
* This tests if "Aal izz well" (i.e. if we can start-up with the [almost]
* "production" Spring XML configuration) by doing nothing - it doesn't have
* to, as the SpringJUnit4ClassRunner with this @ContextConfiguration will
* automatically fail if e.g. there is any invalid Spring XML, an invalid
* bean definition somewhere or anything like that.
*
* @see https://www.google.ch/search?q=Aal+izz+well
*/
@Test
public void testSpringXMLConfiguration() {}
}
@@ -0,0 +1,57 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.infrastructure.configuration.spring;
import javax.sql.DataSource;
import org.mifosplatform.infrastructure.core.boot.AbstractApplicationConfiguration;
import org.mifosplatform.infrastructure.core.service.TenantDatabaseUpgradeService;
import org.mifosplatform.infrastructure.jobs.service.JobRegisterService;
import org.mockito.Mockito;
import org.springframework.context.annotation.Bean;
/**
* Spring @Configuration which does not require a running database. It also does
* not load any job configuration (as they are in the DB), thus nor starts any
* background jobs. For some integration tests, this may be perfectly sufficient
* (and faster to run such tests).
*/
public class TestsWithoutDatabaseAndNoJobsConfiguration extends AbstractApplicationConfiguration {
/**
* Override TenantDatabaseUpgradeService binding, because the real one has a @PostConstruct
* upgradeAllTenants() which accesses the database on start-up.
*/
@Bean
public TenantDatabaseUpgradeService tenantDatabaseUpgradeService() {
return new TenantDatabaseUpgradeService(null, null, null) {
@Override
public void upgradeAllTenants() {
// NOOP
}
};
}
/**
* Override JobRegisterService binding, because the real
* JobRegisterServiceImpl has a @PostConstruct loadAllJobs() which accesses
* the database on start-up.
*/
@Bean
public JobRegisterService jobRegisterServiceImpl() {
JobRegisterService mockJobRegisterService = Mockito.mock(JobRegisterService.class);
return mockJobRegisterService;
}
/**
* DataSource with Mockito RETURNS_MOCKS black magic.
*/
@Bean
public DataSource tenantDataSourceJndi() {
DataSource mockDataSource = Mockito.mock(DataSource.class, Mockito.RETURNS_MOCKS);
return mockDataSource;
}
}
@@ -0,0 +1,27 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.infrastructure.core.boot.tests;
import org.junit.runner.RunWith;
import org.mifosplatform.ServerWithMariaDB4jApplication;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ServerWithMariaDB4jApplication.Configuration.class)
@WebAppConfiguration
@ActiveProfiles("basicauth")
@IntegrationTest({ "server.port=0", "management.port=0", "mariaDB4j.port=0", "mariaDB4j.dataDir=null" })
public abstract class AbstractSpringBootWithMariaDB4jIntegrationTest {
// do NOT put any helper methods here!
// it's much better to use composition instead of inheritance
// so write a test util ("fixture") and use it as a field in your test
}
@@ -0,0 +1,43 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.infrastructure.core.boot.tests;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import org.junit.Test;
import org.mifosplatform.infrastructure.core.boot.EmbeddedTomcatWithSSLConfiguration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class EmbeddedTomcatWithSSLConfigurationTest {
@Test
public void testGetFileWithFileResource() throws IOException {
// Test class probably isn't in a JAR
checkClassResource(getClass());
}
@Test
public void testGetFileWithClasspathResource() throws IOException {
// Spring Resource class probably is in a JAR
File f1 = checkClassResource(Resource.class);
f1.delete();
checkClassResource(Resource.class);
}
protected File checkClassResource(Class<?> clazz) throws IOException {
String testClasspathResourcePath = clazz.getCanonicalName().replace('.', '/') + ".class";
Resource r = new ClassPathResource(testClasspathResourcePath);
File f = new EmbeddedTomcatWithSSLConfiguration().getFile(r);
assertTrue(f.exists());
f = new EmbeddedTomcatWithSSLConfiguration().getFile(r);
assertTrue(f.exists());
return f;
}
}
@@ -0,0 +1,36 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.infrastructure.core.boot.tests;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import java.util.List;
import java.util.Map;
import org.junit.Ignore;
import org.junit.Test;
import org.mifosplatform.ServerApplication;
import org.mifosplatform.common.RestAssuredFixture;
/**
* This is an integration test for the Spring Boot launch stuff.
*
* @see ServerApplication
*/
public class SpringBootServerLoginTest extends AbstractSpringBootWithMariaDB4jIntegrationTest {
protected RestAssuredFixture util;
@Test
@Ignore("Failing on Cloubees")
public void hasMifosPlatformStarted() {
util = new RestAssuredFixture(8443);
List<Map<String, String>> response = util.httpGet("/users");
assertThat(response.get(0).get("username"), is("mifos"));
}
}
@@ -0,0 +1,39 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.mix.report.service;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
import org.mifosplatform.mix.service.XBRLResultServiceImpl;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class ReadTaxonomyMappingServiceImplTest {
private XBRLResultServiceImpl readService;
@Before
public void setUp() throws Exception {
final RoutingDataSource dataSource = Mockito.mock(RoutingDataSource.class);
this.readService = new XBRLResultServiceImpl(dataSource, null, null);
}
@Test
public void shouldCorrectlyGetGLCode() {
final ArrayList<String> result = this.readService.getGLCodes("{12000}+{11000}");
assertEquals("12000", result.get(0));
assertEquals("11000", result.get(1));
}
}
@@ -0,0 +1,82 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.mix.report.service;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.when;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Date;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mifosplatform.mix.data.MixTaxonomyData;
import org.mifosplatform.mix.data.NamespaceData;
import org.mifosplatform.mix.service.NamespaceReadPlatformServiceImpl;
import org.mifosplatform.mix.service.XBRLBuilder;
import org.mockito.InjectMocks;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
@RunWith(MockitoJUnitRunner.class)
public class XBRLBuilderTest {
@Mock
private NamespaceReadPlatformServiceImpl readNamespaceService;
@InjectMocks
private final XBRLBuilder xbrlBuilder = new XBRLBuilder();
@Before
public void setUp() throws Exception {
this.readNamespaceService = Mockito.mock(NamespaceReadPlatformServiceImpl.class);
when(this.readNamespaceService.retrieveNamespaceByPrefix(Matchers.anyString())).thenReturn(
new NamespaceData(1l, "mockedprefix", "mockedurl"));
}
@SuppressWarnings("null")
@Test
public void shouldCorrectlyBuildMap() {
final HashMap<MixTaxonomyData, BigDecimal> map = new HashMap<MixTaxonomyData, BigDecimal>();
final MixTaxonomyData data1 = Mockito.mock(MixTaxonomyData.class);
when(data1.getName()).thenReturn("Assets");
map.put(data1, new BigDecimal(10000));
final String result = this.xbrlBuilder.build(map, Date.valueOf("2005-11-11"), Date.valueOf("2013-07-17"), "USD");
System.out.println(result);
NodeList nodes = null;
try {
nodes = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(result.getBytes()))
.getElementsByTagName("Assets");
} catch (final SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (final IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (final ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
assertNotNull(nodes);
assertNotNull(nodes.item(0));
assertEquals("Assets", nodes.item(0).getNodeName());
}
}
@@ -0,0 +1,213 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.loanaccount;
import java.lang.reflect.Field;
import java.math.RoundingMode;
import java.util.List;
import org.joda.time.LocalDate;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.MoneyHelper;
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.impl.RBILoanRepaymentScheduleTransactionProcessor;
import org.mockito.runners.MockitoJUnitRunner;
@SuppressWarnings("unused")
@RunWith(MockitoJUnitRunner.class)
public class AdhikarLoanRepaymentScheduleTransactionProcessorTest {
// class under test
private RBILoanRepaymentScheduleTransactionProcessor processor;
//
private final LocalDate july2nd = new LocalDate(2012, 7, 2);
private final MonetaryCurrency usDollars = new MonetaryCurrencyBuilder().withCode("USD").withDigitsAfterDecimal(2).build();
private List<LoanRepaymentScheduleInstallment> installments;
@Before
public void setUpForEachTestCase() throws Exception {
Field field = MoneyHelper.class.getDeclaredField("roundingMode");
field.setAccessible(true);
field.set(null, RoundingMode.HALF_EVEN);
this.installments = LoanScheduleTestDataHelper.createSimpleLoanSchedule(this.july2nd, this.usDollars);
this.processor = new RBILoanRepaymentScheduleTransactionProcessor();
}
/**
* Scenario 1: Given no overdue installments, current interest due is paid
* before principal.
*/
@Test
public void givenNoOverdueInstallmentsOnTimeRepaymentPaysOffInterestDueFirst() {
// // setup
// Money repaymentAmount = new
// MoneyBuilder().with(usDollars).with("100.00").build();
// LoanTransaction onTimePartialRepayment = new
// LoanTransactionBuilder().repayment().with(july2nd).with(repaymentAmount).build();
//
// // execute test
// processor.handleTransaction(onTimePartialRepayment, usDollars,
// installments);
//
// // verification of derived fields on installments
// LoanRepaymentScheduleInstallment firstInstallment =
// this.installments.get(0);
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("0.00"),
// interestOf("100.00"), interestWaivedOf("0.00"), firstInstallment,
// usDollars);
//
// assertThatLoanTransactionHasDerivedFieldsOf(principalOf("0.00"),
// interestOf("100.00"), onTimePartialRepayment, usDollars);
}
// /**
// * Scenario 2: Given overdue interest exists on overdue installment, a
// late
// * repayment results in overdue interest and current interest being paid
// * before principal component for overdue or current installments.
// */
// @Test
// public void
// givenOverdueInterestOnOverdueInstallmentsLateRepaymentPaysOffOverdueInterestAndCurrentInterestDue()
// {
//
// // setup
// Money repaymentAmount = new
// MoneyBuilder().with(usDollars).with("300.00").build();
// LoanTransaction lateRepayment = new
// LoanTransactionBuilder().repayment().with(july2nd.plusMonths(1)).with(repaymentAmount).build();
//
// // execute test
// processor.handleTransaction(lateRepayment, usDollars, installments);
//
// // verification of derived fields on installments
// LoanRepaymentScheduleInstallment firstInstallment =
// this.installments.get(0);
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("0.00"),
// interestOf("200.00"), interestWaivedOf("0.00"), firstInstallment,
// usDollars);
//
// LoanRepaymentScheduleInstallment secondInstallment =
// this.installments.get(1);
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("0.00"),
// interestOf("100.00"), interestWaivedOf("0.00"), secondInstallment,
// usDollars);
//
// LoanRepaymentScheduleInstallment thirdInstallment =
// this.installments.get(2);
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("0.00"),
// interestOf("0.00"), interestWaivedOf("0.00"), thirdInstallment,
// usDollars);
//
// assertThatLoanTransactionHasDerivedFieldsOf(principalOf("0.00"),
// interestOf("300.00"), lateRepayment, usDollars);
// }
//
// /**
// * Scenario 3: Given an overdue installment with overdue interest and
// principal, a late
// * repayment results in overdue interest and current interest being paid
// * before principal component for overdue or current installments.
// */
// @Test
// public void
// givenAFullyOverdueInstallmentALateRepaymentShouldPayOffOverdueInterestAndCurrentInterestDueFirstThenOverduePrincipal()
// {
//
// // setup
// Money repaymentAmount = new
// MoneyBuilder().with(usDollars).with("900.00").build();
// LoanTransaction lateRepayment = new
// LoanTransactionBuilder().repayment().with(july2nd.plusMonths(1)).with(repaymentAmount).build();
//
// // execute test
// processor.handleTransaction(lateRepayment, usDollars, installments);
//
// // verification of derived fields on installments
// LoanRepaymentScheduleInstallment firstInstallment =
// this.installments.get(0);
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("500.00"),
// interestOf("200.00"), interestWaivedOf("0.00"), firstInstallment,
// usDollars);
//
// LoanRepaymentScheduleInstallment secondInstallment =
// this.installments.get(1);
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("0.00"),
// interestOf("200.00"), interestWaivedOf("0.00"), secondInstallment,
// usDollars);
//
// LoanRepaymentScheduleInstallment thirdInstallment =
// this.installments.get(2);
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("0.00"),
// interestOf("0.00"), interestWaivedOf("0.00"), thirdInstallment,
// usDollars);
//
// assertThatLoanTransactionHasDerivedFieldsOf(principalOf("500.00"),
// interestOf("400.00"), lateRepayment, usDollars);
// }
//
// private void assertThatLoanTransactionHasDerivedFieldsOf(
// final String principal,
// final String interest,
// final LoanTransaction transaction, final MonetaryCurrency currency) {
//
// Money expectedPrincipalPortion = new
// MoneyBuilder().with(currency).with(principal).build();
// assertThat("Principal portion of transaction not as expected: ",
// transaction.getPrincipalPortion(currency).toString(),
// is(expectedPrincipalPortion.toString()));
//
// Money expectedInterestPortion = new
// MoneyBuilder().with(currency).with(interest).build();
// assertThat("Interest portion of transaction not as expected: ",
// transaction.getInterestPortion(currency).toString(),
// is(expectedInterestPortion.toString()));
// }
//
// private void assertThatLoanInstallmentHasDerivedFieldsOf(
// final String principal,
// final String interest,
// final String interestWaived,
// final LoanRepaymentScheduleInstallment installment, final
// MonetaryCurrency currency) {
//
// Money expectedPrincipalCompleted = new
// MoneyBuilder().with(currency).with(principal).build();
// assertThat("principal not as expected",
// installment.getPrincipalCompleted(currency).toString(),
// is(expectedPrincipalCompleted.toString()));
//
// Money expectedInterestCompleted = new
// MoneyBuilder().with(currency).with(interest).build();
// assertThat("interest completed not as expected: ",installment.getInterestCompleted(currency).toString(),
// is(expectedInterestCompleted.toString()));
//
// Money expectedInterestWaived = new
// MoneyBuilder().with(currency).with(interestWaived).build();
// assertThat("interest waived not as expected: ",
// installment.getInterestWaived(currency).toString(),
// is(expectedInterestWaived.toString()));
// }
//
// private String principalOf(final String value) {
// return value;
// }
//
// private String interestOf(final String value) {
// return value;
// }
//
// private String interestWaivedOf(final String value) {
// return value;
// }
}
@@ -0,0 +1,617 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.loanaccount;
import java.lang.reflect.Field;
import java.math.RoundingMode;
import java.util.List;
import org.joda.time.LocalDate;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.MoneyHelper;
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.impl.HeavensFamilyLoanRepaymentScheduleTransactionProcessor;
import org.mockito.runners.MockitoJUnitRunner;
@SuppressWarnings("unused")
@RunWith(MockitoJUnitRunner.class)
public class HeavensFamilyLoanRepaymentScheduleTransactionProcessorTest {
// class under test
private HeavensFamilyLoanRepaymentScheduleTransactionProcessor processor;
//
private final LocalDate july2nd = new LocalDate(2012, 7, 2);
private final MonetaryCurrency usDollars = new MonetaryCurrencyBuilder().withCode("USD").withDigitsAfterDecimal(2).build();
private List<LoanRepaymentScheduleInstallment> installments;
@Before
public void setUpForEachTestCase() throws Exception {
Field field = MoneyHelper.class.getDeclaredField("roundingMode");
field.setAccessible(true);
field.set(null, RoundingMode.HALF_EVEN);
this.installments = LoanScheduleTestDataHelper.createSimpleLoanSchedule(this.july2nd, this.usDollars);
this.processor = new HeavensFamilyLoanRepaymentScheduleTransactionProcessor();
}
/**
* Scenario 1: Single transaction which is less than the interest component
* of the first installment.
*
* Expectation: - First installment shows interest completed equal to that
* of transactions, zero principal completed. (payment order interest,
* principal) - transaction has interest portion equal to transaction
* amount, and zero principal portion
*/
@Test
public void givenSingleOnTimeLoanTransactionShouldPayoffInterestComponentFirst() {
// // setup
// LoanRepaymentScheduleInstallment singleInstallment =
// this.installments.get(0);
//
// Money oneHundredDollars = new
// MoneyBuilder().with(usDollars).with("100.00").build();
// LoanTransaction onTimePartialPayment = new
// LoanTransactionBuilder().repayment().with(july2nd).with(oneHundredDollars).build();
//
// // execute test
// processor.handleTransaction(onTimePartialPayment, usDollars,
// installments);
//
// // verification of derived fields on installments
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("0.00",
// "100.00", singleInstallment);
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("0.00",
// "100.00", onTimePartialPayment);
}
// /**
// * Scenario 2: Two transactions which is less than the interest component
// of the first installment.
// *
// * Expectation:
// * - First installment shows interest completed equal to that of
// transactions, zero principal completed. (payment order interest,
// principal)
// * - transactions has interest portion equal to transaction amount, and
// zero principal portion
// */
// @Test
// public void
// givenMultipleOnTimeLoanTransactionShouldPayoffInterestComponentFirst() {
//
// // setup
// LoanRepaymentScheduleInstallment singleInstallment =
// this.installments.get(0);
//
// Money oneHundredDollars = new
// MoneyBuilder().with(usDollars).with("100.00").build();
// LoanTransaction onTimePartialPayment = new
// LoanTransactionBuilder().repayment().with(july2nd).with(oneHundredDollars).build();
//
// Money fiftyDollars = new
// MoneyBuilder().with(usDollars).with("50.00").build();
// LoanTransaction secondOnTimePartialPayment = new
// LoanTransactionBuilder().repayment().with(july2nd).with(fiftyDollars).build();
//
//
// // execute test
// processor.handleTransaction(onTimePartialPayment, usDollars,
// installments);
// processor.handleTransaction(secondOnTimePartialPayment, usDollars,
// installments);
//
// // verification of derived fields on installments
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("0.00",
// "150.00", singleInstallment);
//
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("0.00",
// "100.00", onTimePartialPayment);
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("0.00",
// "50.00", secondOnTimePartialPayment);
// }
//
// /**
// * Scenario 3: Single transaction which is greater than the interest
// component of the first installment but less than the total due for
// installment.
// *
// * Expectation:
// * - First installment shows interest completed equal to that interest
// due, remainder is against principal completed. (payment order interest,
// principal)
// * - transaction has interest portion equal to interest expected and
// principal portion of remainder.
// */
// @Test
// public void
// givenSingleOnTimeLoanTransactionShouldPayoffInterestThenPrincipalComponents()
// {
//
// // setup
// LoanRepaymentScheduleInstallment singleInstallment =
// this.installments.get(0);
//
// Money amount = new MoneyBuilder().with(usDollars).with("300.00").build();
// LoanTransaction onTimePartialPayment = new
// LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
//
// // execute test
// processor.handleTransaction(onTimePartialPayment, usDollars,
// installments);
//
// // verification of derived fields on installments
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("100.00",
// "200.00", singleInstallment);
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("100.00",
// "200.00", onTimePartialPayment);
// }
//
// /**
// * Scenario 4: Single transaction which is greater than the interest
// component of the first installment but less than the total due for
// installment.
// *
// * Expectation:
// * - First installment shows interest completed equal to that interest
// due, remainder is against principal completed. (payment order interest,
// principal)
// * - transaction has interest portion equal to interest expected and
// principal portion of remainder.
// */
// @Test
// public void
// givenMultipleOnTimeLoanTransactionShouldPayoffInterestThenPrincipalComponents()
// {
//
// // setup
// LoanRepaymentScheduleInstallment singleInstallment =
// this.installments.get(0);
//
// Money amount = new MoneyBuilder().with(usDollars).with("300.00").build();
// LoanTransaction onTimePartialPayment = new
// LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
//
// Money secondTransactionAmount = new
// MoneyBuilder().with(usDollars).with("50.00").build();
// LoanTransaction secondOnTimePartialPayment = new
// LoanTransactionBuilder().repayment().with(july2nd).with(secondTransactionAmount).build();
//
// // execute test
// processor.handleTransaction(onTimePartialPayment, usDollars,
// installments);
// processor.handleTransaction(secondOnTimePartialPayment, usDollars,
// installments);
//
// // verification of derived fields on installments
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("150.00",
// "200.00", singleInstallment);
//
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("100.00",
// "200.00", onTimePartialPayment);
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("50.00",
// "0.00", secondOnTimePartialPayment);
// }
//
// /**
// * Scenario 5:Single transaction which is equal to the total due for
// installment.
// *
// * Expectation:
// * - First installment shows interest completed and principal completed
// equal to their due amounts. (payment order interest, principal)
// * - transaction has interest portion and principal portions
// */
// @Test
// public void
// givenSingleFullOnTimeLoanTransactionShouldPayoffInterestThenPrincipalComponentInFull()
// {
//
// // setup
// LoanRepaymentScheduleInstallment singleInstallment =
// this.installments.get(0);
//
// Money amount = new
// MoneyBuilder().with(usDollars).with("1200.00").build();
// LoanTransaction onTimePartialPayment = new
// LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
//
// // execute test
// processor.handleTransaction(onTimePartialPayment, usDollars,
// installments);
//
// // verification of derived fields on installments
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("1000.00",
// "200.00", singleInstallment);
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("1000.00",
// "200.00", onTimePartialPayment);
// }
//
// /**
// * Scenario 6: Multiple transactions which together equal to the total due
// for installment.
// *
// * Expectation:
// * - First installment shows interest completed and principal completed
// equal to their due amounts. (payment order interest, principal)
// * - transaction has interest portion and principal portions
// */
// @Test
// public void
// givenMuliptleOnTimeLoanTransactionsThatInFullShouldPayoffInterestThenPrincipalComponentInFull()
// {
//
// // setup
// LoanRepaymentScheduleInstallment singleInstallment =
// this.installments.get(0);
//
// Money amount = new MoneyBuilder().with(usDollars).with("600.00").build();
// LoanTransaction onTimePartialPayment = new
// LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
//
// Money secondTransactionAmount = new
// MoneyBuilder().with(usDollars).with("600.00").build();
// LoanTransaction secondOnTimePartialPayment = new
// LoanTransactionBuilder().repayment().with(july2nd).with(secondTransactionAmount).build();
//
// // execute test
// processor.handleTransaction(onTimePartialPayment, usDollars,
// installments);
// processor.handleTransaction(secondOnTimePartialPayment, usDollars,
// installments);
//
// // verification of derived fields on installments
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("1000.00",
// "200.00", singleInstallment);
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("400.00",
// "200.00", onTimePartialPayment);
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("600.00",
// "0.00", secondOnTimePartialPayment);
// }
//
// /**
// * Scenario 7: Single transaction which is greater than total due for
// first installment.
// *
// * Expectation:
// * - First installment shows interest completed and principal completed
// equal to their due amounts. (payment order interest, principal)
// * - Second installment shows principal completed equal to the remaining
// amount
// * - transaction has interest portion and principal portions, the
// principal portion is the sum of principal completed for first and second
// installments
// */
// @Test
// public void
// givenSingleOnTimeLoanTransactionThatOverpaysInstallmentShouldPayoffInterestThenPrincipalComponentInFullOfFirstInstallmentWithRemainingOverpaymentAgainstPrincipalOfNextInstallment()
// {
//
// // setup
// Money amount = new
// MoneyBuilder().with(usDollars).with("1300.00").build();
// LoanTransaction onTimePartialPayment = new
// LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
//
// // execute test
// processor.handleTransaction(onTimePartialPayment, usDollars,
// installments);
//
// // verification of derived fields on installments
// LoanRepaymentScheduleInstallment firstInstallment =
// this.installments.get(0);
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("1000.00",
// "200.00", firstInstallment);
//
// LoanRepaymentScheduleInstallment secondInstallment =
// this.installments.get(1);
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("100.00",
// "0.00", secondInstallment);
//
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("1100.00",
// "200.00", onTimePartialPayment);
// }
//
// /**
// * Scenario 8: Multiple transactions which together are greater than total
// due for first installment.
// *
// * Expectation:
// * - First installment shows interest completed and principal completed
// equal to their due amounts. (payment order interest, principal)
// * - Second installment shows principal completed equal to the remaining
// amount
// */
// @Test
// public void
// givenMultipleOnTimeLoanTransactionThatOverpaysInstallmentShouldPayoffInterestThenPrincipalComponentInFullOfFirstInstallmentWithRemainingOverpaymentAgainstPrincipalOfNextInstallment()
// {
//
// // setup
// Money amount = new MoneyBuilder().with(usDollars).with("600.00").build();
// LoanTransaction onTimePartialPayment = new
// LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
//
// Money secondTransactionAmount = new
// MoneyBuilder().with(usDollars).with("700.00").build();
// LoanTransaction secondOnTimePartialPayment = new
// LoanTransactionBuilder().repayment().with(july2nd).with(secondTransactionAmount).build();
//
// // execute test
// processor.handleTransaction(onTimePartialPayment, usDollars,
// installments);
// processor.handleTransaction(secondOnTimePartialPayment, usDollars,
// installments);
//
// // verification of derived fields on installments
// LoanRepaymentScheduleInstallment singleInstallment =
// this.installments.get(0);
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("1000.00",
// "200.00", singleInstallment);
//
// LoanRepaymentScheduleInstallment secondInstallment =
// this.installments.get(1);
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("100.00",
// "0.00", secondInstallment);
//
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("400.00",
// "200.00", onTimePartialPayment);
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("700.00",
// "0.00", secondOnTimePartialPayment);
// }
//
// /**
// * Scenario 9: Single transaction which overpays first installment and
// second installment with outstanding amount been account as principal in
// third installment.
// *
// * Where an installments principal is paid for fully in advance - the
// interest component is waived.
// */
// @Test
// public void
// givenOverPaymentShouldPayoffInterestThenPrincipalComponentsOfFirstInstallmentWithRemainingOverpaymentAgainstPrincipalOfAllSubsequentInstallments()
// {
// // setup
// Money amount = new
// MoneyBuilder().with(usDollars).with("3000.00").build();
// LoanTransaction onTimePartialPayment = new
// LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
//
// // execute test
// processor.handleTransaction(onTimePartialPayment, usDollars,
// installments);
//
// // verification of derived fields on installments
// LoanRepaymentScheduleInstallment firstInstallment =
// this.installments.get(0);
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("1000.00"),
// interestOf("200.00"), interestWaivedOf("0.00"), firstInstallment,
// usDollars);
//
// LoanRepaymentScheduleInstallment secondInstallment =
// this.installments.get(1);
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("1000.00"),
// interestOf("0.00"), interestWaivedOf("200.00"), secondInstallment,
// usDollars);
//
// LoanRepaymentScheduleInstallment thirdInstallment =
// this.installments.get(2);
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("800.00"),
// interestOf("0.00"), interestWaivedOf("0.00"), thirdInstallment,
// usDollars);
//
// assertThatLoanTransactionHasDerivedFieldsOf(principalOf("2800.00"),
// interestOf("200.00"), onTimePartialPayment, usDollars);
// }
//
// /**
// * Scenario 10: Single transaction which is a repayment in advance
// */
// @Test
// public void
// givenRepaymentOfInstallmentInAdvanceShouldPayoffOnlyPrincipalComponent()
// {
// // setup
// installments =
// LoanScheduleTestDataHelper.createSimpleLoanScheduleWithFirstInstallmentFullyPaid(july2nd,
// usDollars);
// LoanRepaymentScheduleInstallment firstInstallment =
// this.installments.get(0);
// LocalDate paymentInAdvanceDate =
// firstInstallment.getDueDate().minusDays(1);
//
// Money amount = new MoneyBuilder().with(usDollars).with("900.00").build();
// LoanTransaction paymentInAdvance = new
// LoanTransactionBuilder().repayment().with(paymentInAdvanceDate).with(amount).build();
//
// // execute test
// processor.handleTransaction(paymentInAdvance, usDollars, installments);
//
// // verification of derived fields on installments
// LoanRepaymentScheduleInstallment secondInstallment =
// this.installments.get(1);
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("900.00",
// "0.00", secondInstallment);
//
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("900.00",
// "0.00", paymentInAdvance);
// }
//
// /**
// * Scenario 11: Single transaction which is a repayment many days early
// but still does not qualify for 'in advance'.
// */
// @Test
// public void
// givenRepaymentOfInstallmentBeforeDueDateButNotInAdvanceShouldPayoffInterestAndPrincipalComponents()
// {
// // setup
// installments =
// LoanScheduleTestDataHelper.createSimpleLoanScheduleWithFirstInstallmentFullyPaid(july2nd,
// usDollars);
// LoanRepaymentScheduleInstallment firstInstallment =
// this.installments.get(0);
// LocalDate paymentBeforeDueDateButNotInAdvanceDate =
// firstInstallment.getDueDate().plusDays(1);
//
// Money amount = new MoneyBuilder().with(usDollars).with("900.00").build();
// LoanTransaction paymentBeforeDueDateButNotInAdvance = new
// LoanTransactionBuilder().repayment().with(paymentBeforeDueDateButNotInAdvanceDate).with(amount).build();
//
// // execute test
// processor.handleTransaction(paymentBeforeDueDateButNotInAdvance,
// usDollars, installments);
//
// // verification of derived fields on installments
// LoanRepaymentScheduleInstallment secondInstallment =
// this.installments.get(1);
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("700.00",
// "200.00", secondInstallment);
//
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("700.00",
// "200.00", paymentBeforeDueDateButNotInAdvance);
// }
//
//
// /**
// * Scenario 12: Single transaction which is a repayment many days early
// but still does not qualify for 'in advance'.
// */
// @Test
// public void
// givenLateRepaymentOfInstallmentShouldPayoffInterestAndPrincipalComponentsOfOverdueInstallmentsWithNoWaiveOfInterest()
// {
// // setup
// installments =
// LoanScheduleTestDataHelper.createSimpleLoanSchedule(july2nd, usDollars);
// LoanRepaymentScheduleInstallment firstInstallment =
// this.installments.get(0);
// LocalDate latePaymentDate = firstInstallment.getDueDate().plusMonths(5);
//
// Money amount = new
// MoneyBuilder().with(usDollars).with("3600.00").build();
// LoanTransaction lateRepaymentTransaction = new
// LoanTransactionBuilder().repayment().with(latePaymentDate).with(amount).build();
//
// // execute test
// processor.handleTransaction(lateRepaymentTransaction, usDollars,
// installments);
//
// // verification of derived fields on installments
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("1000.00"),
// interestOf("200.00"), interestWaivedOf("0.00"), firstInstallment,
// usDollars);
//
// LoanRepaymentScheduleInstallment secondInstallment =
// this.installments.get(1);
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("1000.00"),
// interestOf("200.00"), interestWaivedOf("0.00"), secondInstallment,
// usDollars);
//
// LoanRepaymentScheduleInstallment thirdInstallment =
// this.installments.get(2);
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("1000.00"),
// interestOf("200.00"), interestWaivedOf("0.00"), thirdInstallment,
// usDollars);
//
// assertThatLoanTransactionHasDerivedFieldsOf(principalOf("3000.00"),
// interestOf("600.00"), lateRepaymentTransaction, usDollars);
// }
//
//
// private void
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf(
// final String principal, final String interest, final LoanTransaction
// transaction) {
//
// Money expectedInterestPortion = new
// MoneyBuilder().with(usDollars).with(interest).build();
// assertThat(transaction.getInterestPortion(usDollars).toString(),
// is(expectedInterestPortion.toString()));
//
// Money expectedPrincipalPortion = new
// MoneyBuilder().with(usDollars).with(principal).build();
// assertThat(transaction.getPrincipalPortion(usDollars).toString(),
// is(expectedPrincipalPortion.toString()));
// }
//
// private void
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf(final
// String principal, final String interest,
// final LoanRepaymentScheduleInstallment installment) {
// Money expectedInterestCompleted = new
// MoneyBuilder().with(usDollars).with(interest).build();
// assertThat(installment.getInterestCompleted(usDollars).toString(),
// is(expectedInterestCompleted.toString()));
//
// Money expectedPrincipalCompleted = new
// MoneyBuilder().with(usDollars).with(principal).build();
// assertThat(installment.getPrincipalCompleted(usDollars).toString(),
// is(expectedPrincipalCompleted.toString()));
// }
//
// private void assertThatLoanTransactionHasDerivedFieldsOf(
// final String principal,
// final String interest,
// final LoanTransaction transaction, final MonetaryCurrency currency) {
//
// Money expectedPrincipalPortion = new
// MoneyBuilder().with(currency).with(principal).build();
// assertThat("Principal portion of transaction not as expected: ",
// transaction.getPrincipalPortion(currency).toString(),
// is(expectedPrincipalPortion.toString()));
//
// Money expectedInterestPortion = new
// MoneyBuilder().with(currency).with(interest).build();
// assertThat("Interest portion of transaction not as expected: ",
// transaction.getInterestPortion(currency).toString(),
// is(expectedInterestPortion.toString()));
// }
//
// private void assertThatLoanInstallmentHasDerivedFieldsOf(
// final String principal,
// final String interest,
// final String interestWaived,
// final LoanRepaymentScheduleInstallment installment, final
// MonetaryCurrency currency) {
//
// Money expectedPrincipalCompleted = new
// MoneyBuilder().with(currency).with(principal).build();
// assertThat("principal not as expected",
// installment.getPrincipalCompleted(currency).toString(),
// is(expectedPrincipalCompleted.toString()));
//
// Money expectedInterestCompleted = new
// MoneyBuilder().with(currency).with(interest).build();
// assertThat("interest completed not as expected: ",installment.getInterestCompleted(currency).toString(),
// is(expectedInterestCompleted.toString()));
//
// Money expectedInterestWaived = new
// MoneyBuilder().with(currency).with(interestWaived).build();
// assertThat("interest waived not as expected: ",
// installment.getInterestWaived(currency).toString(),
// is(expectedInterestWaived.toString()));
// }
//
// private String principalOf(final String value) {
// return value;
// }
//
// private String interestOf(final String value) {
// return value;
// }
//
// private String interestWaivedOf(final String value) {
// return value;
// }
}
@@ -0,0 +1,148 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.loanaccount;
import java.math.BigDecimal;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.portfolio.common.domain.DaysInMonthType;
import org.mifosplatform.portfolio.common.domain.DaysInYearType;
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGenerator;
import org.mifosplatform.portfolio.loanproduct.domain.AmortizationMethod;
import org.mifosplatform.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRelatedDetail;
/**
* This class is used to keep in one place configurations for setting up
* {@link LoanProductRelatedDetail} object used in {@link LoanScheduleGenerator}
* 's
*/
public class LoanProductRelatedDetailTestHelper {
public static LoanProductRelatedDetail createSettingsForEqualPrincipalAmortizationQuarterly() {
final MonetaryCurrency currency = new MonetaryCurrencyBuilder().withCode("USD").withDigitsAfterDecimal(2).build();
final BigDecimal defaultPrincipal = BigDecimal.valueOf(Double.valueOf("200000"));
// 2% per month, 24% per year
final BigDecimal defaultNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.valueOf("2"));
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.MONTHS;
final BigDecimal defaultAnnualNominalInterestRate = BigDecimal.valueOf(Double.valueOf("24"));
final InterestMethod interestMethod = InterestMethod.DECLINING_BALANCE;
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.SAME_AS_REPAYMENT_PERIOD;
final Integer repayEvery = Integer.valueOf(3);
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.MONTHS;
final Integer defaultNumberOfRepayments = Integer.valueOf(4);
final AmortizationMethod amortizationMethod = AmortizationMethod.EQUAL_PRINCIPAL;
final BigDecimal inArrearsTolerance = BigDecimal.ZERO;
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance);
}
public static LoanProductRelatedDetail createSettingsForEqualInstallmentAmortizationQuarterly() {
final MonetaryCurrency currency = new MonetaryCurrencyBuilder().withCode("USD").withDigitsAfterDecimal(2).build();
final BigDecimal defaultPrincipal = BigDecimal.valueOf(Double.valueOf("200000"));
// 2% per month, 24% per year
final BigDecimal defaultNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.valueOf("2"));
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.MONTHS;
final BigDecimal defaultAnnualNominalInterestRate = BigDecimal.valueOf(Double.valueOf("24"));
final InterestMethod interestMethod = InterestMethod.DECLINING_BALANCE;
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.SAME_AS_REPAYMENT_PERIOD;
final Integer repayEvery = Integer.valueOf(3);
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.MONTHS;
final Integer defaultNumberOfRepayments = Integer.valueOf(4);
final AmortizationMethod amortizationMethod = AmortizationMethod.EQUAL_INSTALLMENTS;
final BigDecimal inArrearsTolerance = BigDecimal.ZERO;
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance);
}
public static LoanProductRelatedDetail createSettingsForFlatQuarterly(final AmortizationMethod amortizationMethod) {
final MonetaryCurrency currency = new MonetaryCurrencyBuilder().withCode("USD").withDigitsAfterDecimal(2).build();
final BigDecimal defaultPrincipal = BigDecimal.valueOf(Double.valueOf("200000"));
// 2% per month, 24% per year
final BigDecimal defaultNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.valueOf("2"));
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.MONTHS;
final BigDecimal defaultAnnualNominalInterestRate = BigDecimal.valueOf(Double.valueOf("24"));
final InterestMethod interestMethod = InterestMethod.FLAT;
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.SAME_AS_REPAYMENT_PERIOD;
final Integer repayEvery = Integer.valueOf(3);
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.MONTHS;
final Integer defaultNumberOfRepayments = Integer.valueOf(4);
final BigDecimal inArrearsTolerance = BigDecimal.ZERO;
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance);
}
public static LoanProductRelatedDetail createSettingsForIrregularFlatEveryFourMonths() {
final MonetaryCurrency currency = new MonetaryCurrencyBuilder().withCode("KSH").withDigitsAfterDecimal(0).build();
final BigDecimal defaultPrincipal = BigDecimal.valueOf(Double.valueOf("15000"));
// 2% per month, 24% per year
final BigDecimal defaultNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.valueOf("2"));
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.MONTHS;
final BigDecimal defaultAnnualNominalInterestRate = BigDecimal.valueOf(Double.valueOf("24"));
final InterestMethod interestMethod = InterestMethod.FLAT;
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.SAME_AS_REPAYMENT_PERIOD;
final Integer repayEvery = Integer.valueOf(3);
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.MONTHS;
final Integer defaultNumberOfRepayments = Integer.valueOf(2);
final BigDecimal inArrearsTolerance = BigDecimal.ZERO;
final AmortizationMethod amortizationMethod = AmortizationMethod.EQUAL_PRINCIPAL;
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance);
}
private static LoanProductRelatedDetail createLoanProductRelatedDetail(final MonetaryCurrency currency,
final BigDecimal defaultPrincipal, final BigDecimal defaultNominalInterestRatePerPeriod,
final PeriodFrequencyType interestPeriodFrequencyType, final BigDecimal defaultAnnualNominalInterestRate,
final InterestMethod interestMethod, final InterestCalculationPeriodMethod interestCalculationPeriodMethod,
final Integer repayEvery, final PeriodFrequencyType repaymentFrequencyType, final Integer defaultNumberOfRepayments,
final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance) {
final Integer graceOnPrincipalPayment = Integer.valueOf(0);
final Integer graceOnInterestPayment = Integer.valueOf(0);
final Integer graceOnInterestCharged = Integer.valueOf(0);
final Integer graceOnArrearsAgeing = Integer.valueOf(0);
final Integer daysInMonthType = DaysInMonthType.ACTUAL.getValue();
final Integer daysInYearType = DaysInYearType.ACTUAL.getValue();
final boolean isInterestRecalculationEnabled = false;
final boolean considerPartialPeriodInterest = false;
return new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, considerPartialPeriodInterest, repayEvery,
repaymentFrequencyType, defaultNumberOfRepayments, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged,
amortizationMethod, inArrearsTolerance, graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled);
}
}
@@ -0,0 +1,70 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.loanaccount;
import org.joda.time.LocalDate;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
public class LoanRepaymentScheduleInstallmentBuilder {
private final Loan loan = null;
private Integer installmentNumber = Integer.valueOf(1);
private final LocalDate fromDate = LocalDate.now();
private LocalDate dueDate = LocalDate.now();
private final LocalDate latestTransactionDate = LocalDate.now();
private MonetaryCurrency currencyDetail = new MonetaryCurrencyBuilder().build();
private Money principal = new MoneyBuilder().build();
private Money interest = new MoneyBuilder().build();
private final Money feeCharges = new MoneyBuilder().build();
private final Money penaltyCharges = new MoneyBuilder().build();
private boolean completed = false;
private boolean recalculatedInterestComponent = false;
public LoanRepaymentScheduleInstallmentBuilder(final MonetaryCurrency currencyDetail) {
this.currencyDetail = currencyDetail;
this.principal = new MoneyBuilder().with(currencyDetail).build();
this.interest = new MoneyBuilder().with(currencyDetail).build();
}
public LoanRepaymentScheduleInstallment build() {
final LoanRepaymentScheduleInstallment installment = new LoanRepaymentScheduleInstallment(this.loan, this.installmentNumber,
this.fromDate, this.dueDate, this.principal.getAmount(), this.interest.getAmount(), this.feeCharges.getAmount(),
this.penaltyCharges.getAmount(), this.recalculatedInterestComponent);
if (this.completed) {
installment.payPrincipalComponent(this.latestTransactionDate, this.principal);
installment.payInterestComponent(this.latestTransactionDate, this.interest);
}
return installment;
}
public LoanRepaymentScheduleInstallmentBuilder withPrincipal(final String withPrincipal) {
this.principal = new MoneyBuilder().with(this.currencyDetail).with(withPrincipal).build();
return this;
}
public LoanRepaymentScheduleInstallmentBuilder withInterest(final String withInterest) {
this.interest = new MoneyBuilder().with(this.currencyDetail).with(withInterest).build();
return this;
}
public LoanRepaymentScheduleInstallmentBuilder withDueDate(final LocalDate withDueDate) {
this.dueDate = withDueDate;
return this;
}
public LoanRepaymentScheduleInstallmentBuilder completed() {
this.completed = true;
return this;
}
public LoanRepaymentScheduleInstallmentBuilder withInstallmentNumber(final int withInstallmentNumber) {
this.installmentNumber = withInstallmentNumber;
return this;
}
}
@@ -0,0 +1,71 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.loanaccount;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
/**
* Helper class for creating loan schedule data suitable for testing.
*/
public class LoanScheduleTestDataHelper {
/**
* Creates brand new three installment loan:
*
* For example: with firstDueDate = 02 July 2011
*
* Date Principal Interest Interest Waived
* ==================================
* ================================================ 02 July 2011 1,000 200 0
* 02 August 2011 1,000 200 0 02 September 2011 1,000 200 0
*/
public static List<LoanRepaymentScheduleInstallment> createSimpleLoanSchedule(final LocalDate firstDueDate,
final MonetaryCurrency currency) {
final LoanRepaymentScheduleInstallment firstInstallment = new LoanRepaymentScheduleInstallmentBuilder(currency)
.withInstallmentNumber(1).withDueDate(firstDueDate).withPrincipal("1000.00").withInterest("200.00").build();
final LoanRepaymentScheduleInstallment secondInstallment = new LoanRepaymentScheduleInstallmentBuilder(currency)
.withInstallmentNumber(2).withDueDate(firstDueDate.plusMonths(1)).withPrincipal("1000.00").withInterest("200.00").build();
final LoanRepaymentScheduleInstallment thirdInstallment = new LoanRepaymentScheduleInstallmentBuilder(currency)
.withInstallmentNumber(3).withDueDate(firstDueDate.plusMonths(2)).withPrincipal("1000.00").withInterest("200.00").build();
return Arrays.asList(firstInstallment, secondInstallment, thirdInstallment);
}
/**
* Creates three installment loan with first installment fully completed:
*
* For example: with firstDueDate = 02 July 2011
*
* Date Principal Interest Interest Waived Completed
* ========================
* ==================================================
* ====================================== 02 July 2011 1,000 200 0 true
* (principal paid, interest paid) 02 August 2011 1,000 200 0 false 02
* September 2011 1,000 200 0 false
*/
public static List<LoanRepaymentScheduleInstallment> createSimpleLoanScheduleWithFirstInstallmentFullyPaid(
final LocalDate firstDueDate, final MonetaryCurrency currency) {
final LoanRepaymentScheduleInstallment firstInstallment = new LoanRepaymentScheduleInstallmentBuilder(currency)
.withInstallmentNumber(1).withDueDate(firstDueDate).withPrincipal("1000.00").withInterest("200.00").completed().build();
final LoanRepaymentScheduleInstallment secondInstallment = new LoanRepaymentScheduleInstallmentBuilder(currency)
.withInstallmentNumber(2).withDueDate(firstDueDate.plusMonths(1)).withPrincipal("1000.00").withInterest("200.00").build();
final LoanRepaymentScheduleInstallment thirdInstallment = new LoanRepaymentScheduleInstallmentBuilder(currency)
.withInstallmentNumber(3).withDueDate(firstDueDate.plusMonths(2)).withPrincipal("1000.00").withInterest("200.00").build();
return Arrays.asList(firstInstallment, secondInstallment, thirdInstallment);
}
}
@@ -0,0 +1,45 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.loanaccount;
import org.joda.time.LocalDate;
import org.mifosplatform.organisation.monetary.domain.Money;
public class LoanTransactionBuilder {
@SuppressWarnings("unused")
private Money transactionAmount = new MoneyBuilder().build();
@SuppressWarnings("unused")
private LocalDate transactionDate = LocalDate.now();
@SuppressWarnings("unused")
private boolean repayment = false;
/**
* public LoanTransaction build() {
*
* LoanTransaction transaction = null;
*
* if (repayment) { transaction =
* LoanTransaction.repayment(transactionAmount, transactionDate); }
*
* return transaction; }
**/
public LoanTransactionBuilder with(final Money newAmount) {
this.transactionAmount = newAmount;
return this;
}
public LoanTransactionBuilder with(final LocalDate withTransactionDate) {
this.transactionDate = withTransactionDate;
return this;
}
public LoanTransactionBuilder repayment() {
this.repayment = true;
return this;
}
}
@@ -0,0 +1,29 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.loanaccount;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
public class MonetaryCurrencyBuilder {
private String code = "XOF";
private int digitsAfterDecimal = 0;
private final Integer inMultiplesOf = null;
public MonetaryCurrency build() {
return new MonetaryCurrency(this.code, this.digitsAfterDecimal, this.inMultiplesOf);
}
public MonetaryCurrencyBuilder withCode(final String withCode) {
this.code = withCode;
return this;
}
public MonetaryCurrencyBuilder withDigitsAfterDecimal(final int withDigitsAfterDecimal) {
this.digitsAfterDecimal = withDigitsAfterDecimal;
return this;
}
}
@@ -0,0 +1,31 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.loanaccount;
import java.math.BigDecimal;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
public class MoneyBuilder {
private MonetaryCurrency currencyDetail = new MonetaryCurrencyBuilder().build();
private BigDecimal newAmount = BigDecimal.ZERO;
public Money build() {
return Money.of(this.currencyDetail, this.newAmount);
}
public MoneyBuilder with(final MonetaryCurrency withDetail) {
this.currencyDetail = withDetail;
return this;
}
public MoneyBuilder with(final String withAmount) {
this.newAmount = BigDecimal.valueOf(Double.valueOf(withAmount));
return this;
}
}
@@ -0,0 +1,121 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.template;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.math.RoundingMode;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.joda.time.LocalDate;
import org.junit.Before;
import org.junit.Test;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.MoneyHelper;
import org.mifosplatform.portfolio.loanaccount.LoanScheduleTestDataHelper;
import org.mifosplatform.portfolio.loanaccount.MonetaryCurrencyBuilder;
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.mifosplatform.template.domain.Template;
import org.mifosplatform.template.domain.TemplateMapper;
import org.mifosplatform.template.service.TemplateMergeService;
import com.google.common.base.Charsets;
import com.google.common.io.Resources;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
public class TemplateMergeServiceTest {
private TemplateMergeService tms = new TemplateMergeService();
@Before
public void setUpForEachTestCase() throws Exception {
Field field = MoneyHelper.class.getDeclaredField("roundingMode");
field.setAccessible(true);
field.set(null, RoundingMode.HALF_EVEN);
}
@Test
public void compileHelloTemplate() throws Exception {
String templateText = "Hello Test for Template {{file.name}}!";
File file = new File("hello");
Map<String, Object> scopes = new HashMap<>();
scopes.put("file", file);
String output = compileTemplateText(templateText, scopes);
assertEquals("Hello Test for Template hello!", output);
}
@Test
public void compileLoanSummary() throws IOException {
LocalDate july2nd = new LocalDate(2012, 7, 2);
MonetaryCurrency usDollars = new MonetaryCurrencyBuilder().withCode("USD").withDigitsAfterDecimal(2).build();
List<LoanRepaymentScheduleInstallment> installments = LoanScheduleTestDataHelper.createSimpleLoanSchedule(july2nd, usDollars);
Map<String, Object> scopes = new HashMap<>();
scopes.put("installments", installments);
String templateText = Resources.toString(Resources.getResource("template.mustache"), Charsets.UTF_8);
String expectedOutput = Resources.toString(Resources.getResource("template-expected.html"), Charsets.UTF_8);
String output = compileTemplateText(templateText, scopes);
// System.out.println(output);
assertEquals(expectedOutput, output);
}
@Test
public void arrayUsingLoop() throws Exception {
String templateText = "Hello Test for Template{{#data.name}} {{.}}{{/data.name}}!";
String jsonData = "{\"name\": [ \"Michael\", \"Terence\" ] }";
String expectedOutput = "Hello Test for Template Michael Terence!";
Map<String, Object> scopes = new HashMap<>();
scopes.put("data", createMapFromJSON(jsonData));
String output = compileTemplateText(templateText, scopes);
assertEquals(expectedOutput, output);
}
@Test
public void arrayUsingIndex() throws Exception {
String templateText = "Hello Test for Template {{data.name#1}} & {{data.name#0}}!";
String jsonData = "{\"name\": [ \"Michael\", \"Terence\" ] }";
String expectedOutput = "Hello Test for Template Terence & Michael!";
Map<String, Object> scopes = new HashMap<>();
scopes.put("data", createMapFromJSON(jsonData));
String output = compileTemplateText(templateText, scopes);
assertEquals(expectedOutput, output);
}
protected String compileTemplateText(String templateText, Map<String, Object> scope) throws MalformedURLException, IOException {
List<TemplateMapper> mappers = new ArrayList<>();
Template template = new Template("TemplateName", templateText, null, null, mappers);
return tms.compile(template, scope);
}
protected Map<String, Object> createMapFromJSON(String jsonText) {
Gson gson = new Gson();
Type ssMap = new TypeToken<Map<String, Object>>(){}.getType();
JsonElement json = new JsonParser().parse(jsonText);
return gson.fromJson(json, ssMap);
}
}