From e817542db74fe832e6b0c479a17bf3302d4bf979 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Tue, 12 Dec 2023 17:37:54 +0100 Subject: [PATCH] added tests and fix --- .../BaseEntityQueryControllerTest.java | 63 +++++++++++++++++++ .../query/DefaultEntityQueryRepository.java | 2 +- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseEntityQueryControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseEntityQueryControllerTest.java index 8c692ef8a2..f1a342b767 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseEntityQueryControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseEntityQueryControllerTest.java @@ -46,7 +46,11 @@ import org.thingsboard.server.common.data.query.EntityTypeFilter; import org.thingsboard.server.common.data.query.FilterPredicateValue; import org.thingsboard.server.common.data.query.KeyFilter; import org.thingsboard.server.common.data.query.NumericFilterPredicate; +import org.thingsboard.server.common.data.query.RelationsQueryFilter; import org.thingsboard.server.common.data.query.TsValue; +import org.thingsboard.server.common.data.relation.EntityRelation; +import org.thingsboard.server.common.data.relation.EntitySearchDirection; +import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter; import org.thingsboard.server.common.data.security.Authority; import java.util.ArrayList; @@ -224,6 +228,65 @@ public abstract class BaseEntityQueryControllerTest extends AbstractControllerTe } + @Test + public void testFindEntityDataByQueryWithNegateParam() throws Exception { + List devices = new ArrayList<>(); + for (int i = 0; i < 97; i++) { + Device device = new Device(); + device.setName("Device" + i); + device.setType("default"); + device.setLabel("testLabel" + (int) (Math.random() * 1000)); + devices.add(doPost("/api/device", device, Device.class)); + Thread.sleep(1); + } + + Device mainDevice = new Device(); + mainDevice.setName("Main device"); + mainDevice = doPost("/api/device", mainDevice, Device.class); + + for (int i = 0; i < 10; i++) { + EntityRelation relation = createFromRelation(mainDevice, devices.get(i), "CONTAINS"); + doPost("/api/relation", relation).andExpect(status().isOk()); + } + + for (int i = 10; i < 97; i++) { + EntityRelation relation = createFromRelation(mainDevice, devices.get(i), "NOT_CONTAINS"); + doPost("/api/relation", relation).andExpect(status().isOk()); + } + + RelationsQueryFilter filter = new RelationsQueryFilter(); + filter.setRootEntity(mainDevice.getId()); + filter.setDirection(EntitySearchDirection.FROM); + filter.setNegate(true); + filter.setFilters(List.of(new RelationEntityTypeFilter("CONTAINS", List.of(EntityType.DEVICE), false))); + + EntityDataSortOrder sortOrder = new EntityDataSortOrder( + new EntityKey(EntityKeyType.ENTITY_FIELD, "createdTime"), EntityDataSortOrder.Direction.ASC + ); + EntityDataPageLink pageLink = new EntityDataPageLink(10, 0, null, sortOrder); + List entityFields = Collections.singletonList(new EntityKey(EntityKeyType.ENTITY_FIELD, "name")); + + EntityDataQuery query = new EntityDataQuery(filter, pageLink, entityFields, null, null); + + PageData data = doPostWithTypedResponse("/api/entitiesQuery/find", query, new TypeReference<>() {}); + + Assert.assertEquals(87, data.getTotalElements()); + + filter.setFilters(List.of(new RelationEntityTypeFilter("NOT_CONTAINS", List.of(EntityType.DEVICE), false))); + query = new EntityDataQuery(filter, pageLink, entityFields, null, null); + data = doPostWithTypedResponse("/api/entitiesQuery/find", query, new TypeReference<>() {}); + Assert.assertEquals(10, data.getTotalElements()); + + filter.setFilters(List.of(new RelationEntityTypeFilter("NOT_CONTAINS", List.of(EntityType.DEVICE), true))); + query = new EntityDataQuery(filter, pageLink, entityFields, null, null); + data = doPostWithTypedResponse("/api/entitiesQuery/find", query, new TypeReference<>() {}); + Assert.assertEquals(87, data.getTotalElements()); + } + + private EntityRelation createFromRelation(Device mainDevice, Device device, String relationType) { + return new EntityRelation(mainDevice.getId(), device.getId(), relationType); + } + @Test public void testFindEntityDataByQueryWithAttributes() throws Exception { List devices = new ArrayList<>(); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java index be91d78704..cdae7eff0f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java @@ -711,7 +711,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { .append(whereFilter).append(")"); } else if (entityFilter.isNegate()) { whereFilter = new StringBuilder() - .append(" NOT ") + .append(" NOT (") .append(whereFilter).append(")"); } }