diff --git a/application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java index 7e1b9b30c9..d427c26d05 100644 --- a/application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java @@ -27,13 +27,16 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import org.springframework.test.context.ContextConfiguration; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.DashboardInfo; +import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.ShortCustomerInfo; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.asset.AssetProfile; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.id.CustomerId; @@ -48,6 +51,7 @@ import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.ArrayList; import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.containsString; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -547,6 +551,33 @@ public class DashboardControllerTest extends AbstractControllerTest { testEntityDaoWithRelationsTransactionalException(dashboardDao, savedTenant.getId(), dashboardId, "/api/dashboard/" + dashboardId); } + @Test + public void whenDeletingDashboard_ifReferencedByDeviceProfile_thenReturnError() throws Exception { + Dashboard dashboard = createDashboard("test"); + DeviceProfile deviceProfile = createDeviceProfile("test"); + deviceProfile.setDefaultDashboardId(dashboard.getId()); + doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); + + String response = doDelete("/api/dashboard/" + dashboard.getUuidId()).andExpect(status().isBadRequest()) + .andReturn().getResponse().getContentAsString(); + String errorMessage = JacksonUtil.toJsonNode(response).get("message").asText(); + assertThat(errorMessage).containsIgnoringCase("referenced by a device profile"); + } + + @Test + public void whenDeletingDashboard_ifReferencedByAssetProfile_thenReturnError() throws Exception { + Dashboard dashboard = createDashboard("test"); + AssetProfile assetProfile = createAssetProfile("test"); + assetProfile.setDefaultDashboardId(dashboard.getId()); + doPost("/api/assetProfile", assetProfile, AssetProfile.class); + + String response = doDelete("/api/dashboard/" + dashboard.getUuidId()).andExpect(status().isBadRequest()) + .andReturn().getResponse().getContentAsString(); + String errorMessage = JacksonUtil.toJsonNode(response).get("message").asText(); + assertThat(errorMessage).containsIgnoringCase("referenced by an asset profile"); + + } + private Dashboard createDashboard(String title) { Dashboard dashboard = new Dashboard(); dashboard.setTitle(title); diff --git a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java index 6a0de28bf2..5c7430ebc8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java @@ -18,7 +18,6 @@ package org.thingsboard.server.dao.dashboard; import com.google.common.util.concurrent.ListenableFuture; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; @@ -57,6 +56,7 @@ import org.thingsboard.server.dao.service.Validator; import org.thingsboard.server.dao.sql.JpaExecutorService; import java.util.List; +import java.util.Map; import java.util.Optional; import static org.thingsboard.server.dao.service.Validator.validateId; @@ -235,13 +235,12 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb publishEvictEvent(new DashboardTitleEvictEvent(dashboardId)); countService.publishCountEntityEvictEvent(tenantId, EntityType.DASHBOARD); eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entityId(dashboardId).build()); - } catch (Exception t) { - ConstraintViolationException e = extractConstraintViolationException(t).orElse(null); - if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_default_dashboard_device_profile")) { - throw new DataValidationException("The dashboard referenced by the device profiles cannot be deleted!"); - } else { - throw t; - } + } catch (Exception e) { + checkConstraintViolation(e, Map.of( + "fk_default_dashboard_device_profile", "The dashboard is referenced by a device profile", + "fk_default_dashboard_asset_profile", "The dashboard is referenced by an asset profile" + )); + throw e; } }