Fixing the move action API by removing invocations to subscribe (#17)
* Fixing the move action API by removing invocations to subscribe Calling subscribe() inside function calls is an anti-pattern and we shouldn't be doing it. The reactiveContext is not called if the subscribe() function is called in the middle of execution flows. This breaks DB queries. * Added test case for move action. Co-authored-by: Trisha Anand <trisha@appsmith.com>
This commit is contained in:
parent
5df9395003
commit
fdeed757ff
|
|
@ -217,30 +217,23 @@ public class LayoutActionServiceImpl implements LayoutActionService {
|
|||
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, actionMoveDTO.getAction().getId())))
|
||||
.flatMap(savedAction -> pageService
|
||||
.findById(oldPageId, MANAGE_PAGES)
|
||||
.map(page -> {
|
||||
.flatMap(page -> {
|
||||
if (page.getLayouts() == null) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
return page.getLayouts()
|
||||
.stream()
|
||||
/*
|
||||
* subscribe() is being used here because within a stream, the master subscriber provided
|
||||
* by spring framework does not get attached here leading to the updateLayout mono not
|
||||
* emitting. The same is true for the updateLayout call for the new page.
|
||||
*/
|
||||
.map(layout -> updateLayout(oldPageId, layout.getId(), layout).subscribe())
|
||||
return Flux.fromIterable(page.getLayouts())
|
||||
.flatMap(layout -> updateLayout(oldPageId, layout.getId(), layout))
|
||||
.collect(toSet());
|
||||
})
|
||||
.then(pageService.findById(actionMoveDTO.getDestinationPageId(), MANAGE_PAGES))
|
||||
.map(page -> {
|
||||
.flatMap(page -> {
|
||||
if (page.getLayouts() == null) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
return page.getLayouts()
|
||||
.stream()
|
||||
.map(layout -> updateLayout(actionMoveDTO.getDestinationPageId(), layout.getId(), layout).subscribe())
|
||||
return Flux.fromIterable(page.getLayouts())
|
||||
.flatMap(layout -> updateLayout(actionMoveDTO.getDestinationPageId(), layout.getId(), layout))
|
||||
.collect(toSet());
|
||||
})
|
||||
.thenReturn(savedAction));
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import com.appsmith.server.domains.Organization;
|
|||
import com.appsmith.server.domains.Page;
|
||||
import com.appsmith.server.domains.Plugin;
|
||||
import com.appsmith.server.domains.User;
|
||||
import com.appsmith.server.dtos.ActionMoveDTO;
|
||||
import com.appsmith.server.dtos.ExecuteActionDTO;
|
||||
import com.appsmith.server.exceptions.AppsmithError;
|
||||
import com.appsmith.server.exceptions.AppsmithException;
|
||||
|
|
@ -43,6 +44,7 @@ import reactor.test.StepVerifier;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.appsmith.server.acl.AclPermission.MANAGE_ACTIONS;
|
||||
import static com.appsmith.server.acl.AclPermission.READ_ACTIONS;
|
||||
|
|
@ -83,12 +85,13 @@ public class ActionServiceTest {
|
|||
@Autowired
|
||||
ObjectMapper objectMapper;
|
||||
|
||||
@Autowired
|
||||
LayoutActionService layoutActionService;
|
||||
|
||||
Application testApp = null;
|
||||
|
||||
Page testPage = null;
|
||||
|
||||
int i = 0;
|
||||
|
||||
Datasource datasource;
|
||||
|
||||
@Before
|
||||
|
|
@ -102,8 +105,7 @@ public class ActionServiceTest {
|
|||
if (testApp == null && testPage == null) {
|
||||
//Create application and page which will be used by the tests to create actions for.
|
||||
Application application = new Application();
|
||||
application.setName("ActionServiceTest-App-" + String.valueOf(i));
|
||||
i++;
|
||||
application.setName(UUID.randomUUID().toString());
|
||||
testApp = applicationPageService.createApplication(application, organization.getId()).block();
|
||||
testPage = pageService.getById(testApp.getPages().get(0).getId()).block();
|
||||
}
|
||||
|
|
@ -158,8 +160,51 @@ public class ActionServiceTest {
|
|||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUserDetails(value = "api_user")
|
||||
public void validMoveAction() {
|
||||
Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())).thenReturn(Mono.just(new MockPluginExecutor()));
|
||||
|
||||
@Test
|
||||
Page newPage = new Page();
|
||||
newPage.setName("Destination Page");
|
||||
newPage.setApplicationId(testApp.getId());
|
||||
Page destinationPage = applicationPageService.createPage(newPage).block();
|
||||
|
||||
Action action = new Action();
|
||||
action.setName("validAction");
|
||||
action.setPageId(testPage.getId());
|
||||
ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
actionConfiguration.setHttpMethod(HttpMethod.GET);
|
||||
action.setActionConfiguration(actionConfiguration);
|
||||
action.setDatasource(datasource);
|
||||
|
||||
Mono<Action> createActionMono = actionService.create(action).cache();
|
||||
|
||||
Mono<Action> movedActionMono = createActionMono
|
||||
.flatMap(savedAction -> {
|
||||
ActionMoveDTO actionMoveDTO = new ActionMoveDTO();
|
||||
actionMoveDTO.setAction(savedAction);
|
||||
actionMoveDTO.setDestinationPageId(destinationPage.getId());
|
||||
return layoutActionService.moveAction(actionMoveDTO);
|
||||
});
|
||||
|
||||
StepVerifier
|
||||
.create(Mono.zip(createActionMono, movedActionMono))
|
||||
.assertNext(tuple -> {
|
||||
Action originalAction = tuple.getT1();
|
||||
Action movedAction = tuple.getT2();
|
||||
|
||||
assertThat(movedAction.getId()).isEqualTo(originalAction.getId());
|
||||
assertThat(movedAction.getName()).isEqualTo(originalAction.getName());
|
||||
assertThat(movedAction.getPolicies()).containsAll(originalAction.getPolicies());
|
||||
assertThat(movedAction.getPageId()).isEqualTo(destinationPage.getId());
|
||||
})
|
||||
.verifyComplete();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@WithUserDetails(value = "api_user")
|
||||
public void createValidActionWithJustName() {
|
||||
Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())).thenReturn(Mono.just(new MockPluginExecutor()));
|
||||
|
|
@ -376,72 +421,6 @@ public class ActionServiceTest {
|
|||
executeAndAssertAction(executeActionDTO, actionConfiguration, mockResult);
|
||||
}
|
||||
|
||||
// @Test
|
||||
// @WithUserDetails(value = "api_user")
|
||||
// public void testActionExecuteDuplicateRequestHeader() {
|
||||
// ActionExecutionResult mockResult = new ActionExecutionResult();
|
||||
// mockResult.setIsExecutionSuccess(true);
|
||||
// mockResult.setBody("response-body");
|
||||
//
|
||||
// Action action = new Action();
|
||||
// ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
// actionConfiguration.setHeaders(List.of(
|
||||
// new Property("random-header-key", "random-header-value"),
|
||||
// new Property("dup-key", "dup-value1"),
|
||||
// new Property("DUP-key", "dup-value2")
|
||||
// ));
|
||||
// action.setActionConfiguration(actionConfiguration);
|
||||
//
|
||||
// ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
// executeActionDTO.setAction(action);
|
||||
//
|
||||
// Mono<ActionExecutionResult> executionResultMono = executeAction(executeActionDTO, actionConfiguration, mockResult);
|
||||
// StepVerifier.create(executionResultMono)
|
||||
// .assertNext(result -> {
|
||||
// // Assert that the fxn should pick up the latest key based on the case-insensitive values
|
||||
// ActionExecutionRequest request = result.getRequest();
|
||||
// assertThat(request.getRequestHeaders().size()).isEqualTo(2);
|
||||
// MultiValueMap<String, String> resultHeader = CollectionUtils.toMultiValueMap(Map.of(
|
||||
// "random-header-key", Arrays.asList("random-header-value"),
|
||||
// "DUP-key", Arrays.asList("dup-value2")));
|
||||
// assertThat(request.getRequestHeaders()).isEqualTo(objectMapper.valueToTree(resultHeader));
|
||||
// })
|
||||
// .verifyComplete();
|
||||
// }
|
||||
|
||||
|
||||
// @Test
|
||||
// @WithUserDetails(value = "api_user")
|
||||
// public void testActionExecuteEmptyRequestHeader() {
|
||||
// ActionExecutionResult mockResult = new ActionExecutionResult();
|
||||
// mockResult.setIsExecutionSuccess(true);
|
||||
// mockResult.setBody("response-body");
|
||||
//
|
||||
// Action action = new Action();
|
||||
// ActionConfiguration actionConfiguration = new ActionConfiguration();
|
||||
// actionConfiguration.setHeaders(List.of(
|
||||
// new Property("random-header-key", "random-header-value"),
|
||||
// new Property("", "")
|
||||
// ));
|
||||
// action.setActionConfiguration(actionConfiguration);
|
||||
//
|
||||
// ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||
// executeActionDTO.setAction(action);
|
||||
//
|
||||
// Mono<ActionExecutionResult> executionResultMono = executeAction(executeActionDTO, actionConfiguration, mockResult);
|
||||
// StepVerifier.create(executionResultMono)
|
||||
// .assertNext(result -> {
|
||||
// // The fxn should have ignored all duplicate headers
|
||||
// ActionExecutionRequest request = result.getRequest();
|
||||
// assertThat(request.getRequestHeaders().size()).isEqualTo(1);
|
||||
// MultiValueMap<String, String> resultHeader = CollectionUtils.toMultiValueMap(Map.of(
|
||||
// "random-header-key", Arrays.asList("random-header-value")));
|
||||
//
|
||||
// assertThat(request.getRequestHeaders()).isEqualTo(objectMapper.valueToTree(resultHeader));
|
||||
// })
|
||||
// .verifyComplete();
|
||||
// }
|
||||
|
||||
@Test
|
||||
@WithUserDetails(value = "api_user")
|
||||
public void testActionExecuteErrorResponse() {
|
||||
|
|
@ -483,14 +462,6 @@ public class ActionServiceTest {
|
|||
.assertNext(result -> {
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getBody()).isEqualTo(mockResult.getBody());
|
||||
|
||||
// ActionExecutionRequest request = result.getRequest();
|
||||
// if (actionConfiguration.getHeaders() != null) {
|
||||
// assertThat(request.getRequestHeaders().size()).isEqualTo(actionConfiguration.getHeaders().size());
|
||||
// }
|
||||
//
|
||||
// assertThat(request.getRequestBody() == actionConfiguration.getBody()).isTrue();
|
||||
// assertThat(result.getHeaders()).isEqualTo(mockResult.getHeaders());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user