Added tests & temporary removed RelationQueryDynamicSourceConfiguration from interface
This commit is contained in:
parent
909497703a
commit
2cb05c9d2b
@ -26,7 +26,6 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
|||||||
property = "type"
|
property = "type"
|
||||||
)
|
)
|
||||||
@JsonSubTypes({
|
@JsonSubTypes({
|
||||||
@JsonSubTypes.Type(value = RelationQueryDynamicSourceConfiguration.class, name = "RELATION_QUERY"),
|
|
||||||
@JsonSubTypes.Type(value = RelationPathQueryDynamicSourceConfiguration.class, name = "RELATION_PATH_QUERY")
|
@JsonSubTypes.Type(value = RelationPathQueryDynamicSourceConfiguration.class, name = "RELATION_PATH_QUERY")
|
||||||
})
|
})
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
|||||||
@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2025 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.thingsboard.server.common.data.cf.configuration;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.NullAndEmptySource;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
|
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||||
|
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
|
||||||
|
import org.thingsboard.server.common.data.relation.RelationPathLevel;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class RelationPathQueryDynamicSourceConfigurationTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void typeShouldBeRelationQuery() {
|
||||||
|
var cfg = new RelationPathQueryDynamicSourceConfiguration();
|
||||||
|
assertThat(cfg.getType()).isEqualTo(CFArgumentDynamicSourceType.RELATION_PATH_QUERY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@NullAndEmptySource
|
||||||
|
void validateShouldThrowWhenLevelsIsNull(List<RelationPathLevel> levels) {
|
||||||
|
var cfg = new RelationPathQueryDynamicSourceConfiguration();
|
||||||
|
cfg.setLevels(levels);
|
||||||
|
|
||||||
|
assertThatThrownBy(cfg::validate)
|
||||||
|
.isInstanceOf(IllegalArgumentException.class)
|
||||||
|
.hasMessage("At least one relation level must be specified!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validateShouldCallValidateForPathLevels() {
|
||||||
|
List<RelationPathLevel> levels = new ArrayList<>();
|
||||||
|
|
||||||
|
RelationPathLevel lvl1 = mock(RelationPathLevel.class);
|
||||||
|
RelationPathLevel lvl2 = mock(RelationPathLevel.class);
|
||||||
|
levels.add(lvl1);
|
||||||
|
levels.add(lvl2);
|
||||||
|
|
||||||
|
var cfg = new RelationPathQueryDynamicSourceConfiguration();
|
||||||
|
cfg.setLevels(levels);
|
||||||
|
|
||||||
|
assertThatCode(cfg::validate).doesNotThrowAnyException();
|
||||||
|
|
||||||
|
verify(lvl1).validate();
|
||||||
|
verify(lvl2).validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void resolveEntityIds_whenDirectionFROM_thenReturnsToIds() {
|
||||||
|
List<RelationPathLevel> levels = new ArrayList<>();
|
||||||
|
|
||||||
|
RelationPathLevel lvl1 = mock(RelationPathLevel.class);
|
||||||
|
RelationPathLevel lvl2 = mock(RelationPathLevel.class);
|
||||||
|
levels.add(lvl1);
|
||||||
|
levels.add(lvl2);
|
||||||
|
|
||||||
|
when(lvl2.direction()).thenReturn(EntitySearchDirection.FROM);
|
||||||
|
|
||||||
|
EntityRelation rel1 = mock(EntityRelation.class);
|
||||||
|
EntityRelation rel2 = mock(EntityRelation.class);
|
||||||
|
|
||||||
|
when(rel1.getTo()).thenReturn(mock(EntityId.class));
|
||||||
|
when(rel2.getTo()).thenReturn(mock(EntityId.class));
|
||||||
|
|
||||||
|
var cfg = new RelationPathQueryDynamicSourceConfiguration();
|
||||||
|
cfg.setLevels(levels);
|
||||||
|
|
||||||
|
var out = cfg.resolveEntityIds(List.of(rel1, rel2));
|
||||||
|
|
||||||
|
assertThat(out).containsExactly(rel1.getTo(), rel2.getTo());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void resolveEntityIds_whenDirectionTO_thenReturnsFromIds() {
|
||||||
|
List<RelationPathLevel> levels = new ArrayList<>();
|
||||||
|
|
||||||
|
RelationPathLevel lvl1 = mock(RelationPathLevel.class);
|
||||||
|
RelationPathLevel lvl2 = mock(RelationPathLevel.class);
|
||||||
|
levels.add(lvl1);
|
||||||
|
levels.add(lvl2);
|
||||||
|
|
||||||
|
when(lvl2.direction()).thenReturn(EntitySearchDirection.TO);
|
||||||
|
|
||||||
|
EntityRelation rel1 = mock(EntityRelation.class);
|
||||||
|
EntityRelation rel2 = mock(EntityRelation.class);
|
||||||
|
|
||||||
|
when(rel1.getFrom()).thenReturn(mock(EntityId.class));
|
||||||
|
when(rel2.getFrom()).thenReturn(mock(EntityId.class));
|
||||||
|
|
||||||
|
var cfg = new RelationPathQueryDynamicSourceConfiguration();
|
||||||
|
cfg.setLevels(levels);
|
||||||
|
|
||||||
|
var out = cfg.resolveEntityIds(List.of(rel1, rel2));
|
||||||
|
|
||||||
|
assertThat(out).containsExactly(rel1.getFrom(), rel2.getFrom());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -123,9 +123,8 @@ public class RelationQueryDynamicSourceConfigurationTest {
|
|||||||
.hasMessage("Relation query dynamic source configuration relation type must be specified!");
|
.hasMessage("Relation query dynamic source configuration relation type must be specified!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@Test
|
||||||
@NullAndEmptySource
|
void isSimpleRelationTrueWhenLevelIsOneAndEntityTypesEmptyOrNull() {
|
||||||
void isSimpleRelationTrueWhenLevelIsOneAndEntityTypesEmptyOrNull(List<EntityType> entityTypes) {
|
|
||||||
var cfg = new RelationQueryDynamicSourceConfiguration();
|
var cfg = new RelationQueryDynamicSourceConfiguration();
|
||||||
cfg.setMaxLevel(1);
|
cfg.setMaxLevel(1);
|
||||||
assertThat(cfg.isSimpleRelation()).isTrue();
|
assertThat(cfg.isSimpleRelation()).isTrue();
|
||||||
@ -138,9 +137,8 @@ public class RelationQueryDynamicSourceConfigurationTest {
|
|||||||
assertThat(cfg.isSimpleRelation()).isFalse();
|
assertThat(cfg.isSimpleRelation()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@Test
|
||||||
@NullAndEmptySource
|
void toEntityRelationsQueryShouldThrowForSimpleRelation() {
|
||||||
void toEntityRelationsQueryShouldThrowForSimpleRelation(List<EntityType> entityTypes) {
|
|
||||||
var cfg = new RelationQueryDynamicSourceConfiguration();
|
var cfg = new RelationQueryDynamicSourceConfiguration();
|
||||||
cfg.setMaxLevel(1);
|
cfg.setMaxLevel(1);
|
||||||
cfg.setFetchLastLevelOnly(false);
|
cfg.setFetchLastLevelOnly(false);
|
||||||
@ -177,7 +175,7 @@ public class RelationQueryDynamicSourceConfigurationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void resolveEntityIdsFromDirectionFROMReturnsToIds() {
|
void resolveEntityIds_whenDirectionFROM_thenReturnsToIds() {
|
||||||
when(rel1.getTo()).thenReturn(mock(EntityId.class));
|
when(rel1.getTo()).thenReturn(mock(EntityId.class));
|
||||||
when(rel2.getTo()).thenReturn(mock(EntityId.class));
|
when(rel2.getTo()).thenReturn(mock(EntityId.class));
|
||||||
|
|
||||||
@ -190,7 +188,7 @@ public class RelationQueryDynamicSourceConfigurationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void resolveEntityIdsFromDirectionTOReturnsFromIds() {
|
void resolveEntityIds_whenDirectionTO_thenReturnsFromIds() {
|
||||||
when(rel1.getFrom()).thenReturn(mock(EntityId.class));
|
when(rel1.getFrom()).thenReturn(mock(EntityId.class));
|
||||||
when(rel2.getFrom()).thenReturn(mock(EntityId.class));
|
when(rel2.getFrom()).thenReturn(mock(EntityId.class));
|
||||||
|
|
||||||
|
|||||||
@ -28,9 +28,11 @@ import org.thingsboard.server.common.data.EntityType;
|
|||||||
import org.thingsboard.server.common.data.id.AssetId;
|
import org.thingsboard.server.common.data.id.AssetId;
|
||||||
import org.thingsboard.server.common.data.id.DeviceId;
|
import org.thingsboard.server.common.data.id.DeviceId;
|
||||||
import org.thingsboard.server.common.data.relation.EntityRelation;
|
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||||
|
import org.thingsboard.server.common.data.relation.EntityRelationPathQuery;
|
||||||
import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
|
import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
|
||||||
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
|
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
|
||||||
import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter;
|
import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter;
|
||||||
|
import org.thingsboard.server.common.data.relation.RelationPathLevel;
|
||||||
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
||||||
import org.thingsboard.server.common.data.relation.RelationsSearchParameters;
|
import org.thingsboard.server.common.data.relation.RelationsSearchParameters;
|
||||||
import org.thingsboard.server.dao.exception.DataValidationException;
|
import org.thingsboard.server.dao.exception.DataValidationException;
|
||||||
@ -42,6 +44,8 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@DaoSqlTest
|
@DaoSqlTest
|
||||||
public class RelationServiceTest extends AbstractServiceTest {
|
public class RelationServiceTest extends AbstractServiceTest {
|
||||||
|
|
||||||
@ -348,14 +352,14 @@ public class RelationServiceTest extends AbstractServiceTest {
|
|||||||
query.setFilters(Collections.singletonList(new RelationEntityTypeFilter(EntityRelation.CONTAINS_TYPE, Collections.singletonList(EntityType.ASSET))));
|
query.setFilters(Collections.singletonList(new RelationEntityTypeFilter(EntityRelation.CONTAINS_TYPE, Collections.singletonList(EntityType.ASSET))));
|
||||||
List<EntityRelation> relations = relationService.findByQuery(SYSTEM_TENANT_ID, query).get();
|
List<EntityRelation> relations = relationService.findByQuery(SYSTEM_TENANT_ID, query).get();
|
||||||
Assert.assertEquals(expected.size(), relations.size());
|
Assert.assertEquals(expected.size(), relations.size());
|
||||||
for(EntityRelation r : expected){
|
for (EntityRelation r : expected) {
|
||||||
Assert.assertTrue(relations.contains(r));
|
Assert.assertTrue(relations.contains(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Test from cache
|
//Test from cache
|
||||||
relations = relationService.findByQuery(SYSTEM_TENANT_ID, query).get();
|
relations = relationService.findByQuery(SYSTEM_TENANT_ID, query).get();
|
||||||
Assert.assertEquals(expected.size(), relations.size());
|
Assert.assertEquals(expected.size(), relations.size());
|
||||||
for(EntityRelation r : expected){
|
for (EntityRelation r : expected) {
|
||||||
Assert.assertTrue(relations.contains(r));
|
Assert.assertTrue(relations.contains(r));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -623,6 +627,51 @@ public class RelationServiceTest extends AbstractServiceTest {
|
|||||||
Assert.assertTrue(relations.contains(relationF));
|
Assert.assertTrue(relations.contains(relationF));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindByPathQuery() throws Exception {
|
||||||
|
/*
|
||||||
|
A
|
||||||
|
└──[firstLevel, TO]→ B
|
||||||
|
└──[secondLevel, TO]→ C
|
||||||
|
├──[thirdLevel, FROM]→ D
|
||||||
|
├──[thirdLevel, FROM]→ E
|
||||||
|
└──[thirdLevel, FROM]→ F
|
||||||
|
*/
|
||||||
|
// rootEntity
|
||||||
|
AssetId assetA = new AssetId(Uuids.timeBased());
|
||||||
|
// firstLevelEntity
|
||||||
|
AssetId assetB = new AssetId(Uuids.timeBased());
|
||||||
|
// secondLevelEntity
|
||||||
|
AssetId assetC = new AssetId(Uuids.timeBased());
|
||||||
|
// thirdLevelEntities
|
||||||
|
AssetId assetD = new AssetId(Uuids.timeBased());
|
||||||
|
AssetId assetE = new AssetId(Uuids.timeBased());
|
||||||
|
AssetId assetF = new AssetId(Uuids.timeBased());
|
||||||
|
|
||||||
|
EntityRelation firstLevelRelation = new EntityRelation(assetB, assetA, "firstLevel");
|
||||||
|
EntityRelation secondLevelRelation = new EntityRelation(assetC, assetB, "secondLevel");
|
||||||
|
EntityRelation thirdLevelRelation1 = new EntityRelation(assetC, assetD, "thirdLevel");
|
||||||
|
EntityRelation thirdLevelRelation2 = new EntityRelation(assetC, assetE, "thirdLevel");
|
||||||
|
EntityRelation thirdLevelRelation3 = new EntityRelation(assetC, assetF, "thirdLevel");
|
||||||
|
|
||||||
|
firstLevelRelation = saveRelation(firstLevelRelation);
|
||||||
|
secondLevelRelation = saveRelation(secondLevelRelation);
|
||||||
|
thirdLevelRelation1 = saveRelation(thirdLevelRelation1);
|
||||||
|
thirdLevelRelation2 = saveRelation(thirdLevelRelation2);
|
||||||
|
thirdLevelRelation3 = saveRelation(thirdLevelRelation3);
|
||||||
|
|
||||||
|
List<EntityRelation> expectedRelations = List.of(thirdLevelRelation1, thirdLevelRelation2, thirdLevelRelation3);
|
||||||
|
|
||||||
|
EntityRelationPathQuery relationPathQuery = new EntityRelationPathQuery(assetA, List.of(
|
||||||
|
new RelationPathLevel(EntitySearchDirection.TO, "firstLevel"),
|
||||||
|
new RelationPathLevel(EntitySearchDirection.TO, "secondLevel"),
|
||||||
|
new RelationPathLevel(EntitySearchDirection.FROM, "thirdLevel")
|
||||||
|
));
|
||||||
|
List<EntityRelation> entityRelations = relationService.findByRelationPathQueryAsync(tenantId, relationPathQuery).get();
|
||||||
|
|
||||||
|
assertThat(expectedRelations).containsExactlyInAnyOrderElementsOf(entityRelations);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFindByQueryLargeHierarchyFetchAllWithUnlimLvl() throws Exception {
|
public void testFindByQueryLargeHierarchyFetchAllWithUnlimLvl() throws Exception {
|
||||||
AssetId rootAsset = new AssetId(Uuids.timeBased());
|
AssetId rootAsset = new AssetId(Uuids.timeBased());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user