This commit is contained in:
2026-02-19 17:50:14 +00:00
parent da95a64fb7
commit 6f629c53a6
171 changed files with 7281 additions and 1144 deletions

View File

@@ -0,0 +1,133 @@
package com.example.mapper.conversation;
import com.example.dto.dialogflow.base.DetectIntentRequestDTO;
import com.example.dto.dialogflow.conversation.QueryInputDTO;
import com.example.dto.dialogflow.conversation.QueryParamsDTO;
import com.example.dto.dialogflow.conversation.TextInputDTO;
import com.example.dto.dialogflow.notification.EventInputDTO;
import com.google.cloud.dialogflow.cx.v3.DetectIntentRequest;
import com.google.cloud.dialogflow.cx.v3.QueryInput;
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.junit.jupiter.MockitoExtension;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.Collections;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.*;
@ExtendWith(MockitoExtension.class)
class DialogflowRequestMapperTest {
@InjectMocks
private DialogflowRequestMapper dialogflowRequestMapper;
@BeforeEach
void setUp() {
ReflectionTestUtils.setField(dialogflowRequestMapper, "defaultLanguageCode", "es");
}
@Test
void mapToDetectIntentRequestBuilder_withTextInput_shouldMapCorrectly() {
// Given
TextInputDTO textInputDTO = new TextInputDTO("Hola");
QueryInputDTO queryInputDTO = new QueryInputDTO(textInputDTO, null, "es");
DetectIntentRequestDTO requestDTO = new DetectIntentRequestDTO(queryInputDTO, null);
// When
DetectIntentRequest.Builder builder = dialogflowRequestMapper.mapToDetectIntentRequestBuilder(requestDTO);
DetectIntentRequest request = builder.build();
// Then
assertNotNull(request);
assertTrue(request.hasQueryInput());
QueryInput queryInput = request.getQueryInput();
assertEquals("es", queryInput.getLanguageCode());
assertTrue(queryInput.hasText());
assertEquals("Hola", queryInput.getText().getText());
assertFalse(queryInput.hasEvent());
}
@Test
void mapToDetectIntentRequestBuilder_withEventInput_shouldMapCorrectly() {
// Given
EventInputDTO eventInputDTO = new EventInputDTO("welcome_event");
QueryInputDTO queryInputDTO = new QueryInputDTO(null, eventInputDTO, "es");
DetectIntentRequestDTO requestDTO = new DetectIntentRequestDTO(queryInputDTO, null);
// When
DetectIntentRequest.Builder builder = dialogflowRequestMapper.mapToDetectIntentRequestBuilder(requestDTO);
DetectIntentRequest request = builder.build();
// Then
assertNotNull(request);
assertTrue(request.hasQueryInput());
QueryInput queryInput = request.getQueryInput();
assertEquals("es", queryInput.getLanguageCode());
assertTrue(queryInput.hasEvent());
assertEquals("welcome_event", queryInput.getEvent().getEvent());
assertFalse(queryInput.hasText());
}
@Test
void mapToDetectIntentRequestBuilder_withNoInput_shouldThrowException() {
// Given
QueryInputDTO queryInputDTO = new QueryInputDTO(null, null, "es");
DetectIntentRequestDTO requestDTO = new DetectIntentRequestDTO(queryInputDTO, null);
// When & Then
assertThrows(IllegalArgumentException.class, () -> {
dialogflowRequestMapper.mapToDetectIntentRequestBuilder(requestDTO);
});
}
@Test
void mapToDetectIntentRequestBuilder_withParameters_shouldMapCorrectly() {
// Given
TextInputDTO textInputDTO = new TextInputDTO("Hola");
QueryInputDTO queryInputDTO = new QueryInputDTO(textInputDTO, null, "es");
Map<String, Object> parameters = Collections.singletonMap("param1", "value1");
QueryParamsDTO queryParamsDTO = new QueryParamsDTO(parameters);
DetectIntentRequestDTO requestDTO = new DetectIntentRequestDTO(queryInputDTO, queryParamsDTO);
// When
DetectIntentRequest.Builder builder = dialogflowRequestMapper.mapToDetectIntentRequestBuilder(requestDTO);
DetectIntentRequest request = builder.build();
// Then
assertNotNull(request);
assertTrue(request.hasQueryParams());
assertTrue(request.getQueryParams().hasParameters());
assertEquals("value1", request.getQueryParams().getParameters().getFieldsMap().get("param1").getStringValue());
}
@Test
void mapToDetectIntentRequestBuilder_withNullRequestDTO_shouldThrowException() {
// When & Then
assertThrows(NullPointerException.class, () -> {
dialogflowRequestMapper.mapToDetectIntentRequestBuilder(null);
});
}
@Test
void mapToDetectIntentRequestBuilder_withDefaultLanguageCode_shouldMapCorrectly() {
// Given
TextInputDTO textInputDTO = new TextInputDTO("Hola");
QueryInputDTO queryInputDTO = new QueryInputDTO(textInputDTO, null, null);
DetectIntentRequestDTO requestDTO = new DetectIntentRequestDTO(queryInputDTO, null);
// When
DetectIntentRequest.Builder builder = dialogflowRequestMapper.mapToDetectIntentRequestBuilder(requestDTO);
DetectIntentRequest request = builder.build();
// Then
assertNotNull(request);
assertTrue(request.hasQueryInput());
assertEquals("es", request.getQueryInput().getLanguageCode());
}
}

View File

@@ -0,0 +1,129 @@
package com.example.mapper.conversation;
import com.example.dto.dialogflow.base.DetectIntentResponseDTO;
import com.example.dto.dialogflow.conversation.QueryResultDTO;
import com.google.cloud.dialogflow.cx.v3.DetectIntentResponse;
import com.google.cloud.dialogflow.cx.v3.QueryResult;
import com.google.cloud.dialogflow.cx.v3.ResponseMessage;
import com.google.protobuf.Struct;
import com.google.protobuf.Value;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@ExtendWith(MockitoExtension.class)
class DialogflowResponseMapperTest {
@InjectMocks
private DialogflowResponseMapper dialogflowResponseMapper;
@Test
void mapFromDialogflowResponse_shouldMapCorrectly() {
// Given
ResponseMessage.Text text1 = ResponseMessage.Text.newBuilder()
.addAllText(Collections.singletonList("Hello")).build();
ResponseMessage message1 = ResponseMessage.newBuilder().setText(text1).build();
ResponseMessage.Text text2 = ResponseMessage.Text.newBuilder()
.addAllText(Collections.singletonList("World")).build();
ResponseMessage message2 = ResponseMessage.newBuilder().setText(text2).build();
Struct params = Struct.newBuilder()
.putFields("param1", Value.newBuilder().setStringValue("value1").build())
.putFields("param2", Value.newBuilder().setNumberValue(123).build())
.build();
QueryResult queryResult = QueryResult.newBuilder()
.addAllResponseMessages(Arrays.asList(message1, message2))
.setParameters(params)
.build();
DetectIntentResponse detectIntentResponse = DetectIntentResponse.newBuilder()
.setResponseId("test-response-id")
.setQueryResult(queryResult)
.build();
// When
DetectIntentResponseDTO responseDTO = dialogflowResponseMapper
.mapFromDialogflowResponse(detectIntentResponse, "test-session-id");
// Then
assertNotNull(responseDTO);
assertEquals("test-response-id", responseDTO.responseId());
QueryResultDTO queryResultDTO = responseDTO.queryResult();
assertNotNull(queryResultDTO);
assertEquals("Hello World", queryResultDTO.responseText());
Map<String, Object> parameters = queryResultDTO.parameters();
assertNotNull(parameters);
assertEquals(2, parameters.size());
assertEquals("value1", parameters.get("param1"));
assertEquals(123.0, parameters.get("param2"));
}
@Test
void mapFromDialogflowResponse_withNoMessages_shouldReturnEmptyFulfillmentText() {
// Given
QueryResult queryResult = QueryResult.newBuilder()
.build();
DetectIntentResponse detectIntentResponse = DetectIntentResponse.newBuilder()
.setResponseId("test-response-id")
.setQueryResult(queryResult)
.build();
// When
DetectIntentResponseDTO responseDTO = dialogflowResponseMapper
.mapFromDialogflowResponse(detectIntentResponse, "test-session-id");
// Then
assertNotNull(responseDTO);
assertEquals("test-response-id", responseDTO.responseId());
QueryResultDTO queryResultDTO = responseDTO.queryResult();
assertNotNull(queryResultDTO);
assertEquals("", queryResultDTO.responseText());
}
@Test
void mapFromDialogflowResponse_withNoParameters_shouldReturnEmptyMap() {
// Given
ResponseMessage.Text text = ResponseMessage.Text.newBuilder()
.addAllText(Collections.singletonList("Hello")).build();
ResponseMessage message = ResponseMessage.newBuilder().setText(text).build();
QueryResult queryResult = QueryResult.newBuilder()
.addResponseMessages(message)
.build();
DetectIntentResponse detectIntentResponse = DetectIntentResponse.newBuilder()
.setResponseId("test-response-id")
.setQueryResult(queryResult)
.build();
// When
DetectIntentResponseDTO responseDTO = dialogflowResponseMapper
.mapFromDialogflowResponse(detectIntentResponse, "test-session-id");
// Then
assertNotNull(responseDTO);
assertEquals("test-response-id", responseDTO.responseId());
QueryResultDTO queryResultDTO = responseDTO.queryResult();
assertNotNull(queryResultDTO);
assertEquals("Hello", queryResultDTO.responseText());
Map<String, Object> parameters = queryResultDTO.parameters();
assertNotNull(parameters);
assertEquals(0, parameters.size());
}
}

View File

@@ -0,0 +1,148 @@
package com.example.mapper.messagefilter;
import com.example.dto.dialogflow.conversation.ConversationMessageDTO;
import com.example.dto.dialogflow.conversation.MessageType;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Method;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class ConversationContextMapperTest {
@Test
public void testCleanAgentMessage() throws Exception {
ConversationContextMapper mapper = new ConversationContextMapper();
Method method = ConversationContextMapper.class.getDeclaredMethod("cleanAgentMessage", String.class);
method.setAccessible(true);
String input = "Agent: ¡Seguro, déjame buscarlo para ti! 😉 El 'mejor' banco es " +
"subjetivo y depende de sus necesidades financieras personales. Para determinar " +
"cuál es el más adecuado para usted, considere los siguientes factores:\n" +
"* **Comisiones y cargos**: Evalúe las tarifas por mantenimiento de cuenta, " +
"transferencias, retiros en cajeros automáticos de otras redes, y otros servicios.\n" +
"* **Tasas de interés**: Compare las tasas de interés ofrecidas en cuentas de " +
"ahorro, depósitos a plazo fijo y préstamos.\n" +
"* **Servicios y productos**: Verifique si el banco ofrece los productos que " +
"necesita, como cuentas corrientes, cuentas de ahorro, tarjetas de crédito, " +
"hipotecas, inversiones, etc.\n" +
"* **Accesibilidad y conveniencia**: Considere la ubicación de sucursales y " +
"cajeros automáticos, la calidad de la banca en línea y móvil, y el servicio al " +
"cliente.\n" +
"* **Tecnología**: Evalúe la facilidad de uso de sus plataformas digitales, la " +
"seguridad y las herramientas de gestión financiera que ofrecen.\n" +
"**Ejemplo**: Si usted realiza muchas transacciones en línea y rara vez visita una " +
"sucursal, un banco con una excelente aplicación móvil y bajas comisiones por " +
"transacciones digitales podría ser ideal. Si, por el contrario, prefiere la " +
"atención personalizada, un banco con una red de sucursales amplia y un buen " +
"servicio al cliente presencial sería más adecuado.\n" +
"**Siguientes pasos**: Le recomendamos investigar y comparar al menos tres bancos " +
"diferentes basándose en sus prioridades financieras. Revise sus sitios web, lea " +
"las condiciones de sus productos y, si es posible, consulte opiniones de otros " +
"usuarios para tomar una decisión informada. \n" +
"{response=El 'mejor' banco es subjetivo y depende de sus necesidades financieras " +
"personales. Para determinar cuál es el más adecuado para usted, considere los " +
"siguientes factores:* **Comisiones y cargos**: Evalúe las tarifas por " +
"mantenimiento de cuenta, transferencias, retiros en cajeros automáticos de " +
"otras redes, y otros servicios.* **Tasas de interés**: Compare las tasas de " +
"interés ofrecidas en cuentas de ahorro, depósitos a plazo fijo y préstamos." +
"* **Servicios y productos**: Verifique si el banco ofrece los productos que " +
"necesita, como cuentas corrientes, cuentas de ahorro, tarjetas de crédito, " +
"hipotecas, inversiones, etc.* **Accesibilidad y conveniencia**: Considere la " +
"ubicación de sucursales y cajeros automáticos, la calidad de la banca en línea y " +
"móvil, y el servicio al cliente.* **Tecnología**: Evalúe la facilidad de uso " +
"de sus plataformas digitales, la seguridad y las herramientas de gestión " +
"financiera que ofrecen.**Ejemplo**: Si usted realiza muchas transacciones en línea " +
"y rara vez visita una sucursal, un banco con una excelente aplicación móvil y " +
"bajas comisiones por transacciones digitales podría ser ideal. Si, por el " +
"contrario, prefiere la atención personalizada, un banco con una red de " +
"sucursales amplia y un buen servicio al cliente presencial sería más adecuado." +
"**Siguientes pasos**: Le recomendamos investigar y comparar al menos tres bancos " +
"diferentes basándose en sus prioridades financieras. Revise sus sitios web, lea " +
"las condiciones de sus productos y, si es posible, consulte opiniones de otros " +
"Gente, tomen una decisión informada., telefono=123456789, pregunta_nueva=NO, " +
"usuario_id=user_by_phone_123456789, historial=que son las capsulas?cual es la mejor " +
"para mi?, query_inicial=Cual es el mejor banco?, canal=sigma, " +
"$request.generative.confirmacion_ayuda=¡Seguro, déjame buscarlo para ti! 😉, " +
"query=Cual es el mejor banco?, webhook_success=true, " +
"$request.generative.respuesta_algo_mas=¿Te puedo echar la mano con otra cosa? ¡Tú dime! 😎, " +
"conversacion_notificacion=false, nickname=John Doe, notificacion= }";
String expected = "Agent: ¡Seguro, déjame buscarlo para ti! 😉 El 'mejor' banco es " +
"subjetivo y depende de sus necesidades financieras personales. Para determinar " +
"cuál es el más adecuado para usted, considere los siguientes factores:\n" +
"* **Comisiones y cargos**: Evalúe las tarifas por mantenimiento de cuenta, " +
"transferencias, retiros en cajeros automáticos de otras redes, y otros servicios.\n" +
"* **Tasas de interés**: Compare las tasas de interés ofrecidas en cuentas de " +
"ahorro, depósitos a plazo fijo y préstamos.\n" +
"* **Servicios y productos**: Verifique si el banco ofrece los productos que " +
"necesita, como cuentas corrientes, cuentas de ahorro, tarjetas de crédito, " +
"hipotecas, inversiones, etc.\n" +
"* **Accesibilidad y conveniencia**: Considere la ubicación de sucursales y " +
"cajeros automáticos, la calidad de la banca en línea y móvil, y el servicio al " +
"cliente.\n" +
"* **Tecnología**: Evalúe la facilidad de uso de sus plataformas digitales, la " +
"seguridad y las herramientas de gestión financiera que ofrecen.\n" +
"**Ejemplo**: Si usted realiza muchas transacciones en línea y rara vez visita una " +
"sucursal, un banco con una excelente aplicación móvil y bajas comisiones por " +
"transacciones digitales podría ser ideal. Si, por el contrario, prefiere la " +
"atención personalizada, un banco con una red de sucursales amplia y un buen " +
"servicio al cliente presencial sería más adecuado.\n" +
"**Siguientes pasos**: Le recomendamos investigar y comparar al menos tres bancos " +
"diferentes basándose en sus prioridades financieras. Revise sus sitios web, lea " +
"las condiciones de sus productos y, si es posible, consulte opiniones de otros " +
"usuarios para tomar una decisión informada.";
String result = (String) method.invoke(mapper, input);
assertEquals(expected, result);
}
@Test
public void testToTextWithTruncation() {
ConversationContextMapper mapper = new ConversationContextMapper();
List<ConversationMessageDTO> messages = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
messages.add(createMessage("This is message " + i, MessageType.USER));
}
for (int i = 1000; i < 2000; i++) {
messages.add(createMessage("This is message " + i, MessageType.AGENT));
}
String result = mapper.toTextWithTruncation(messages);
assertTrue(result.length() > 0);
assertTrue(result.getBytes(java.nio.charset.StandardCharsets.UTF_8).length <= 50 * 1024);
}
private ConversationMessageDTO createMessage(String text, MessageType type) {
return new ConversationMessageDTO(type, Instant.now(), text, null, null);
}
@Test
public void testToTextFromMessages_SystemNotification_ShouldUseParamText() {
ConversationContextMapper mapper = new ConversationContextMapper();
Map<String, Object> params = new java.util.HashMap<>();
params.put("notification_text", "Tu estado de cuenta está listo");
ConversationMessageDTO systemMessage = new ConversationMessageDTO(
MessageType.SYSTEM,
Instant.now(),
"NOTIFICATION",
params,
"whatsapp"
);
List<ConversationMessageDTO> messages = new java.util.ArrayList<>();
messages.add(systemMessage);
// WHEN
String result = mapper.toTextFromMessages(messages);
System.out.println(result);
// THEN
assertEquals("System: Tu estado de cuenta está listo", result);
}
}