AI rule node: add tests for audit logs and rule engine lifecycle messages
This commit is contained in:
parent
7bb5347fbe
commit
8dd5a4e7cd
@ -18,7 +18,6 @@ package org.thingsboard.server.controller;
|
|||||||
import com.datastax.oss.driver.api.core.uuid.Uuids;
|
import com.datastax.oss.driver.api.core.uuid.Uuids;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
|
||||||
import org.springframework.test.web.servlet.ResultActions;
|
import org.springframework.test.web.servlet.ResultActions;
|
||||||
import org.thingsboard.server.common.data.EntityType;
|
import org.thingsboard.server.common.data.EntityType;
|
||||||
import org.thingsboard.server.common.data.ai.AiModel;
|
import org.thingsboard.server.common.data.ai.AiModel;
|
||||||
@ -28,38 +27,21 @@ import org.thingsboard.server.common.data.ai.model.chat.OpenAiChatModelConfig;
|
|||||||
import org.thingsboard.server.common.data.ai.provider.AnthropicProviderConfig;
|
import org.thingsboard.server.common.data.ai.provider.AnthropicProviderConfig;
|
||||||
import org.thingsboard.server.common.data.ai.provider.GoogleAiGeminiProviderConfig;
|
import org.thingsboard.server.common.data.ai.provider.GoogleAiGeminiProviderConfig;
|
||||||
import org.thingsboard.server.common.data.ai.provider.OpenAiProviderConfig;
|
import org.thingsboard.server.common.data.ai.provider.OpenAiProviderConfig;
|
||||||
import org.thingsboard.server.common.data.audit.ActionType;
|
|
||||||
import org.thingsboard.server.common.data.id.AiModelId;
|
import org.thingsboard.server.common.data.id.AiModelId;
|
||||||
import org.thingsboard.server.common.data.id.EntityId;
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
import org.thingsboard.server.common.data.page.PageData;
|
import org.thingsboard.server.common.data.page.PageData;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
import org.thingsboard.server.common.data.page.SortOrder;
|
import org.thingsboard.server.common.data.page.SortOrder;
|
||||||
import org.thingsboard.server.dao.service.DaoSqlTest;
|
import org.thingsboard.server.dao.service.DaoSqlTest;
|
||||||
import org.thingsboard.server.service.entitiy.TbLogEntityActionService;
|
|
||||||
import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.argThat;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.BDDMockito.then;
|
|
||||||
import static org.mockito.Mockito.never;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
@DaoSqlTest
|
@DaoSqlTest
|
||||||
public class AiModelControllerTest extends AbstractControllerTest {
|
public class AiModelControllerTest extends AbstractControllerTest {
|
||||||
|
|
||||||
@SpyBean
|
|
||||||
private EntitiesVersionControlService versionControlService;
|
|
||||||
|
|
||||||
@SpyBean
|
|
||||||
private TbLogEntityActionService logEntityActionService;
|
|
||||||
|
|
||||||
/* --- Save API tests --- */
|
/* --- Save API tests --- */
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -106,29 +88,12 @@ public class AiModelControllerTest extends AbstractControllerTest {
|
|||||||
assertThat(savedModel.getId()).isNotNull();
|
assertThat(savedModel.getId()).isNotNull();
|
||||||
assertThat(savedModel.getUuidId()).isNotNull().isNotEqualTo(EntityId.NULL_UUID);
|
assertThat(savedModel.getUuidId()).isNotNull().isNotEqualTo(EntityId.NULL_UUID);
|
||||||
assertThat(savedModel.getId().getEntityType()).isEqualTo(EntityType.AI_MODEL);
|
assertThat(savedModel.getId().getEntityType()).isEqualTo(EntityType.AI_MODEL);
|
||||||
|
|
||||||
assertThat(savedModel.getCreatedTime()).isPositive();
|
assertThat(savedModel.getCreatedTime()).isPositive();
|
||||||
assertThat(savedModel.getVersion()).isEqualTo(1);
|
assertThat(savedModel.getVersion()).isEqualTo(1);
|
||||||
|
|
||||||
assertThat(savedModel.getTenantId()).isEqualTo(tenantId);
|
assertThat(savedModel.getTenantId()).isEqualTo(tenantId);
|
||||||
assertThat(savedModel.getName()).isEqualTo("Test model");
|
assertThat(savedModel.getName()).isEqualTo("Test model");
|
||||||
assertThat(savedModel.getConfiguration()).isEqualTo(model.getConfiguration());
|
assertThat(savedModel.getConfiguration()).isEqualTo(model.getConfiguration());
|
||||||
|
|
||||||
assertThat(savedModel.getExternalId()).isNull();
|
assertThat(savedModel.getExternalId()).isNull();
|
||||||
|
|
||||||
// verify auto-commit
|
|
||||||
then(versionControlService).should().autoCommit(
|
|
||||||
argThat(actualUser -> Objects.equals(actualUser.getId(), tenantAdminUser.getId())), eq(savedModel.getId())
|
|
||||||
);
|
|
||||||
|
|
||||||
// verify a rule engine message was sent, and an audit log was created
|
|
||||||
then(logEntityActionService).should().logEntityAction(
|
|
||||||
eq(tenantId),
|
|
||||||
eq(savedModel.getId()),
|
|
||||||
eq(savedModel),
|
|
||||||
eq(ActionType.ADDED),
|
|
||||||
argThat(actualUser -> Objects.equals(actualUser.getId(), tenantAdminUser.getId()))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -160,26 +125,12 @@ public class AiModelControllerTest extends AbstractControllerTest {
|
|||||||
|
|
||||||
// verify returned object
|
// verify returned object
|
||||||
assertThat(updatedModel.getId()).isEqualTo(model.getId());
|
assertThat(updatedModel.getId()).isEqualTo(model.getId());
|
||||||
|
|
||||||
assertThat(updatedModel.getCreatedTime()).isEqualTo(model.getCreatedTime());
|
assertThat(updatedModel.getCreatedTime()).isEqualTo(model.getCreatedTime());
|
||||||
assertThat(updatedModel.getVersion()).isEqualTo(2);
|
assertThat(updatedModel.getVersion()).isEqualTo(2);
|
||||||
|
|
||||||
assertThat(updatedModel.getTenantId()).isEqualTo(tenantId);
|
assertThat(updatedModel.getTenantId()).isEqualTo(tenantId);
|
||||||
assertThat(updatedModel.getName()).isEqualTo("Test model updated");
|
assertThat(updatedModel.getName()).isEqualTo("Test model updated");
|
||||||
assertThat(updatedModel.getConfiguration()).isEqualTo(newModelConfig);
|
assertThat(updatedModel.getConfiguration()).isEqualTo(newModelConfig);
|
||||||
|
|
||||||
assertThat(updatedModel.getExternalId()).isNull();
|
assertThat(updatedModel.getExternalId()).isNull();
|
||||||
|
|
||||||
// verify auto-commit
|
|
||||||
then(versionControlService).should(times(2)).autoCommit(
|
|
||||||
argThat(actualUser -> Objects.equals(actualUser.getId(), tenantAdminUser.getId())), eq(updatedModel.getId())
|
|
||||||
);
|
|
||||||
|
|
||||||
// verify a rule engine message was sent, and an audit log was created
|
|
||||||
then(logEntityActionService).should().logEntityAction(
|
|
||||||
eq(tenantId), eq(updatedModel.getId()), eq(updatedModel), eq(ActionType.UPDATED),
|
|
||||||
argThat(actualUser -> Objects.equals(actualUser.getId(), tenantAdminUser.getId()))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- Get by ID API tests --- */
|
/* --- Get by ID API tests --- */
|
||||||
@ -284,6 +235,32 @@ public class AiModelControllerTest extends AbstractControllerTest {
|
|||||||
assertThat(result.hasNext()).isTrue();
|
assertThat(result.hasNext()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getAiModels_testSearchAndSortAppliedBeforePagination() throws Exception {
|
||||||
|
// GIVEN
|
||||||
|
loginTenantAdmin();
|
||||||
|
|
||||||
|
// Create 5 models: 3 with "Alpha" in name, 2 with "Beta" in name
|
||||||
|
var alpha1 = doPost("/api/ai/model", constructValidOpenAiModel("Alpha Model 1"), AiModel.class);
|
||||||
|
var beta1 = doPost("/api/ai/model", constructValidOpenAiModel("Beta Model 1"), AiModel.class);
|
||||||
|
var alpha2 = doPost("/api/ai/model", constructValidOpenAiModel("Alpha Model 2"), AiModel.class);
|
||||||
|
var beta2 = doPost("/api/ai/model", constructValidOpenAiModel("Beta Model 2"), AiModel.class);
|
||||||
|
var alpha3 = doPost("/api/ai/model", constructValidOpenAiModel("Alpha Model 3"), AiModel.class);
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
// Search for "Alpha", sort by name DESC, get the first page with size 2
|
||||||
|
PageData<AiModel> result = doGetTypedWithPageLink("/api/ai/model?",
|
||||||
|
new TypeReference<>() {},
|
||||||
|
new PageLink(2, 0, "Alpha", SortOrder.of("name", SortOrder.Direction.DESC)));
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
// Should find only 3 "Alpha" models, sort them DESC (3, 2, 1), then return first 2
|
||||||
|
assertThat(result.getData()).containsExactly(alpha3, alpha2);
|
||||||
|
assertThat(result.getTotalPages()).isEqualTo(2); // One more "Alpha" model on the next page
|
||||||
|
assertThat(result.getTotalElements()).isEqualTo(3); // Only 3 models match "Alpha", not 5
|
||||||
|
assertThat(result.hasNext()).isTrue(); // One more "Alpha" model on the next page
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getAiModels_testTextSearch() throws Exception {
|
public void getAiModels_testTextSearch() throws Exception {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
@ -595,16 +572,6 @@ public class AiModelControllerTest extends AbstractControllerTest {
|
|||||||
// THEN
|
// THEN
|
||||||
assertThat(deleted).isTrue();
|
assertThat(deleted).isTrue();
|
||||||
|
|
||||||
// verify a rule engine message was sent, and an audit log was created
|
|
||||||
then(logEntityActionService).should().logEntityAction(
|
|
||||||
eq(tenantId),
|
|
||||||
eq(model.getId()),
|
|
||||||
eq(model),
|
|
||||||
eq(ActionType.DELETED),
|
|
||||||
argThat(actualUser -> Objects.equals(actualUser.getId(), tenantAdminUser.getId())),
|
|
||||||
eq(model.getId().toString())
|
|
||||||
);
|
|
||||||
|
|
||||||
// verify model cannot be found anymore
|
// verify model cannot be found anymore
|
||||||
doGet("/api/ai/model/" + model.getId())
|
doGet("/api/ai/model/" + model.getId())
|
||||||
.andExpect(status().isNotFound())
|
.andExpect(status().isNotFound())
|
||||||
@ -623,16 +590,6 @@ public class AiModelControllerTest extends AbstractControllerTest {
|
|||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
assertThat(deleted).isFalse();
|
assertThat(deleted).isFalse();
|
||||||
|
|
||||||
// verify a rule engine message was not sent, and an audit log was not created
|
|
||||||
then(logEntityActionService).should(never()).logEntityAction(
|
|
||||||
eq(tenantId),
|
|
||||||
eq(nonexistentModelId),
|
|
||||||
any(AiModel.class),
|
|
||||||
eq(ActionType.DELETED),
|
|
||||||
argThat(actualUser -> Objects.equals(actualUser.getId(), tenantAdminUser.getId())),
|
|
||||||
eq(nonexistentModelId.toString())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AiModel constructValidOpenAiModel(String name) {
|
private AiModel constructValidOpenAiModel(String name) {
|
||||||
|
|||||||
@ -0,0 +1,268 @@
|
|||||||
|
/**
|
||||||
|
* 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.service.entitiy.ai;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Spy;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
import org.thingsboard.server.common.data.User;
|
||||||
|
import org.thingsboard.server.common.data.ai.AiModel;
|
||||||
|
import org.thingsboard.server.common.data.ai.model.AiModelConfig;
|
||||||
|
import org.thingsboard.server.common.data.ai.model.chat.OpenAiChatModelConfig;
|
||||||
|
import org.thingsboard.server.common.data.ai.provider.OpenAiProviderConfig;
|
||||||
|
import org.thingsboard.server.common.data.audit.ActionType;
|
||||||
|
import org.thingsboard.server.common.data.id.AiModelId;
|
||||||
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
|
import org.thingsboard.server.dao.ai.AiModelService;
|
||||||
|
import org.thingsboard.server.service.entitiy.TbLogEntityActionService;
|
||||||
|
import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.mockito.BDDMockito.then;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class DefaultTbAiModelServiceTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
EntitiesVersionControlService vcServiceMock;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
AiModelService aiModelServiceMock;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
TbLogEntityActionService logEntityActionServiceMock;
|
||||||
|
|
||||||
|
@Spy
|
||||||
|
@InjectMocks
|
||||||
|
DefaultTbAiModelService service;
|
||||||
|
|
||||||
|
TenantId tenantId = TenantId.fromUUID(UUID.randomUUID());
|
||||||
|
|
||||||
|
User user;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
user = new User();
|
||||||
|
user.setTenantId(tenantId);
|
||||||
|
|
||||||
|
service = new DefaultTbAiModelService(aiModelServiceMock);
|
||||||
|
ReflectionTestUtils.setField(service, "vcService", vcServiceMock);
|
||||||
|
ReflectionTestUtils.setField(service, "logEntityActionService", logEntityActionServiceMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void save_whenCreatingNewModel_shouldAutoCommitAndLogAddedActionAndUseTenantIdFromUser() {
|
||||||
|
// GIVEN
|
||||||
|
var modelToSave = AiModel.builder()
|
||||||
|
.name("Model to save")
|
||||||
|
.configuration(constructValidOpenAiModelConfig())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
var savedModel = new AiModel(modelToSave);
|
||||||
|
savedModel.setId(new AiModelId(UUID.randomUUID()));
|
||||||
|
savedModel.setTenantId(user.getTenantId());
|
||||||
|
savedModel.setVersion(1L);
|
||||||
|
savedModel.setCreatedTime(System.currentTimeMillis());
|
||||||
|
|
||||||
|
given(aiModelServiceMock.save(modelToSave)).willReturn(savedModel);
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
AiModel result = service.save(modelToSave, user);
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
assertThat(result).isEqualTo(savedModel);
|
||||||
|
|
||||||
|
then(aiModelServiceMock).should().save(modelToSave);
|
||||||
|
then(vcServiceMock).should().autoCommit(user, savedModel.getId());
|
||||||
|
then(logEntityActionServiceMock).should().logEntityAction(tenantId, savedModel.getId(), savedModel, ActionType.ADDED, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void save_whenUpdatingExistingModel_shouldAutoCommitAndLogUpdatedAction() {
|
||||||
|
// GIVEN
|
||||||
|
var modelToUpdate = AiModel.builder()
|
||||||
|
.tenantId(tenantId)
|
||||||
|
.version(1L)
|
||||||
|
.name("Model to update")
|
||||||
|
.configuration(constructValidOpenAiModelConfig())
|
||||||
|
.build();
|
||||||
|
modelToUpdate.setId(new AiModelId(UUID.randomUUID()));
|
||||||
|
modelToUpdate.setCreatedTime(System.currentTimeMillis());
|
||||||
|
|
||||||
|
var updatedModel = new AiModel(modelToUpdate);
|
||||||
|
updatedModel.setVersion(2L);
|
||||||
|
updatedModel.setName("Updated model");
|
||||||
|
|
||||||
|
given(aiModelServiceMock.save(modelToUpdate)).willReturn(updatedModel);
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
AiModel result = service.save(modelToUpdate, user);
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
assertThat(result).isEqualTo(updatedModel);
|
||||||
|
|
||||||
|
then(aiModelServiceMock).should().save(modelToUpdate);
|
||||||
|
then(vcServiceMock).should().autoCommit(user, updatedModel.getId());
|
||||||
|
then(logEntityActionServiceMock).should().logEntityAction(tenantId, updatedModel.getId(), updatedModel, ActionType.UPDATED, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void save_whenCreatingNewModelThrowsException_shouldUseEmptyIdAndLogError() {
|
||||||
|
// GIVEN
|
||||||
|
var modelToSave = AiModel.builder()
|
||||||
|
.tenantId(tenantId)
|
||||||
|
.name("Model to save")
|
||||||
|
.configuration(constructValidOpenAiModelConfig())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
var exception = new RuntimeException("Failed to save");
|
||||||
|
|
||||||
|
given(aiModelServiceMock.save(modelToSave)).willThrow(exception);
|
||||||
|
|
||||||
|
// WHEN-THEN
|
||||||
|
assertThatThrownBy(() -> service.save(modelToSave, user))
|
||||||
|
.isInstanceOf(RuntimeException.class)
|
||||||
|
.hasMessageContaining("Failed to save");
|
||||||
|
|
||||||
|
then(aiModelServiceMock).should().save(modelToSave);
|
||||||
|
then(vcServiceMock).should(never()).autoCommit(any(), any());
|
||||||
|
then(logEntityActionServiceMock).should().logEntityAction(tenantId, new AiModelId(EntityId.NULL_UUID), modelToSave, ActionType.ADDED, user, exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void save_whenUpdatingExistingModelThrowsException_shouldUseExistingModelIdAndLogError() {
|
||||||
|
// GIVEN
|
||||||
|
var modelToUpdate = AiModel.builder()
|
||||||
|
.tenantId(tenantId)
|
||||||
|
.version(1L)
|
||||||
|
.name("Model to update")
|
||||||
|
.configuration(constructValidOpenAiModelConfig())
|
||||||
|
.build();
|
||||||
|
modelToUpdate.setId(new AiModelId(UUID.randomUUID()));
|
||||||
|
modelToUpdate.setCreatedTime(System.currentTimeMillis());
|
||||||
|
|
||||||
|
var exception = new RuntimeException("Failed to save");
|
||||||
|
|
||||||
|
given(aiModelServiceMock.save(modelToUpdate)).willThrow(exception);
|
||||||
|
|
||||||
|
// WHEN-THEN
|
||||||
|
assertThatThrownBy(() -> service.save(modelToUpdate, user))
|
||||||
|
.isInstanceOf(RuntimeException.class)
|
||||||
|
.hasMessageContaining("Failed to save");
|
||||||
|
|
||||||
|
then(aiModelServiceMock).should().save(modelToUpdate);
|
||||||
|
then(vcServiceMock).should(never()).autoCommit(any(), any());
|
||||||
|
then(logEntityActionServiceMock).should().logEntityAction(tenantId, modelToUpdate.getId(), modelToUpdate, ActionType.UPDATED, user, exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void delete_whenDeleteSuccessful_shouldLogDeletedAction() {
|
||||||
|
// GIVEN
|
||||||
|
var modelToDelete = AiModel.builder()
|
||||||
|
.tenantId(tenantId)
|
||||||
|
.version(1L)
|
||||||
|
.name("Model to delete")
|
||||||
|
.configuration(constructValidOpenAiModelConfig())
|
||||||
|
.build();
|
||||||
|
modelToDelete.setId(new AiModelId(UUID.randomUUID()));
|
||||||
|
modelToDelete.setCreatedTime(System.currentTimeMillis());
|
||||||
|
|
||||||
|
given(aiModelServiceMock.deleteByTenantIdAndId(tenantId, modelToDelete.getId())).willReturn(true);
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
boolean result = service.delete(modelToDelete, user);
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
assertThat(result).isTrue();
|
||||||
|
then(aiModelServiceMock).should().deleteByTenantIdAndId(tenantId, modelToDelete.getId());
|
||||||
|
then(logEntityActionServiceMock).should().logEntityAction(tenantId, modelToDelete.getId(), modelToDelete, ActionType.DELETED, user, modelToDelete.getId().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void delete_whenDeleteReturnsFalse_shouldNotLogAction() {
|
||||||
|
// GIVEN
|
||||||
|
var modelToDelete = AiModel.builder()
|
||||||
|
.tenantId(tenantId)
|
||||||
|
.version(1L)
|
||||||
|
.name("Model to delete")
|
||||||
|
.configuration(constructValidOpenAiModelConfig())
|
||||||
|
.build();
|
||||||
|
modelToDelete.setId(new AiModelId(UUID.randomUUID()));
|
||||||
|
modelToDelete.setCreatedTime(System.currentTimeMillis());
|
||||||
|
|
||||||
|
given(aiModelServiceMock.deleteByTenantIdAndId(tenantId, modelToDelete.getId())).willReturn(false);
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
boolean result = service.delete(modelToDelete, user);
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
assertThat(result).isFalse();
|
||||||
|
then(aiModelServiceMock).should().deleteByTenantIdAndId(tenantId, modelToDelete.getId());
|
||||||
|
then(logEntityActionServiceMock).should(never()).logEntityAction(tenantId, modelToDelete.getId(), modelToDelete, ActionType.DELETED, user, modelToDelete.getId().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void delete_whenDeleteThrowsException_shouldLogError() {
|
||||||
|
// GIVEN
|
||||||
|
var modelToDelete = AiModel.builder()
|
||||||
|
.tenantId(tenantId)
|
||||||
|
.version(1L)
|
||||||
|
.name("Model to delete")
|
||||||
|
.configuration(constructValidOpenAiModelConfig())
|
||||||
|
.build();
|
||||||
|
modelToDelete.setId(new AiModelId(UUID.randomUUID()));
|
||||||
|
modelToDelete.setCreatedTime(System.currentTimeMillis());
|
||||||
|
|
||||||
|
var exception = new RuntimeException("Failed to delete");
|
||||||
|
|
||||||
|
given(aiModelServiceMock.deleteByTenantIdAndId(tenantId, modelToDelete.getId())).willThrow(exception);
|
||||||
|
|
||||||
|
// WHEN-THEN
|
||||||
|
assertThatThrownBy(() -> service.delete(modelToDelete, user))
|
||||||
|
.isInstanceOf(RuntimeException.class)
|
||||||
|
.hasMessageContaining("Failed to delete");
|
||||||
|
|
||||||
|
then(aiModelServiceMock).should().deleteByTenantIdAndId(tenantId, modelToDelete.getId());
|
||||||
|
then(logEntityActionServiceMock).should().logEntityAction(tenantId, modelToDelete.getId(), modelToDelete, ActionType.DELETED, user, exception, modelToDelete.getId().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AiModelConfig constructValidOpenAiModelConfig() {
|
||||||
|
return OpenAiChatModelConfig.builder()
|
||||||
|
.providerConfig(new OpenAiProviderConfig("test-api-key"))
|
||||||
|
.modelId("gpt-4o")
|
||||||
|
.temperature(0.5)
|
||||||
|
.topP(0.3)
|
||||||
|
.frequencyPenalty(0.1)
|
||||||
|
.presencePenalty(0.2)
|
||||||
|
.maxOutputTokens(1000)
|
||||||
|
.timeoutSeconds(60)
|
||||||
|
.maxRetries(2)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user