From f48513e779b9ca79a0c9249e901f43c1004e3e86 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Mon, 4 Aug 2025 17:07:07 +0300 Subject: [PATCH] Add test to ensure relations with empty or blank types can be deleted --- .../controller/EntityRelationController.java | 5 +-- .../EntityRelationControllerTest.java | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java index 6c2f08898f..ff0f8fd91d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java @@ -42,7 +42,6 @@ import org.thingsboard.server.service.security.permission.Operation; import java.util.List; import java.util.concurrent.ExecutionException; -import java.util.stream.Collectors; import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE_PARAM_DESCRIPTION; @@ -295,7 +294,6 @@ public class EntityRelationController extends BaseController { @PostMapping("/relations") public List findByQuery(@Parameter(description = "A JSON value representing the entity relations query object.", required = true) @RequestBody EntityRelationsQuery query) throws ThingsboardException, ExecutionException, InterruptedException { - checkNotNull(query); checkNotNull(query.getParameters()); checkNotNull(query.getFilters()); checkEntityId(query.getParameters().getEntityId(), Operation.READ); @@ -310,7 +308,6 @@ public class EntityRelationController extends BaseController { @PostMapping("/relations/info") public List findInfoByQuery(@Parameter(description = "A JSON value representing the entity relations query object.", required = true) @RequestBody EntityRelationsQuery query) throws ThingsboardException, ExecutionException, InterruptedException { - checkNotNull(query); checkNotNull(query.getParameters()); checkNotNull(query.getFilters()); checkEntityId(query.getParameters().getEntityId(), Operation.READ); @@ -338,7 +335,7 @@ public class EntityRelationController extends BaseController { return false; } return true; - }).collect(Collectors.toList()); + }).toList(); } private static RelationTypeGroup parseRelationTypeGroup(String strRelationTypeGroup, RelationTypeGroup defaultValue) { diff --git a/application/src/test/java/org/thingsboard/server/controller/EntityRelationControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/EntityRelationControllerTest.java index 7016f14697..e935ff8a5d 100644 --- a/application/src/test/java/org/thingsboard/server/controller/EntityRelationControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/EntityRelationControllerTest.java @@ -21,6 +21,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.web.servlet.ResultActions; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; @@ -34,6 +35,7 @@ import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter; import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.relation.RelationsSearchParameters; +import org.thingsboard.server.dao.relation.RelationDao; import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.Collections; @@ -49,6 +51,9 @@ public class EntityRelationControllerTest extends AbstractControllerTest { public static final String BASE_DEVICE_NAME = "Test dummy device"; + @Autowired + private RelationDao relationDao; + private Device mainDevice; @Before @@ -356,6 +361,45 @@ public class EntityRelationControllerTest extends AbstractControllerTest { .andExpect(statusReason(is(msgErrorNotFound))); } + @Test + public void testDeleteRelationWithTypeEmptyOrBlank() throws Exception { + // GIVEN + Device device = createDevice("Test device"); + + // WHEN-THEN + for (String endpoint : List.of("/api/relation", "/api/v2/relation")) { + // saving relation with empty type + EntityRelation emptyRelation = createFromRelation(mainDevice, device, ""); + relationDao.saveRelation(tenantId, emptyRelation); + + // saving relation with blank type + EntityRelation blankRelation = createFromRelation(mainDevice, device, " "); + relationDao.saveRelation(tenantId, blankRelation); + + // deleting relation with empty type + String deleteEmptyUrl = String.format(endpoint + "?fromId=%s&fromType=%s&relationType=%s&toId=%s&toType=%s", + mainDevice.getUuidId(), EntityType.DEVICE, + emptyRelation.getType(), device.getUuidId(), EntityType.DEVICE + ); + doDelete(deleteEmptyUrl).andExpect(status().isOk()); + + getRelation(emptyRelation) + .andExpect(status().isNotFound()) + .andExpect(statusReason(is(msgErrorNotFound))); + + // deleting relation with blank type + String deleteBlankUrl = String.format(endpoint + "?fromId=%s&fromType=%s&relationType=%s&toId=%s&toType=%s", + mainDevice.getUuidId(), EntityType.DEVICE, + blankRelation.getType(), device.getUuidId(), EntityType.DEVICE + ); + doDelete(deleteBlankUrl).andExpect(status().isOk()); + + getRelation(blankRelation) + .andExpect(status().isNotFound()) + .andExpect(statusReason(is(msgErrorNotFound))); + } + } + @Test public void testDeleteRelationWithOtherFromDeviceError() throws Exception { Device device = createDevice("Test device 1");