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.fasterxml.jackson.core.type.TypeReference;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.springframework.boot.test.mock.mockito.SpyBean;
 | 
			
		||||
import org.springframework.test.web.servlet.ResultActions;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
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.GoogleAiGeminiProviderConfig;
 | 
			
		||||
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.page.PageData;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageLink;
 | 
			
		||||
import org.thingsboard.server.common.data.page.SortOrder;
 | 
			
		||||
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.hamcrest.Matchers.equalTo;
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
@DaoSqlTest
 | 
			
		||||
public class AiModelControllerTest extends AbstractControllerTest {
 | 
			
		||||
 | 
			
		||||
    @SpyBean
 | 
			
		||||
    private EntitiesVersionControlService versionControlService;
 | 
			
		||||
 | 
			
		||||
    @SpyBean
 | 
			
		||||
    private TbLogEntityActionService logEntityActionService;
 | 
			
		||||
 | 
			
		||||
    /* --- Save API tests --- */
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
@ -106,29 +88,12 @@ public class AiModelControllerTest extends AbstractControllerTest {
 | 
			
		||||
        assertThat(savedModel.getId()).isNotNull();
 | 
			
		||||
        assertThat(savedModel.getUuidId()).isNotNull().isNotEqualTo(EntityId.NULL_UUID);
 | 
			
		||||
        assertThat(savedModel.getId().getEntityType()).isEqualTo(EntityType.AI_MODEL);
 | 
			
		||||
 | 
			
		||||
        assertThat(savedModel.getCreatedTime()).isPositive();
 | 
			
		||||
        assertThat(savedModel.getVersion()).isEqualTo(1);
 | 
			
		||||
 | 
			
		||||
        assertThat(savedModel.getTenantId()).isEqualTo(tenantId);
 | 
			
		||||
        assertThat(savedModel.getName()).isEqualTo("Test model");
 | 
			
		||||
        assertThat(savedModel.getConfiguration()).isEqualTo(model.getConfiguration());
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
@ -160,26 +125,12 @@ public class AiModelControllerTest extends AbstractControllerTest {
 | 
			
		||||
 | 
			
		||||
        // verify returned object
 | 
			
		||||
        assertThat(updatedModel.getId()).isEqualTo(model.getId());
 | 
			
		||||
 | 
			
		||||
        assertThat(updatedModel.getCreatedTime()).isEqualTo(model.getCreatedTime());
 | 
			
		||||
        assertThat(updatedModel.getVersion()).isEqualTo(2);
 | 
			
		||||
 | 
			
		||||
        assertThat(updatedModel.getTenantId()).isEqualTo(tenantId);
 | 
			
		||||
        assertThat(updatedModel.getName()).isEqualTo("Test model updated");
 | 
			
		||||
        assertThat(updatedModel.getConfiguration()).isEqualTo(newModelConfig);
 | 
			
		||||
 | 
			
		||||
        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 --- */
 | 
			
		||||
@ -284,6 +235,32 @@ public class AiModelControllerTest extends AbstractControllerTest {
 | 
			
		||||
        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
 | 
			
		||||
    public void getAiModels_testTextSearch() throws Exception {
 | 
			
		||||
        // GIVEN
 | 
			
		||||
@ -595,16 +572,6 @@ public class AiModelControllerTest extends AbstractControllerTest {
 | 
			
		||||
        // THEN
 | 
			
		||||
        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
 | 
			
		||||
        doGet("/api/ai/model/" + model.getId())
 | 
			
		||||
                .andExpect(status().isNotFound())
 | 
			
		||||
@ -623,16 +590,6 @@ public class AiModelControllerTest extends AbstractControllerTest {
 | 
			
		||||
 | 
			
		||||
        // THEN
 | 
			
		||||
        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) {
 | 
			
		||||
 | 
			
		||||
@ -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