Added test for RelationQueryDynamicSourceConfiguration class

This commit is contained in:
dshvaika 2025-08-13 13:19:02 +03:00
parent 44a9327a26
commit ad511e9355
2 changed files with 204 additions and 1 deletions

View File

@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.cf.configuration;
import lombok.Data;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
@ -50,7 +51,7 @@ public class RelationQueryDynamicSourceConfiguration implements CfArgumentDynami
if (direction == null) {
throw new IllegalArgumentException("Relation query dynamic source configuration direction must be specified!");
}
if (relationType == null) {
if (StringUtils.isBlank(relationType)) {
throw new IllegalArgumentException("Relation query dynamic source configuration relation type must be specified!");
}
}

View File

@ -0,0 +1,202 @@
/**
* 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.junit.jupiter.params.provider.ValueSource;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.thingsboard.server.common.data.EntityType;
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.RelationEntityTypeFilter;
import org.thingsboard.server.common.data.relation.RelationsSearchParameters;
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.when;
@ExtendWith(MockitoExtension.class)
public class RelationQueryDynamicSourceConfigurationTest {
@Mock
EntityId rootEntityId;
@Mock
EntityRelation rel1;
@Mock
EntityRelation rel2;
@Test
void typeShouldBeRelationQuery() {
var cfg = new RelationQueryDynamicSourceConfiguration();
assertThat(cfg.getType()).isEqualTo(CFArgumentDynamicSourceType.RELATION_QUERY);
}
@Test
void validateShouldThrowWhenMaxLevelGreaterThanTwo() {
var cfg = new RelationQueryDynamicSourceConfiguration();
cfg.setMaxLevel(3);
cfg.setDirection(EntitySearchDirection.FROM);
cfg.setRelationType(EntityRelation.CONTAINS_TYPE);
assertThatThrownBy(cfg::validate)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Relation query dynamic source configuration max relation level can't be greater than 2!");
}
@Test
void validateShouldThrowWhenDirectionIsNull() {
var cfg = new RelationQueryDynamicSourceConfiguration();
cfg.setMaxLevel(1);
cfg.setDirection(null);
cfg.setRelationType(EntityRelation.CONTAINS_TYPE);
assertThatThrownBy(cfg::validate)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Relation query dynamic source configuration direction must be specified!");
}
@ParameterizedTest
@ValueSource(strings = {" "})
@NullAndEmptySource
void validateShouldThrowWhenRelationTypeIsNull(String relationType) {
var cfg = new RelationQueryDynamicSourceConfiguration();
cfg.setMaxLevel(1);
cfg.setDirection(EntitySearchDirection.TO);
cfg.setRelationType(relationType);
assertThatThrownBy(cfg::validate)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Relation query dynamic source configuration relation type must be specified!");
}
@ParameterizedTest
@NullAndEmptySource
void isSimpleRelationTrueWhenLevelIsOneAndEntityTypesEmptyOrNull(List<EntityType> entityTypes) {
var cfg = new RelationQueryDynamicSourceConfiguration();
cfg.setMaxLevel(1);
cfg.setEntityTypes(entityTypes);
assertThat(cfg.isSimpleRelation()).isTrue();
}
@Test
void isSimpleRelationFalseWhenMaxLevelNotOne() {
var cfg = new RelationQueryDynamicSourceConfiguration();
cfg.setMaxLevel(2);
cfg.setEntityTypes(null);
assertThat(cfg.isSimpleRelation()).isFalse();
}
@Test
void isSimpleRelationFalseWhenEntityTypesProvided() {
var cfg = new RelationQueryDynamicSourceConfiguration();
cfg.setMaxLevel(1);
cfg.setEntityTypes(List.of(EntityType.DEVICE));
assertThat(cfg.isSimpleRelation()).isFalse();
}
@ParameterizedTest
@NullAndEmptySource
void toEntityRelationsQueryShouldThrowForSimpleRelation(List<EntityType> entityTypes) {
var cfg = new RelationQueryDynamicSourceConfiguration();
cfg.setMaxLevel(1);
cfg.setFetchLastLevelOnly(false);
cfg.setDirection(EntitySearchDirection.FROM);
cfg.setRelationType(EntityRelation.CONTAINS_TYPE);
cfg.setEntityTypes(entityTypes);
assertThatThrownBy(() -> cfg.toEntityRelationsQuery(rootEntityId))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Entity relations query can't be created for a simple relation!");
}
@Test
void toEntityRelationsQueryShouldBuildQueryForNonSimpleRelation() {
var cfg = new RelationQueryDynamicSourceConfiguration();
cfg.setMaxLevel(2);
cfg.setFetchLastLevelOnly(true);
cfg.setDirection(EntitySearchDirection.TO);
cfg.setRelationType(EntityRelation.MANAGES_TYPE);
cfg.setEntityTypes(List.of(EntityType.DEVICE, EntityType.ASSET));
var query = cfg.toEntityRelationsQuery(rootEntityId);
assertThat(query).isNotNull();
RelationsSearchParameters params = query.getParameters();
assertThat(params).isNotNull();
assertThat(params.getRootId()).isEqualTo(rootEntityId.getId());
assertThat(params.getDirection()).isEqualTo(EntitySearchDirection.TO);
assertThat(params.getMaxLevel()).isEqualTo(2);
assertThat(params.isFetchLastLevelOnly()).isTrue();
assertThat(query.getFilters()).hasSize(1);
assertThat(query.getFilters().get(0)).isInstanceOf(RelationEntityTypeFilter.class);
RelationEntityTypeFilter filter = query.getFilters().get(0);
assertThat(filter.getRelationType()).isEqualTo(EntityRelation.MANAGES_TYPE);
assertThat(filter.getEntityTypes()).containsExactly(EntityType.DEVICE, EntityType.ASSET);
}
@Test
void resolveEntityIdsFromDirectionFROMReturnsToIds() {
when(rel1.getTo()).thenReturn(mock(EntityId.class));
when(rel2.getTo()).thenReturn(mock(EntityId.class));
var cfg = new RelationQueryDynamicSourceConfiguration();
cfg.setDirection(EntitySearchDirection.FROM);
var out = cfg.resolveEntityIds(List.of(rel1, rel2));
assertThat(out).containsExactly(rel1.getTo(), rel2.getTo());
}
@Test
void resolveEntityIdsFromDirectionTOReturnsFromIds() {
when(rel1.getFrom()).thenReturn(mock(EntityId.class));
when(rel2.getFrom()).thenReturn(mock(EntityId.class));
var cfg = new RelationQueryDynamicSourceConfiguration();
cfg.setDirection(EntitySearchDirection.TO);
var out = cfg.resolveEntityIds(List.of(rel1, rel2));
assertThat(out).containsExactly(rel1.getFrom(), rel2.getFrom());
}
@Test
void validateShouldPassForValidConfig() {
var cfg = new RelationQueryDynamicSourceConfiguration();
cfg.setMaxLevel(2);
cfg.setFetchLastLevelOnly(false);
cfg.setDirection(EntitySearchDirection.FROM);
cfg.setRelationType(EntityRelation.CONTAINS_TYPE);
cfg.setEntityTypes(List.of(EntityType.DEVICE));
assertThatCode(cfg::validate).doesNotThrowAnyException();
}
}