Files
matrix/cygnus-onprem-app/src/test/java/matrix/services/edp/PunchingServiceTest.java

247 lines
13 KiB
Java

package matrix.services.edp;
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 com.cygnus.db.CygnusDbExecutor;
import com.cygnus.db.RowView;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.sql.Date;
import java.time.LocalDate;
import lib.exceptions.ApplicationException;
import lib.models.PunchedRecordsData;
import lib.models.CasePunching;
import lib.models.UserSession;
import lib.models.Option;
import matrix.services.commons.CommonService;
import org.junit.jupiter.api.Test;
class PunchingServiceTest {
@Test
void loadsDuplicateDetailsWithAllowlistedQueryAndSessionScope() {
AtomicReference<Integer> query = new AtomicReference<>();
AtomicReference<Object[]> parameters = new AtomicReference<>();
RowView row = row(new LinkedHashMap<>(Map.of("paddr1", "House 1", "pcolony", 42)));
CygnusDbExecutor executor = (CygnusDbExecutor) Proxy.newProxyInstance(
getClass().getClassLoader(), new Class<?>[] { CygnusDbExecutor.class },
(proxy, method, args) -> {
if (method.getName().equals("query") && args.length == 2) {
query.set((Integer) args[0]);
parameters.set(((Object[]) args[1]).clone());
return List.of(row);
}
throw new UnsupportedOperationException(method.toString());
});
PunchingService service = new PunchingService(
new CommonService(), executor, new ObjectMapper());
UserSession session = UserSession.builder()
.companyId((short) 3).branchId((short) 7).build();
var result = service.findDuplicateDetails(" APP-1 ", (short) 38, 21, session);
assertEquals(21, query.get());
assertArrayEquals(new Object[] { "APP-1", (short) 38, (short) 3, (short) 7,
Date.valueOf(LocalDate.now()) }, parameters.get());
assertEquals("House 1", result.records().getFirst().get("paddr1"));
assertThrows(ApplicationException.class,
() -> service.findDuplicateDetails("APP-1", (short) 38, 23, session));
}
@Test
void derivesLocalityCompanyScopeFromSessionBranch() {
AtomicReference<Object[]> parameters = new AtomicReference<>();
Map<String, Object> columns = new LinkedHashMap<>();
columns.put("id", 42);
columns.put("location", "Sector 14");
columns.put("pincode", "122001 ");
columns.put("city", "Gurugram");
CygnusDbExecutor executor = (CygnusDbExecutor) Proxy.newProxyInstance(
getClass().getClassLoader(), new Class<?>[] { CygnusDbExecutor.class },
(proxy, method, args) -> {
if (method.getName().equals("query") && args.length == 2) {
assertEquals(13, args[0]);
parameters.set(((Object[]) args[1]).clone());
return List.of(row(columns));
}
throw new UnsupportedOperationException(method.toString());
});
PunchingService service = new PunchingService(
new CommonService(), executor, new ObjectMapper());
UserSession session = UserSession.builder()
.companyId((short) 3).branchId((short) 7).build();
var result = service.findLocalities(" Gurugram ", " Sec ", session);
assertArrayEquals(new Object[] { (short) 7, "Sec", "Gurugram", "Gurugram" },
parameters.get());
assertEquals(42, result.localities().getFirst().id());
assertEquals("122001", result.localities().getFirst().pincode());
}
@Test
void loadsPunchedRecordsAsFormShapedObjectsAndMergesDynamicFields() {
AtomicReference<Object[]> parameters = new AtomicReference<>();
Map<String, Object> columns = new LinkedHashMap<>();
columns.put("case_id", 101);
columns.put("applno", "APP-1");
columns.put("dynamic_fields", "{\"field1\":\"Dealer\",\"field150_2\":\"Note\"}");
RowView row = row(columns);
CygnusDbExecutor executor = (CygnusDbExecutor) Proxy.newProxyInstance(
getClass().getClassLoader(), new Class<?>[] { CygnusDbExecutor.class },
(proxy, method, args) -> {
if (method.getName().equals("query") && args.length == 2) {
assertEquals(24, args[0]);
parameters.set(((Object[]) args[1]).clone());
return List.of(row);
}
throw new UnsupportedOperationException(method.toString());
});
PunchingService service = new PunchingService(
new CommonService(), executor, new ObjectMapper());
UserSession session = UserSession.builder()
.companyId((short) 3).branchId((short) 7).build();
PunchedRecordsData result = service.loadPunchedRecords(
(short) 38, "c4e2680c-fdb0-48cb-aa07-a563aa64cdb9", session);
assertArrayEquals(new Object[] { "c4e2680c-fdb0-48cb-aa07-a563aa64cdb9",
"c4e2680c-fdb0-48cb-aa07-a563aa64cdb9",
"c4e2680c-fdb0-48cb-aa07-a563aa64cdb9", (short) 38, (short) 3, (short) 7 },
parameters.get());
assertEquals(101, result.records().getFirst().get("case_id"));
assertEquals("Dealer", result.records().getFirst().get("field1"));
assertEquals("Note", result.records().getFirst().get("field150_2"));
assertEquals(false, result.records().getFirst().containsKey("dynamic_fields"));
}
@Test
void loadsParameterizedOptionsAndNormalizesApplicationTypeGroup() {
RecordingCommonService commonService = new RecordingCommonService();
PunchingService service = new PunchingService(
commonService, null, new ObjectMapper());
Map<String, List<Option>> options = service.loadOptions((short) 5, (short) 1, (short) 38);
assertEquals(List.of(3, 4),
commonService.calls.stream().map(Call::queryId).toList());
assertArrayEquals(new Object[] { (short) 5, (short) 1 },
commonService.calls.get(0).parameters());
assertArrayEquals(new Object[] { (short) 38, (short) 1 },
commonService.calls.get(1).parameters());
assertEquals("Portfolio", options.get("portfolio.").getFirst().getLabel());
assertEquals("Branch", options.get("branch.").getFirst().getLabel());
assertEquals("City", options.get("city.").getFirst().getLabel());
assertEquals("Applicant", options.get("applicationType.").getFirst().getLabel());
assertEquals("Category", options.get("category.").getFirst().getLabel());
assertEquals("Product", options.get("product.").getFirst().getLabel());
assertThrows(UnsupportedOperationException.class,
() -> options.put("other.", List.of()));
}
@Test
void preparesNewApplicationWithoutLegacyPunchingHandlerQueries() {
List<Call> databaseCalls = new ArrayList<>();
CygnusDbExecutor executor = (CygnusDbExecutor) Proxy.newProxyInstance(
getClass().getClassLoader(), new Class<?>[] { CygnusDbExecutor.class },
(proxy, method, args) -> {
if (!method.getName().equals("query") || args.length != 2) {
throw new UnsupportedOperationException(method.toString());
}
int queryId = (Integer) args[0];
databaseCalls.add(new Call(queryId, ((Object[]) args[1]).clone()));
return queryId == 10
? List.of(row(new LinkedHashMap<>(
Map.of("control", "section1"))))
: List.of();
});
PunchingService service = new PunchingService(
new RecordingCommonService(), executor, new ObjectMapper());
CasePunching submitted = new CasePunching();
submitted.setPortfolioId((short) 38);
CasePunching result = service.prepareNewApplication(
submitted, (short) 5, (short) 1, (short) 9);
assertEquals(List.of(10, 74),
databaseCalls.stream().map(Call::queryId).toList());
assertArrayEquals(new Object[] { (short) 10, (short) 38 },
databaseCalls.get(0).parameters());
assertArrayEquals(new Object[] { (short) 38, (short) 10, "ADDCASE" },
databaseCalls.get(1).parameters());
assertEquals(List.of("section1"), result.getVisibleSections());
assertEquals("", result.getDynamicHtml());
assertEquals("", result.getDynamicFields());
}
private static final class RecordingCommonService extends CommonService {
private final List<Call> calls = new ArrayList<>();
@Override
public List<Option> getOptions(Integer queryId, Object[] queryParams) {
calls.add(new Call(queryId, queryParams.clone()));
return switch (queryId) {
case 3 -> List.of(option(38, "Portfolio", "portfolio.",
"88e0cb4a-3b4d-401c-b11b-fe4117842fef"));
case 4 -> List.of(option(7, "Branch", "branch."));
default -> List.of();
};
}
@Override
public List<Option> getCloudOptions(String scope, Map<String, Object> data) {
return switch (scope) {
case "company-options" -> List.of(
option("DEL", "City", "city."),
option("APPLICANT", "Applicant", "apptype."));
case "portfolio-options" -> List.of(
option("DIRECTOR", "Category", "category."),
option("AUTO", "Product", "product."));
default -> List.of();
};
}
}
private static Option option(Object value, String label, String group) {
return option(value, label, group, null);
}
private static Option option(Object value, String label, String group, String description) {
Option option = new Option();
option.setValue(value);
option.setLabel(label);
option.setGroup(group);
option.setDescription(description);
return option;
}
private static RowView row(Map<String, Object> columns) {
return new RowView() {
@Override
public Object get(String column) {
return columns.get(column);
}
@Override
public <T> T get(String column, Class<T> type) {
return type.cast(columns.get(column));
}
@Override
public Map<String, Object> asMap() {
return columns;
}
};
}
private record Call(int queryId, Object[] parameters) {
}
}