/* * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose. * Your use of it is subject to your agreement with Google. */ package com.example.service.conversation; import com.example.dto.dialogflow.base.DetectIntentRequestDTO; import com.example.dto.dialogflow.base.DetectIntentResponseDTO; import com.example.dto.dialogflow.conversation.*; import com.example.dto.dialogflow.notification.NotificationDTO; import com.example.mapper.conversation.ConversationEntryMapper; import com.example.mapper.conversation.ExternalConvRequestMapper; import com.example.mapper.messagefilter.ConversationContextMapper; import com.example.mapper.messagefilter.NotificationContextMapper; import com.example.service.base.DialogflowClientService; import com.example.service.base.MessageEntryFilter; import com.example.service.base.NotificationContextResolver; import com.example.service.llm.LlmResponseTunerService; import com.example.service.notification.MemoryStoreNotificationService; import com.example.service.quickreplies.QuickRepliesManagerService; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import java.time.Instant; import java.util.Collections; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) public class ConversationManagerServiceTest { @Mock private ExternalConvRequestMapper externalRequestToDialogflowMapper; @Mock private DialogflowClientService dialogflowServiceClient; @Mock private FirestoreConversationService firestoreConversationService; @Mock private MemoryStoreConversationService memoryStoreConversationService; @Mock private QuickRepliesManagerService quickRepliesManagerService; @Mock private MessageEntryFilter messageEntryFilter; @Mock private MemoryStoreNotificationService memoryStoreNotificationService; @Mock private NotificationContextMapper notificationContextMapper; @Mock private ConversationContextMapper conversationContextMapper; @Mock private DataLossPrevention dataLossPrevention; @Mock private NotificationContextResolver notificationContextResolver; @Mock private LlmResponseTunerService llmResponseTunerService; @Mock private ConversationEntryMapper conversationEntryMapper; @InjectMocks private ConversationManagerService conversationManagerService; @Test void startNotificationConversation_shouldSaveResolvedContextAndReturnIt() { // Given String userId = "test-user"; String userPhoneNumber = "1234567890"; String userMessageText = "test message"; String sessionId = "test-session"; String resolvedContext = "resolved context"; ConversationContext context = new ConversationContext(userId, null, userMessageText, userPhoneNumber); DetectIntentRequestDTO request = new DetectIntentRequestDTO(null, null); NotificationDTO notification = new NotificationDTO("1", "1234567890", Instant.now(), "test text", "test_event", "es", Collections.emptyMap(), "active"); ConversationSessionDTO session = ConversationSessionDTO.create(sessionId, userId, userPhoneNumber); when(memoryStoreConversationService.getSessionByTelefono(userPhoneNumber)).thenReturn(Mono.just(session)); when(memoryStoreConversationService.getMessages(anyString())).thenReturn(Flux.empty()); when(conversationContextMapper.toTextFromMessages(any())).thenReturn("history"); when(notificationContextMapper.toText(notification)).thenReturn("notification text"); when(notificationContextResolver.resolveContext(anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), anyString())) .thenReturn(resolvedContext); when(llmResponseTunerService.setValue(anyString(), anyString())).thenReturn(Mono.empty()); when(memoryStoreConversationService.saveSession(any(ConversationSessionDTO.class))).thenReturn(Mono.empty()); when(memoryStoreConversationService.saveMessage(anyString(), any(ConversationMessageDTO.class))).thenReturn(Mono.empty()); when(firestoreConversationService.saveSession(any(ConversationSessionDTO.class))).thenReturn(Mono.empty()); when(firestoreConversationService.saveMessage(anyString(), any(ConversationMessageDTO.class))).thenReturn(Mono.empty()); when(conversationEntryMapper.toConversationMessageDTO(any(ConversationEntryDTO.class))).thenReturn(new ConversationMessageDTO(MessageType.USER, Instant.now(), "text", null, null)); when(dialogflowServiceClient.detectIntent(anyString(), any(DetectIntentRequestDTO.class))).thenReturn(Mono.just(new DetectIntentResponseDTO(sessionId, new QueryResultDTO(resolvedContext, null), null))); // When Mono result = conversationManagerService.startNotificationConversation(context, request, notification); // Then StepVerifier.create(result) .expectNextMatches(response -> response.queryResult().responseText().equals(resolvedContext)) .verifyComplete(); } }