diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutServiceCE.java index dac9bcb9c9a2..63d3e389999c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutServiceCE.java @@ -5,8 +5,6 @@ public interface LayoutServiceCE { - Mono createLayout(String pageId, Layout layout); - Mono getLayout(String pageId, String layoutId, Boolean viewMode); Mono getLayout(String defaultPageId, String layoutId, Boolean viewMode, String branchName); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutServiceCEImpl.java index 32fd82873a1b..80b7f163674f 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutServiceCEImpl.java @@ -2,64 +2,26 @@ import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.Layout; -import com.appsmith.server.dtos.PageDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.helpers.ResponseUtils; import com.appsmith.server.newpages.base.NewPageService; import com.appsmith.server.solutions.PagePermission; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.bson.types.ObjectId; -import org.springframework.beans.factory.annotation.Autowired; import reactor.core.publisher.Mono; -import java.util.ArrayList; import java.util.List; @Slf4j +@RequiredArgsConstructor public class LayoutServiceCEImpl implements LayoutServiceCE { private final NewPageService newPageService; private final ResponseUtils responseUtils; private final PagePermission pagePermission; - @Autowired - public LayoutServiceCEImpl( - NewPageService newPageService, ResponseUtils responseUtils, PagePermission pagePermission) { - this.newPageService = newPageService; - this.responseUtils = responseUtils; - this.pagePermission = pagePermission; - } - - @Override - public Mono createLayout(String pageId, Layout layout) { - if (pageId == null) { - return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.PAGE_ID)); - } - - // fetch the unpublished page - Mono pageMono = newPageService - .findPageById(pageId, pagePermission.getEditPermission(), false) - .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.PAGE_ID))); - - return pageMono.map(page -> { - List layoutList = page.getLayouts(); - if (layoutList == null) { - // no layouts exist for this page - layoutList = new ArrayList(); - } - // Adding an Id to the layout to ensure that a layout can be referred to by its ID as well. - layout.setId(new ObjectId().toString()); - - layoutList.add(layout); - page.setLayouts(layoutList); - return page; - }) - .flatMap(newPageService::saveUnpublishedPage) - .then(Mono.just(layout)); - } - @Override public Mono getLayout(String pageId, String layoutId, Boolean viewMode) { return newPageService diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutServiceTest.java index af3e5a29f547..457e364d64ce 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/LayoutServiceTest.java @@ -122,7 +122,6 @@ public class LayoutServiceTest { @BeforeEach public void setup() { User currentUser = sessionUserService.getCurrentUser().block(); - purgeAllPages(); User apiUser = userService.findByEmail("api_user").block(); Workspace toCreate = new Workspace(); toCreate.setName("LayoutServiceTest"); @@ -132,6 +131,7 @@ public void setup() { Workspace workspace = workspaceService.create(toCreate, apiUser, Boolean.FALSE).block(); + assertThat(workspace).isNotNull(); workspaceId = workspace.getId(); Set afterCreatingWorkspace = cacheableRepositoryHelper.getPermissionGroupsOfUser(currentUser).block(); @@ -140,6 +140,7 @@ public void setup() { log.info("Workspace ID: {}", workspaceId); log.info("Workspace Role Ids: {}", workspace.getDefaultPermissionGroups()); log.info("Policy for created Workspace: {}", workspace.getPolicies()); + assertThat(currentUser).isNotNull(); log.info("Current User ID: {}", currentUser.getId()); datasource = new Datasource(); @@ -149,78 +150,18 @@ public void setup() { pluginRepository.findByPackageName("installed-plugin").block(); installedJsPlugin = pluginRepository.findByPackageName("installed-js-plugin").block(); + assertThat(installedPlugin).isNotNull(); datasource.setPluginId(installedPlugin.getId()); } @AfterEach public void cleanup() { - List deletedApplications = applicationService + applicationService .findByWorkspaceId(workspaceId, applicationPermission.getDeletePermission()) .flatMap(remainingApplication -> applicationPageService.deleteApplication(remainingApplication.getId())) .collectList() .block(); - Workspace deletedWorkspace = workspaceService.archiveById(workspaceId).block(); - } - - private void purgeAllPages() { - newPageService.deleteAll(); - } - - @Test - @WithUserDetails(value = "api_user") - public void createLayoutWithNullPageId() { - Layout layout = new Layout(); - Mono layoutMono = layoutService.createLayout(null, layout); - StepVerifier.create(layoutMono) - .expectErrorMatches(throwable -> throwable instanceof AppsmithException - && throwable.getMessage().equals(AppsmithError.INVALID_PARAMETER.getMessage(FieldName.PAGE_ID))) - .verify(); - } - - @Test - @WithUserDetails(value = "api_user") - public void createLayoutWithInvalidPageID() { - Layout layout = new Layout(); - String pageId = "Some random ID which can never be a page's ID"; - Mono layoutMono = layoutService.createLayout(pageId, layout); - StepVerifier.create(layoutMono) - .expectErrorMatches(throwable -> throwable instanceof AppsmithException - && throwable.getMessage().equals(AppsmithError.INVALID_PARAMETER.getMessage(FieldName.PAGE_ID))) - .verify(); - } - - @Test - @WithUserDetails(value = "api_user") - public void createValidLayout() { - PageDTO testPage = new PageDTO(); - testPage.setName("createLayoutPageName"); - - Application application = new Application(); - application.setName("createValidLayout-Test-Application"); - Mono applicationMono = applicationPageService.createApplication(application, workspaceId); - - Mono pageMono = applicationMono - .switchIfEmpty(Mono.error(new Exception("No application found"))) - .map(app -> { - testPage.setApplicationId(app.getId()); - return testPage; - }) - .flatMap(applicationPageService::createPage); - - Layout testLayout = new Layout(); - JSONObject obj = new JSONObject(); - obj.put("key1", "value1"); - testLayout.setDsl(obj); - - Mono layoutMono = pageMono.flatMap(page -> layoutService.createLayout(page.getId(), testLayout)); - - StepVerifier.create(layoutMono) - .assertNext(layout -> { - assertThat(layout).isNotNull(); - assertThat(layout.getId()).isNotNull(); - assertThat(layout.getDsl()).isEqualTo(obj); - }) - .verifyComplete(); + workspaceService.archiveById(workspaceId).block(); } private Mono createPage(Application app, PageDTO page) { @@ -253,11 +194,11 @@ public void updateLayoutInvalidPageId() { app.setName("newApplication-updateLayoutInvalidPageId-Test"); PageDTO page = createPage(app, testPage).block(); - Layout startLayout = - layoutService.createLayout(page.getId(), testLayout).block(); + assertThat(page).isNotNull(); + final String layoutId = page.getLayouts().get(0).getId(); Mono updatedLayoutMono = updateLayoutService.updateLayout( - "random-impossible-id-page", page.getApplicationId(), startLayout.getId(), updateLayout); + "random-impossible-id-page", page.getApplicationId(), layoutId, updateLayout); StepVerifier.create(updatedLayoutMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -265,7 +206,7 @@ public void updateLayoutInvalidPageId() { .getMessage() .equals(AppsmithError.ACL_NO_RESOURCE_FOUND.getMessage( FieldName.PAGE_ID + " or " + FieldName.LAYOUT_ID, - "random-impossible-id-page" + ", " + startLayout.getId()))) + "random-impossible-id-page" + ", " + layoutId))) .verify(); } @@ -289,11 +230,11 @@ public void updateLayoutInvalidAppId() { app.setName("newApplication-updateLayoutInvalidPageId-Test"); PageDTO page = createPage(app, testPage).block(); - Layout startLayout = - layoutService.createLayout(page.getId(), testLayout).block(); + assertThat(page).isNotNull(); + final String layoutId = page.getLayouts().get(0).getId(); - Mono updatedLayoutMono = updateLayoutService.updateLayout( - page.getId(), "random-impossible-id-app", startLayout.getId(), updateLayout); + Mono updatedLayoutMono = + updateLayoutService.updateLayout(page.getId(), "random-impossible-id-app", layoutId, updateLayout); StepVerifier.create(updatedLayoutMono) .expectErrorMatches(throwable -> throwable instanceof AppsmithException @@ -307,16 +248,6 @@ public void updateLayoutInvalidAppId() { @Test @WithUserDetails(value = "api_user") public void updateLayoutValidPageId() { - Layout testLayout = new Layout(); - JSONObject obj = new JSONObject(); - obj.put("key", "value"); - testLayout.setDsl(obj); - - Layout updateLayout = new Layout(); - JSONObject obj1 = new JSONObject(); - obj1.put("key1", "value-updated"); - updateLayout.setDsl(obj); - PageDTO testPage = new PageDTO(); testPage.setName("LayoutServiceTest updateLayoutValidPageId"); @@ -325,28 +256,46 @@ public void updateLayoutValidPageId() { Mono pageMono = createPage(app, testPage).cache(); - Mono startLayoutMono = pageMono.flatMap(page -> layoutService.createLayout(page.getId(), testLayout)); - - Mono updatedLayoutMono = Mono.zip(pageMono, startLayoutMono).flatMap(tuple -> { - PageDTO page = tuple.getT1(); - Layout startLayout = tuple.getT2(); - startLayout.setDsl(obj1); + Mono updatedLayoutMono = pageMono.flatMap(page -> { + Layout firstLayout = new Layout(); + firstLayout.setDsl(new JSONObject(Map.of("key", "value"))); return updateLayoutService.updateLayout( - page.getId(), page.getApplicationId(), startLayout.getId(), startLayout); + page.getId(), + page.getApplicationId(), + page.getLayouts().get(0).getId(), + firstLayout); }); StepVerifier.create(updatedLayoutMono) .assertNext(layout -> { assertThat(layout).isNotNull(); assertThat(layout.getId()).isNotNull(); - assertThat(layout.getDsl()).isEqualTo(obj1); + assertThat(layout.getDsl()).containsExactlyEntriesOf(Map.of("key", "value")); + }) + .verifyComplete(); + + Mono updatedLayoutMono2 = pageMono.flatMap(page -> { + Layout secondLayout = new Layout(); + secondLayout.setDsl(new JSONObject(Map.of("key-new", "value-new"))); + return updateLayoutService.updateLayout( + page.getId(), + page.getApplicationId(), + page.getLayouts().get(0).getId(), + secondLayout); + }); + + StepVerifier.create(updatedLayoutMono2) + .assertNext(layout -> { + assertThat(layout).isNotNull(); + assertThat(layout.getId()).isNotNull(); + assertThat(layout.getDsl()).containsExactlyEntriesOf(Map.of("key-new", "value-new")); }) .verifyComplete(); } private Mono createComplexAppForExecuteOnLoad(Mono pageMono) { - Mono testMono = pageMono.flatMap(page1 -> { + return pageMono.flatMap(page1 -> { List> monos = new ArrayList<>(); // Create a GET API Action @@ -562,17 +511,8 @@ private Mono createComplexAppForExecuteOnLoad(Mono pageMono) return Mono.zip(monos, objects -> page1); }) - .zipWhen(page1 -> { - Layout layout = new Layout(); - - JSONObject obj = new JSONObject(Map.of("key", "value")); - layout.setDsl(obj); - - return layoutService.createLayout(page1.getId(), layout); - }) - .flatMap(tuple2 -> { - final PageDTO page1 = tuple2.getT1(); - final Layout layout = tuple2.getT2(); + .flatMap(page1 -> { + final Layout layout = page1.getLayouts().get(0); Layout newLayout = new Layout(); @@ -586,14 +526,17 @@ private Mono createComplexAppForExecuteOnLoad(Mono pageMono) "dynamicGet", "some dynamic {{\"anIgnoredAction.data:\" + aGetAction.data}}", "dynamicPost", - "some dynamic {{\n" + "(function(ignoredAction1){\n" - + "\tlet a = ignoredAction1.data\n" - + "\tlet ignoredAction2 = { data: \"nothing\" }\n" - + "\tlet b = ignoredAction2.data\n" - + "\tlet c = \"ignoredAction3.data\"\n" - + "\t// ignoredAction4.data\n" - + "\treturn aPostAction.data\n" - + "})(anotherPostAction.data)}}", + """ + some dynamic {{ + (function(ignoredAction1){ + \tlet a = ignoredAction1.data + \tlet ignoredAction2 = { data: "nothing" } + \tlet b = ignoredAction2.data + \tlet c = "ignoredAction3.data" + \t// ignoredAction4.data + \treturn aPostAction.data + })(anotherPostAction.data)}} + """, "dynamicPostWithAutoExec", "some dynamic {{aPostActionWithAutoExec.data}}", "dynamicDelete", @@ -631,13 +574,11 @@ private Mono createComplexAppForExecuteOnLoad(Mono pageMono) return updateLayoutService.updateLayout( page1.getId(), page1.getApplicationId(), layout.getId(), newLayout); }); - - return testMono; } private Mono createAppWithAllTypesOfReferencesForExecuteOnLoad(Mono pageMono) { - Mono testMono = pageMono.flatMap(page1 -> { + return pageMono.flatMap(page1 -> { List> monos = new ArrayList<>(); // Create a GET API Action for : aGetAction.data @@ -796,17 +737,8 @@ private Mono createAppWithAllTypesOfReferencesForExecuteOnLoad(Mono

page1); }) - .zipWhen(page1 -> { - Layout layout = new Layout(); - - JSONObject obj = new JSONObject(Map.of("key", "value")); - layout.setDsl(obj); - - return layoutService.createLayout(page1.getId(), layout); - }) - .flatMap(tuple2 -> { - final PageDTO page1 = tuple2.getT1(); - final Layout layout = tuple2.getT2(); + .flatMap(page1 -> { + final Layout layout = page1.getLayouts().get(0); Layout newLayout = new Layout(); @@ -840,8 +772,6 @@ private Mono createAppWithAllTypesOfReferencesForExecuteOnLoad(Mono

> actionDTOMono = pageMono.flatMap(page -> { - return newActionService - .findByUnpublishedNameAndPageId("aGetAction", page.getId(), AclPermission.MANAGE_ACTIONS) - .zipWith(newActionService.findByUnpublishedNameAndPageId( - "hiddenAction3", page.getId(), AclPermission.MANAGE_ACTIONS)); - }); + Mono> actionDTOMono = pageMono.flatMap(page -> newActionService + .findByUnpublishedNameAndPageId("aGetAction", page.getId(), AclPermission.MANAGE_ACTIONS) + .zipWith(newActionService.findByUnpublishedNameAndPageId( + "hiddenAction3", page.getId(), AclPermission.MANAGE_ACTIONS))); StepVerifier.create(actionDTOMono) .assertNext(tuple -> { @@ -1001,13 +929,16 @@ public void getActionsExecuteOnLoadWithAstLogic() { List.of("\"anIgnoredAction.data:\" + aGetAction.data"), EVALUATION_VERSION)) .thenReturn(Flux.just(Tuples.of( "\"anIgnoredAction.data:\" + aGetAction.data", new HashSet<>(Set.of("aGetAction.data"))))); - String bindingValue = "\n(function(ignoredAction1){\n" + "\tlet a = ignoredAction1.data\n" - + "\tlet ignoredAction2 = { data: \"nothing\" }\n" - + "\tlet b = ignoredAction2.data\n" - + "\tlet c = \"ignoredAction3.data\"\n" - + "\t// ignoredAction4.data\n" - + "\treturn aPostAction.data\n" - + "})(anotherPostAction.data)"; + String bindingValue = "\n" + + """ + (function(ignoredAction1){ + \tlet a = ignoredAction1.data + \tlet ignoredAction2 = { data: "nothing" } + \tlet b = ignoredAction2.data + \tlet c = "ignoredAction3.data" + \t// ignoredAction4.data + \treturn aPostAction.data + })(anotherPostAction.data)"""; Mockito.when(astService.getPossibleReferencesFromDynamicBinding(List.of(bindingValue), EVALUATION_VERSION)) .thenReturn(Flux.just( Tuples.of(bindingValue, new HashSet<>(Set.of("aPostAction.data", "anotherPostAction.data"))))); @@ -1117,12 +1048,10 @@ public void getActionsExecuteOnLoadWithAstLogic() { }) .verifyComplete(); - Mono> actionDTOMono = pageMono.flatMap(page -> { - return newActionService - .findByUnpublishedNameAndPageId("aGetAction", page.getId(), AclPermission.MANAGE_ACTIONS) - .zipWith(newActionService.findByUnpublishedNameAndPageId( - "ignoredAction1", page.getId(), AclPermission.MANAGE_ACTIONS)); - }); + Mono> actionDTOMono = pageMono.flatMap(page -> newActionService + .findByUnpublishedNameAndPageId("aGetAction", page.getId(), AclPermission.MANAGE_ACTIONS) + .zipWith(newActionService.findByUnpublishedNameAndPageId( + "ignoredAction1", page.getId(), AclPermission.MANAGE_ACTIONS))); StepVerifier.create(actionDTOMono) .assertNext(tuple -> { @@ -1217,12 +1146,10 @@ public void getActionsExecuteOnLoadWithoutAstLogic() { }) .verifyComplete(); - Mono> actionDTOMono = pageMono.flatMap(page -> { - return newActionService - .findByUnpublishedNameAndPageId("aGetAction", page.getId(), AclPermission.MANAGE_ACTIONS) - .zipWith(newActionService.findByUnpublishedNameAndPageId( - "ignoredAction1", page.getId(), AclPermission.MANAGE_ACTIONS)); - }); + Mono> actionDTOMono = pageMono.flatMap(page -> newActionService + .findByUnpublishedNameAndPageId("aGetAction", page.getId(), AclPermission.MANAGE_ACTIONS) + .zipWith(newActionService.findByUnpublishedNameAndPageId( + "ignoredAction1", page.getId(), AclPermission.MANAGE_ACTIONS))); StepVerifier.create(actionDTOMono) .assertNext(tuple -> { @@ -1245,34 +1172,22 @@ public void testIncorrectDynamicBindingPathInDsl() { app.setName("newApplication-testIncorrectDynamicBinding-Test"); PageDTO page = createPage(app, testPage).block(); + assertThat(page).isNotNull(); String pageId = page.getId(); final AtomicReference layoutId = new AtomicReference<>(); Mono testMono = Mono.just(page) .flatMap(page1 -> { - List> monos = new ArrayList<>(); - ActionDTO action = new ActionDTO(); action.setName("aGetAction"); action.setActionConfiguration(new ActionConfiguration()); action.getActionConfiguration().setHttpMethod(HttpMethod.GET); action.setPageId(page1.getId()); action.setDatasource(datasource); - monos.add(layoutActionService.createSingleAction(action, Boolean.FALSE)); - - return Mono.zip(monos, objects -> page1); + return layoutActionService.createSingleAction(action, false).thenReturn(page1); }) - .zipWhen(page1 -> { - Layout layout = new Layout(); - - JSONObject obj = new JSONObject(Map.of("key", "value")); - layout.setDsl(obj); - - return layoutService.createLayout(page1.getId(), layout); - }) - .flatMap(tuple2 -> { - final PageDTO page1 = tuple2.getT1(); - final Layout layout = tuple2.getT2(); + .flatMap(page1 -> { + final Layout layout = page1.getLayouts().get(0); layoutId.set(layout.getId()); Layout newLayout = new Layout(); @@ -1334,33 +1249,18 @@ public void testIncorrectMustacheExpressionInBindingInDsl() { Application app = new Application(); app.setName("newApplication-testIncorrectMustacheExpressionInBinding-Test"); - PageDTO page = createPage(app, testPage).block(); - - Mono testMono = Mono.just(page) + Mono testMono = createPage(app, testPage) .flatMap(page1 -> { - List> monos = new ArrayList<>(); - ActionDTO action = new ActionDTO(); action.setName("aGetAction"); action.setActionConfiguration(new ActionConfiguration()); action.getActionConfiguration().setHttpMethod(HttpMethod.GET); action.setPageId(page1.getId()); action.setDatasource(datasource); - monos.add(layoutActionService.createSingleAction(action, Boolean.FALSE)); - - return Mono.zip(monos, objects -> page1); + return layoutActionService.createSingleAction(action, false).thenReturn(page1); }) - .zipWhen(page1 -> { - Layout layout = new Layout(); - - JSONObject obj = new JSONObject(Map.of("key", "value")); - layout.setDsl(obj); - - return layoutService.createLayout(page1.getId(), layout); - }) - .flatMap(tuple2 -> { - final PageDTO page1 = tuple2.getT1(); - final Layout layout = tuple2.getT2(); + .flatMap(page1 -> { + final Layout layout = page1.getLayouts().get(0); Layout newLayout = new Layout(); @@ -1392,6 +1292,6 @@ public void testIncorrectMustacheExpressionInBindingInDsl() { @AfterEach public void purgePages() { - newPageService.deleteAll(); + newPageService.deleteAll().block(); } } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ActionServiceCE_Test.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ActionServiceCE_Test.java index a8d3d5c56f9c..b9eeb6e5269d 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ActionServiceCE_Test.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/ActionServiceCE_Test.java @@ -1411,17 +1411,8 @@ public void getActionsExecuteOnLoadPaginatedApi() { return Mono.zip(monos, objects -> page1); }) - .zipWhen(page1 -> { - Layout layout = new Layout(); - - JSONObject obj = new JSONObject(Map.of("key", "value")); - layout.setDsl(obj); - - return layoutService.createLayout(page1.getId(), layout); - }) - .flatMap(tuple2 -> { - final PageDTO page1 = tuple2.getT1(); - final Layout layout = tuple2.getT2(); + .flatMap(page1 -> { + final Layout layout = page1.getLayouts().get(0); Layout newLayout = new Layout();