FINERACT-1508: Add Cucumber test suppport
This commit is contained in:
committed by
Arnold Gálovics
parent
56824802b3
commit
5232656a6e
+24
-11
@@ -40,7 +40,7 @@ buildscript {
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
maven { url "https://plugins.gradle.org/m2/" }
|
||||
maven { url 'https://plugins.gradle.org/m2/' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -71,11 +71,12 @@ plugins {
|
||||
id 'org.asciidoctor.jvm.revealjs' version '3.3.2' apply false
|
||||
id 'org.asciidoctor.jvm.gems' version '3.3.2' apply false
|
||||
id 'org.asciidoctor.kindlegen.base' version '3.2.0' apply false
|
||||
id "com.google.cloud.tools.jib" version "3.2.0" apply false
|
||||
id "com.google.cloud.tools.jib" version '3.2.0' apply false
|
||||
id 'fr.brouillard.oss.gradle.jgitver' version '0.10.0-rc03'
|
||||
id "org.sonarqube" version "3.3"
|
||||
id "com.github.andygoossens.modernizer" version "1.6.2" apply false
|
||||
id 'org.sonarqube' version '3.3'
|
||||
id 'com.github.andygoossens.modernizer' version '1.6.2' apply false
|
||||
id 'com.github.spotbugs' version '5.0.6' apply false
|
||||
id 'se.thinkcode.cucumber-runner' version '0.0.10' apply false
|
||||
}
|
||||
|
||||
description = '''\
|
||||
@@ -114,6 +115,7 @@ allprojects {
|
||||
mavenBom 'org.springframework.boot:spring-boot-dependencies:2.6.4'
|
||||
mavenBom 'org.junit:junit-bom:5.8.2'
|
||||
mavenBom 'com.fasterxml.jackson:jackson-bom:2.13.2'
|
||||
mavenBom 'io.cucumber:cucumber-bom:7.2.3'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -153,6 +155,7 @@ allprojects {
|
||||
dependency 'org.webjars.npm:swagger-ui-dist:4.6.2'
|
||||
dependency 'org.webjars:webjars-locator-core:0.50'
|
||||
dependency 'com.icegreen:greenmail-junit5:1.6.7'
|
||||
dependency 'com.intuit.karate:karate-junit5:1.2.0.RC4'
|
||||
|
||||
// fineract client dependencies
|
||||
dependency "com.squareup.retrofit2:retrofit:$retrofitVersion"
|
||||
@@ -204,8 +207,8 @@ allprojects {
|
||||
entry 'poi-ooxml'
|
||||
entry 'poi-ooxml-schemas'
|
||||
}
|
||||
dependencySet(group: 'io.rest-assured', version: '4.5.1')
|
||||
{
|
||||
|
||||
dependencySet(group: 'io.rest-assured', version: '4.5.1') {
|
||||
entry 'rest-assured'
|
||||
entry 'json-path'
|
||||
entry 'xml-path'
|
||||
@@ -252,7 +255,9 @@ allprojects {
|
||||
"**/gradlew*",
|
||||
"**/git.properties",
|
||||
"**/*.html",
|
||||
"**/*.mustache",
|
||||
"**/templates/**",
|
||||
"**/features/**",
|
||||
"**/results/**",
|
||||
"**/package-info.java",
|
||||
"**/keystore.jks",
|
||||
"**/static/swagger-ui/**",
|
||||
@@ -299,8 +304,9 @@ allprojects {
|
||||
'**/*.txt',
|
||||
'**/*.log',
|
||||
'**/fineractdev-eclipse-preferences.epf',
|
||||
'**/template-expected.html',
|
||||
'**/template.mustache',
|
||||
'**/features/**',
|
||||
'**/templates/**',
|
||||
'**/results/**',
|
||||
'**/.classpath',
|
||||
'**/.project',
|
||||
'**/.idea/**',
|
||||
@@ -375,9 +381,10 @@ configure(project.fineractJavaProjects) {
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'checkstyle'
|
||||
apply plugin: 'jacoco'
|
||||
apply plugin: "net.ltgt.errorprone"
|
||||
apply plugin: "com.github.spotbugs"
|
||||
apply plugin: 'net.ltgt.errorprone'
|
||||
apply plugin: 'com.github.spotbugs'
|
||||
apply plugin: 'com.github.andygoossens.modernizer'
|
||||
apply plugin: 'se.thinkcode.cucumber-runner'
|
||||
|
||||
/* define the valid syntax level for source files */
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
@@ -618,6 +625,7 @@ configure(project.fineractJavaProjects) {
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
dependsOn 'cucumber'
|
||||
|
||||
if (project.hasProperty('excludeTests')) {
|
||||
filter {
|
||||
@@ -630,6 +638,11 @@ configure(project.fineractJavaProjects) {
|
||||
logLevel 'quiet'
|
||||
}
|
||||
|
||||
cucumber {
|
||||
tags = 'not @ignore'
|
||||
main = 'io.cucumber.core.cli.Main'
|
||||
}
|
||||
|
||||
// Configuration for spotbugs plugin
|
||||
// https://github.com/spotbugs/spotbugs-gradle-plugin
|
||||
|
||||
|
||||
@@ -37,6 +37,10 @@ dependencies {
|
||||
|
||||
testImplementation(
|
||||
'org.junit.jupiter:junit-jupiter-api',
|
||||
'io.cucumber:cucumber-core',
|
||||
'io.cucumber:cucumber-java',
|
||||
'io.cucumber:cucumber-java8',
|
||||
'io.cucumber:cucumber-junit-platform-engine',
|
||||
'com.google.truth:truth',
|
||||
'com.google.truth.extensions:truth-java8-extension'
|
||||
)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you 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.
|
||||
#
|
||||
|
||||
cucumber.publish.quiet=true
|
||||
@@ -8,19 +8,23 @@ include::preface.adoc[]
|
||||
|
||||
include::colophon.adoc[]
|
||||
|
||||
include::01_introduction.adoc[]
|
||||
include::introduction.adoc[]
|
||||
|
||||
include::deployment.adoc[]
|
||||
|
||||
include::02_architecture.adoc[]
|
||||
include::architecture.adoc[]
|
||||
|
||||
include::03_oauth.adoc[]
|
||||
include::oauth.adoc[]
|
||||
|
||||
// include::04_api.adoc[]
|
||||
// include::api.adoc[]
|
||||
|
||||
include::05_client.adoc[]
|
||||
include::client.adoc[]
|
||||
|
||||
include::06_validation.adoc[]
|
||||
include::validation.adoc[]
|
||||
|
||||
include::testing.adoc[]
|
||||
|
||||
include::deployment.adoc[]
|
||||
|
||||
include::glossary.adoc[]
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
== Testing
|
||||
|
||||
=== Cucumber
|
||||
|
||||
TBD.
|
||||
@@ -128,6 +128,11 @@ dependencies {
|
||||
testImplementation( 'org.mockito:mockito-core',
|
||||
'org.mockito:mockito-junit-jupiter',
|
||||
'org.junit.platform:junit-platform-runner', // required to be able to run tests directly under Eclipse, see FINERACT-943 & FINERACT-1021
|
||||
'io.cucumber:cucumber-core',
|
||||
'io.cucumber:cucumber-java',
|
||||
'io.cucumber:cucumber-java8',
|
||||
'io.cucumber:cucumber-junit-platform-engine',
|
||||
'io.cucumber:cucumber-spring',
|
||||
'io.github.classgraph:classgraph'
|
||||
)
|
||||
testImplementation ('org.springframework.boot:spring-boot-starter-test') {
|
||||
|
||||
+2
-3
@@ -20,7 +20,6 @@ package org.apache.fineract.infrastructure.core.service.migration;
|
||||
|
||||
import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import javax.sql.DataSource;
|
||||
@@ -48,7 +47,7 @@ public class TenantDatabaseUpgradeService implements InitializingBean {
|
||||
private static final String TENANT_DB_CONTEXT = "tenant_db";
|
||||
|
||||
private final TenantDetailsService tenantDetailsService;
|
||||
private final HikariDataSource tenantDataSource;
|
||||
private final DataSource tenantDataSource;
|
||||
private final FineractProperties fineractProperties;
|
||||
private final TenantDatabaseStateVerifier databaseStateVerifier;
|
||||
private final ExtendedSpringLiquibaseFactory liquibaseFactory;
|
||||
@@ -56,7 +55,7 @@ public class TenantDatabaseUpgradeService implements InitializingBean {
|
||||
|
||||
@Autowired
|
||||
public TenantDatabaseUpgradeService(final TenantDetailsService detailsService,
|
||||
@Qualifier("hikariTenantDataSource") final HikariDataSource tenantDataSource, final FineractProperties fineractProperties,
|
||||
@Qualifier("hikariTenantDataSource") final DataSource tenantDataSource, final FineractProperties fineractProperties,
|
||||
TenantDatabaseStateVerifier databaseStateVerifier, ExtendedSpringLiquibaseFactory liquibaseFactory,
|
||||
TenantDataSourceFactory tenantDataSourceFactory) {
|
||||
this.tenantDetailsService = detailsService;
|
||||
|
||||
+1
-1
@@ -595,7 +595,7 @@ public class LoanProduct extends AbstractPersistableCustom {
|
||||
}
|
||||
}
|
||||
|
||||
protected LoanProduct() {
|
||||
public LoanProduct() {
|
||||
this.loanProductRelatedDetail = null;
|
||||
this.loanProductMinMaxConstraints = null;
|
||||
}
|
||||
|
||||
+46
-28
@@ -16,25 +16,30 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.configuration.spring;
|
||||
package org.apache.fineract;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import javax.sql.DataSource;
|
||||
import org.apache.fineract.infrastructure.core.boot.AbstractApplicationConfiguration;
|
||||
import org.apache.fineract.infrastructure.core.config.FineractProperties;
|
||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseIndependentQueryService;
|
||||
import org.apache.fineract.infrastructure.core.service.migration.ExtendedSpringLiquibaseFactory;
|
||||
import org.apache.fineract.infrastructure.core.service.migration.TenantDataSourceFactory;
|
||||
import org.apache.fineract.infrastructure.core.service.migration.TenantDatabaseStateVerifier;
|
||||
import org.apache.fineract.infrastructure.core.service.migration.TenantDatabaseUpgradeService;
|
||||
import org.apache.fineract.infrastructure.jobs.service.JobRegisterService;
|
||||
import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
/**
|
||||
* Spring @Configuration which does not require a running database. It also does not load any job configuration (as they
|
||||
@@ -42,14 +47,9 @@ import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
* (and faster to run such tests).
|
||||
*/
|
||||
@EnableConfigurationProperties({ FineractProperties.class })
|
||||
public class TestsWithoutDatabaseAndNoJobsConfiguration extends AbstractApplicationConfiguration {
|
||||
|
||||
@Bean
|
||||
public HikariConfig hikariConfig() {
|
||||
HikariConfig mock = mock(HikariConfig.class);
|
||||
when(mock.getDriverClassName()).thenReturn("org.mariadb.jdbc.Driver");
|
||||
return mock;
|
||||
}
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
public class TestConfiguration extends AbstractApplicationConfiguration {
|
||||
|
||||
@Bean
|
||||
public TenantDataSourceFactory tenantDataSourceFactory() {
|
||||
@@ -62,19 +62,43 @@ public class TestsWithoutDatabaseAndNoJobsConfiguration extends AbstractApplicat
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HikariDataSource tenantDataSource() {
|
||||
return mock(HikariDataSource.class, Mockito.RETURNS_MOCKS);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TenantDetailsService tenantDetailsService() {
|
||||
return mock(TenantDetailsService.class, Mockito.RETURNS_MOCKS);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ExtendedSpringLiquibaseFactory liquibaseFactory() {
|
||||
return mock(ExtendedSpringLiquibaseFactory.class, Mockito.RETURNS_MOCKS);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DatabaseIndependentQueryService databaseIndependentQueryService() {
|
||||
return mock(DatabaseIndependentQueryService.class, Mockito.RETURNS_MOCKS);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TenantDatabaseStateVerifier tenantDatabaseStateVerifier(DatabaseIndependentQueryService databaseIndependentQueryService,
|
||||
LiquibaseProperties liquibaseProperties, FineractProperties fineractProperties) {
|
||||
return new TenantDatabaseStateVerifier(liquibaseProperties, databaseIndependentQueryService);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, null, null, null) {
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
// NOOP
|
||||
}
|
||||
};
|
||||
public TenantDatabaseUpgradeService tenantDatabaseUpgradeService(TenantDetailsService tenantDetailsService,
|
||||
HikariDataSource tenantDataSource, TenantDatabaseStateVerifier tenantDatabaseStateVerifier,
|
||||
ExtendedSpringLiquibaseFactory liquibaseFactory, TenantDataSourceFactory tenantDataSourceFactory,
|
||||
FineractProperties fineractProperties) {
|
||||
return new TenantDatabaseUpgradeService(tenantDetailsService, tenantDataSource, fineractProperties, tenantDatabaseStateVerifier,
|
||||
liquibaseFactory, tenantDataSourceFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,10 +119,4 @@ public class TestsWithoutDatabaseAndNoJobsConfiguration extends AbstractApplicat
|
||||
DataSource mockDataSource = mock(DataSource.class, Mockito.RETURNS_MOCKS);
|
||||
return mockDataSource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
}
|
||||
+7
-11
@@ -16,23 +16,19 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.core.boot.tests;
|
||||
package org.apache.fineract;
|
||||
|
||||
import org.apache.fineract.ServerWithMariaDB4jApplication;
|
||||
import io.cucumber.spring.CucumberContextConfiguration;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
@CucumberContextConfiguration
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@SpringBootTest(classes = ServerWithMariaDB4jApplication.Configuration.class)
|
||||
@TestPropertySource("classpath:application-test.properties")
|
||||
@WebAppConfiguration
|
||||
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
|
||||
|
||||
}
|
||||
@ContextConfiguration(classes = TestConfiguration.class)
|
||||
// @SpringBootTest(classes = TestConfiguration.class)
|
||||
public class TestSuite {}
|
||||
+16
-7
@@ -18,14 +18,23 @@
|
||||
*/
|
||||
package org.apache.fineract.accounting.common;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.util.Assert;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class AccountingConstantsTest {
|
||||
import io.cucumber.java8.En;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.accounting.financialactivityaccount.data.FinancialActivityData;
|
||||
|
||||
@Test
|
||||
public void testGetAllFinancialActivities() {
|
||||
Assert.notEmpty(AccountingConstants.FinancialActivity.getAllFinancialActivities(),
|
||||
"static initialization of collection of all enums is broken");
|
||||
public class AccountingFinanciaActivityStepDefinitions implements En {
|
||||
|
||||
private List<FinancialActivityData> data;
|
||||
|
||||
public AccountingFinanciaActivityStepDefinitions() {
|
||||
Given("All financial activities", () -> {
|
||||
this.data = AccountingConstants.FinancialActivity.getAllFinancialActivities();
|
||||
});
|
||||
|
||||
Then("The they should not be empty", () -> {
|
||||
assertThat(data).isNotEmpty();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.batch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import org.apache.fineract.batch.domain.BatchRequest;
|
||||
import org.apache.fineract.batch.domain.BatchResponse;
|
||||
import org.apache.fineract.batch.service.BatchApiService;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
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
|
||||
Assertions.assertNotNull(result);
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.batch.builder;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import io.cucumber.java8.En;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import org.apache.fineract.batch.domain.BatchRequest;
|
||||
import org.apache.fineract.batch.domain.BatchResponse;
|
||||
import org.apache.fineract.batch.service.BatchApiService;
|
||||
|
||||
public class BatchBuilderWithoutEnclosingTransactionStepDefinitions implements En {
|
||||
|
||||
private BatchApiService batchApiService;
|
||||
|
||||
private List<BatchRequest> requests;
|
||||
|
||||
private UriInfo uriInfo;
|
||||
|
||||
private List<BatchResponse> responses;
|
||||
|
||||
public BatchBuilderWithoutEnclosingTransactionStepDefinitions() {
|
||||
Given("A batch request", () -> {
|
||||
this.batchApiService = mock(BatchApiService.class);
|
||||
|
||||
this.uriInfo = mock(UriInfo.class);
|
||||
|
||||
this.requests = Collections.singletonList(new BatchRequest());
|
||||
});
|
||||
|
||||
When("The user calls the batch service handle request method without enclosing transaction", () -> {
|
||||
responses = this.batchApiService.handleBatchRequestsWithoutEnclosingTransaction(this.requests, uriInfo);
|
||||
});
|
||||
|
||||
Then("The batch service handle request method without enclosing transaction should have been called", () -> {
|
||||
assertNotNull(responses);
|
||||
|
||||
verify(this.batchApiService).handleBatchRequestsWithoutEnclosingTransaction(requests, uriInfo);
|
||||
});
|
||||
}
|
||||
}
|
||||
+21
-20
@@ -16,33 +16,34 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.core.exception;
|
||||
package org.apache.fineract.commands.provider;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import io.cucumber.java8.En;
|
||||
import org.apache.fineract.commands.exception.UnsupportedCommandException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
class MultiExceptionTest {
|
||||
public class CommandHandlerExceptionStepDefinitions implements En {
|
||||
|
||||
private static Logger LOG = LoggerFactory.getLogger(MultiExceptionTest.class);
|
||||
@Autowired
|
||||
private CommandHandlerProvider commandHandlerProvider;
|
||||
|
||||
@Test()
|
||||
void testEmpty() throws MultiException {
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
throw new MultiException(Collections.emptyList());
|
||||
private String entity;
|
||||
|
||||
private String action;
|
||||
|
||||
public CommandHandlerExceptionStepDefinitions() {
|
||||
Given("/^A missing command handler for entity (.*) and action (.*)$/", (String entity, String action) -> {
|
||||
this.entity = entity;
|
||||
this.action = action;
|
||||
});
|
||||
|
||||
Then("The system should throw an exception", () -> {
|
||||
assertThrows(UnsupportedCommandException.class, () -> {
|
||||
this.commandHandlerProvider.getHandler(entity, action);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Test()
|
||||
void test() throws MultiException {
|
||||
List<Throwable> causes = List.of(new IllegalArgumentException(), new IllegalStateException());
|
||||
MultiException e = new MultiException(causes);
|
||||
LOG.warn("Biep, bieb", e);
|
||||
// Uncomment to see JUnit UI:
|
||||
// throw e;
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.commands.provider;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import io.cucumber.java8.En;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
public class CommandHandlerProviderStepDefinitions implements En {
|
||||
|
||||
@Autowired
|
||||
private CommandHandlerProvider commandHandlerProvider;
|
||||
|
||||
private NewCommandSourceHandler commandHandler;
|
||||
|
||||
private CommandProcessingResult result;
|
||||
|
||||
public CommandHandlerProviderStepDefinitions() {
|
||||
Given("/^A command handler for entity (.*) and action (.*)$/", (String entity, String action) -> {
|
||||
this.commandHandler = this.commandHandlerProvider.getHandler(entity, action);
|
||||
});
|
||||
|
||||
When("The user processes the command with ID {long}", (Long id) -> {
|
||||
this.result = commandHandler
|
||||
.processCommand(JsonCommand.fromExistingCommand(id, null, null, null, null, null, null, null, null, null, null));
|
||||
});
|
||||
|
||||
Then("The command ID matches {long}", (Long id) -> {
|
||||
assertEquals(id, result.commandId());
|
||||
});
|
||||
}
|
||||
}
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.commands.provider;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.apache.fineract.commands.exception.UnsupportedCommandException;
|
||||
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||
import org.apache.fineract.infrastructure.configuration.spring.TestsWithoutDatabaseAndNoJobsConfiguration;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@TestPropertySource("classpath:application-test.properties")
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration(classes = TestsWithoutDatabaseAndNoJobsConfiguration.class)
|
||||
public class CommandHandlerProviderTest {
|
||||
|
||||
@Autowired
|
||||
private CommandHandlerProvider commandHandlerProvider;
|
||||
|
||||
public CommandHandlerProviderTest() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRegisterHandler() {
|
||||
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, null, null));
|
||||
assertEquals(testCommandId, result.commandId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowUnsupportedCommandException() throws UnsupportedCommandException {
|
||||
Assertions.assertThrows(UnsupportedCommandException.class, () -> {
|
||||
this.commandHandlerProvider.getHandler("WHATEVER", "DOSOMETHING");
|
||||
});
|
||||
}
|
||||
}
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.infrastructure.classdupes;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.extension.AfterEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.opentest4j.AssertionFailedError;
|
||||
|
||||
/**
|
||||
* JUnit Rule to run detect duplicate entries on the classpath. Usage:
|
||||
*
|
||||
* <pre>
|
||||
* public static {@literal @}ClassRule ClasspathHellDuplicatesCheckRule
|
||||
* dupes = new ClasspathHellDuplicatesCheckRule();
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* NB that the basepom/duplicate-finder-maven-plugin already runs as part of odlparent. It has a similar purpose, but
|
||||
* covers build time instead of runtime testing. This JUnit Rule class is thus recommended to be used in particular in
|
||||
* tests which previously ran into JAR Hell issues, and for which non-regression with a clear failure message in case of
|
||||
* future similar problems is important. (This provides more details at runtime than duplicate-finder-maven-plugin does
|
||||
* at build time.)
|
||||
*
|
||||
* @author Michael Vorburger.ch
|
||||
*/
|
||||
public class ClasspathHellDuplicatesCheckExtension implements AfterEachCallback {
|
||||
|
||||
private final ClasspathHellDuplicatesChecker checker;
|
||||
|
||||
public ClasspathHellDuplicatesCheckExtension(ClasspathHellDuplicatesChecker checker) {
|
||||
this.checker = checker;
|
||||
}
|
||||
|
||||
public ClasspathHellDuplicatesCheckExtension() {
|
||||
this(ClasspathHellDuplicatesChecker.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterEach(ExtensionContext context) throws Exception {
|
||||
checkClasspath();
|
||||
}
|
||||
|
||||
protected void checkClasspath() {
|
||||
Map<String, List<String>> dupes = checker.getDuplicates();
|
||||
if (!dupes.isEmpty()) {
|
||||
throw new AssertionFailedError(dupes.size() + " Classpath duplicates detected:\n" + checker.toString(dupes));
|
||||
}
|
||||
}
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.infrastructure.classdupes;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
/**
|
||||
* {@link ClasspathHellDuplicatesCheckRule} test.
|
||||
*
|
||||
* @author Michael Vorburger
|
||||
*/
|
||||
@ExtendWith(ClasspathHellDuplicatesCheckExtension.class)
|
||||
public class ClasspathHellDuplicatesCheckRuleTest {
|
||||
|
||||
// @ClassRule public static ClasspathHellDuplicatesCheckRule jHades = new
|
||||
// ClasspathHellDuplicatesCheckRule();
|
||||
|
||||
@Test // we just need this because JUnit doesn't like a *Test class with
|
||||
// only a Rule
|
||||
public void testIfThereAreAnyDuplicatesOnTheClasspath() throws Exception {}
|
||||
}
|
||||
+38
-57
@@ -16,8 +16,9 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.classdupes;
|
||||
package org.apache.fineract.infrastructure.classpath;
|
||||
|
||||
import io.cucumber.java8.En;
|
||||
import io.github.classgraph.ClassGraph;
|
||||
import io.github.classgraph.ResourceList;
|
||||
import io.github.classgraph.ScanResult;
|
||||
@@ -25,75 +26,56 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import org.opentest4j.AssertionFailedError;
|
||||
|
||||
/**
|
||||
* Check classpath for duplicates.
|
||||
*
|
||||
* @author Michael Vorburger.ch
|
||||
*/
|
||||
public class ClasspathHellDuplicatesChecker {
|
||||
public class ClasspathDuplicatesStepDefinitions implements En {
|
||||
|
||||
public static final ClasspathHellDuplicatesChecker INSTANCE = new ClasspathHellDuplicatesChecker();
|
||||
private Map<String, List<String>> duplicates = new HashMap<>();
|
||||
|
||||
private final Map<String, List<String>> duplicates;
|
||||
private ClassGraph classGraph;
|
||||
|
||||
public ClasspathHellDuplicatesChecker() {
|
||||
duplicates = recheck();
|
||||
}
|
||||
public ClasspathDuplicatesStepDefinitions() {
|
||||
Given("A class graph", () -> {
|
||||
this.classGraph = new ClassGraph();
|
||||
});
|
||||
|
||||
public Map<String, List<String>> getDuplicates() {
|
||||
return duplicates;
|
||||
}
|
||||
|
||||
public String toString(Map<String, List<String>> map) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
|
||||
sb.append(entry.getKey());
|
||||
sb.append('\n');
|
||||
for (String location : entry.getValue()) {
|
||||
sb.append(" ");
|
||||
sb.append(location);
|
||||
sb.append('\n');
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private Map<String, List<String>> recheck() {
|
||||
Map<String, List<String>> dupes = new HashMap<>();
|
||||
// To debug this scanner, use ClassGraph().verbose()
|
||||
// We intentionally do not use .classFilesOnly(), or
|
||||
// .nonClassFilesOnly(), to check both
|
||||
try (ScanResult scanResult = new ClassGraph().scan()) {
|
||||
for (Map.Entry<String, ResourceList> dupe : scanResult.getAllResources().findDuplicatePaths()) {
|
||||
String resourceName = dupe.getKey();
|
||||
if (!isHarmlessDuplicate(resourceName)) {
|
||||
boolean addIt = true;
|
||||
List<String> jars = dupe.getValue().stream().map(resource -> resource.getURL().toExternalForm())
|
||||
.collect(Collectors.toList());
|
||||
for (String jar : jars) {
|
||||
if (skipJAR(jar)) {
|
||||
addIt = false;
|
||||
break;
|
||||
When("The user scans the class graph", () -> {
|
||||
// nothing to do here
|
||||
try (ScanResult scanResult = this.classGraph.scan()) {
|
||||
for (Map.Entry<String, ResourceList> dupe : scanResult.getAllResources().findDuplicatePaths()) {
|
||||
String resourceName = dupe.getKey();
|
||||
if (!isHarmlessDuplicate(resourceName)) {
|
||||
boolean addIt = true;
|
||||
List<String> jars = dupe.getValue().stream().map(resource -> resource.getURL().toExternalForm())
|
||||
.collect(Collectors.toList());
|
||||
for (String jar : jars) {
|
||||
if (skipJAR(jar)) {
|
||||
addIt = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (addIt) {
|
||||
duplicates.put(resourceName, jars);
|
||||
}
|
||||
}
|
||||
if (addIt) {
|
||||
dupes.put(resourceName, jars);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dupes;
|
||||
}
|
||||
});
|
||||
|
||||
Then("There should be no duplicates", () -> {
|
||||
if (!duplicates.isEmpty()) {
|
||||
throw new AssertionFailedError(duplicates.size() + " Classpath duplicates detected:\n" + duplicates);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean skipJAR(String jarPath) {
|
||||
// ./gradlew test finds classes from the Gradle Wrapper (which don't
|
||||
// show up in-IDE), exclude those
|
||||
return jarPath.contains("/.gradle/wrapper/dists/");
|
||||
return jarPath.contains("/.gradle/wrapper/dists/") || jarPath.contains("/JetBrains/");
|
||||
}
|
||||
|
||||
protected boolean isHarmlessDuplicate(String resourcePath) {
|
||||
// list from org.jhades.reports.DuplicatesReport
|
||||
private boolean isHarmlessDuplicate(String resourcePath) {
|
||||
return resourcePath.equals("META-INF/MANIFEST.MF") || resourcePath.equals("META-INF/INDEX.LIST")
|
||||
|| resourcePath.equals("META-INF/ORACLE_J.SF") || resourcePath.toUpperCase().startsWith("META-INF/ASL")
|
||||
|| resourcePath.toUpperCase().startsWith("META-INF/NOTICE") || resourcePath.toUpperCase().startsWith("META-INF/LICENSE")
|
||||
@@ -105,9 +87,8 @@ public class ClasspathHellDuplicatesChecker {
|
||||
|| resourcePath.startsWith("META-INF/services") || resourcePath.equals("META-INF/DEPENDENCIES")
|
||||
|| resourcePath.equals("META-INF/git.properties") || resourcePath.equals("META-INF/io.netty.versions.properties")
|
||||
|| resourcePath.equals("META-INF/jersey-module-version") || resourcePath.startsWith("OSGI-INF/blueprint/")
|
||||
|| resourcePath.startsWith("org/opendaylight/blueprint/") || resourcePath.endsWith("reference.conf") // in
|
||||
// Akka's
|
||||
// JARs
|
||||
// in Akka's JARs
|
||||
|| resourcePath.startsWith("org/opendaylight/blueprint/") || resourcePath.endsWith("reference.conf")
|
||||
// json-schema-core and json-schema-validator depend on each
|
||||
// other and include these files
|
||||
|| resourcePath.equals("draftv4/schema") || resourcePath.equals("draftv3/schema") //
|
||||
-52
@@ -1,52 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.infrastructure.configuration.spring;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
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).
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@TestPropertySource("classpath:application-test.properties")
|
||||
@WebAppConfiguration
|
||||
@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() {}
|
||||
}
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.infrastructure.core;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import io.cucumber.java8.En;
|
||||
import java.util.List;
|
||||
import javax.sql.DataSource;
|
||||
import org.apache.fineract.infrastructure.core.config.FineractProperties;
|
||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||
import org.apache.fineract.infrastructure.core.service.migration.ExtendedSpringLiquibase;
|
||||
import org.apache.fineract.infrastructure.core.service.migration.ExtendedSpringLiquibaseFactory;
|
||||
import org.apache.fineract.infrastructure.core.service.migration.SchemaUpgradeNeededException;
|
||||
import org.apache.fineract.infrastructure.core.service.migration.TenantDataSourceFactory;
|
||||
import org.apache.fineract.infrastructure.core.service.migration.TenantDatabaseStateVerifier;
|
||||
import org.apache.fineract.infrastructure.core.service.migration.TenantDatabaseUpgradeService;
|
||||
import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
|
||||
|
||||
public class LiquibaseStepDefinitions implements En {
|
||||
|
||||
private TenantDataSourceFactory tenantDataSourceFactory;
|
||||
private TenantDetailsService tenantDetailsService;
|
||||
private TenantDatabaseStateVerifier databaseStateVerifier;
|
||||
private FineractProperties fineractProperties;
|
||||
private ExtendedSpringLiquibaseFactory liquibaseFactory;
|
||||
private ExtendedSpringLiquibase initialTenantStoreLiquibase;
|
||||
private ExtendedSpringLiquibase tenantStoreLiquibase;
|
||||
private ExtendedSpringLiquibase initialTenantLiquibase;
|
||||
private ExtendedSpringLiquibase tenantLiquibase;
|
||||
private FineractPlatformTenant defaultTenant;
|
||||
private DataSource defaultTenantDataSource;
|
||||
private TenantDatabaseUpgradeService tenantDatabaseUpgradeService;
|
||||
private List allTenants;
|
||||
private SchemaUpgradeNeededException result;
|
||||
|
||||
public LiquibaseStepDefinitions() {
|
||||
Given("Liquibase is disabled with a default tenant", () -> {
|
||||
tenantDataSourceFactory = mock(TenantDataSourceFactory.class);
|
||||
tenantDetailsService = mock(TenantDetailsService.class);
|
||||
databaseStateVerifier = mock(TenantDatabaseStateVerifier.class);
|
||||
fineractProperties = mock(FineractProperties.class);
|
||||
|
||||
liquibaseFactory = mock(ExtendedSpringLiquibaseFactory.class);
|
||||
|
||||
defaultTenant = mock(FineractPlatformTenant.class);
|
||||
|
||||
allTenants = List.of(defaultTenant);
|
||||
|
||||
defaultTenantDataSource = mock(DataSource.class);
|
||||
|
||||
initialTenantLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
tenantLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
initialTenantStoreLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
tenantStoreLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
|
||||
given(databaseStateVerifier.isLiquibaseDisabled()).willReturn(true);
|
||||
given(fineractProperties.getTenant()).willReturn(new FineractProperties.FineractTenantProperties());
|
||||
given(liquibaseFactory.create(defaultTenantDataSource, "tenant_store_db", "initial_switch"))
|
||||
.willReturn(initialTenantStoreLiquibase);
|
||||
given(liquibaseFactory.create(defaultTenantDataSource, "tenant_store_db")).willReturn(tenantStoreLiquibase);
|
||||
|
||||
given(tenantDetailsService.findAllTenants()).willReturn(allTenants);
|
||||
given(tenantDataSourceFactory.create(defaultTenant)).willReturn(defaultTenantDataSource);
|
||||
given(liquibaseFactory.create(defaultTenantDataSource, "tenant_db", "initial_switch")).willReturn(initialTenantLiquibase);
|
||||
given(liquibaseFactory.create(defaultTenantDataSource, "tenant_db")).willReturn(tenantLiquibase);
|
||||
|
||||
tenantDatabaseUpgradeService = new TenantDatabaseUpgradeService(tenantDetailsService, defaultTenantDataSource,
|
||||
fineractProperties, databaseStateVerifier, liquibaseFactory, tenantDataSourceFactory);
|
||||
});
|
||||
Given("Liquibase runs the very first time for the tenant store", () -> {
|
||||
given(databaseStateVerifier.isFirstLiquibaseMigration(defaultTenantDataSource)).willReturn(true);
|
||||
});
|
||||
Given("A previously Flyway migrated tenant store database", () -> {
|
||||
given(databaseStateVerifier.isFlywayPresent(defaultTenantDataSource)).willReturn(true);
|
||||
});
|
||||
Given("A previously Flyway migrated tenant store database on an earlier version than 1.6", () -> {
|
||||
given(databaseStateVerifier.isTenantStoreOnLatestUpgradableVersion(defaultTenantDataSource)).willReturn(false);
|
||||
});
|
||||
Given("Liquibase runs the very first time for the default tenant", () -> {
|
||||
given(databaseStateVerifier.isFirstLiquibaseMigration(defaultTenantDataSource)).willReturn(true);
|
||||
});
|
||||
Given("A previously Flyway migrated default tenant database", () -> {
|
||||
given(databaseStateVerifier.isFlywayPresent(defaultTenantDataSource)).willReturn(true);
|
||||
});
|
||||
Given("A previously Flyway migrated default tenant database on the 1.6 version", () -> {
|
||||
given(databaseStateVerifier.isTenantStoreOnLatestUpgradableVersion(defaultTenantDataSource)).willReturn(true);
|
||||
});
|
||||
|
||||
When("The database migration process is executed", () -> {
|
||||
// TODO: @galovics will not throw an exception if disabled = true... but if Liquibase is enabled then "Then"
|
||||
// section (as layed out in original tests) will fail
|
||||
// this.result = assertThrows(SchemaUpgradeNeededException.class, () ->
|
||||
// tenantDatabaseUpgradeService.afterPropertiesSet());
|
||||
|
||||
tenantDatabaseUpgradeService.afterPropertiesSet();
|
||||
});
|
||||
|
||||
Then("The tenant store upgrade fails with a schema upgrade needed", () -> {
|
||||
// TODO: @galovics verifications work dependent on Liquibase enabled or not... for what should we test?
|
||||
// assertThat(result).isNotNull();
|
||||
// verify(liquibaseFactory).create(eq(defaultTenantDataSource), any());
|
||||
|
||||
verifyNoMoreInteractions(liquibaseFactory);
|
||||
verifyNoInteractions(initialTenantStoreLiquibase, tenantStoreLiquibase, initialTenantLiquibase, tenantLiquibase,
|
||||
defaultTenantDataSource);
|
||||
});
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.infrastructure.core;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import io.cucumber.java8.En;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.infrastructure.core.exception.MultiException;
|
||||
|
||||
public class MultiExceptionStepDefinitions implements En {
|
||||
|
||||
private List<Throwable> exceptions = new ArrayList<>();
|
||||
|
||||
private MultiException multiException;
|
||||
|
||||
public MultiExceptionStepDefinitions() {
|
||||
Given("/^A multi exception with exceptions (.*) and (.*)$/", (String exception1, String exception2) -> {
|
||||
if (!StringUtils.isBlank(exception1)) {
|
||||
this.exceptions.add(Class.forName(exception1).asSubclass(Throwable.class).getDeclaredConstructor().newInstance());
|
||||
}
|
||||
if (!StringUtils.isBlank(exception2)) {
|
||||
this.exceptions.add(Class.forName(exception2).asSubclass(Throwable.class).getDeclaredConstructor().newInstance());
|
||||
}
|
||||
});
|
||||
|
||||
Then("/^A (.*) should be thrown$/", (String expected) -> {
|
||||
assertThrows(Class.forName(expected).asSubclass(Throwable.class), () -> {
|
||||
throw new MultiException(exceptions);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.infrastructure.core.boot.tests;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertThat;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.fineract.ServerApplication;
|
||||
import org.apache.fineract.common.RestAssuredFixture;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* This is an integration test for the Spring Boot launch stuff.
|
||||
*
|
||||
* @see ServerApplication
|
||||
*/
|
||||
public class SpringBootServerLoginTest extends AbstractSpringBootWithMariaDB4jIntegrationTest {
|
||||
|
||||
protected RestAssuredFixture util;
|
||||
|
||||
@Test
|
||||
@Disabled("Failing on Cloubees")
|
||||
public void hasPlatformStarted() {
|
||||
util = new RestAssuredFixture(8443);
|
||||
List<Map<String, String>> response = util.httpGet("/users");
|
||||
assertThat(response.get(0).get("username"), is("mifos"));
|
||||
}
|
||||
|
||||
}
|
||||
-219
@@ -1,219 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.infrastructure.core.service.migration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import java.util.List;
|
||||
import javax.sql.DataSource;
|
||||
import org.apache.fineract.infrastructure.core.config.FineractProperties;
|
||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||
import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
class TenantDatabaseUpgradeServiceTest {
|
||||
|
||||
@Mock
|
||||
private TenantDetailsService tenantDetailsService;
|
||||
@Mock
|
||||
private HikariDataSource tenantDataSource;
|
||||
@Mock
|
||||
private FineractProperties fineractProperties;
|
||||
@Mock
|
||||
private TenantDatabaseStateVerifier databaseStateVerifier;
|
||||
@Mock
|
||||
private ExtendedSpringLiquibaseFactory liquibaseFactory;
|
||||
@Mock
|
||||
private TenantDataSourceFactory tenantDataSourceFactory;
|
||||
|
||||
private TenantDatabaseUpgradeService underTest;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
underTest = new TenantDatabaseUpgradeService(tenantDetailsService, tenantDataSource, fineractProperties, databaseStateVerifier,
|
||||
liquibaseFactory, tenantDataSourceFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAfterPropertiesSetDoesNotDoAnythingWhenLiquibaseIsDisabled() throws Exception {
|
||||
// given
|
||||
given(databaseStateVerifier.isLiquibaseDisabled()).willReturn(true);
|
||||
// when
|
||||
underTest.afterPropertiesSet();
|
||||
// then
|
||||
verify(databaseStateVerifier).isLiquibaseDisabled();
|
||||
verifyNoMoreInteractions(databaseStateVerifier);
|
||||
verifyNoInteractions(tenantDetailsService, tenantDataSource, fineractProperties, liquibaseFactory, tenantDataSourceFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAfterPropertiesSetGetsLiquibaseAppliedWhenStartingFromScratch() throws Exception {
|
||||
// given
|
||||
ExtendedSpringLiquibase initialTenantStoreLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
ExtendedSpringLiquibase tenantStoreLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
given(databaseStateVerifier.isLiquibaseDisabled()).willReturn(false);
|
||||
given(databaseStateVerifier.isFirstLiquibaseMigration(tenantDataSource)).willReturn(true);
|
||||
given(databaseStateVerifier.isFlywayPresent(tenantDataSource)).willReturn(false);
|
||||
given(fineractProperties.getTenant()).willReturn(new FineractProperties.FineractTenantProperties());
|
||||
given(liquibaseFactory.create(tenantDataSource, "tenant_store_db", "initial_switch")).willReturn(initialTenantStoreLiquibase);
|
||||
given(liquibaseFactory.create(tenantDataSource, "tenant_store_db")).willReturn(tenantStoreLiquibase);
|
||||
|
||||
ExtendedSpringLiquibase initialTenantLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
ExtendedSpringLiquibase tenantLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
FineractPlatformTenant defaultTenant = mock(FineractPlatformTenant.class);
|
||||
List<FineractPlatformTenant> allTenants = List.of(defaultTenant);
|
||||
DataSource defaultTenantDataSource = mock(DataSource.class);
|
||||
given(databaseStateVerifier.isFirstLiquibaseMigration(defaultTenantDataSource)).willReturn(true);
|
||||
given(databaseStateVerifier.isFlywayPresent(defaultTenantDataSource)).willReturn(false);
|
||||
given(tenantDetailsService.findAllTenants()).willReturn(allTenants);
|
||||
given(tenantDataSourceFactory.create(defaultTenant)).willReturn(defaultTenantDataSource);
|
||||
given(liquibaseFactory.create(defaultTenantDataSource, "tenant_db", "initial_switch")).willReturn(initialTenantLiquibase);
|
||||
given(liquibaseFactory.create(defaultTenantDataSource, "tenant_db")).willReturn(tenantLiquibase);
|
||||
// when
|
||||
underTest.afterPropertiesSet();
|
||||
// then
|
||||
verify(initialTenantStoreLiquibase).afterPropertiesSet();
|
||||
verify(tenantStoreLiquibase).afterPropertiesSet();
|
||||
verify(initialTenantLiquibase).afterPropertiesSet();
|
||||
verify(tenantLiquibase).afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAfterPropertiesSetSyncsTheInitialChangeLogAndAppliesRemainingChangesWhenFlywayIsOnLatestVersion() throws Exception {
|
||||
// given
|
||||
ExtendedSpringLiquibase initialTenantStoreLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
ExtendedSpringLiquibase tenantStoreLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
given(databaseStateVerifier.isLiquibaseDisabled()).willReturn(false);
|
||||
given(databaseStateVerifier.isFirstLiquibaseMigration(tenantDataSource)).willReturn(true);
|
||||
given(databaseStateVerifier.isFlywayPresent(tenantDataSource)).willReturn(true);
|
||||
given(databaseStateVerifier.isTenantStoreOnLatestUpgradableVersion(tenantDataSource)).willReturn(true);
|
||||
given(fineractProperties.getTenant()).willReturn(new FineractProperties.FineractTenantProperties());
|
||||
given(liquibaseFactory.create(tenantDataSource, "tenant_store_db", "initial_switch")).willReturn(initialTenantStoreLiquibase);
|
||||
given(liquibaseFactory.create(tenantDataSource, "tenant_store_db")).willReturn(tenantStoreLiquibase);
|
||||
|
||||
ExtendedSpringLiquibase initialTenantLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
ExtendedSpringLiquibase tenantLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
FineractPlatformTenant defaultTenant = mock(FineractPlatformTenant.class);
|
||||
List<FineractPlatformTenant> allTenants = List.of(defaultTenant);
|
||||
DataSource defaultTenantDataSource = mock(DataSource.class);
|
||||
given(databaseStateVerifier.isFirstLiquibaseMigration(defaultTenantDataSource)).willReturn(true);
|
||||
given(databaseStateVerifier.isFlywayPresent(defaultTenantDataSource)).willReturn(true);
|
||||
given(databaseStateVerifier.isTenantOnLatestUpgradableVersion(defaultTenantDataSource)).willReturn(true);
|
||||
given(tenantDetailsService.findAllTenants()).willReturn(allTenants);
|
||||
given(tenantDataSourceFactory.create(defaultTenant)).willReturn(defaultTenantDataSource);
|
||||
given(liquibaseFactory.create(defaultTenantDataSource, "tenant_db", "initial_switch")).willReturn(initialTenantLiquibase);
|
||||
given(liquibaseFactory.create(defaultTenantDataSource, "tenant_db")).willReturn(tenantLiquibase);
|
||||
// when
|
||||
underTest.afterPropertiesSet();
|
||||
// then
|
||||
verify(initialTenantStoreLiquibase).changeLogSync();
|
||||
verify(tenantStoreLiquibase).afterPropertiesSet();
|
||||
verify(initialTenantLiquibase).changeLogSync();
|
||||
verify(tenantLiquibase).afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAfterPropertiesSetFailsWhenTenantStoreFlywayIsNotOnLatestVersion() throws Exception {
|
||||
// given
|
||||
ExtendedSpringLiquibase initialTenantStoreLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
ExtendedSpringLiquibase tenantStoreLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
given(databaseStateVerifier.isLiquibaseDisabled()).willReturn(false);
|
||||
given(databaseStateVerifier.isFirstLiquibaseMigration(tenantDataSource)).willReturn(true);
|
||||
given(databaseStateVerifier.isFlywayPresent(tenantDataSource)).willReturn(true);
|
||||
given(databaseStateVerifier.isTenantStoreOnLatestUpgradableVersion(tenantDataSource)).willReturn(false);
|
||||
given(fineractProperties.getTenant()).willReturn(new FineractProperties.FineractTenantProperties());
|
||||
given(liquibaseFactory.create(tenantDataSource, "tenant_store_db", "initial_switch")).willReturn(initialTenantStoreLiquibase);
|
||||
given(liquibaseFactory.create(tenantDataSource, "tenant_store_db")).willReturn(tenantStoreLiquibase);
|
||||
|
||||
ExtendedSpringLiquibase initialTenantLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
ExtendedSpringLiquibase tenantLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
FineractPlatformTenant defaultTenant = mock(FineractPlatformTenant.class);
|
||||
List<FineractPlatformTenant> allTenants = List.of(defaultTenant);
|
||||
DataSource defaultTenantDataSource = mock(DataSource.class);
|
||||
given(databaseStateVerifier.isFirstLiquibaseMigration(defaultTenantDataSource)).willReturn(true);
|
||||
given(databaseStateVerifier.isFlywayPresent(defaultTenantDataSource)).willReturn(true);
|
||||
given(databaseStateVerifier.isTenantOnLatestUpgradableVersion(defaultTenantDataSource)).willReturn(true);
|
||||
given(tenantDetailsService.findAllTenants()).willReturn(allTenants);
|
||||
given(tenantDataSourceFactory.create(defaultTenant)).willReturn(defaultTenantDataSource);
|
||||
given(liquibaseFactory.create(defaultTenantDataSource, "tenant_db", "initial_switch")).willReturn(initialTenantLiquibase);
|
||||
given(liquibaseFactory.create(defaultTenantDataSource, "tenant_db")).willReturn(tenantLiquibase);
|
||||
// when
|
||||
SchemaUpgradeNeededException result = assertThrows(SchemaUpgradeNeededException.class, () -> underTest.afterPropertiesSet());
|
||||
// then
|
||||
assertThat(result).isNotNull();
|
||||
verify(liquibaseFactory).create(eq(tenantDataSource), any());
|
||||
verifyNoMoreInteractions(liquibaseFactory);
|
||||
verifyNoInteractions(initialTenantStoreLiquibase, tenantStoreLiquibase, initialTenantLiquibase, tenantLiquibase);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAfterPropertiesSetFailsWhenTenantFlywayIsNotOnLatestVersion() throws Exception {
|
||||
// given
|
||||
ExtendedSpringLiquibase initialTenantStoreLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
ExtendedSpringLiquibase tenantStoreLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
given(databaseStateVerifier.isLiquibaseDisabled()).willReturn(false);
|
||||
given(databaseStateVerifier.isFirstLiquibaseMigration(tenantDataSource)).willReturn(true);
|
||||
given(databaseStateVerifier.isFlywayPresent(tenantDataSource)).willReturn(true);
|
||||
given(databaseStateVerifier.isTenantStoreOnLatestUpgradableVersion(tenantDataSource)).willReturn(true);
|
||||
given(fineractProperties.getTenant()).willReturn(new FineractProperties.FineractTenantProperties());
|
||||
given(liquibaseFactory.create(tenantDataSource, "tenant_store_db", "initial_switch")).willReturn(initialTenantStoreLiquibase);
|
||||
given(liquibaseFactory.create(tenantDataSource, "tenant_store_db")).willReturn(tenantStoreLiquibase);
|
||||
|
||||
ExtendedSpringLiquibase initialTenantLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
ExtendedSpringLiquibase tenantLiquibase = mock(ExtendedSpringLiquibase.class);
|
||||
FineractPlatformTenant defaultTenant = mock(FineractPlatformTenant.class);
|
||||
List<FineractPlatformTenant> allTenants = List.of(defaultTenant);
|
||||
DataSource defaultTenantDataSource = mock(DataSource.class);
|
||||
given(databaseStateVerifier.isFirstLiquibaseMigration(defaultTenantDataSource)).willReturn(true);
|
||||
given(databaseStateVerifier.isFlywayPresent(defaultTenantDataSource)).willReturn(true);
|
||||
given(databaseStateVerifier.isTenantOnLatestUpgradableVersion(defaultTenantDataSource)).willReturn(false);
|
||||
given(tenantDetailsService.findAllTenants()).willReturn(allTenants);
|
||||
given(tenantDataSourceFactory.create(defaultTenant)).willReturn(defaultTenantDataSource);
|
||||
given(liquibaseFactory.create(defaultTenantDataSource, "tenant_db", "initial_switch")).willReturn(initialTenantLiquibase);
|
||||
given(liquibaseFactory.create(defaultTenantDataSource, "tenant_db")).willReturn(tenantLiquibase);
|
||||
// when
|
||||
SchemaUpgradeNeededException result = assertThrows(SchemaUpgradeNeededException.class, () -> underTest.afterPropertiesSet());
|
||||
// then
|
||||
assertThat(result).isNotNull();
|
||||
verify(liquibaseFactory, times(2)).create(eq(tenantDataSource), any());
|
||||
verify(liquibaseFactory).create(eq(defaultTenantDataSource), any());
|
||||
verifyNoMoreInteractions(liquibaseFactory);
|
||||
verify(initialTenantStoreLiquibase).changeLogSync();
|
||||
verify(tenantStoreLiquibase).afterPropertiesSet();
|
||||
verifyNoInteractions(initialTenantLiquibase, tenantLiquibase);
|
||||
}
|
||||
}
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.infrastructure.security.utils;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Unit Test for {@link SQLBuilder}.
|
||||
*
|
||||
* @author Michael Vorburger <mike@vorburger.ch>
|
||||
*/
|
||||
public class SQLBuilderTest {
|
||||
|
||||
@Test
|
||||
public void testEmpty() {
|
||||
SQLBuilder sqlBuilder = new SQLBuilder();
|
||||
assertEquals("", sqlBuilder.getSQLTemplate());
|
||||
assertArrayEquals(new Object[] {}, sqlBuilder.getArguments());
|
||||
assertEquals("SQLBuilder{}", sqlBuilder.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUsage() {
|
||||
SQLBuilder sqlBuilder = new SQLBuilder();
|
||||
sqlBuilder.addCriteria("name =", "Michael");
|
||||
sqlBuilder.addCriteria("hobby LIKE ", "Mifos/Apache Fineract");
|
||||
sqlBuilder.addCriteria("age < ", 123);
|
||||
assertEquals(" WHERE name = ? AND hobby LIKE ? AND age < ?", sqlBuilder.getSQLTemplate());
|
||||
assertArrayEquals(new Object[] { "Michael", "Mifos/Apache Fineract", 123 }, sqlBuilder.getArguments());
|
||||
assertEquals("SQLBuilder{WHERE name = ['Michael'] AND hobby LIKE ['Mifos/Apache Fineract'] AND age < [123]}",
|
||||
sqlBuilder.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullArgument() {
|
||||
SQLBuilder sqlBuilder = new SQLBuilder();
|
||||
sqlBuilder.addCriteria("ref =", null);
|
||||
assertEquals(" WHERE ref = ?", sqlBuilder.getSQLTemplate());
|
||||
assertArrayEquals(new Object[] { null }, sqlBuilder.getArguments());
|
||||
assertEquals("SQLBuilder{WHERE ref = [null]}", sqlBuilder.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLowerAndUpperCaseOperators() {
|
||||
SQLBuilder sqlBuilder = new SQLBuilder();
|
||||
sqlBuilder.addCriteria("hobby LIKE ", "Mifos/Apache Fineract");
|
||||
sqlBuilder.addCriteria("hobby like ", "Mifos/Apache Fineract");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddIllegalArguments() throws Exception {
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new SQLBuilder().addCriteria("age<", 123);
|
||||
}, "space between column and operator");
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new SQLBuilder().addCriteria(null, "argument");
|
||||
}, "null Criteria Fragment");
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new SQLBuilder().addCriteria("", "argument");
|
||||
}, "empty Criteria Fragment");
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new SQLBuilder().addCriteria(" ", "argument");
|
||||
}, "space only Criteria Fragment");
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new SQLBuilder().addCriteria("age = ?", 123);
|
||||
}, "Criteria Fragment with ?");
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new SQLBuilder().addCriteria("age", 123);
|
||||
}, "Criteria Fragment missing operator");
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new SQLBuilder().addCriteria("and age = ?", 123);
|
||||
}, "Criteria starts with AND");
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new SQLBuilder().addCriteria("age = ? and", 123);
|
||||
}, "Criteria ends with AND");
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new SQLBuilder().addCriteria("or age =", 123);
|
||||
}, "Criteria starts with OR");
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new SQLBuilder().addCriteria("age = ? or", 123);
|
||||
}, "Criteria ends with OR");
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new SQLBuilder().addCriteria("(age =", 123);
|
||||
}, "Criteria contains opening parentheis");
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new SQLBuilder().addCriteria("age = ?)", 123);
|
||||
}, "Criteria contains closing parentheis");
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new SQLBuilder().addCriteria("age< = ?)", 123);
|
||||
}, "Offset corner case");
|
||||
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.infrastructure.sqlbuilder;
|
||||
|
||||
import static org.apache.fineract.infrastructure.sqlbuilder.SqlBuilderUtil.transform;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import io.cucumber.java8.En;
|
||||
import org.apache.fineract.infrastructure.security.utils.SQLBuilder;
|
||||
|
||||
public class SqlBuilderExceptionStepDefinitions implements En {
|
||||
|
||||
private SQLBuilder sqlBuilder;
|
||||
|
||||
private Throwable throwable;
|
||||
|
||||
public SqlBuilderExceptionStepDefinitions() {
|
||||
Given("/^An illegal criteria (.*) with argument (.*)$/", (String criteria, String argument) -> {
|
||||
sqlBuilder = new SQLBuilder();
|
||||
try {
|
||||
sqlBuilder.addCriteria(criteria, transform(argument));
|
||||
} catch (Throwable t) {
|
||||
this.throwable = t;
|
||||
}
|
||||
});
|
||||
|
||||
Then("/^The builder should throw an exception (.*) with message (.*)$/", (String exception, String message) -> {
|
||||
assertEquals(Class.forName(exception), throwable.getClass());
|
||||
});
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.infrastructure.sqlbuilder;
|
||||
|
||||
import static org.apache.fineract.infrastructure.sqlbuilder.SqlBuilderUtil.transform;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import io.cucumber.java8.En;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.infrastructure.security.utils.SQLBuilder;
|
||||
|
||||
public class SqlBuilderStepDefinitions implements En {
|
||||
|
||||
private SQLBuilder sqlBuilder;
|
||||
|
||||
private List<Object> expectedArguments;
|
||||
|
||||
public SqlBuilderStepDefinitions() {
|
||||
|
||||
Given("/^A criteria (.*), (.*), (.*), (.*) and arguments (.*), (.*), (.*), (.*)$/", (String criteria1, String criteria2,
|
||||
String criteria3, String criteria4, String argument1, String argument2, String argument3, String argument4) -> {
|
||||
sqlBuilder = new SQLBuilder();
|
||||
expectedArguments = new ArrayList<>();
|
||||
|
||||
if (!StringUtils.isEmpty(criteria1)) {
|
||||
sqlBuilder.addCriteria(criteria1, transform(argument1));
|
||||
}
|
||||
if (!StringUtils.isEmpty(criteria2)) {
|
||||
sqlBuilder.addCriteria(criteria2, transform(argument2));
|
||||
}
|
||||
if (!StringUtils.isEmpty(criteria3)) {
|
||||
sqlBuilder.addCriteria(criteria3, transform(argument3));
|
||||
}
|
||||
if (!StringUtils.isEmpty(criteria4)) {
|
||||
sqlBuilder.addCriteria(criteria4, transform(argument4));
|
||||
}
|
||||
|
||||
if (!StringUtils.isBlank(argument1)) {
|
||||
expectedArguments.add(transform(argument1));
|
||||
}
|
||||
if (!StringUtils.isBlank(argument2)) {
|
||||
expectedArguments.add(transform(argument2));
|
||||
}
|
||||
if (!StringUtils.isBlank(argument3)) {
|
||||
expectedArguments.add(transform(argument3));
|
||||
}
|
||||
if (!StringUtils.isBlank(argument4)) {
|
||||
expectedArguments.add(transform(argument4));
|
||||
}
|
||||
});
|
||||
|
||||
Then("/^The template should match expected template (.*)$/", (String template) -> {
|
||||
assertEquals(template.trim(), sqlBuilder.getSQLTemplate().trim());
|
||||
});
|
||||
|
||||
Then("/^The arguments should match expected arguments (.*)$/", (String argLine) -> {
|
||||
assertArrayEquals(expectedArguments.toArray(new Object[0]), sqlBuilder.getArguments(), sqlBuilder.toString());
|
||||
});
|
||||
|
||||
Then("/^The builder should match (.*)$/", (String expected) -> {
|
||||
if (!StringUtils.isBlank(expected)) {
|
||||
assertEquals(expected, sqlBuilder.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.infrastructure.sqlbuilder;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
final class SqlBuilderUtil {
|
||||
|
||||
private SqlBuilderUtil() {}
|
||||
|
||||
static Object transform(String argument) {
|
||||
if (!StringUtils.isBlank(argument)) {
|
||||
if ("NULL".equals(argument)) {
|
||||
return null;
|
||||
} else if ("EMPTY".equals(argument)) {
|
||||
return "";
|
||||
} else if (isInt(argument)) {
|
||||
return Integer.parseInt(argument);
|
||||
} else if (isDouble(argument)) {
|
||||
return Double.parseDouble(argument);
|
||||
} else {
|
||||
return argument;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static boolean isInt(String str) {
|
||||
return str != null && str.matches("\\d+");
|
||||
}
|
||||
|
||||
static boolean isDouble(String str) {
|
||||
return str != null && str.matches("\\d+\\.\\d+");
|
||||
}
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.mix.report;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import io.cucumber.java8.En;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.Date;
|
||||
import java.util.HashMap;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.fineract.mix.data.MixTaxonomyData;
|
||||
import org.apache.fineract.mix.data.NamespaceData;
|
||||
import org.apache.fineract.mix.service.NamespaceReadPlatformServiceImpl;
|
||||
import org.apache.fineract.mix.service.XBRLBuilder;
|
||||
import org.apache.fineract.template.service.TemplateServiceStepDefinitions;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
|
||||
public class MixXbrlBuilderStepDefinitions implements En {
|
||||
|
||||
private NamespaceReadPlatformServiceImpl readNamespaceService;
|
||||
|
||||
private final XBRLBuilder xbrlBuilder = new XBRLBuilder();
|
||||
|
||||
private Date start;
|
||||
|
||||
private Date end;
|
||||
|
||||
private String currency;
|
||||
|
||||
private HashMap<MixTaxonomyData, BigDecimal> data = new HashMap<>();
|
||||
|
||||
private String result;
|
||||
|
||||
public MixXbrlBuilderStepDefinitions() {
|
||||
Given("/^The XBRL input parameters start date (.*), end date (.*), currency (.*), taxonomy (.*) and sample (.*)$/",
|
||||
(String start, String end, String currency, String taxonomy, String sample) -> {
|
||||
readNamespaceService = mock(NamespaceReadPlatformServiceImpl.class);
|
||||
lenient().when(this.readNamespaceService.retrieveNamespaceByPrefix(ArgumentMatchers.anyString()))
|
||||
.thenReturn(new NamespaceData(1L, "mockedprefix", "mockedurl"));
|
||||
|
||||
this.start = Date.valueOf(start);
|
||||
this.end = Date.valueOf(end);
|
||||
this.currency = currency;
|
||||
|
||||
MixTaxonomyData taxonomyData = mock(MixTaxonomyData.class);
|
||||
when(taxonomyData.getName()).thenReturn(taxonomy);
|
||||
this.data.put(taxonomyData, BigDecimal.valueOf(Long.parseLong(sample)));
|
||||
});
|
||||
|
||||
When("The user builds the XBRL report", () -> {
|
||||
result = this.xbrlBuilder.build(data, start, end, currency);
|
||||
});
|
||||
|
||||
Then("/^The XBRL result should match (.*)$/", (String file) -> {
|
||||
String expected = IOUtils.resourceToString("results/" + file, StandardCharsets.UTF_8,
|
||||
TemplateServiceStepDefinitions.class.getClassLoader());
|
||||
assertEquals(expected.trim(), result.trim());
|
||||
});
|
||||
}
|
||||
}
|
||||
+23
-22
@@ -16,36 +16,37 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.mix.report.service;
|
||||
package org.apache.fineract.mix.report;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import io.cucumber.java8.En;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
|
||||
import org.apache.fineract.mix.service.XBRLResultServiceImpl;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.assertj.core.util.Arrays;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class ReadTaxonomyMappingServiceImplTest {
|
||||
public class MixXbrlTaxonomyStepDefinitions implements En {
|
||||
|
||||
private XBRLResultServiceImpl readService;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
final RoutingDataSource dataSource = Mockito.mock(RoutingDataSource.class);
|
||||
this.readService = new XBRLResultServiceImpl(dataSource, null, null);
|
||||
private String template;
|
||||
|
||||
private List<String> result;
|
||||
|
||||
public MixXbrlTaxonomyStepDefinitions() {
|
||||
Given("/^A XBRL template (.*)$/", (String template) -> {
|
||||
this.readService = new XBRLResultServiceImpl(mock(RoutingDataSource.class), null, null);
|
||||
this.template = template;
|
||||
});
|
||||
|
||||
When("The user resolves GL codes", () -> {
|
||||
this.result = this.readService.getGLCodes(template);
|
||||
});
|
||||
|
||||
Then("/^The result should contain (.*)$/", (String line) -> {
|
||||
assertArrayEquals(result.toArray(new String[0]), Arrays.array(line.split(",")));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCorrectlyGetGLCode() {
|
||||
final ArrayList<String> result = this.readService.getGLCodes("{12000}+{11000}");
|
||||
assertEquals("12000", result.get(0));
|
||||
assertEquals("11000", result.get(1));
|
||||
}
|
||||
|
||||
}
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.mix.report.service;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.Date;
|
||||
import java.util.HashMap;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.apache.fineract.mix.data.MixTaxonomyData;
|
||||
import org.apache.fineract.mix.data.NamespaceData;
|
||||
import org.apache.fineract.mix.service.NamespaceReadPlatformServiceImpl;
|
||||
import org.apache.fineract.mix.service.XBRLBuilder;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class XBRLBuilderTest {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(XBRLBuilderTest.class);
|
||||
@Mock
|
||||
private NamespaceReadPlatformServiceImpl readNamespaceService;
|
||||
|
||||
@InjectMocks
|
||||
private final XBRLBuilder xbrlBuilder = new XBRLBuilder();
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
this.readNamespaceService = Mockito.mock(NamespaceReadPlatformServiceImpl.class);
|
||||
lenient().when(this.readNamespaceService.retrieveNamespaceByPrefix(ArgumentMatchers.anyString()))
|
||||
.thenReturn(new NamespaceData(1L, "mockedprefix", "mockedurl"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCorrectlyBuildMap() throws SAXException, IOException, ParserConfigurationException {
|
||||
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");
|
||||
LOG.info("{}", result);
|
||||
NodeList nodes = DocumentBuilderFactory.newInstance().newDocumentBuilder()
|
||||
.parse(new ByteArrayInputStream(result.getBytes(StandardCharsets.UTF_8))).getElementsByTagName("Assets");
|
||||
assertNotNull(nodes);
|
||||
assertNotNull(nodes.item(0));
|
||||
assertEquals("Assets", nodes.item(0).getNodeName());
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.notification;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.TextMessage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.jms.listener.SessionAwareMessageListener;
|
||||
|
||||
public class Listener implements SessionAwareMessageListener {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Listener.class);
|
||||
|
||||
@Override
|
||||
public void onMessage(Message message, Session session) throws JMSException {
|
||||
TextMessage msg = (TextMessage) message;
|
||||
LOG.info("Received: {}", msg.getText());
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.notification;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.TextMessage;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class ListenerTest {
|
||||
|
||||
private Listener listener;
|
||||
private Session session;
|
||||
private TextMessage textMessageMock;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
listener = new Listener();
|
||||
session = Mockito.mock(Session.class);
|
||||
textMessageMock = Mockito.mock(TextMessage.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListener() throws JMSException {
|
||||
Mockito.when(textMessageMock.getText()).thenReturn("content");
|
||||
listener.onMessage(textMessageMock, session);
|
||||
Mockito.verify(textMessageMock).getText();
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.notification;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.refEq;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
import org.apache.fineract.notification.domain.Notification;
|
||||
import org.apache.fineract.notification.domain.NotificationMapper;
|
||||
import org.apache.fineract.notification.service.NotificationGeneratorReadRepositoryWrapper;
|
||||
import org.apache.fineract.notification.service.NotificationGeneratorWritePlatformService;
|
||||
import org.apache.fineract.notification.service.NotificationMapperWritePlatformService;
|
||||
import org.apache.fineract.notification.service.NotificationWritePlatformServiceImpl;
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
import org.apache.fineract.useradministration.domain.AppUserRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class StorageTest {
|
||||
|
||||
private NotificationWritePlatformServiceImpl notificationWritePlatformServiceImpl;
|
||||
|
||||
@Mock
|
||||
private NotificationGeneratorReadRepositoryWrapper notificationGeneratorReadRepositoryWrapper;
|
||||
|
||||
@Mock
|
||||
private NotificationGeneratorWritePlatformService notificationGeneratorWritePlatformService;
|
||||
|
||||
@Mock
|
||||
private NotificationMapperWritePlatformService notificationMapperWritePlatformService;
|
||||
|
||||
@Mock
|
||||
private AppUserRepository appUserRepository;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
notificationWritePlatformServiceImpl = new NotificationWritePlatformServiceImpl(notificationGeneratorWritePlatformService,
|
||||
notificationGeneratorReadRepositoryWrapper, appUserRepository, notificationMapperWritePlatformService);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled // TODO FINERACT-828
|
||||
public void testNotificationStorage() {
|
||||
Long userId = 1L;
|
||||
String objectType = "CLIENT";
|
||||
Long objectIdentifier = 1L;
|
||||
String action = "created";
|
||||
Long actor = 1L;
|
||||
String notificationContent = "A client was created";
|
||||
boolean isSystemGenerated = false;
|
||||
String now = getCurrentDateTime();
|
||||
|
||||
Notification notification = new Notification(objectType, objectIdentifier, action, actor, isSystemGenerated, notificationContent,
|
||||
now);
|
||||
|
||||
AppUser appUser = new AppUser(null, new User("J.J.", "", true, true, true, true, Collections.emptyList()), null, "user@com", "John",
|
||||
"", null, false, false, null, null);
|
||||
|
||||
NotificationMapper notificationMapper = new NotificationMapper(notification, appUser, false, now);
|
||||
|
||||
when(this.notificationGeneratorWritePlatformService.create(refEq(notification))).thenReturn(1L);
|
||||
|
||||
when(this.appUserRepository.findById(userId)).thenReturn(Optional.of(appUser));
|
||||
|
||||
when(this.notificationGeneratorReadRepositoryWrapper.findById(1L)).thenReturn(notification);
|
||||
|
||||
when(this.notificationMapperWritePlatformService.create(refEq(notificationMapper))).thenReturn(1L);
|
||||
|
||||
Long actualGeneratedNotificationId = notificationWritePlatformServiceImpl.notify(userId, objectType, objectIdentifier, action,
|
||||
actor, notificationContent, isSystemGenerated);
|
||||
|
||||
verify(this.notificationGeneratorWritePlatformService, times(1)).create(refEq(notification, "createdAt"));
|
||||
verify(this.notificationMapperWritePlatformService, times(1)).create(refEq(notificationMapper, "createdAt"));
|
||||
verify(this.notificationGeneratorReadRepositoryWrapper, times(1)).findById(1L);
|
||||
assertEquals(Long.valueOf(1), actualGeneratedNotificationId);
|
||||
}
|
||||
|
||||
private String getCurrentDateTime() {
|
||||
Date date = new Date();
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
return formatter.format(date);
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.notification;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.refEq;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Date;
|
||||
import org.apache.fineract.notification.domain.Topic;
|
||||
import org.apache.fineract.notification.domain.TopicRepository;
|
||||
import org.apache.fineract.notification.domain.TopicSubscriber;
|
||||
import org.apache.fineract.notification.service.TopicSubscriberWritePlatformService;
|
||||
import org.apache.fineract.notification.service.TopicWritePlatformService;
|
||||
import org.apache.fineract.organisation.office.domain.Office;
|
||||
import org.apache.fineract.organisation.office.domain.OfficeRepository;
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
import org.apache.fineract.useradministration.domain.AppUserRepository;
|
||||
import org.apache.fineract.useradministration.domain.Role;
|
||||
import org.apache.fineract.useradministration.domain.RoleRepository;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class TopicTest {
|
||||
|
||||
@Mock
|
||||
private OfficeRepository officeRepository;
|
||||
|
||||
@Mock
|
||||
private RoleRepository roleRepository;
|
||||
|
||||
@Mock
|
||||
private TopicWritePlatformService topicWritePltfService;
|
||||
|
||||
@Mock
|
||||
private TopicRepository topicRepository;
|
||||
|
||||
@Mock
|
||||
private TopicSubscriberWritePlatformService topicSubscriberWritePltfService;
|
||||
|
||||
@Mock
|
||||
private AppUserRepository appUserRepository;
|
||||
|
||||
@Test
|
||||
public void testTopicStorage() {
|
||||
Office office = officeRepository.getById(1L);
|
||||
Role role = new Role("New Member_Type", "Testing topic creation");
|
||||
Topic topic = topicRepository.getById(1L);
|
||||
|
||||
lenient().when(this.officeRepository.getById(1L)).thenReturn(office);
|
||||
lenient().when(this.topicRepository.getById(1L)).thenReturn(topic);
|
||||
when(this.roleRepository.save(role)).thenReturn(role);
|
||||
when(this.topicWritePltfService.create(refEq(topic))).thenReturn(1L);
|
||||
|
||||
this.roleRepository.save(role);
|
||||
Long topicId = this.topicWritePltfService.create(topic);
|
||||
|
||||
verify(this.roleRepository, times(1)).save(role);
|
||||
verify(this.topicWritePltfService, times(1)).create(refEq(topic));
|
||||
assertEquals(topicId, Long.valueOf(1));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTopicSubscriberStorage() {
|
||||
AppUser user = appUserRepository.getById(1L);
|
||||
Topic topic = topicRepository.getById(1L);
|
||||
|
||||
TopicSubscriber topicSubscriber = new TopicSubscriber(topic, user, new Date());
|
||||
|
||||
lenient().when(this.appUserRepository.getById(1L)).thenReturn(user);
|
||||
lenient().when(this.topicRepository.getById(1L)).thenReturn(topic);
|
||||
when(this.topicSubscriberWritePltfService.create(refEq(topicSubscriber))).thenReturn(1L);
|
||||
|
||||
Long subscriberId = this.topicSubscriberWritePltfService.create(topicSubscriber);
|
||||
|
||||
verify(this.topicSubscriberWritePltfService, times(1)).create(refEq(topicSubscriber));
|
||||
assertEquals(subscriberId, Long.valueOf(1));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-225
@@ -1,225 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.portfolio.loanaccount;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.RBILoanRepaymentScheduleTransactionProcessor;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class AdhikarLoanRepaymentScheduleTransactionProcessorTest {
|
||||
|
||||
// class under test
|
||||
private RBILoanRepaymentScheduleTransactionProcessor processor;
|
||||
|
||||
private final LocalDate july2nd = LocalDate.of(2012, 7, 2);
|
||||
private final MonetaryCurrency usDollars = new MonetaryCurrencyBuilder().withCode("USD").withDigitsAfterDecimal(2).build();
|
||||
private List<LoanRepaymentScheduleInstallment> installments;
|
||||
|
||||
@BeforeEach
|
||||
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
|
||||
@Disabled
|
||||
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;
|
||||
// }
|
||||
}
|
||||
-628
@@ -1,628 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.portfolio.loanaccount;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.HeavensFamilyLoanRepaymentScheduleTransactionProcessor;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class HeavensFamilyLoanRepaymentScheduleTransactionProcessorTest {
|
||||
|
||||
// class under test
|
||||
private HeavensFamilyLoanRepaymentScheduleTransactionProcessor processor;
|
||||
|
||||
private final LocalDate july2nd = LocalDate.of(2012, 7, 2);
|
||||
private final MonetaryCurrency usDollars = new MonetaryCurrencyBuilder().withCode("USD").withDigitsAfterDecimal(2).build();
|
||||
private List<LoanRepaymentScheduleInstallment> installments;
|
||||
|
||||
@BeforeEach
|
||||
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
|
||||
@Disabled
|
||||
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;
|
||||
// }
|
||||
}
|
||||
-166
@@ -1,166 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.portfolio.loanaccount;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.portfolio.common.domain.DaysInMonthType;
|
||||
import org.apache.fineract.portfolio.common.domain.DaysInYearType;
|
||||
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleGenerator;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.AmortizationMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestMethod;
|
||||
import org.apache.fineract.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 final class LoanProductRelatedDetailTestHelper {
|
||||
|
||||
private LoanProductRelatedDetailTestHelper() {
|
||||
|
||||
}
|
||||
|
||||
public static LoanProductRelatedDetail createSettingsForEqualPrincipalAmortizationQuarterly() {
|
||||
|
||||
final MonetaryCurrency currency = new MonetaryCurrencyBuilder().withCode("USD").withDigitsAfterDecimal(2).build();
|
||||
final BigDecimal defaultPrincipal = BigDecimal.valueOf(Double.parseDouble("200000"));
|
||||
|
||||
// 2% per month, 24% per year
|
||||
final BigDecimal defaultNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.parseDouble("2"));
|
||||
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
final BigDecimal defaultAnnualNominalInterestRate = BigDecimal.valueOf(Double.parseDouble("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.parseDouble("200000"));
|
||||
|
||||
// 2% per month, 24% per year
|
||||
final BigDecimal defaultNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.parseDouble("2"));
|
||||
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
final BigDecimal defaultAnnualNominalInterestRate = BigDecimal.valueOf(Double.parseDouble("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.parseDouble("200000"));
|
||||
|
||||
// 2% per month, 24% per year
|
||||
final BigDecimal defaultNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.parseDouble("2"));
|
||||
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
final BigDecimal defaultAnnualNominalInterestRate = BigDecimal.valueOf(Double.parseDouble("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.parseDouble("15000"));
|
||||
|
||||
// 2% per month, 24% per year
|
||||
final BigDecimal defaultNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.parseDouble("2"));
|
||||
final PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
final BigDecimal defaultAnnualNominalInterestRate = BigDecimal.valueOf(Double.parseDouble("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 recurringMoratoriumOnPrincipalPeriods = 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;
|
||||
final boolean isEqualAmortization = false;
|
||||
return new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, considerPartialPeriodInterest,
|
||||
repayEvery, repaymentFrequencyType, defaultNumberOfRepayments, graceOnPrincipalPayment,
|
||||
recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, amortizationMethod,
|
||||
inArrearsTolerance, graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||
isEqualAmortization);
|
||||
}
|
||||
}
|
||||
-87
@@ -1,87 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.portfolio.loanaccount;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Set;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalcualtionAdditionalDetails;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||
|
||||
public class LoanRepaymentScheduleInstallmentBuilder {
|
||||
|
||||
private final Loan loan = null;
|
||||
private Integer installmentNumber = Integer.valueOf(1);
|
||||
private final LocalDate fromDate = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
||||
private LocalDate dueDate = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
||||
private final LocalDate latestTransactionDate = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
||||
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 Set<LoanInterestRecalcualtionAdditionalDetails> compoundingDetails = null;
|
||||
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, compoundingDetails);
|
||||
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;
|
||||
}
|
||||
}
|
||||
-83
@@ -1,83 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.portfolio.loanaccount;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||
|
||||
/**
|
||||
* Helper class for creating loan schedule data suitable for testing.
|
||||
*/
|
||||
public final class LoanScheduleTestDataHelper {
|
||||
|
||||
private 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);
|
||||
}
|
||||
|
||||
}
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.portfolio.loanaccount;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
|
||||
public class LoanTransactionBuilder {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private Money transactionAmount = new MoneyBuilder().build();
|
||||
@SuppressWarnings("unused")
|
||||
private LocalDate transactionDate = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
||||
@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;
|
||||
}
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.portfolio.loanaccount;
|
||||
|
||||
import org.apache.fineract.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;
|
||||
}
|
||||
}
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.portfolio.loanaccount;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.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.parseDouble(withAmount));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
-134
@@ -1,134 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.portfolio.loanaccount;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import java.io.File;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.infrastructure.creditbureau.service.CreditReportWritePlatformServiceImpl;
|
||||
import org.apache.fineract.infrastructure.creditbureau.service.ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl;
|
||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class ThitsaworksCreditBureauTest {
|
||||
|
||||
private FromJsonHelper fromApiJsonHelper = new FromJsonHelper();
|
||||
|
||||
@Mock
|
||||
private ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl;
|
||||
|
||||
@InjectMocks
|
||||
private final CreditReportWritePlatformServiceImpl creditReportWritePlatformServiceImpl = null;
|
||||
|
||||
/*
|
||||
* @Autowired CreditBureauIntegrationTest(final FromJsonHelper fromApiJsonHelper) { this.fromApiJsonHelper =
|
||||
* fromApiJsonHelper; }
|
||||
*/
|
||||
|
||||
static String process = "process";
|
||||
static String nrcID = "13/MiFoS(N)163525";
|
||||
|
||||
static String userName = "demomfi1@mifos.com";
|
||||
static String password = "password";
|
||||
static String subscriptionKey = "15c15ff17493acb44cb223f2feab2fe4";
|
||||
|
||||
static String subscriptionId = "4A7C-317A41BA-1FF8-8A64-F8EDBE0F625D";
|
||||
static String url = "url";
|
||||
static String token = "token";
|
||||
static Long uniqueId = 8113399260L;
|
||||
static byte[] file;
|
||||
static File report;
|
||||
static String fileName;
|
||||
static UriInfo uriInfo;
|
||||
static FormDataContentDisposition fileData;
|
||||
|
||||
static String testresult = "{ 'Data': {'BorrowerInfo': {'MainIdentifier': '2113439293', 'Name': 'Aung Khant Min',"
|
||||
+ " 'NRC': '13/MiFoS(N)163525', 'Gender': '', 'DOB': '1990-01-20', 'FatherName': '', 'Address': '',"
|
||||
+ " 'LastUpdatedDtm': 'Jul 8 2020 9:27AM', 'PrintedDtm': 'Aug 2 2020 2:54AM' }, "
|
||||
+ " 'ActiveLoanStatus': 'Record found', 'ActiveLoans': [{'ReportingDate': '2020-03-01',"
|
||||
+ " 'LoanGUID': 'BC309AD3-0444-4EFD-807E-79ECB99EE999',"
|
||||
+ " 'Institution': 'Demo 1', 'Division': 'YANGON ',"
|
||||
+ " 'Township': 'YANKIN ', 'DisbursedDate': 'xxxx',"
|
||||
+ " 'DisbursedAmount': '500000', 'PrincipalOutstandingAmount': '300000',"
|
||||
+ " 'TotalOutstandingAmount': 'xxxx', 'PrincipalOverdueAmount': '100000',"
|
||||
+ " 'TotalOverdueAmount': '', 'DaysInDelay': '10',"
|
||||
+ " 'UpdatedDtm': 'Apr 27 2020 9:41AM', 'SortColumn': '2020-03-01T00:00:00'}], "
|
||||
+ " 'WriteOffLoanStatus': 'No record found', 'WriteOffLoans': null,"
|
||||
+ " 'CreditScore': { 'Score': 'N/A','Class': 'N/A', 'Note': ''},"
|
||||
+ " 'InquiryStatus': 'Record found', 'Inquiries': [{ 'InquiryDate': '', 'Institution': '','NoOfInquiry': ''} ] },"
|
||||
+ " 'MessageDtm': '8/1/2020 8:24:20 PM UTC','SubscriptionID': '4A7C-317A41BA-1FF8-8A64-F8EDBE0F625D',"
|
||||
+ " 'CallerIP': '207.46.228.155',"
|
||||
+ " 'URI': 'https://qa-mmcix-api.azurewebsites.net/20200324/api/Dashboard/GetCreditReport?uniqueId=2113439292',"
|
||||
+ " 'ResponseMessage': 'Record found'}";
|
||||
|
||||
@Test
|
||||
public void getUniqueIdFromSearchMethodTest() {
|
||||
String searchResult = "{\"Data\":[{\"UniqueID\":\"8113399260\",\"NRC\":\"12/KaMaRa(N)253426\",\"FullName\":\"Aye Aye\",\"DOB\":\"1990-05-22,1991-05-22\",\"FatherFullName\":\"U Aye Myint Maung\",\"Location\":\"Yangon-Thongwa,Twantay,Yankin\",\"Flag\":\"[{\\\"WriteOff\\\":1}]\",\"Active\":\"Y\"}],\"MessageDtm\":\"8/1/2020 6:39:00 PM UTC\",\"SubscriptionID\":\"317A1FF8-625D-41BA-BE0F-F8ED8A644A7C\",\"CallerIP\":\"207.46.228.155\",\"URI\":\"https://qa-mmcix-api.azurewebsites.net/20200324/api/Search/SimpleSearch?nrc=253426\",\"ResponseMessage\":\"Record found\"}";
|
||||
|
||||
when(this.thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.okHttpConnectionMethod(userName, password, subscriptionKey,
|
||||
subscriptionId, url, token, report, fileData, uniqueId, nrcID, process)).thenReturn(searchResult);
|
||||
|
||||
final String search = thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.okHttpConnectionMethod(userName, password,
|
||||
subscriptionKey, subscriptionId, url, token, report, fileData, uniqueId, nrcID, process);
|
||||
|
||||
when(thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.extractUniqueId(search)).thenCallRealMethod();
|
||||
|
||||
Long uniqueId = thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.extractUniqueId(searchResult);
|
||||
|
||||
Long expectedUniqueId = 8113399260L;
|
||||
assertEquals(expectedUniqueId, uniqueId);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCreditReportTest() {
|
||||
String curentNrc = "13/MiFoS(N)163525";
|
||||
|
||||
when(this.thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.okHttpConnectionMethod(userName, password, subscriptionKey,
|
||||
subscriptionId, url, token, report, fileData, uniqueId, nrcID, process)).thenReturn(testresult);
|
||||
|
||||
String creditReport = thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.okHttpConnectionMethod(userName, password,
|
||||
subscriptionKey, subscriptionId, url, token, report, fileData, uniqueId, nrcID, process);
|
||||
|
||||
JsonObject resultObject = JsonParser.parseString(creditReport).getAsJsonObject();
|
||||
String data = resultObject.get("Data").toString();
|
||||
|
||||
JsonObject dataObject = JsonParser.parseString(data).getAsJsonObject();
|
||||
String borrowerInfo = dataObject.get("BorrowerInfo").toString();
|
||||
|
||||
JsonObject borrowerObject = JsonParser.parseString(borrowerInfo).getAsJsonObject();
|
||||
String nrc = borrowerObject.get("NRC").toString();
|
||||
|
||||
nrc = nrc.substring(1, nrc.length() - 1);
|
||||
|
||||
assertEquals(nrc, curentNrc);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.portfolio.loanproduct;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import io.cucumber.java8.En;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductTrancheDetails;
|
||||
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductGeneralRuleException;
|
||||
|
||||
public class LoanProductValidationStepDefinitions implements En {
|
||||
|
||||
private LoanProduct loanProduct;
|
||||
|
||||
private LoanProductGeneralRuleException ruleException;
|
||||
|
||||
public LoanProductValidationStepDefinitions() {
|
||||
Given("/^A loan product with values `allowMultipleDisbursal` is (.*), `disallowExpectedDisbursements` is (.*), `allowApprovedDisbursedAmountsOverApplied` is (.*), `overAppliedCalculationType` is (.*) and `overAppliedNumber` is (.*)$/",
|
||||
(String allowMultipleDisbursal, String disallowExpectedDisbursements, String allowApprovedDisbursedAmountsOverApplied,
|
||||
String overAppliedCalculationType, String overAppliedNumber) -> {
|
||||
this.loanProduct = newLoanProduct(Boolean.parseBoolean(allowMultipleDisbursal));
|
||||
|
||||
if (!StringUtils.isBlank(disallowExpectedDisbursements)) {
|
||||
loanProduct.setDisallowExpectedDisbursements(Boolean.parseBoolean(disallowExpectedDisbursements));
|
||||
}
|
||||
if (!StringUtils.isBlank(allowApprovedDisbursedAmountsOverApplied)) {
|
||||
loanProduct.setAllowApprovedDisbursedAmountsOverApplied(
|
||||
Boolean.parseBoolean(allowApprovedDisbursedAmountsOverApplied));
|
||||
}
|
||||
if (!StringUtils.isBlank(overAppliedCalculationType) && !"-".equals(overAppliedCalculationType)) {
|
||||
loanProduct.setOverAppliedCalculationType(overAppliedCalculationType);
|
||||
}
|
||||
if (!StringUtils.isBlank(overAppliedNumber) && Integer.parseInt(overAppliedNumber) >= 0) {
|
||||
loanProduct.setOverAppliedNumber(Integer.parseInt(overAppliedNumber));
|
||||
}
|
||||
});
|
||||
|
||||
When("/^The user validates the loan product before saving$/", () -> {
|
||||
this.ruleException = assertThrows(LoanProductGeneralRuleException.class, () -> loanProduct.validateLoanProductPreSave());
|
||||
});
|
||||
|
||||
Then("/^An exception (.*) with message template (.*) should be thrown$/", (String exception, String messageTemplate) -> {
|
||||
if (!StringUtils.isBlank(exception)) {
|
||||
assertEquals(Class.forName(exception.trim()), this.ruleException.getClass());
|
||||
}
|
||||
if (!StringUtils.isBlank(messageTemplate)) {
|
||||
assertThat(messageTemplate.trim(), is(this.ruleException.getGlobalisationMessageCode()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private LoanProduct newLoanProduct(boolean allowMultipleDisbursals) {
|
||||
LoanProduct lp = new LoanProduct();
|
||||
lp.setLoanProducTrancheDetails(new LoanProductTrancheDetails(allowMultipleDisbursals, null, null));
|
||||
return lp;
|
||||
}
|
||||
}
|
||||
-158
@@ -1,158 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.portfolio.loanproduct.domain;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductGeneralRuleException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class LoanProductTest {
|
||||
|
||||
@Test
|
||||
public void shouldThrowExceptionWhenAllowMultipleDisbursalsFalseAndDisallowExpectedDisbursementsIsTrue() {
|
||||
|
||||
LoanProduct lp = stubLoanProduct(false);
|
||||
lp.setDisallowExpectedDisbursements(true);
|
||||
|
||||
LoanProductGeneralRuleException expectedEx = assertThrows(LoanProductGeneralRuleException.class,
|
||||
() -> lp.validateLoanProductPreSave());
|
||||
|
||||
assertThat(expectedEx.getGlobalisationMessageCode(),
|
||||
is("error.msg.allowMultipleDisbursals.not.set.disallowExpectedDisbursements.cant.be.set"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowExceptionWhenDisallowExpectedDisbursementIsFalseAndAllowApprovedDisbursedAmountsOverAppliedIsTrue() {
|
||||
|
||||
LoanProduct lp = stubLoanProduct(true);
|
||||
lp.setDisallowExpectedDisbursements(false);
|
||||
lp.setAllowApprovedDisbursedAmountsOverApplied(true);
|
||||
|
||||
LoanProductGeneralRuleException expectedEx = assertThrows(LoanProductGeneralRuleException.class,
|
||||
() -> lp.validateLoanProductPreSave());
|
||||
|
||||
assertThat(expectedEx.getGlobalisationMessageCode(),
|
||||
is("error.msg.disallowExpectedDisbursements.not.set.allowApprovedDisbursedAmountsOverApplied.cant.be.set"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowExceptionWhenAllowApprovedDisbursedAmountsOverAppliedIsTrueAndAppliedCalculationTypeIsNull() {
|
||||
|
||||
LoanProduct lp = stubLoanProduct(true);
|
||||
lp.setDisallowExpectedDisbursements(true);
|
||||
lp.setAllowApprovedDisbursedAmountsOverApplied(true);
|
||||
lp.setOverAppliedCalculationType(null);
|
||||
|
||||
LoanProductGeneralRuleException expectedEx = assertThrows(LoanProductGeneralRuleException.class,
|
||||
() -> lp.validateLoanProductPreSave());
|
||||
|
||||
assertThat(expectedEx.getGlobalisationMessageCode(),
|
||||
is("error.msg.allowApprovedDisbursedAmountsOverApplied.is.set.overAppliedCalculationType.is.mandatory"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowExceptionWhenAllowApprovedDisbursedAmountsOverAppliedIsTrueAndAppliedCalculationTypeIsEmpty() {
|
||||
|
||||
LoanProduct lp = stubLoanProduct(true);
|
||||
lp.setDisallowExpectedDisbursements(true);
|
||||
lp.setAllowApprovedDisbursedAmountsOverApplied(true);
|
||||
lp.setOverAppliedCalculationType("");
|
||||
|
||||
LoanProductGeneralRuleException expectedEx = assertThrows(LoanProductGeneralRuleException.class,
|
||||
() -> lp.validateLoanProductPreSave());
|
||||
|
||||
assertThat(expectedEx.getGlobalisationMessageCode(),
|
||||
is("error.msg.allowApprovedDisbursedAmountsOverApplied.is.set.overAppliedCalculationType.is.mandatory"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowExceptionWhenAllowApprovedDisbursedAmountsOverAppliedIsFalseAndAppliedCalculationTypeIsNotEmpty() {
|
||||
|
||||
LoanProduct lp = stubLoanProduct(true);
|
||||
lp.setDisallowExpectedDisbursements(true);
|
||||
lp.setAllowApprovedDisbursedAmountsOverApplied(false);
|
||||
lp.setOverAppliedCalculationType("flat");
|
||||
|
||||
LoanProductGeneralRuleException expectedEx = assertThrows(LoanProductGeneralRuleException.class,
|
||||
() -> lp.validateLoanProductPreSave());
|
||||
|
||||
assertThat(expectedEx.getGlobalisationMessageCode(),
|
||||
is("error.msg.allowApprovedDisbursedAmountsOverApplied.is.not.set.overAppliedCalculationType.cant.be.entered"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowExceptionWhenOverAppliedCalculationTypeNotValid() {
|
||||
|
||||
LoanProduct lp = stubLoanProduct(true);
|
||||
lp.setDisallowExpectedDisbursements(true);
|
||||
lp.setAllowApprovedDisbursedAmountsOverApplied(true);
|
||||
lp.setOverAppliedCalculationType("notflat");
|
||||
|
||||
LoanProductGeneralRuleException expectedEx = assertThrows(LoanProductGeneralRuleException.class,
|
||||
() -> lp.validateLoanProductPreSave());
|
||||
|
||||
assertThat(expectedEx.getGlobalisationMessageCode(), is("error.msg.overAppliedCalculationType.must.be.percentage.or.flat"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowExceptionWhenAllowApprovedDisbursedAmountsOverAppliedIsTrueAndAppliedCalculationNumberIsNull() {
|
||||
|
||||
LoanProduct lp = stubLoanProduct(true);
|
||||
lp.setDisallowExpectedDisbursements(true);
|
||||
lp.setAllowApprovedDisbursedAmountsOverApplied(true);
|
||||
lp.setOverAppliedCalculationType("flat");
|
||||
lp.setOverAppliedNumber(null);
|
||||
|
||||
LoanProductGeneralRuleException expectedEx = assertThrows(LoanProductGeneralRuleException.class,
|
||||
() -> lp.validateLoanProductPreSave());
|
||||
|
||||
assertThat(expectedEx.getGlobalisationMessageCode(),
|
||||
is("error.msg.allowApprovedDisbursedAmountsOverApplied.is.set.overAppliedNumber.is.mandatory"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowExceptionWhenAllowApprovedDisbursedAmountsOverAppliedIsFalseAndAppliedCalculationNumberIsNotNull() {
|
||||
|
||||
LoanProduct lp = stubLoanProduct(true);
|
||||
lp.setDisallowExpectedDisbursements(true);
|
||||
lp.setAllowApprovedDisbursedAmountsOverApplied(false);
|
||||
lp.setOverAppliedNumber(80);
|
||||
|
||||
LoanProductGeneralRuleException expectedEx = assertThrows(LoanProductGeneralRuleException.class,
|
||||
() -> lp.validateLoanProductPreSave());
|
||||
|
||||
assertThat(expectedEx.getGlobalisationMessageCode(),
|
||||
is("error.msg.allowApprovedDisbursedAmountsOverApplied.is.not.set.overAppliedNumber.cant.be.entered"));
|
||||
}
|
||||
|
||||
private LoanProduct stubLoanProduct(boolean allowMultipleDisbursals) {
|
||||
LoanProduct lp = new LoanProduct();
|
||||
lp.setLoanProducTrancheDetails(new LoanProductTrancheDetails(allowMultipleDisbursals, null, null));
|
||||
return lp;
|
||||
}
|
||||
|
||||
}
|
||||
-129
@@ -1,129 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.template;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
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;
|
||||
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.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||
import org.apache.fineract.portfolio.loanaccount.LoanScheduleTestDataHelper;
|
||||
import org.apache.fineract.portfolio.loanaccount.MonetaryCurrencyBuilder;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||
import org.apache.fineract.template.domain.Template;
|
||||
import org.apache.fineract.template.domain.TemplateMapper;
|
||||
import org.apache.fineract.template.service.TemplateMergeService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class TemplateMergeServiceTest {
|
||||
|
||||
private TemplateMergeService tms = new TemplateMergeService();
|
||||
|
||||
@BeforeEach
|
||||
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 = LocalDate.of(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"), StandardCharsets.UTF_8);
|
||||
String expectedOutput = Resources.toString(Resources.getResource("template-expected.html"), StandardCharsets.UTF_8);
|
||||
|
||||
String output = compileTemplateText(templateText, scopes);
|
||||
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 = JsonParser.parseString(jsonText);
|
||||
return gson.fromJson(json, ssMap);
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.template.service;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import io.cucumber.java8.En;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.fineract.template.domain.Template;
|
||||
import org.apache.fineract.template.domain.TemplateMapper;
|
||||
|
||||
public class TemplateServiceStepDefinitions implements En {
|
||||
|
||||
private TemplateMergeService tms = new TemplateMergeService();
|
||||
|
||||
private String template;
|
||||
|
||||
private Map<String, Object> data;
|
||||
|
||||
private String result;
|
||||
|
||||
public TemplateServiceStepDefinitions() {
|
||||
Given("/^A mustache template file (.*)$/", (String file) -> {
|
||||
template = IOUtils.resourceToString("templates/" + file, StandardCharsets.UTF_8,
|
||||
TemplateServiceStepDefinitions.class.getClassLoader());
|
||||
});
|
||||
|
||||
Given("/^A JSON data file (.*)$/", (String file) -> {
|
||||
data = parse(IOUtils.resourceToString("templates/" + file, StandardCharsets.UTF_8,
|
||||
TemplateServiceStepDefinitions.class.getClassLoader()));
|
||||
});
|
||||
|
||||
When("The user merges the template with data", () -> {
|
||||
result = compile(template, data);
|
||||
});
|
||||
|
||||
Then("/^The result should match the content of file (.*)$/", (String file) -> {
|
||||
String expected = IOUtils.resourceToString("results/" + file, StandardCharsets.UTF_8,
|
||||
TemplateServiceStepDefinitions.class.getClassLoader());
|
||||
assertEquals(expected, result);
|
||||
});
|
||||
}
|
||||
|
||||
private String compile(String templateText, Map<String, Object> scope) throws IOException {
|
||||
List<TemplateMapper> mappers = new ArrayList<>();
|
||||
Template template = new Template("TemplateName", templateText, null, null, mappers);
|
||||
return tms.compile(template, scope);
|
||||
}
|
||||
|
||||
private Map<String, Object> parse(String data) {
|
||||
Gson gson = new Gson();
|
||||
Type ssMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
JsonElement json = JsonParser.parseString(data);
|
||||
return gson.fromJson(json, ssMap);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you 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.
|
||||
#
|
||||
|
||||
cucumber.publish.quiet=true
|
||||
@@ -0,0 +1,6 @@
|
||||
Feature: Accounting Service
|
||||
|
||||
@accounting
|
||||
Scenario: Verify financial activities constants
|
||||
Given All financial activities
|
||||
Then The they should not be empty
|
||||
@@ -0,0 +1,7 @@
|
||||
Feature: Batch Service
|
||||
|
||||
@batch
|
||||
Scenario: Verify that batch builder methods are called
|
||||
Given A batch request
|
||||
When The user calls the batch service handle request method without enclosing transaction
|
||||
Then The batch service handle request method without enclosing transaction should have been called
|
||||
@@ -0,0 +1,20 @@
|
||||
Feature: Commands Service
|
||||
|
||||
@template
|
||||
Scenario Outline: Verify that command providers are injected
|
||||
Given A command handler for entity <entity> and action <action>
|
||||
When The user processes the command with ID <id>
|
||||
Then The command ID matches <id>
|
||||
|
||||
Examples:
|
||||
| id | entity | action |
|
||||
| 815 | HUMAN | UPDATE |
|
||||
|
||||
@template
|
||||
Scenario Outline: Verify that command no command handler is provided
|
||||
Given A missing command handler for entity <entity> and action <action>
|
||||
Then The system should throw an exception
|
||||
|
||||
Examples:
|
||||
| entity | action |
|
||||
| WHATEVER | DOSOMETHING |
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
Feature: Classpath duplicates
|
||||
|
||||
@infrastructure
|
||||
Scenario: Verify if any duplicates exist in the classpath
|
||||
Given A class graph
|
||||
When The user scans the class graph
|
||||
Then There should be no duplicates
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
Feature: Core Infrastructure
|
||||
|
||||
@infrastructure
|
||||
Scenario: Verify that tenant migration service is properly executed
|
||||
Given Liquibase is disabled with a default tenant
|
||||
Given Liquibase runs the very first time for the tenant store
|
||||
Given A previously Flyway migrated tenant store database
|
||||
Given A previously Flyway migrated tenant store database on an earlier version than 1.6
|
||||
Given Liquibase runs the very first time for the default tenant
|
||||
Given A previously Flyway migrated default tenant database
|
||||
Given A previously Flyway migrated default tenant database on the 1.6 version
|
||||
When The database migration process is executed
|
||||
Then The tenant store upgrade fails with a schema upgrade needed
|
||||
|
||||
@infrastructure
|
||||
Scenario Outline: Verify empty multi exceptions
|
||||
Given A multi exception with exceptions <exception1> and <exception2>
|
||||
Then A <expected> should be thrown
|
||||
|
||||
Examples:
|
||||
| exception1 | exception2 | expected |
|
||||
| | | java.lang.IllegalArgumentException |
|
||||
| java.lang.IllegalArgumentException | java.lang.IllegalStateException | org.apache.fineract.infrastructure.core.exception.MultiException |
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
Feature: SQL Builder
|
||||
|
||||
@sqlbuilder
|
||||
Scenario Outline: Verify that SQL builder has expected template and arguments
|
||||
Given A criteria <criteria1>, <criteria2>, <criteria3>, <criteria4> and arguments <argument1>, <argument2>, <argument3>, <argument4>
|
||||
Then The template should match expected template <template>
|
||||
Then The arguments should match expected arguments <arguments>
|
||||
Then The builder should match <expected>
|
||||
|
||||
Examples:
|
||||
| criteria1 | argument1 | criteria2 | argument2 | criteria3 | argument3 | criteria4 | argument4 | template | expected |
|
||||
| | | | | | | | | | SQLBuilder{} |
|
||||
| name = | Michael | hobby LIKE | Mifos/Apache Fineract | age < | 123 | | | WHERE name = ? AND hobby LIKE ? AND age < ? | SQLBuilder{WHERE name = ['Michael'] AND hobby LIKE ['Mifos/Apache Fineract'] AND age < [123]} |
|
||||
| ref = | NULL | | | | | | | WHERE ref = ? | SQLBuilder{WHERE ref = [null]} |
|
||||
| hobby LIKE | Mifos/Apache Fineract | hobby like | Mifos/Apache Fineract | | | | | WHERE hobby LIKE ? AND hobby like ? | |
|
||||
|
||||
@sqlbuilder
|
||||
Scenario Outline: Verify that SQL builder detects illegal criteria
|
||||
Given An illegal criteria <criteria> with argument <argument>
|
||||
Then The builder should throw an exception <exception> with message <message>
|
||||
|
||||
Examples:
|
||||
| criteria | argument | message | exception |
|
||||
| NULL | argument | <NULL> criteria fragment | java.lang.IllegalArgumentException |
|
||||
| EMPTY | argument | <EMPTY> criteria fragment | java.lang.IllegalArgumentException |
|
||||
| age< | 123 | Space between column and operator | java.lang.IllegalArgumentException |
|
||||
| age = ? | 123 | Criteria with placeholder ? | java.lang.IllegalArgumentException |
|
||||
| age | 123 | Criteria missing operator | java.lang.IllegalArgumentException |
|
||||
| and age = ? | 123 | Criteria starts with AND | java.lang.IllegalArgumentException |
|
||||
| age = ? and | 123 | Criteria ends with AND | java.lang.IllegalArgumentException |
|
||||
| or age = ? | 123 | Criteria start with OR | java.lang.IllegalArgumentException |
|
||||
| age = ? or | 123 | Criteria ends with OR | java.lang.IllegalArgumentException |
|
||||
| (age = | 123 | Criteria contains opening parenthesis | java.lang.IllegalArgumentException |
|
||||
| age = ? | 123 | Criteria contains closing parenthesis | java.lang.IllegalArgumentException |
|
||||
| age< = ? | 123 | Offset corner case | java.lang.IllegalArgumentException |
|
||||
@@ -0,0 +1,21 @@
|
||||
Feature: MIX XBRL
|
||||
|
||||
@mix
|
||||
Scenario Outline: Verify that GL codes resolve
|
||||
Given A XBRL template <template>
|
||||
When The user resolves GL codes
|
||||
Then The result should contain <values>
|
||||
|
||||
Examples:
|
||||
| template | values |
|
||||
| {12000}+{11000} | 12000,11000 |
|
||||
|
||||
@mix
|
||||
Scenario Outline: Verify XBRL builder is working
|
||||
Given The XBRL input parameters start date <start>, end date <end>, currency <currency>, taxonomy <taxonomy> and sample <sample>
|
||||
When The user builds the XBRL report
|
||||
Then The XBRL result should match <result>
|
||||
|
||||
Examples:
|
||||
| start | end | currency | taxonomy | sample | result |
|
||||
| 2005-11-11 | 2013-07-17 | USD | Assets | 10000 | xbrl.xml |
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
Feature: Loan Product Validation
|
||||
|
||||
@loanproduct
|
||||
Scenario Outline: Verify that loan product settings are throwing expected exceptions
|
||||
Given A loan product with values `allowMultipleDisbursal` is <allowMultipleDisbursal>, `disallowExpectedDisbursements` is <disallowExpectedDisbursements>, `allowApprovedDisbursedAmountsOverApplied` is <allowApprovedDisbursedAmountsOverApplied>, `overAppliedCalculationType` is <overAppliedCalculationType> and `overAppliedNumber` is <overAppliedNumber>
|
||||
When The user validates the loan product before saving
|
||||
Then An exception <exception> with message template <template> should be thrown
|
||||
|
||||
Examples:
|
||||
| allowMultipleDisbursal | disallowExpectedDisbursements | allowApprovedDisbursedAmountsOverApplied | overAppliedCalculationType | overAppliedNumber | exception | template |
|
||||
| false | true | false | - | -1 | org.apache.fineract.portfolio.loanproduct.exception.LoanProductGeneralRuleException | error.msg.allowMultipleDisbursals.not.set.disallowExpectedDisbursements.cant.be.set |
|
||||
| true | false | true | - | -1 | org.apache.fineract.portfolio.loanproduct.exception.LoanProductGeneralRuleException | error.msg.disallowExpectedDisbursements.not.set.allowApprovedDisbursedAmountsOverApplied.cant.be.set |
|
||||
| true | true | true | - | -1 | org.apache.fineract.portfolio.loanproduct.exception.LoanProductGeneralRuleException | error.msg.allowApprovedDisbursedAmountsOverApplied.is.set.overAppliedCalculationType.is.mandatory |
|
||||
| true | true | true | - | -1 | org.apache.fineract.portfolio.loanproduct.exception.LoanProductGeneralRuleException | error.msg.allowApprovedDisbursedAmountsOverApplied.is.set.overAppliedCalculationType.is.mandatory |
|
||||
| true | false | true | - | -1 | org.apache.fineract.portfolio.loanproduct.exception.LoanProductGeneralRuleException | error.msg.disallowExpectedDisbursements.not.set.allowApprovedDisbursedAmountsOverApplied.cant.be.set |
|
||||
| true | true | true | notflat | -1 | org.apache.fineract.portfolio.loanproduct.exception.LoanProductGeneralRuleException | error.msg.overAppliedCalculationType.must.be.percentage.or.flat |
|
||||
| true | true | false | flat | -1 | org.apache.fineract.portfolio.loanproduct.exception.LoanProductGeneralRuleException | error.msg.allowApprovedDisbursedAmountsOverApplied.is.not.set.overAppliedCalculationType.cant.be.entered |
|
||||
| true | true | true | flat | -1 | org.apache.fineract.portfolio.loanproduct.exception.LoanProductGeneralRuleException | error.msg.allowApprovedDisbursedAmountsOverApplied.is.set.overAppliedNumber.is.mandatory |
|
||||
| true | true | false | - | 80 | org.apache.fineract.portfolio.loanproduct.exception.LoanProductGeneralRuleException | error.msg.allowApprovedDisbursedAmountsOverApplied.is.not.set.overAppliedNumber.cant.be.entered |
|
||||
@@ -0,0 +1,15 @@
|
||||
Feature: Template Service
|
||||
|
||||
@template
|
||||
Scenario Outline: Verify that mustache templates have expected results
|
||||
Given A mustache template file <template>
|
||||
Given A JSON data file <json>
|
||||
When The user merges the template with data
|
||||
Then The result should match the content of file <result>
|
||||
|
||||
Examples:
|
||||
| template | json | result |
|
||||
| hello.mustache | hello.json | hello.txt |
|
||||
| loan.mustache | loan.json | loan.html |
|
||||
| array.loop.mustache | array.json | array.loop.txt |
|
||||
| array.index.mustache | array.json | array.index.txt |
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!--
|
||||
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you 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.
|
||||
|
||||
-->
|
||||
<configuration scan="false">
|
||||
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
|
||||
<resetJUL>false</resetJUL>
|
||||
</contextListener>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<withJansi>true</withJansi>
|
||||
<encoder>
|
||||
<pattern>%green(%d{yyyy-MM-dd HH:mm:ss.SSS}) [%thread] %highlight(%-5level) %cyan(%logger{36}) - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework.transaction" level="INFO" />
|
||||
<logger name="org.springframework.data.convert" level="ERROR" />
|
||||
<logger name="org.springframework.http.converter.json" level="ERROR" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -0,0 +1 @@
|
||||
Hello Test for Template Terence & Michael!
|
||||
@@ -0,0 +1 @@
|
||||
Hello Test for Template Michael Terence!
|
||||
@@ -0,0 +1 @@
|
||||
Hello Test for Template hello!
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xbrl><schemaRef xmlns:link="http://www.themix.org/sites/default/files/Taxonomy2010/dct/dc-all_2010-08-31.xsd"></schemaRef><Assets contextRef="As_Of_07_17_20131" unitRef="Unit2" decimals="0">10000</Assets><context id="As_Of_07_17_20131"><entity><identifier scheme="http://www.themix.org">000000</identifier></entity><period><instant>2013-07-17</instant></period></context><unit id="Unit2"><measure>iso4217:USD</measure></unit><unit id="Unit1"><measure>xbrli:pure</measure></unit></xbrl>
|
||||
@@ -0,0 +1 @@
|
||||
Hello Test for Template {{data.name#1}} & {{data.name#0}}!
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"data": {
|
||||
"name": [
|
||||
"Michael",
|
||||
"Terence"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Hello Test for Template{{#data.name}} {{.}}{{/data.name}}!
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"file": {
|
||||
"name": "hello"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Hello Test for Template {{file.name}}!
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"installments": [
|
||||
{
|
||||
"dueDate": "2012-07-02",
|
||||
"installmentNumber": "1",
|
||||
"principal": "",
|
||||
"feeChargesCharged": ""
|
||||
},
|
||||
{
|
||||
"dueDate": "2012-08-02",
|
||||
"installmentNumber": "2",
|
||||
"principal": "",
|
||||
"feeChargesCharged": ""
|
||||
},
|
||||
{
|
||||
"dueDate": "2012-09-02",
|
||||
"installmentNumber": "3",
|
||||
"principal": "",
|
||||
"feeChargesCharged": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
-1
File diff suppressed because one or more lines are too long
@@ -29,7 +29,13 @@ dependencies {
|
||||
'com.google.truth.extensions:truth-java8-extension',
|
||||
'org.awaitility:awaitility',
|
||||
'org.bouncycastle:bcpkix-jdk15on',
|
||||
'org.bouncycastle:bcprov-jdk15on'
|
||||
'org.bouncycastle:bcprov-jdk15on',
|
||||
'io.cucumber:cucumber-core',
|
||||
'io.cucumber:cucumber-java',
|
||||
'io.cucumber:cucumber-java8',
|
||||
'io.cucumber:cucumber-junit-platform-engine',
|
||||
'io.cucumber:cucumber-spring',
|
||||
'com.intuit.karate:karate-junit5',
|
||||
// 'com.google.code.gson:gson',
|
||||
)
|
||||
testImplementation ('org.mock-server:mockserver-junit-jupiter') {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you 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.
|
||||
#
|
||||
|
||||
cucumber.publish.quiet=true
|
||||
@@ -23,7 +23,13 @@ dependencies {
|
||||
tomcat 'org.apache.tomcat:tomcat:9.0.60@zip'
|
||||
testImplementation( files("$rootDir/fineract-provider/build/classes/java/main/"),
|
||||
project(path: ':fineract-provider', configuration: 'runtimeElements'),
|
||||
'org.junit.jupiter:junit-jupiter-api'
|
||||
'org.junit.jupiter:junit-jupiter-api',
|
||||
'io.cucumber:cucumber-core',
|
||||
'io.cucumber:cucumber-java',
|
||||
'io.cucumber:cucumber-java8',
|
||||
'io.cucumber:cucumber-junit-platform-engine',
|
||||
'io.cucumber:cucumber-spring',
|
||||
'com.intuit.karate:karate-junit5',
|
||||
)
|
||||
testImplementation ('io.rest-assured:rest-assured') {
|
||||
exclude group: 'commons-logging'
|
||||
|
||||
@@ -24,7 +24,13 @@ dependencies {
|
||||
testImplementation( files("$rootDir/fineract-provider/build/classes/java/main/"),
|
||||
project(path: ':fineract-provider', configuration: 'runtimeElements'),
|
||||
'org.junit.jupiter:junit-jupiter-api',
|
||||
'com.icegreen:greenmail-junit5'
|
||||
'io.cucumber:cucumber-core',
|
||||
'io.cucumber:cucumber-java',
|
||||
'io.cucumber:cucumber-java8',
|
||||
'io.cucumber:cucumber-junit-platform-engine',
|
||||
'io.cucumber:cucumber-spring',
|
||||
'com.icegreen:greenmail-junit5',
|
||||
'com.intuit.karate:karate-junit5',
|
||||
)
|
||||
testImplementation ('io.rest-assured:rest-assured') {
|
||||
exclude group: 'commons-logging'
|
||||
|
||||
Reference in New Issue
Block a user