FINERACT-1927: Incorrect exception info in BatchAPI response
This commit is contained in:
+14
-28
@@ -20,6 +20,7 @@ package org.apache.fineract.commands.service;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
||||
import io.cucumber.java8.En;
|
||||
import io.github.resilience4j.retry.RetryRegistry;
|
||||
@@ -33,11 +34,14 @@ import org.apache.fineract.commands.domain.CommandWrapper;
|
||||
import org.apache.fineract.commands.exception.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.domain.FineractRequestContextHolder;
|
||||
import org.mockito.Mockito;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.CannotAcquireLockException;
|
||||
import org.springframework.orm.ObjectOptimisticLockingFailureException;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
public class CommandServiceStepDefinitions implements En {
|
||||
|
||||
@@ -55,16 +59,24 @@ public class CommandServiceStepDefinitions implements En {
|
||||
|
||||
private RetryEvent retryEvent;
|
||||
|
||||
private AtomicInteger counter = new AtomicInteger();
|
||||
|
||||
public CommandServiceStepDefinitions() {
|
||||
Given("/^A command source write service$/", () -> {
|
||||
this.commandSourceWritePlatformService = new DummyCommandSourceWriteService(processAndLogCommandService);
|
||||
this.command = new DummyCommand();
|
||||
FineractRequestContextHolder contextHolder = Mockito.spy(FineractRequestContextHolder.class);
|
||||
ReflectionTestUtils.setField(processAndLogCommandService, "fineractRequestContextHolder", contextHolder);
|
||||
Mockito.when(contextHolder.getAttribute(any(), any())).thenThrow(new CannotAcquireLockException("BLOW IT UP!!!"))
|
||||
.thenThrow(new ObjectOptimisticLockingFailureException("Dummy", new RuntimeException("BLOW IT UP!!!")))
|
||||
.thenThrow(new RollbackTransactionAsCommandIsNotApprovedByCheckerException(new DummyCommandSource()));
|
||||
|
||||
this.retryRegistry.retry("executeCommand").getEventPublisher().onRetry(event -> {
|
||||
log.warn("... retry event: {}", event);
|
||||
|
||||
counter.incrementAndGet();
|
||||
CommandServiceStepDefinitions.this.retryEvent = event;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
When("/^The user executes the command via a command write service with exceptions$/", () -> {
|
||||
@@ -84,47 +96,21 @@ public class CommandServiceStepDefinitions implements En {
|
||||
});
|
||||
|
||||
Then("/^The command processing service execute function should be called 3 times$/", () -> {
|
||||
assertEquals(3, command.getCount());
|
||||
assertEquals(2, counter.get());
|
||||
});
|
||||
}
|
||||
|
||||
public static class DummyCommand extends CommandWrapper {
|
||||
|
||||
private AtomicInteger counter = new AtomicInteger();
|
||||
|
||||
public DummyCommand() {
|
||||
super(null, null, null, null, null, null, null, null, null, null, "{}", null, null, null, null, null, null,
|
||||
UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String taskPermissionName() {
|
||||
// NOTE: simulating a failure scenario that triggers retries; using this function, because it is the first
|
||||
// called in the command processing service
|
||||
|
||||
int step = counter.incrementAndGet();
|
||||
|
||||
log.warn("Round: {}", step);
|
||||
|
||||
if (step == 1) {
|
||||
throw new CannotAcquireLockException("BLOW IT UP!!!");
|
||||
} else if (step == 2) {
|
||||
throw new ObjectOptimisticLockingFailureException("Dummy", new RuntimeException("BLOW IT UP!!!"));
|
||||
} else if (step == 3) {
|
||||
throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(new DummyCommandSource());
|
||||
}
|
||||
|
||||
return "dummy";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String actionName() {
|
||||
return "dummy";
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return counter.get();
|
||||
}
|
||||
}
|
||||
|
||||
public static class DummyCommandSourceWriteService implements PortfolioCommandSourceWritePlatformService {
|
||||
|
||||
+5
-4
@@ -74,7 +74,7 @@ public class CommandSourceServiceTest {
|
||||
ThreadLocalContextUtil.setTenant(ft);
|
||||
|
||||
String idk = "idk";
|
||||
underTest.saveInitial(wrapper, jsonCommand, appUser, idk);
|
||||
underTest.saveInitialNewTransaction(wrapper, jsonCommand, appUser, idk);
|
||||
|
||||
ArgumentCaptor<CommandSource> commandSourceArgumentCaptor = ArgumentCaptor.forClass(CommandSource.class);
|
||||
Mockito.verify(commandSourceRepository).saveAndFlush(commandSourceArgumentCaptor.capture());
|
||||
@@ -97,7 +97,7 @@ public class CommandSourceServiceTest {
|
||||
|
||||
ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, "t1", "n1", ZoneId.systemDefault().toString(), null));
|
||||
|
||||
CommandSource actual = underTest.saveInitial(wrapper, jsonCommand, appUser, "idk");
|
||||
CommandSource actual = underTest.saveInitialNewTransaction(wrapper, jsonCommand, appUser, "idk");
|
||||
|
||||
ArgumentCaptor<CommandSource> commandSourceArgumentCaptor = ArgumentCaptor.forClass(CommandSource.class);
|
||||
Mockito.verify(commandSourceRepository).saveAndFlush(commandSourceArgumentCaptor.capture());
|
||||
@@ -108,9 +108,10 @@ public class CommandSourceServiceTest {
|
||||
|
||||
@Test
|
||||
public void testGenerateErrorException() {
|
||||
Mockito.when(errorHandler.getMappable(any())).thenAnswer(i -> i.getArguments()[0]);
|
||||
Mockito.when(errorHandler.handle(any(CodeNotFoundException.class)))
|
||||
.thenReturn(new ErrorInfo(404, 1001, "Code with name `foo` does not exist"));
|
||||
ErrorInfo result = underTest.generateErrorException(new CodeNotFoundException("foo"));
|
||||
.thenReturn(new ErrorInfo(404, 1001, "Code with name `foo` does not exist", null));
|
||||
ErrorInfo result = underTest.generateErrorInfo(new CodeNotFoundException("foo"));
|
||||
Assertions.assertEquals(404, result.getStatusCode());
|
||||
Assertions.assertEquals(1001, result.getErrorCode());
|
||||
Assertions.assertTrue(result.getMessage().contains("Code with name `foo` does not exist"));
|
||||
|
||||
+15
-10
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.apache.fineract.commands.service;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -85,7 +86,6 @@ public class SynchronousCommandProcessingServiceTest {
|
||||
|
||||
@Test
|
||||
public void testExecuteCommandSuccess() {
|
||||
|
||||
CommandWrapper commandWrapper = Mockito.mock(CommandWrapper.class);
|
||||
when(commandWrapper.isDatatableResource()).thenReturn(false);
|
||||
when(commandWrapper.isNoteResource()).thenReturn(false);
|
||||
@@ -103,19 +103,24 @@ public class SynchronousCommandProcessingServiceTest {
|
||||
String idk = "idk";
|
||||
when(idempotencyKeyResolver.resolve(commandWrapper)).thenReturn(idk);
|
||||
CommandSource commandSource = Mockito.mock(CommandSource.class);
|
||||
when(commandSourceService.findCommandSource(commandWrapper, idk)).thenReturn(null).thenReturn(commandSource);
|
||||
long commandId = 1L;
|
||||
when(commandSource.getId()).thenReturn(commandId);
|
||||
when(commandSourceService.findCommandSource(commandWrapper, idk)).thenReturn(null);
|
||||
when(commandSourceService.getCommandSource(commandId)).thenReturn(commandSource);
|
||||
|
||||
AppUser appUser = Mockito.mock(AppUser.class);
|
||||
when(commandSourceService.saveInitial(commandWrapper, jsonCommand, appUser, idk)).thenReturn(commandSource);
|
||||
when(commandSourceService.saveInitialNewTransaction(commandWrapper, jsonCommand, appUser, idk)).thenReturn(commandSource);
|
||||
when(commandSourceService.saveResultSameTransaction(commandSource)).thenReturn(commandSource);
|
||||
when(commandSource.getStatus()).thenReturn(CommandProcessingResultType.PROCESSED.getValue());
|
||||
when(context.authenticatedUser(Mockito.any(CommandWrapper.class))).thenReturn(appUser);
|
||||
|
||||
CommandProcessingResult actualCommandProcessingResult = underTest.executeCommand(commandWrapper, jsonCommand, false);
|
||||
|
||||
verify(commandSourceService).saveInitial(commandWrapper, jsonCommand, appUser, idk);
|
||||
verify(commandSource).setStatus(CommandProcessingResultType.PROCESSED.getValue());
|
||||
verify(commandSourceService).saveResult(commandSource);
|
||||
verify(commandSourceService).saveInitialNewTransaction(commandWrapper, jsonCommand, appUser, idk);
|
||||
assertEquals(CommandProcessingResultType.PROCESSED.getValue(), commandSource.getStatus());
|
||||
verify(commandSourceService).saveResultSameTransaction(commandSource);
|
||||
|
||||
Assertions.assertEquals(commandProcessingResult, actualCommandProcessingResult);
|
||||
assertEquals(commandProcessingResult, actualCommandProcessingResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -142,7 +147,7 @@ public class SynchronousCommandProcessingServiceTest {
|
||||
|
||||
AppUser appUser = Mockito.mock(AppUser.class);
|
||||
when(context.authenticatedUser(Mockito.any(CommandWrapper.class))).thenReturn(appUser);
|
||||
when(commandSourceService.saveInitial(commandWrapper, jsonCommand, appUser, idk)).thenReturn(commandSource);
|
||||
when(commandSourceService.saveInitialNewTransaction(commandWrapper, jsonCommand, appUser, idk)).thenReturn(commandSource);
|
||||
|
||||
CommandSource initialCommandSource = Mockito.mock(CommandSource.class);
|
||||
|
||||
@@ -152,7 +157,7 @@ public class SynchronousCommandProcessingServiceTest {
|
||||
underTest.executeCommand(commandWrapper, jsonCommand, false);
|
||||
});
|
||||
|
||||
verify(commandSourceService).saveInitial(commandWrapper, jsonCommand, appUser, idk);
|
||||
verify(commandSourceService).generateErrorException(runtimeException);
|
||||
verify(commandSourceService).saveInitialNewTransaction(commandWrapper, jsonCommand, appUser, idk);
|
||||
verify(commandSourceService).generateErrorInfo(runtimeException);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ public class InvalidInstanceTypeMethodExceptionMapperTest {
|
||||
assertEquals(Response.Status.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatus());
|
||||
assertNotNull(response.getEntity());
|
||||
final ApiGlobalErrorResponse errorResponse = (ApiGlobalErrorResponse) response.getEntity();
|
||||
assertEquals(String.valueOf(Response.Status.METHOD_NOT_ALLOWED.getReasonPhrase()), errorResponse.getHttpStatusCode());
|
||||
assertEquals(String.valueOf(Response.Status.METHOD_NOT_ALLOWED.getStatusCode()), errorResponse.getHttpStatusCode());
|
||||
assertEquals("Invalid instance type called in api request for the method POST", errorResponse.getDeveloperMessage());
|
||||
assertEquals("error.msg.invalid.instance.type", errorResponse.getUserMessageGlobalisationCode());
|
||||
assertEquals("Invalid method POST used with request to this instance type.", errorResponse.getDefaultUserMessage());
|
||||
|
||||
Reference in New Issue
Block a user