From b25248b327a363feeff10edd93d4c5ace0f4020a Mon Sep 17 00:00:00 2001 From: Eugenio Santoboni Date: Thu, 18 Jun 2020 09:17:59 +0200 Subject: [PATCH] ENG-66: Definition of default widgets available via PageModel api (#909) * ENG-66: added missing objects for default widgets definition * ENG-66: Improvement of pageModel request converter and improvement of integration tests * ENG-66: Improvement of pageModel service and integration tests * ENG-66: Improvement of service and integration test * ENG-66: Message upgrade * ENG-66: Fix unit test --- .../services/pagemodel/PageModelService.java | 143 ++++++++--- .../pagemodel/model/DefaultWidgetDto.java | 14 ++ .../services/pagemodel/model/FrameDto.java | 14 +- .../model/PageModelConfigurationDto.java | 13 + .../pagemodel/model/PageModelDto.java | 13 + .../pagemodel/model/PageModelDtoBuilder.java | 13 + .../web/pagemodel/PageModelController.java | 47 +--- .../web/pagemodel/model/DefaultWidgetReq.java | 40 +++ .../pagemodel/model/PageModelFrameReq.java | 9 + .../validator/PageModelValidator.java | 4 +- .../main/resources/rest/messages.properties | 2 + .../pagemodel/PageModelServiceTest.java | 57 ++--- .../services/pagemodel/PageModelTestUtil.java | 32 ++- .../PageModelControllerIntegrationTest.java | 236 +++++++++++++----- 14 files changed, 464 insertions(+), 173 deletions(-) create mode 100644 engine/src/main/java/org/entando/entando/web/pagemodel/model/DefaultWidgetReq.java diff --git a/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/PageModelService.java b/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/PageModelService.java index b4207c7fc..57e5ee959 100644 --- a/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/PageModelService.java +++ b/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/PageModelService.java @@ -1,18 +1,31 @@ +/* + * Copyright 2020-Present Entando Inc. (http://www.entando.com) All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + */ package org.entando.entando.aps.system.services.pagemodel; import com.agiletec.aps.system.common.FieldSearchFilter; import com.agiletec.aps.system.common.model.dao.SearcherDaoPaginatedResult; import com.agiletec.aps.system.exception.ApsSystemException; +import com.agiletec.aps.system.services.page.Widget; import com.agiletec.aps.system.services.pagemodel.*; +import com.agiletec.aps.util.ApsProperties; import org.entando.entando.aps.system.exception.*; import org.entando.entando.aps.system.services.IDtoBuilder; import org.entando.entando.aps.system.services.page.model.PageDto; import org.entando.entando.aps.system.services.pagemodel.model.PageModelDto; import org.entando.entando.web.common.assembler.PagedMetadataMapper; -import org.entando.entando.web.common.exceptions.ValidationConflictException; import org.entando.entando.web.common.model.*; import org.entando.entando.web.component.ComponentUsageEntity; -import org.entando.entando.web.page.model.PageSearchRequest; import org.entando.entando.web.pagemodel.model.*; import org.entando.entando.web.pagemodel.validator.PageModelValidator; import org.slf4j.*; @@ -23,6 +36,10 @@ import java.util.*; import java.util.stream.Collectors; +import org.entando.entando.aps.system.services.widgettype.IWidgetTypeManager; +import org.entando.entando.aps.system.services.widgettype.WidgetType; +import org.entando.entando.web.common.exceptions.ValidationConflictException; +import org.entando.entando.web.common.exceptions.ValidationGenericException; @Service public class PageModelService implements IPageModelService, ApplicationContextAware { @@ -31,6 +48,8 @@ public class PageModelService implements IPageModelService, ApplicationContextAw private final IPageModelManager pageModelManager; + private final IWidgetTypeManager widgetTypeManager; + private final IDtoBuilder dtoBuilder; private ApplicationContext applicationContext; @@ -39,8 +58,10 @@ public class PageModelService implements IPageModelService, ApplicationContextAw private PagedMetadataMapper pagedMetadataMapper; @Autowired - public PageModelService(IPageModelManager pageModelManager, IDtoBuilder dtoBuilder) { + public PageModelService(IPageModelManager pageModelManager, + IWidgetTypeManager widgetTypeManager, IDtoBuilder dtoBuilder) { this.pageModelManager = pageModelManager; + this.widgetTypeManager = widgetTypeManager; this.dtoBuilder = dtoBuilder; } @@ -57,17 +78,13 @@ public PagedMetadata getPageModels(RestListRequest restListReq, Ma filters.stream() .filter(i -> i.getKey() != null) .forEach(i -> i.setKey(PageModelDto.getEntityFieldName(i.getKey()))); - SearcherDaoPaginatedResult pageModels = pageModelManager.searchPageModels(filters); - List dtoList = null; if (null != pageModels) { - dtoList = dtoBuilder.convert(pageModels.getList()); + dtoList = this.dtoBuilder.convert(pageModels.getList()); } - PagedMetadata pagedMetadata = new PagedMetadata<>(restListReq, pageModels); pagedMetadata.setBody(dtoList); - return pagedMetadata; } catch (Throwable t) { logger.error("error in search pageModels", t); @@ -77,12 +94,12 @@ public PagedMetadata getPageModels(RestListRequest restListReq, Ma @Override public PageModelDto getPageModel(String code) { - PageModel pageModel = pageModelManager.getPageModel(code); + PageModel pageModel = this.pageModelManager.getPageModel(code); if (null == pageModel) { logger.warn("no pageModel found with code {}", code); throw new ResourceNotFoundException(PageModelValidator.ERRCODE_PAGEMODEL_NOT_FOUND, "pageModel", code); } - PageModelDto dto = dtoBuilder.convert(pageModel); + PageModelDto dto = this.dtoBuilder.convert(pageModel); dto.setReferences(this.getReferencesInfo(pageModel)); return dto; } @@ -92,12 +109,14 @@ public PageModelDto addPageModel(PageModelRequest pageModelRequest) { try { BeanPropertyBindingResult validationResult = this.validateAdd(pageModelRequest); if (validationResult.hasErrors()) { - throw new ValidationConflictException(validationResult); + throw new ValidationGenericException(validationResult); } PageModel pageModel = this.createPageModel(pageModelRequest); - pageModelManager.addPageModel(pageModel); - return dtoBuilder.convert(pageModel); - } catch (ApsSystemException e) { + this.pageModelManager.addPageModel(pageModel); + return this.dtoBuilder.convert(pageModel); + } catch (ValidationGenericException | ValidationConflictException e) { + throw e; + } catch (Exception e) { logger.error("Error in add pageModel", e); throw new RestServerError("error in add pageModel", e); } @@ -106,14 +125,17 @@ public PageModelDto addPageModel(PageModelRequest pageModelRequest) { @Override public PageModelDto updatePageModel(PageModelRequest pageModelRequest) { try { - PageModel pageModel = pageModelManager.getPageModel(pageModelRequest.getCode()); - if (null == pageModel) { - throw new ResourceNotFoundException(PageModelValidator.ERRCODE_PAGEMODEL_NOT_FOUND, "pageModel", pageModelRequest.getCode()); + BeanPropertyBindingResult validationResult = this.validateEdit(pageModelRequest); + if (validationResult.hasErrors()) { + throw new ValidationGenericException(validationResult); } + PageModel pageModel = this.pageModelManager.getPageModel(pageModelRequest.getCode()); this.copyProperties(pageModelRequest, pageModel); - pageModelManager.updatePageModel(pageModel); + this.pageModelManager.updatePageModel(pageModel); return dtoBuilder.convert(pageModel); - } catch (ApsSystemException e) { + } catch (ValidationGenericException | ResourceNotFoundException e) { + throw e; + } catch (Exception e) { logger.error("Error in update pageModel {}", pageModelRequest.getCode(), e); throw new RestServerError("error in update pageMdel", e); } @@ -122,17 +144,18 @@ public PageModelDto updatePageModel(PageModelRequest pageModelRequest) { @Override public void removePageModel(String code) { try { - PageModel pageModel = pageModelManager.getPageModel(code); + PageModel pageModel = this.pageModelManager.getPageModel(code); if (null == pageModel) { return; } BeanPropertyBindingResult validationResult = this.validateDelete(pageModel); if (validationResult.hasErrors()) { - throw new ValidationConflictException(validationResult); + throw new ValidationGenericException(validationResult); } - pageModelManager.deletePageModel(code); - - } catch (ApsSystemException e) { + this.pageModelManager.deletePageModel(code); + } catch (ValidationGenericException e) { + throw e; + } catch (Exception e) { logger.error("Error in delete pagemodel {}", code, e); throw new RestServerError("error in delete pagemodel", e); } @@ -140,7 +163,7 @@ public void removePageModel(String code) { @Override public PagedMetadata getPageModelReferences(String pageModelCode, String managerName, RestListRequest restRequest) { - PageModel pageModel = pageModelManager.getPageModel(pageModelCode); + PageModel pageModel = this.pageModelManager.getPageModel(pageModelCode); if (null == pageModel) { logger.warn("no pageModel found with code {}", pageModelCode); throw new ResourceNotFoundException(PageModelValidator.ERRCODE_PAGEMODEL_NOT_FOUND, "pageModel", pageModelCode); @@ -167,19 +190,16 @@ public Integer getComponentUsage(String pageModelCode) { @Override public PagedMetadata getComponentUsageDetails(String componentCode, RestListRequest restListRequest) { - PagedMetadata pagedMetadata = (PagedMetadata) getPageModelReferences(componentCode, "PageManager", restListRequest); - List componentUsageEntityList = pagedMetadata.getBody().stream() .map(pageDto -> new ComponentUsageEntity(ComponentUsageEntity.TYPE_PAGE, pageDto.getCode(), pageDto.getStatus())) .collect(Collectors.toList()); - - return pagedMetadataMapper.getPagedResult(restListRequest, componentUsageEntityList); + return this.pagedMetadataMapper.getPagedResult(restListRequest, componentUsageEntityList); } protected PageModel createPageModel(PageModelRequest pageModelRequest) { PageModel pageModel = new PageModel(); - copyProperties(pageModelRequest, pageModel); + this.copyProperties(pageModelRequest, pageModel); return pageModel; } @@ -191,14 +211,12 @@ protected void copyProperties(PageModelRequest srcPpageModelRequest, PageModel d descPageModel.setConfiguration(this.createPageModelConfiguration(srcPpageModelRequest)); } - protected Frame[] createPageModelConfiguration(PageModelRequest pageModelRequest) { Frame[] destConfiguration = null; List frameRequestList = pageModelRequest.getConfiguration().getFrames(); if (null == frameRequestList || frameRequestList.isEmpty()) { return destConfiguration; } - return frameRequestList.stream() .map(this::createFrame) .toArray(Frame[]::new); @@ -210,28 +228,78 @@ protected Frame createFrame(PageModelFrameReq pageModelFrameReq) { frame.setDescription(pageModelFrameReq.getDescr()); frame.setMainFrame(pageModelFrameReq.isMainFrame()); frame.setSketch(pageModelFrameReq.getSketch()); + frame.setDefaultWidget(this.createDefaultWidget(pageModelFrameReq.getDefaultWidget())); return frame; } + private Widget createDefaultWidget(DefaultWidgetReq defaultWidgetReq) { + if (null == defaultWidgetReq || null == defaultWidgetReq.getCode()) { + return null; + } + Widget defaultWidget = new Widget(); + defaultWidget.setType(this.widgetTypeManager.getWidgetType(defaultWidgetReq.getCode())); + if (null != defaultWidgetReq.getProperties()) { + ApsProperties properties = new ApsProperties(); + properties.putAll(defaultWidgetReq.getProperties()); + defaultWidget.setConfig(properties); + } + return defaultWidget; + } + protected BeanPropertyBindingResult validateAdd(PageModelRequest pageModelRequest) { BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(pageModelRequest, "pageModel"); PageModel pageModel = pageModelManager.getPageModel(pageModelRequest.getCode()); - if (null == pageModel) { - return bindingResult; + if (null != pageModel) { + bindingResult.reject(PageModelValidator.ERRCODE_CODE_EXISTS, new String[]{pageModelRequest.getCode()}, "pageModel.code.exists"); + throw new ValidationConflictException(bindingResult); } - bindingResult.reject(PageModelValidator.ERRCODE_CODE_EXISTS, new String[]{pageModelRequest.getCode()}, "pageModel.code.exists"); + this.validateDefaultWidgets(pageModelRequest, bindingResult); return bindingResult; } + protected BeanPropertyBindingResult validateEdit(PageModelRequest pageModelRequest) { + BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(pageModelRequest, "pageModel"); + PageModel pageModel = this.pageModelManager.getPageModel(pageModelRequest.getCode()); + if (null == pageModel) { + throw new ResourceNotFoundException(PageModelValidator.ERRCODE_PAGEMODEL_NOT_FOUND, "pageModel", pageModelRequest.getCode()); + } + this.validateDefaultWidgets(pageModelRequest, bindingResult); + return bindingResult; + } + protected BeanPropertyBindingResult validateDelete(PageModel pageModel) throws ApsSystemException { BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(pageModel, "pageModel"); - Map> references = this.getReferencingObjects(pageModel); if (references.size() > 0) { bindingResult.reject(PageModelValidator.ERRCODE_PAGEMODEL_REFERENCES, new Object[]{pageModel.getCode(), references}, "pageModel.cannot.delete.references"); } return bindingResult; + } + private void validateDefaultWidgets(PageModelRequest pageModelRequest, BeanPropertyBindingResult bindingResult) { + if (null == pageModelRequest || null == pageModelRequest.getConfiguration().getFrames()) { + return; + } + List frames = pageModelRequest.getConfiguration().getFrames(); + for (int i = 0; i < frames.size(); i++) { + PageModelFrameReq frameReq = frames.get(i); + DefaultWidgetReq dwr = frameReq.getDefaultWidget(); + if (null == dwr || null == dwr.getCode()) { + continue; + } + WidgetType type = this.widgetTypeManager.getWidgetType(dwr.getCode()); + if (null == type) { + bindingResult.reject(PageModelValidator.ERRCODE_DEFAULT_WIDGET_NOT_EXISTS, new Object[]{dwr.getCode(), i}, "pageModel.defaultWidget.notExists"); + } else if (null != dwr.getProperties()) { + Iterator iter = dwr.getProperties().keySet().iterator(); + while (iter.hasNext()) { + String key = iter.next(); + if (!type.hasParameter(key)) { + bindingResult.reject(PageModelValidator.ERRCODE_DEFAULT_WIDGET_INVALID_PARAMETER, new Object[]{key, dwr.getCode(), i}, "pageModel.defaultWidget.invalidParameter"); + } + } + } + } } @SuppressWarnings("unchecked") @@ -239,7 +307,6 @@ public Map> getReferencingObjects(PageModel pageModel) thro Map> references = new HashMap<>(); try { String[] defNames = applicationContext.getBeanNamesForType(PageModelUtilizer.class); - for (String beanName : defNames) { Object service = null; try { @@ -256,7 +323,6 @@ public Map> getReferencingObjects(PageModel pageModel) thro } } } - } catch (Throwable t) { throw new ApsSystemException("Error on getReferencingObjects methods", t); } @@ -300,4 +366,5 @@ private PageModelServiceUtilizer getPageModelServiceUtilizer(String managerNa .findFirst(); return defName.orElse(null); } + } diff --git a/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/DefaultWidgetDto.java b/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/DefaultWidgetDto.java index 9ee1ba672..64b3ac8e9 100644 --- a/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/DefaultWidgetDto.java +++ b/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/DefaultWidgetDto.java @@ -1,3 +1,16 @@ +/* + * Copyright 2020-Present Entando Inc. (http://www.entando.com) All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + */ package org.entando.entando.aps.system.services.pagemodel.model; import com.agiletec.aps.util.ApsProperties; @@ -23,4 +36,5 @@ public Properties getProperties() { public void setProperties(Properties properties) { this.properties = properties; } + } diff --git a/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/FrameDto.java b/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/FrameDto.java index a765a478a..7ce5a41e9 100644 --- a/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/FrameDto.java +++ b/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/FrameDto.java @@ -1,3 +1,16 @@ +/* + * Copyright 2020-Present Entando Inc. (http://www.entando.com) All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + */ package org.entando.entando.aps.system.services.pagemodel.model; import com.agiletec.aps.system.services.pagemodel.FrameSketch; @@ -5,7 +18,6 @@ public class FrameDto { private int pos; - private String descr; private boolean mainFrame; private DefaultWidgetDto defaultWidget = new DefaultWidgetDto(); diff --git a/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/PageModelConfigurationDto.java b/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/PageModelConfigurationDto.java index 5bb4acbf7..fd212630e 100644 --- a/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/PageModelConfigurationDto.java +++ b/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/PageModelConfigurationDto.java @@ -1,3 +1,16 @@ +/* + * Copyright 2020-Present Entando Inc. (http://www.entando.com) All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + */ package org.entando.entando.aps.system.services.pagemodel.model; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/PageModelDto.java b/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/PageModelDto.java index aac028195..e2248646a 100644 --- a/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/PageModelDto.java +++ b/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/PageModelDto.java @@ -1,3 +1,16 @@ +/* + * Copyright 2020-Present Entando Inc. (http://www.entando.com) All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + */ package org.entando.entando.aps.system.services.pagemodel.model; import com.fasterxml.jackson.annotation.*; diff --git a/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/PageModelDtoBuilder.java b/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/PageModelDtoBuilder.java index 3b24c37ef..fc7e5621b 100644 --- a/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/PageModelDtoBuilder.java +++ b/engine/src/main/java/org/entando/entando/aps/system/services/pagemodel/model/PageModelDtoBuilder.java @@ -1,3 +1,16 @@ +/* + * Copyright 2020-Present Entando Inc. (http://www.entando.com) All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + */ package org.entando.entando.aps.system.services.pagemodel.model; import com.agiletec.aps.system.services.page.Widget; diff --git a/engine/src/main/java/org/entando/entando/web/pagemodel/PageModelController.java b/engine/src/main/java/org/entando/entando/web/pagemodel/PageModelController.java index c16750b96..179a0d0b6 100644 --- a/engine/src/main/java/org/entando/entando/web/pagemodel/PageModelController.java +++ b/engine/src/main/java/org/entando/entando/web/pagemodel/PageModelController.java @@ -18,7 +18,6 @@ import io.swagger.annotations.*; import org.entando.entando.aps.system.services.pagemodel.IPageModelService; import org.entando.entando.aps.system.services.pagemodel.model.PageModelDto; -import org.entando.entando.aps.system.services.widgettype.model.WidgetDto; import org.entando.entando.web.common.annotation.RestAccessControl; import org.entando.entando.web.common.exceptions.ValidationGenericException; import org.entando.entando.web.common.model.*; @@ -40,6 +39,7 @@ @RestController @RequestMapping(value = "/pageModels", produces = MediaType.APPLICATION_JSON_VALUE) public class PageModelController { + public static final String COMPONENT_ID = "pageTemplate"; private final Logger logger = LoggerFactory.getLogger(getClass()); @@ -53,7 +53,6 @@ public PageModelController(IPageModelService pageModelService, PageModelValidato this.pageModelValidator = pageModelValidator; } - @ApiOperation("Retrieve multiple page templates") @ApiResponses({ @ApiResponse(code = 200, message = "OK"), @@ -64,16 +63,12 @@ public PageModelController(IPageModelService pageModelService, PageModelValidato public ResponseEntity> getPageModels( RestListRequest requestList, @RequestParam Map requestParams) { logger.trace("loading page templates"); - - pageModelValidator.validateRestListRequest(requestList, PageModelDto.class); - PagedMetadata result = pageModelService.getPageModels(requestList, requestParams); - - pageModelValidator.validateRestListResult(requestList, result); - + this.pageModelValidator.validateRestListRequest(requestList, PageModelDto.class); + PagedMetadata result = this.pageModelService.getPageModels(requestList, requestParams); + this.pageModelValidator.validateRestListResult(requestList, result); return ResponseEntity.ok(new PagedRestResponse<>(result)); } - @ApiOperation("Retrieve page template by code") @ApiResponses({ @ApiResponse(code = 200, message = "OK"), @@ -82,11 +77,10 @@ public ResponseEntity> getPageModels( @RestAccessControl(permission = Permission.MANAGE_PAGES) @GetMapping(value = "/{code:.+}") public ResponseEntity> getPageModel(@PathVariable String code) { - PageModelDto pageModelDto = pageModelService.getPageModel(code); + PageModelDto pageModelDto = this.pageModelService.getPageModel(code); return ResponseEntity.ok(new SimpleRestResponse<>(pageModelDto)); } - @ApiOperation("Retrieve page template references") @ApiResponses({ @ApiResponse(code = 200, message = "OK") @@ -95,8 +89,7 @@ public ResponseEntity> getPageModel(@PathVariab @GetMapping(value = "/{code:.+}/references/{manager}") public ResponseEntity> getPageModelReferences( @PathVariable String code, @PathVariable String manager, RestListRequest requestList) { - - PagedMetadata result = pageModelService.getPageModelReferences(code, manager, requestList); + PagedMetadata result = this.pageModelService.getPageModelReferences(code, manager, requestList); return ResponseEntity.ok(new PagedRestResponse<>(result)); } @@ -108,17 +101,14 @@ public ResponseEntity> getPageModelReferences( @RequestMapping(value = "/{code}/usage", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity> getComponentUsage(@PathVariable String code) { logger.trace("get {} usage by code {}", COMPONENT_ID, code); - ComponentUsage usage = ComponentUsage.builder() .type(COMPONENT_ID) .code(code) .usage(pageModelService.getComponentUsage(code)) .build(); - return new ResponseEntity<>(new SimpleRestResponse<>(usage), HttpStatus.OK); } - @ApiOperation("Retrieve pageModel usage count") @ApiResponses({ @ApiResponse(code = 200, message = "OK"), @@ -127,18 +117,13 @@ public ResponseEntity> getComponentUsage(@Pat @RestAccessControl(permission = Permission.SUPERUSER) @RequestMapping(value = "/{code}/usage/details", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity> getComponentUsageDetails(@PathVariable String code, PageSearchRequest searchRequest) { - logger.trace("get {} usage details by code {}", COMPONENT_ID, code); - // clear filters searchRequest.setFilters(new Filter[0]); - PagedMetadata result = pageModelService.getComponentUsageDetails(code, searchRequest); - return new ResponseEntity<>(new PagedRestResponse<>(result), HttpStatus.OK); } - @ApiOperation("Update page template") @ApiResponses({ @ApiResponse(code = 200, message = "OK"), @@ -148,25 +133,21 @@ public ResponseEntity> getComponentUsage @PutMapping(value = "/{code:.+}", name = "roleGroup") public ResponseEntity> updatePageModel(@PathVariable String code, @Valid @RequestBody PageModelRequest pageModelRequest, BindingResult bindingResult) { - - validateWithBodyName(code, pageModelRequest, bindingResult); - - PageModelDto pageModel = pageModelService.updatePageModel(pageModelRequest); + this.validateWithBodyName(code, pageModelRequest, bindingResult); + PageModelDto pageModel = this.pageModelService.updatePageModel(pageModelRequest); return ResponseEntity.ok(new SimpleRestResponse<>(pageModel)); } private void validateWithBodyName(String code, PageModelRequest pageModelRequest, BindingResult bindingResult) { - if (bindingResult.hasErrors()) { throw new ValidationGenericException(bindingResult); } - pageModelValidator.validateBodyName(code, pageModelRequest, bindingResult); + this.pageModelValidator.validateBodyName(code, pageModelRequest, bindingResult); if (bindingResult.hasErrors()) { throw new ValidationGenericException(bindingResult); } } - @ApiOperation("Add page template") @ApiResponses({ @ApiResponse(code = 200, message = "OK"), @@ -177,9 +158,7 @@ private void validateWithBodyName(String code, PageModelRequest pageModelRequest @PostMapping public ResponseEntity> addPageModel( @Valid @RequestBody PageModelRequest pagemodelRequest, BindingResult bindingResult) { - - validatePageModelRequest(pagemodelRequest, bindingResult); - + this.validatePageModelRequest(pagemodelRequest, bindingResult); PageModelDto dto = pageModelService.addPageModel(pagemodelRequest); return ResponseEntity.ok(new SimpleRestResponse<>(dto)); } @@ -188,13 +167,12 @@ private void validatePageModelRequest(@RequestBody @Valid PageModelRequest pagem if (bindingResult.hasErrors()) { throw new ValidationGenericException(bindingResult); } - pageModelValidator.validate(pagemodelRequest, bindingResult); + this.pageModelValidator.validate(pagemodelRequest, bindingResult); if (bindingResult.hasErrors()) { throw new ValidationGenericException(bindingResult); } } - @ApiOperation("Delete page template") @ApiResponses({ @ApiResponse(code = 200, message = "OK") @@ -203,8 +181,9 @@ private void validatePageModelRequest(@RequestBody @Valid PageModelRequest pagem @DeleteMapping(value = "/{code:.+}") public ResponseEntity> deletePageModel(@PathVariable String code) { logger.debug("deleting {}", code); - pageModelService.removePageModel(code); + this.pageModelService.removePageModel(code); Map result = ImmutableMap.of("code", code); return ResponseEntity.ok(new SimpleRestResponse<>(result)); } + } diff --git a/engine/src/main/java/org/entando/entando/web/pagemodel/model/DefaultWidgetReq.java b/engine/src/main/java/org/entando/entando/web/pagemodel/model/DefaultWidgetReq.java new file mode 100644 index 000000000..8013f9cb9 --- /dev/null +++ b/engine/src/main/java/org/entando/entando/web/pagemodel/model/DefaultWidgetReq.java @@ -0,0 +1,40 @@ +/* + * Copyright 2020-Present Entando Inc. (http://www.entando.com) All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + */ +package org.entando.entando.web.pagemodel.model; + +import java.util.HashMap; +import java.util.Map; + +public class DefaultWidgetReq { + + private String code; + private Map properties = new HashMap<>(); + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + +} diff --git a/engine/src/main/java/org/entando/entando/web/pagemodel/model/PageModelFrameReq.java b/engine/src/main/java/org/entando/entando/web/pagemodel/model/PageModelFrameReq.java index caed06897..e30f28946 100644 --- a/engine/src/main/java/org/entando/entando/web/pagemodel/model/PageModelFrameReq.java +++ b/engine/src/main/java/org/entando/entando/web/pagemodel/model/PageModelFrameReq.java @@ -30,6 +30,7 @@ public class PageModelFrameReq { private boolean mainFrame; private FrameSketch sketch; + private DefaultWidgetReq defaultWidget = new DefaultWidgetReq(); public PageModelFrameReq() { @@ -72,4 +73,12 @@ public void setSketch(FrameSketch sketch) { this.sketch = sketch; } + public DefaultWidgetReq getDefaultWidget() { + return defaultWidget; + } + + public void setDefaultWidget(DefaultWidgetReq defaultWidget) { + this.defaultWidget = defaultWidget; + } + } diff --git a/engine/src/main/java/org/entando/entando/web/pagemodel/validator/PageModelValidator.java b/engine/src/main/java/org/entando/entando/web/pagemodel/validator/PageModelValidator.java index 4fb0e019a..1ff199cb3 100644 --- a/engine/src/main/java/org/entando/entando/web/pagemodel/validator/PageModelValidator.java +++ b/engine/src/main/java/org/entando/entando/web/pagemodel/validator/PageModelValidator.java @@ -13,13 +13,11 @@ */ package org.entando.entando.web.pagemodel.validator; -import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; -import org.entando.entando.aps.system.services.pagemodel.model.PageModelDto; import org.entando.entando.web.common.validator.AbstractPaginationValidator; import org.entando.entando.web.pagemodel.model.PageModelFrameReq; import org.entando.entando.web.pagemodel.model.PageModelRequest; @@ -34,6 +32,8 @@ public class PageModelValidator extends AbstractPaginationValidator { public static final String ERRCODE_PAGEMODEL_REFERENCES = "3"; public static final String ERRCODE_URINAME_MISMATCH = "4"; public static final String ERRCODE_FRAMES_POS_MISMATCH = "5"; + public static final String ERRCODE_DEFAULT_WIDGET_NOT_EXISTS = "6"; + public static final String ERRCODE_DEFAULT_WIDGET_INVALID_PARAMETER = "7"; @Override public boolean supports(Class paramClass) { diff --git a/engine/src/main/resources/rest/messages.properties b/engine/src/main/resources/rest/messages.properties index 6d9fd03f3..f08a953c6 100644 --- a/engine/src/main/resources/rest/messages.properties +++ b/engine/src/main/resources/rest/messages.properties @@ -107,6 +107,8 @@ pageModel.code.exists=The page template ''{0}'' already exists pageModel.frames.pos.mismatch=frame position should be zero based and progressive pageModel.code.mismatch=the code specified the URI ''{0}'' does not match with the one provided in the payload ''{1}'' pageModel.cannot.delete.references=The page template ''{0}'' can not be deleted due to references +pageModel.defaultWidget.notExists=Default widget ''{0}'' specified in frame ''{1}'' does not exists +pageModel.defaultWidget.invalidParameter=Parameter ''{0}'' of default Widget ''{1}'' specified in frame ''{2}'' is invalid #pageModel.update.patch.invalid.generic=The provided patch for pageModel ''{0}'' is not valid #pageModel.update.patch.invalid.code=The provided JSON patch can not contain operations on the code property diff --git a/engine/src/test/java/org/entando/entando/aps/system/services/pagemodel/PageModelServiceTest.java b/engine/src/test/java/org/entando/entando/aps/system/services/pagemodel/PageModelServiceTest.java index 5cd424504..0ab339c10 100644 --- a/engine/src/test/java/org/entando/entando/aps/system/services/pagemodel/PageModelServiceTest.java +++ b/engine/src/test/java/org/entando/entando/aps/system/services/pagemodel/PageModelServiceTest.java @@ -4,8 +4,6 @@ import com.agiletec.aps.system.exception.ApsSystemException; import com.agiletec.aps.system.services.pagemodel.*; import org.entando.entando.aps.system.services.assertionhelper.PageModelAssertionHelper; -import org.entando.entando.aps.system.services.guifragment.GuiFragment; -import org.entando.entando.aps.system.services.guifragment.model.GuiFragmentDto; import org.entando.entando.aps.system.services.mockhelper.PageMockHelper; import org.entando.entando.aps.system.services.page.IPageService; import org.entando.entando.aps.system.services.page.model.PageDto; @@ -17,7 +15,6 @@ import org.entando.entando.web.pagemodel.model.*; import org.junit.*; import org.junit.runner.RunWith; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.context.ApplicationContext; @@ -25,14 +22,16 @@ import java.lang.reflect.Field; import java.util.*; -import java.util.stream.Collectors; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.entando.entando.aps.system.services.pagemodel.PageModelTestUtil.validPageModelRequest; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import org.entando.entando.aps.system.services.widgettype.IWidgetTypeManager; +import org.entando.entando.aps.system.services.widgettype.WidgetType; +import org.mockito.Mockito; @RunWith(MockitoJUnitRunner.class) public class PageModelServiceTest { @@ -45,11 +44,15 @@ public class PageModelServiceTest { @Mock private IPageModelManager pageModelManager; + @Mock + private IWidgetTypeManager widgetTypeManager; + @Mock private ApplicationContext applicationContext; @Mock private PageModelServiceUtilizer pageModelServiceUtilizer; + @Mock private PagedMetadataMapper pagedMetadataMapper; @@ -60,24 +63,21 @@ public class PageModelServiceTest { @Before public void setUp() throws Exception { dtoBuilder = new PageModelDtoBuilder(); - pageModelService = new PageModelService(pageModelManager, dtoBuilder); + pageModelService = new PageModelService(pageModelManager, widgetTypeManager, dtoBuilder); pageModelService.setApplicationContext(applicationContext); - Field pagedMetadataMapper = ReflectionUtils.findField(pageModelService.getClass(), "pagedMetadataMapper"); pagedMetadataMapper.setAccessible(true); pagedMetadataMapper.set(pageModelService, this.pagedMetadataMapper); } - @Test public void - add_page_model_calls_page_model_manager() throws Exception { - + @Test + public void add_page_model_calls_page_model_manager() throws Exception { + WidgetType mockType = Mockito.mock(WidgetType.class); + when(mockType.hasParameter(Mockito.anyString())).thenReturn(true); + when(widgetTypeManager.getWidgetType(Mockito.anyString())).thenReturn(mockType); PageModelRequest pageModelRequest = validPageModelRequest(); - PageModel pageModel = pageModelFrom(pageModelRequest); - PageModelDto result = pageModelService.addPageModel(pageModelRequest); - - verify(pageModelManager, times(1)).addPageModel(pageModel); - + Mockito.verify(pageModelManager, Mockito.times(1)).addPageModel(Mockito.any(PageModel.class)); assertThat(result).isNotNull(); assertThat(result.getCode()).isEqualTo(pageModelRequest.getCode()); assertThat(result.getDescr()).isEqualTo(pageModelRequest.getDescr()); @@ -86,30 +86,25 @@ public void setUp() throws Exception { assertThat(result.getTemplate()).isEqualTo(pageModelRequest.getTemplate()); } - @Test public void - get_page_models_returns_page_models() throws ApsSystemException { + @Test + public void get_page_models_returns_page_models() throws ApsSystemException { when(pageModelManager.searchPageModels(any())).thenReturn(pageModels()); - PagedMetadata result = pageModelService.getPageModels(EMPTY_REQUEST, null); - PagedMetadata expected = resultPagedMetadata(); assertThat(result).isEqualTo(expected); } @Test public void getPageModelUsageTest() { - String managerName = "PageManager"; - PageModel pageModel = PageMockHelper.mockServicePageModel(); PageDto pageDto = PageMockHelper.mockPageDto(); Map pageModelServiceUtilizerMap = new HashMap<>(); pageModelServiceUtilizerMap.put(managerName, pageModelServiceUtilizer); - - when(pageModelManager.getPageModel(anyString())).thenReturn(pageModel); + when(pageModelManager.getPageModel(Mockito.anyString())).thenReturn(pageModel); when(applicationContext.getBeansOfType(any())).thenReturn(pageModelServiceUtilizerMap); when(pageModelServiceUtilizer.getManagerName()).thenReturn(managerName); - when(pageModelServiceUtilizer.getPageModelUtilizer(anyString())).thenReturn(Collections.singletonList(pageDto)); + when(pageModelServiceUtilizer.getPageModelUtilizer(Mockito.anyString())).thenReturn(Collections.singletonList(pageDto)); RestListRequest restListRequest = new RestListRequest(); restListRequest.setPageSize(1); List componentUsageEntityList = Arrays.asList(new ComponentUsageEntity(ComponentUsageEntity.TYPE_PAGE, PageMockHelper.PAGE_CODE, IPageService.STATUS_ONLINE)); @@ -118,16 +113,12 @@ public void getPageModelUsageTest() { pagedMetadata.setPage(1); pagedMetadata.imposeLimits(); when(pagedMetadataMapper.getPagedResult(any(), any())).thenReturn(pagedMetadata); - PagedMetadata usageDetails = pageModelService.getComponentUsageDetails(pageModel.getCode(), new PageSearchRequest(pageModel.getCode())); - PageModelAssertionHelper.assertUsageDetails(usageDetails); } - private PagedMetadata resultPagedMetadata() { RestListRequest request = new RestListRequest(); - return new PagedMetadata<>(request, asList(dtoBuilder.convert(pageModel())), 1); } @@ -143,27 +134,22 @@ private static PageModel pageModel() { private static PageModel pageModelFrom(PageModelRequest pageModelRequest) { Frame[] frames = framesFrom(pageModelRequest.getConfiguration()); - PageModel pageModel = new PageModel(); pageModel.setCode(pageModelRequest.getCode()); pageModel.setDescription(pageModelRequest.getDescr()); pageModel.setConfiguration(frames); - return pageModel; } private static Frame[] framesFrom(PageModelConfigurationRequest configuration) { List requestFrames = configuration.getFrames(); - if (requestFrames == null) { return new Frame[]{}; } - Frame[] frames = new Frame[requestFrames.size()]; for (int i = 0; i < requestFrames.size(); i++) { frames[i] = frameFrom(requestFrames.get(i)); } - return frames; } @@ -172,4 +158,5 @@ private static Frame frameFrom(PageModelFrameReq request) { frame.setDescription(request.getDescr()); return frame; } + } diff --git a/engine/src/test/java/org/entando/entando/aps/system/services/pagemodel/PageModelTestUtil.java b/engine/src/test/java/org/entando/entando/aps/system/services/pagemodel/PageModelTestUtil.java index 26f43c79a..afb290f2b 100644 --- a/engine/src/test/java/org/entando/entando/aps/system/services/pagemodel/PageModelTestUtil.java +++ b/engine/src/test/java/org/entando/entando/aps/system/services/pagemodel/PageModelTestUtil.java @@ -1,8 +1,23 @@ +/* + * Copyright 2020-Present Entando Inc. (http://www.entando.com) All rights reserved. + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + */ package org.entando.entando.aps.system.services.pagemodel; -import org.entando.entando.web.pagemodel.model.*; - -import static java.util.Collections.singletonList; +import java.util.ArrayList; +import java.util.List; +import org.entando.entando.web.pagemodel.model.PageModelConfigurationRequest; +import org.entando.entando.web.pagemodel.model.PageModelFrameReq; +import org.entando.entando.web.pagemodel.model.PageModelRequest; public final class PageModelTestUtil { @@ -24,11 +39,18 @@ public static PageModelRequest validPageModelRequest() { private static PageModelConfigurationRequest createValidPageModelConfigurationRequest() { PageModelConfigurationRequest configuration = new PageModelConfigurationRequest(); - configuration.setFrames(singletonList(createValidFrameRequest())); + List frames = new ArrayList<>(); + frames.add(createValidFrameRequest()); + frames.add(new PageModelFrameReq(1, "Position 1")); + configuration.setFrames(frames); return configuration; } private static PageModelFrameReq createValidFrameRequest() { - return new PageModelFrameReq(0, FRAME_DESCRIPTION); + PageModelFrameReq pageReq = new PageModelFrameReq(0, FRAME_DESCRIPTION); + pageReq.getDefaultWidget().setCode("leftmenu"); + pageReq.getDefaultWidget().getProperties().put("navSpec", "code(homepage).subtree(5)"); + return pageReq; } + } diff --git a/engine/src/test/java/org/entando/entando/web/pagemodel/PageModelControllerIntegrationTest.java b/engine/src/test/java/org/entando/entando/web/pagemodel/PageModelControllerIntegrationTest.java index 736c646bd..2c95a3d6b 100644 --- a/engine/src/test/java/org/entando/entando/web/pagemodel/PageModelControllerIntegrationTest.java +++ b/engine/src/test/java/org/entando/entando/web/pagemodel/PageModelControllerIntegrationTest.java @@ -35,8 +35,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.entando.entando.aps.system.services.pagemodel.PageModelTestUtil; import org.entando.entando.web.AbstractControllerIntegrationTest; +import org.entando.entando.web.pagemodel.model.PageModelFrameReq; import org.entando.entando.web.pagemodel.model.PageModelRequest; import org.entando.entando.web.utils.OAuth2TestUtils; +import org.hamcrest.CoreMatchers; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -54,61 +57,50 @@ public class PageModelControllerIntegrationTest extends AbstractControllerIntegr private String accessToken; private ObjectMapper jsonMapper = new ObjectMapper().setSerializationInclusion(NON_NULL); - @Autowired private PageModelManager pageModelManager; - @Override @Before public void setUp() throws Exception { super.setUp(); - - setupAuthenticationDetails(); - deletePageModelsFromPreviousTests(); + this.setupAuthenticationDetails(); + this.deletePageModelsFromPreviousTests(); } private void setupAuthenticationDetails() { User user = new OAuth2TestUtils.UserBuilder(USERNAME, PASSWORD) - .grantedToRoleAdmin() - .build(); - + .grantedToRoleAdmin().build(); accessToken = mockOAuthInterceptor(user); } private void deletePageModelsFromPreviousTests() throws ApsSystemException { pageModelManager.deletePageModel(PAGE_MODEL_CODE); } - - - @Test public void - get_all_page_models_return_OK() throws Exception { - + + @Test + public void get_all_page_models_return_OK() throws Exception { ResultActions result = mockMvc.perform( get("/pageModels") .header("Authorization", "Bearer " + accessToken)); result.andExpect(status().isOk()); } - @Test public void - get_page_model_return_OK() throws Exception { - + @Test + public void get_page_model_return_OK() throws Exception { ResultActions result = mockMvc.perform( get("/pageModels/{code}", "home") .header("Authorization", "Bearer " + accessToken)); - result.andExpect(status().isOk()); result.andExpect(jsonPath("$.payload.references.length()", is(1))); } - @Test public void - get_page_models_reference_return_OK() throws Exception { - + @Test + public void get_page_models_reference_return_OK() throws Exception { ResultActions result = mockMvc.perform( get("/pageModels/{code}/references/{manager}", "home", "PageManager") .contentType(MediaType.APPLICATION_JSON_VALUE) .header("Authorization", "Bearer " + accessToken)); - result.andExpect(status().isOk()); result.andExpect(jsonPath("$.metaData.totalItems", is(25))); } @@ -116,7 +108,6 @@ private void deletePageModelsFromPreviousTests() throws ApsSystemException { @Test public void shouldTestGetPageModelUsage() throws Exception { String code = "home"; - mockMvc.perform(get("/pageModels/{code}/usage", code) .contentType(MediaType.APPLICATION_JSON_VALUE) .header("Authorization", "Bearer " + accessToken)) @@ -127,33 +118,28 @@ public void shouldTestGetPageModelUsage() throws Exception { .andReturn();; } - @Test public void - add_repeated_page_model_return_conflict() throws Exception { + @Test + public void add_repeated_page_model_return_conflict() throws Exception { // pageModel home always exists because it's created with DB. String payload = createPageModelPayload("home"); - ResultActions result = mockMvc.perform( - post("/pageModels") - .content(payload) + post("/pageModels").content(payload) .contentType(MediaType.APPLICATION_JSON_VALUE) .header("Authorization", "Bearer " + accessToken)); - result.andExpect(status().isConflict()); } - @Test public void - add_page_model_return_OK() throws Exception { + @Test + public void add_page_model_return_OK() throws Exception { String payload = createPageModelPayload(PAGE_MODEL_CODE); - ResultActions result = mockMvc.perform( post("/pageModels") .content(payload) .contentType(MediaType.APPLICATION_JSON_VALUE) .header("Authorization", "Bearer " + accessToken)); - result.andExpect(status().isOk()); } - + private String createPageModelPayload(String pageModelCode) throws JsonProcessingException { PageModelRequest pageModelRequest = validPageModelRequest(); pageModelRequest.setCode(pageModelCode); @@ -163,10 +149,9 @@ private String createPageModelPayload(String pageModelCode) throws JsonProcessin private String createJson(PageModelRequest pageModelRequest) throws JsonProcessingException { return jsonMapper.writeValueAsString(pageModelRequest); } - - @Test public void - get_nonexistent_page_model_return_not_found() throws Exception { - + + @Test + public void get_nonexistent_page_model_return_not_found() throws Exception { ResultActions result = mockMvc.perform( get("/pageModels/{code}", NONEXISTENT_PAGE_MODEL) .contentType(MediaType.APPLICATION_JSON_VALUE) @@ -174,14 +159,12 @@ private String createJson(PageModelRequest pageModelRequest) throws JsonProcessi result.andExpect(status().isNotFound()); } - @Test public void - delete_page_model_return_OK() throws Exception { - + @Test + public void delete_page_model_return_OK() throws Exception { PageModel pageModel = new PageModel(); pageModel.setCode(PAGE_MODEL_CODE); pageModel.setDescription(PAGE_MODEL_CODE); - pageModelManager.addPageModel(pageModel); - + this.pageModelManager.addPageModel(pageModel); ResultActions result = mockMvc.perform( delete("/pageModels/{code}", PAGE_MODEL_CODE) .contentType(MediaType.APPLICATION_JSON_VALUE) @@ -189,51 +172,53 @@ private String createJson(PageModelRequest pageModelRequest) throws JsonProcessi result.andExpect(status().isOk()); } - @Test public void - delete_page_model_nonexistent_code_return_OK() throws Exception { - + @Test + public void delete_page_model_nonexistent_code_return_OK() throws Exception { ResultActions result = mockMvc.perform( delete("/pageModels/{code}", NONEXISTENT_PAGE_MODEL) .contentType(MediaType.APPLICATION_JSON_VALUE) .header("Authorization", "Bearer " + accessToken)); result.andExpect(status().isOk()); } - - @Test public void - add_page_model_with_dot_return_OK() throws Exception { + + @Test + public void add_page_model_with_dot_return_OK() throws Exception { try { PageModelRequest pageModelRequest = PageModelTestUtil.validPageModelRequest(); - pageModelRequest.setCode(PAGE_MODEL_WITH_DOT_CODE); - ResultActions result = mockMvc.perform( post("/pageModels") .content(createJson(pageModelRequest)) .contentType(MediaType.APPLICATION_JSON_VALUE) .header("Authorization", "Bearer " + accessToken)); - result.andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("$.payload.code", is(PAGE_MODEL_WITH_DOT_CODE))) - .andExpect(jsonPath("$.payload.descr", is("description"))); - + .andExpect(jsonPath("$.payload.descr", is("description"))) + .andExpect(jsonPath("$.payload.configuration.frames[0].defaultWidget.code", is("leftmenu"))) + .andExpect(jsonPath("$.payload.configuration.frames[0].defaultWidget.properties.navSpec", is("code(homepage).subtree(5)"))) + .andExpect(jsonPath("$.payload.configuration.frames[1].defaultWidget", CoreMatchers.nullValue())); + PageModel pageModel = this.pageModelManager.getPageModel(PAGE_MODEL_WITH_DOT_CODE); + Assert.assertNotNull(pageModel); + Assert.assertEquals(2, pageModel.getFrames().length); + Assert.assertEquals(2, pageModel.getFramesConfig().length); + Assert.assertNotNull(pageModel.getFramesConfig()[0].getDefaultWidget()); + Assert.assertEquals("leftmenu", pageModel.getFramesConfig()[0].getDefaultWidget().getType().getCode()); + Assert.assertEquals(1, pageModel.getFramesConfig()[0].getDefaultWidget().getConfig().size()); + Assert.assertEquals("code(homepage).subtree(5)", pageModel.getFramesConfig()[0].getDefaultWidget().getConfig().getProperty("navSpec")); pageModelRequest.setDescr("description2"); - result = mockMvc.perform( put("/pageModels/{code}", PAGE_MODEL_WITH_DOT_CODE) .content(createJson(pageModelRequest)) .contentType(MediaType.APPLICATION_JSON_VALUE) .header("Authorization", "Bearer " + accessToken)); - result.andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("$.payload.code", is(PAGE_MODEL_WITH_DOT_CODE))) .andExpect(jsonPath("$.payload.descr", is("description2"))); - result = mockMvc.perform( get("/pageModels/{code}", PAGE_MODEL_WITH_DOT_CODE) .header("Authorization", "Bearer " + accessToken)); - result.andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("$.payload.code", is(PAGE_MODEL_WITH_DOT_CODE))) @@ -247,7 +232,141 @@ private String createJson(PageModelRequest pageModelRequest) throws JsonProcessi .andExpect(status().isOk()); } } - + + @Test + public void add_page_model_with_errors() throws Exception { + try { + PageModelRequest pageModelRequest = PageModelTestUtil.validPageModelRequest(); + PageModelFrameReq newFrames = new PageModelFrameReq(2, "Position 1"); + newFrames.getDefaultWidget().setCode("invalid_widget"); + pageModelRequest.getConfiguration().getFrames().add(newFrames); + + pageModelRequest.setCode(PAGE_MODEL_CODE); + ResultActions result = mockMvc.perform( + post("/pageModels") + .content(createJson(pageModelRequest)) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer " + accessToken)); + + result.andExpect(status().isBadRequest()); + result.andExpect(jsonPath("$.payload.size()", is(0))); + result.andExpect(jsonPath("$.errors.size()", is(1))); + result.andExpect(jsonPath("$.errors[0].code", is("6"))); + result.andExpect(jsonPath("$.metaData.size()", is(0))); + PageModel pageModel = this.pageModelManager.getPageModel(PAGE_MODEL_CODE); + Assert.assertNull(pageModel); + + newFrames.getDefaultWidget().setCode("leftmenu"); + newFrames.getDefaultWidget().getProperties().put("wrongParam", "code(homepage).subtree(8)"); + + result = mockMvc.perform( + post("/pageModels") + .content(createJson(pageModelRequest)) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer " + accessToken)); + + result.andExpect(status().isBadRequest()); + result.andExpect(jsonPath("$.payload.size()", is(0))); + result.andExpect(jsonPath("$.errors.size()", is(1))); + result.andExpect(jsonPath("$.errors[0].code", is("7"))); + result.andExpect(jsonPath("$.metaData.size()", is(0))); + pageModel = this.pageModelManager.getPageModel(PAGE_MODEL_CODE); + Assert.assertNull(pageModel); + + newFrames.getDefaultWidget().getProperties().remove("wrongParam"); + PageModelFrameReq newWrongFrames = new PageModelFrameReq(7, "Position 7"); + pageModelRequest.getConfiguration().getFrames().add(newWrongFrames); + + result = mockMvc.perform( + post("/pageModels") + .content(createJson(pageModelRequest)) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer " + accessToken)); + + result.andExpect(status().isBadRequest()); + result.andExpect(jsonPath("$.payload.size()", is(0))); + result.andExpect(jsonPath("$.errors.size()", is(1))); + result.andExpect(jsonPath("$.errors[0].code", is("5"))); + result.andExpect(jsonPath("$.metaData.size()", is(0))); + pageModel = this.pageModelManager.getPageModel(PAGE_MODEL_CODE); + Assert.assertNull(pageModel); + + } catch (Exception e) { + throw e; + } finally { + this.pageModelManager.deletePageModel(PAGE_MODEL_CODE); + } + } + + @Test + public void update_page_model_with_errors() throws Exception { + try { + PageModelRequest pageModelRequest = PageModelTestUtil.validPageModelRequest(); + pageModelRequest.setCode(PAGE_MODEL_CODE); + ResultActions result = mockMvc.perform( + post("/pageModels") + .content(createJson(pageModelRequest)) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer " + accessToken)); + result.andDo(print()).andExpect(status().isOk()); + + PageModel pageModel = this.pageModelManager.getPageModel(PAGE_MODEL_CODE); + Assert.assertNotNull(pageModel); + Assert.assertEquals(2, pageModel.getFrames().length); + + PageModelFrameReq newFrames = new PageModelFrameReq(2, "Position 1"); + newFrames.getDefaultWidget().setCode("invalid_widget"); + pageModelRequest.getConfiguration().getFrames().add(newFrames); + + result = mockMvc.perform( + post("/pageModels") + .content(createJson(pageModelRequest)) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer " + accessToken)); + result.andExpect(status().isConflict()); + result.andExpect(jsonPath("$.payload.size()", is(0))); + result.andExpect(jsonPath("$.errors.size()", is(1))); + result.andExpect(jsonPath("$.errors[0].code", is("2"))); + result.andExpect(jsonPath("$.metaData.size()", is(0))); + pageModel = this.pageModelManager.getPageModel(PAGE_MODEL_CODE); + Assert.assertNotNull(pageModel); + Assert.assertEquals(2, pageModel.getFrames().length); + + result = mockMvc.perform( + put("/pageModels/{code}", PAGE_MODEL_CODE) + .content(createJson(pageModelRequest)) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer " + accessToken)); + result.andExpect(status().isBadRequest()); + result.andExpect(jsonPath("$.payload.size()", is(0))); + result.andExpect(jsonPath("$.errors.size()", is(1))); + result.andExpect(jsonPath("$.errors[0].code", is("6"))); + result.andExpect(jsonPath("$.metaData.size()", is(0))); + pageModel = this.pageModelManager.getPageModel(PAGE_MODEL_CODE); + Assert.assertNotNull(pageModel); + Assert.assertEquals(2, pageModel.getFrames().length); + + pageModelRequest.setCode(NONEXISTENT_PAGE_MODEL); + result = mockMvc.perform( + put("/pageModels/{code}", NONEXISTENT_PAGE_MODEL) + .content(createJson(pageModelRequest)) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer " + accessToken)); + result.andExpect(status().isNotFound()); + result.andExpect(jsonPath("$.payload.size()", is(0))); + result.andExpect(jsonPath("$.errors.size()", is(1))); + result.andExpect(jsonPath("$.errors[0].code", is("1"))); + result.andExpect(jsonPath("$.metaData.size()", is(0))); + pageModel = this.pageModelManager.getPageModel(PAGE_MODEL_CODE); + Assert.assertNotNull(pageModel); + Assert.assertEquals(2, pageModel.getFrames().length); + } catch (Exception e) { + throw e; + } finally { + this.pageModelManager.deletePageModel(PAGE_MODEL_CODE); + } + } + @Test public void testGetPageModelWithAdminPermission() throws Exception { UserDetails user = new OAuth2TestUtils.UserBuilder("jack_bauer", "0x24").grantedToRoleAdmin().build(); @@ -275,4 +394,5 @@ public void testGetPageModelWithManagePagesPermission() throws Exception { .header("Authorization", "Bearer " + mockOAuthInterceptor(user))); result.andExpect(status().isOk()); } + }