This is an automated email from the ASF dual-hosted git repository.

liuhongyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 85307386b9 feat(ut): add ai plugin unit test (#6078)
85307386b9 is described below

commit 85307386b9f3412a5afc6c504fc10bf64c859892
Author: shown <[email protected]>
AuthorDate: Sat Aug 2 12:21:19 2025 +0800

    feat(ut): add ai plugin unit test (#6078)
    
    * fix
    
    Signed-off-by: shown.Ji <[email protected]>
    
    * fix
    
    Signed-off-by: shown.Ji <[email protected]>
    
    ---------
    
    Signed-off-by: shown.Ji <[email protected]>
---
 .../request/AiRequestTransformerPlugin.java        |  15 ++-
 .../transformer/request/cache/ChatClientCache.java |   5 +-
 .../handler/AiRequestTransformerPluginHandler.java |   1 -
 .../request/AiRequestTransformerPluginTest.java    | 133 +++++++++++++++++++++
 .../request/cache/ChatClientCacheTest.java         |  83 +++++++++++++
 .../AiRequestTransformerPluginHandlerTest.java     |  99 +++++++++++++++
 .../template/AiRequestTransformerTemplateTest.java | 124 +++++++++++++++++++
 7 files changed, 452 insertions(+), 8 deletions(-)

diff --git 
a/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/main/java/org/apache/shenyu/plugin/ai/transformer/request/AiRequestTransformerPlugin.java
 
b/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/main/java/org/apache/shenyu/plugin/ai/transformer/request/AiRequestTransformerPlugin.java
index bbbce6593e..8232f7c4ed 100644
--- 
a/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/main/java/org/apache/shenyu/plugin/ai/transformer/request/AiRequestTransformerPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/main/java/org/apache/shenyu/plugin/ai/transformer/request/AiRequestTransformerPlugin.java
@@ -142,11 +142,17 @@ public class AiRequestTransformerPlugin extends 
AbstractShenyuPlugin {
 
     }
 
-    private static String convertBodyJson(final String aiResponse) {
+    /**
+     * For unit test.
+     */
+    static String convertBodyJson(final String aiResponse) {
         return extractJsonBodyFromHttpResponse(aiResponse);
     }
 
-    private static String convertBodyFormData(final String aiResponse) {
+    /**
+     * For unit test.
+     */
+    static String convertBodyFormData(final String aiResponse) {
         Map<String, Object> formDataMap = 
GsonUtils.getInstance().toObjectMap(extractJsonBodyFromHttpResponse(aiResponse));
         return mapToFormUrlEncoded(formDataMap);
     }
@@ -212,7 +218,10 @@ public class AiRequestTransformerPlugin extends 
AbstractShenyuPlugin {
         return Mono.just(exchange);
     }
 
-    private static HttpHeaders extractHeadersFromAiResponse(final String 
aiResponse) {
+    /**
+     * For unit test.
+     */
+    static HttpHeaders extractHeadersFromAiResponse(final String aiResponse) {
         HttpHeaders headers = new HttpHeaders();
         if (Objects.isNull(aiResponse) || aiResponse.isEmpty()) {
             return headers;
diff --git 
a/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/main/java/org/apache/shenyu/plugin/ai/transformer/request/cache/ChatClientCache.java
 
b/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/main/java/org/apache/shenyu/plugin/ai/transformer/request/cache/ChatClientCache.java
index e7a21c1f4d..52d76370cb 100644
--- 
a/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/main/java/org/apache/shenyu/plugin/ai/transformer/request/cache/ChatClientCache.java
+++ 
b/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/main/java/org/apache/shenyu/plugin/ai/transformer/request/cache/ChatClientCache.java
@@ -30,9 +30,6 @@ public class ChatClientCache {
 
     private static final Map<String, ChatClient> CHAT_CLIENT_MAP = new 
HashMap<>();
 
-    public ChatClientCache() {
-    }
-
     /**
      * Init.
      *
@@ -78,13 +75,13 @@ public class ChatClientCache {
      * The type Application config cache instance.
      */
     static final class ApplicationConfigCacheInstance {
+
         /**
          * The Instance.
          */
         static final ChatClientCache INSTANCE = new ChatClientCache();
 
         private ApplicationConfigCacheInstance() {
-
         }
     }
 }
diff --git 
a/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/main/java/org/apache/shenyu/plugin/ai/transformer/request/handler/AiRequestTransformerPluginHandler.java
 
b/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/main/java/org/apache/shenyu/plugin/ai/transformer/request/handler/AiRequestTransformerPluginHandler.java
index b84308d54a..3b59020fde 100644
--- 
a/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/main/java/org/apache/shenyu/plugin/ai/transformer/request/handler/AiRequestTransformerPluginHandler.java
+++ 
b/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/main/java/org/apache/shenyu/plugin/ai/transformer/request/handler/AiRequestTransformerPluginHandler.java
@@ -15,7 +15,6 @@
  * limitations under the License.
  */
 
-
 package org.apache.shenyu.plugin.ai.transformer.request.handler;
 
 import org.apache.shenyu.common.dto.PluginData;
diff --git 
a/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/test/java/org/apache/shenyu/plugin/ai/transformer/request/AiRequestTransformerPluginTest.java
 
b/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/test/java/org/apache/shenyu/plugin/ai/transformer/request/AiRequestTransformerPluginTest.java
new file mode 100644
index 0000000000..0d56a48fe0
--- /dev/null
+++ 
b/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/test/java/org/apache/shenyu/plugin/ai/transformer/request/AiRequestTransformerPluginTest.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.shenyu.plugin.ai.transformer.request;
+
+import org.apache.shenyu.common.dto.RuleData;
+import org.apache.shenyu.common.dto.SelectorData;
+import org.apache.shenyu.common.dto.convert.plugin.AiRequestTransformerConfig;
+import org.apache.shenyu.common.dto.convert.rule.AiRequestTransformerHandle;
+import org.apache.shenyu.common.enums.AiModelProviderEnum;
+import org.apache.shenyu.plugin.ai.common.spring.ai.AiModelFactory;
+import 
org.apache.shenyu.plugin.ai.common.spring.ai.registry.AiModelFactoryRegistry;
+import org.apache.shenyu.plugin.ai.transformer.request.cache.ChatClientCache;
+import org.apache.shenyu.plugin.api.ShenyuPluginChain;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.ai.chat.client.ChatClient;
+import org.springframework.ai.chat.model.ChatModel;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
+import org.springframework.mock.web.server.MockServerWebExchange;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+import java.util.Collections;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class AiRequestTransformerPluginTest {
+
+    private AiModelFactoryRegistry aiModelFactoryRegistry;
+
+    private ChatClientCache chatClientCache;
+
+    private ShenyuPluginChain chain;
+
+    private AiRequestTransformerPlugin plugin;
+
+    @BeforeEach
+    void setUp() {
+
+        aiModelFactoryRegistry = mock(AiModelFactoryRegistry.class);
+        chatClientCache = mock(ChatClientCache.class);
+        chain = mock(ShenyuPluginChain.class);
+        plugin = new AiRequestTransformerPlugin(Collections.emptyList(), 
aiModelFactoryRegistry);
+    }
+
+    @Test
+    void testDoExecuteWithMissingConfigurations() {
+
+        MockServerWebExchange exchange = 
MockServerWebExchange.from(MockServerHttpRequest.post("/test").build());
+        SelectorData selector = new SelectorData();
+        RuleData rule = new RuleData();
+
+        when(chain.execute(exchange)).thenReturn(Mono.empty());
+
+        StepVerifier.create(plugin.doExecute(exchange, chain, selector, rule))
+                .verifyComplete();
+
+        verify(chain).execute(exchange);
+    }
+
+    @Test
+    void testDoExecuteWithValidConfigurations() {
+
+        AiRequestTransformerConfig config = new AiRequestTransformerConfig();
+        config.setBaseUrl("http://test.com";);
+        config.setApiKey("test-api-key");
+        config.setProvider("TEST_PROVIDER");
+        config.setModel("test-model");
+
+        AiRequestTransformerHandle handle = new AiRequestTransformerHandle();
+        handle.setProvider("TEST_PROVIDER");
+        handle.setBaseUrl("http://test.com";);
+        handle.setApiKey("test-api-key");
+        handle.setModel("test-model");
+
+        ChatClient mockClient = mock(ChatClient.class);
+        ChatModel mockModel = mock(ChatModel.class);
+        AiModelFactory mockFactory = mock(AiModelFactory.class);
+
+        MockServerWebExchange exchange = 
MockServerWebExchange.from(MockServerHttpRequest.post("/test")
+                .header(HttpHeaders.CONTENT_TYPE, 
MediaType.APPLICATION_JSON_VALUE)
+                .body("{\"key\":\"value\"}"));
+        
when(aiModelFactoryRegistry.getFactory(AiModelProviderEnum.getByName("TEST_PROVIDER"))).thenReturn(mockFactory);
+        when(mockFactory.createAiModel(any())).thenReturn(mockModel);
+        when(chatClientCache.getClient("default")).thenReturn(mockClient);
+        when(chain.execute(exchange)).thenReturn(Mono.empty());
+
+        SelectorData selector = new SelectorData();
+        RuleData rule = new RuleData();
+        StepVerifier.create(plugin.doExecute(exchange, chain, selector, rule))
+                .verifyComplete();
+
+        verify(chain).execute(exchange);
+    }
+
+    @Test
+    void testConvertBodyJson() {
+
+        String aiResponse = "HTTP/1.1 200 OK\nContent-Type: 
application/json\n\n{\"key\":\"value\"}";
+        String result = AiRequestTransformerPlugin.convertBodyJson(aiResponse);
+        assertEquals("{\"key\":\"value\"}", result);
+    }
+
+    @Test
+    void testExtractHeadersFromAiResponse() {
+
+        String aiResponse = "HTTP/1.1 200 OK\nContent-Type: 
application/json\nAuthorization: Bearer token\n\n{\"key\":\"value\"}";
+        HttpHeaders headers = 
AiRequestTransformerPlugin.extractHeadersFromAiResponse(aiResponse);
+        assertEquals("application/json", 
headers.getFirst(HttpHeaders.CONTENT_TYPE));
+        assertEquals("Bearer token", 
headers.getFirst(HttpHeaders.AUTHORIZATION));
+    }
+}
diff --git 
a/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/test/java/org/apache/shenyu/plugin/ai/transformer/request/cache/ChatClientCacheTest.java
 
b/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/test/java/org/apache/shenyu/plugin/ai/transformer/request/cache/ChatClientCacheTest.java
new file mode 100644
index 0000000000..7fee0d68e6
--- /dev/null
+++ 
b/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/test/java/org/apache/shenyu/plugin/ai/transformer/request/cache/ChatClientCacheTest.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.shenyu.plugin.ai.transformer.request.cache;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.ai.chat.client.ChatClient;
+import org.springframework.ai.chat.model.ChatModel;
+import org.springframework.ai.openai.OpenAiChatModel;
+import org.springframework.ai.openai.api.OpenAiApi;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.mockito.Mockito.mock;
+
+class ChatClientCacheTest {
+
+    private ChatClientCache chatClientCache;
+
+    @BeforeEach
+    void setUp() {
+
+        chatClientCache = ChatClientCache.getInstance();
+    }
+
+    @Test
+    void testGetInstance() {
+
+        ChatClientCache instance1 = ChatClientCache.getInstance();
+        ChatClientCache instance2 = ChatClientCache.getInstance();
+        assertNotNull(instance1, "Instance should not be null");
+        assertSame(instance1, instance2, "Instances should be the same 
(singleton)");
+    }
+
+    @Test
+    void testInitAndGetClient() {
+
+        ChatModel chatModel = OpenAiChatModel
+                .builder()
+                .openAiApi(
+                        OpenAiApi.builder()
+                                .apiKey("test-ak")
+                                .build()
+                ).build();
+
+        String ruleId = "testRuleId";
+        ChatClient chatClient = chatClientCache.init(ruleId, chatModel);
+        assertNotNull(chatClient, "ChatClient should not be null");
+
+        ChatClient retrievedClient = chatClientCache.getClient(ruleId);
+        assertNotNull(retrievedClient, "Retrieved ChatClient should not be 
null");
+    }
+
+    @Test
+    void testDestroyClient() {
+
+        String ruleId = "testRuleId";
+        ChatModel chatModel = mock(ChatModel.class);
+
+        chatClientCache.init(ruleId, chatModel);
+        assertNotNull(chatClientCache.getClient(ruleId), "ChatClient should 
exist before destruction");
+
+        chatClientCache.destroyClient(ruleId);
+        assertNull(chatClientCache.getClient(ruleId), "ChatClient should be 
null after destruction");
+    }
+
+}
diff --git 
a/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/test/java/org/apache/shenyu/plugin/ai/transformer/request/handler/AiRequestTransformerPluginHandlerTest.java
 
b/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/test/java/org/apache/shenyu/plugin/ai/transformer/request/handler/AiRequestTransformerPluginHandlerTest.java
new file mode 100644
index 0000000000..7888a7b3da
--- /dev/null
+++ 
b/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/test/java/org/apache/shenyu/plugin/ai/transformer/request/handler/AiRequestTransformerPluginHandlerTest.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.shenyu.plugin.ai.transformer.request.handler;
+
+import org.apache.shenyu.common.dto.PluginData;
+import org.apache.shenyu.common.dto.RuleData;
+import org.apache.shenyu.common.dto.convert.rule.AiRequestTransformerHandle;
+import org.apache.shenyu.common.enums.PluginEnum;
+import org.apache.shenyu.common.utils.GsonUtils;
+import 
org.apache.shenyu.plugin.ai.common.spring.ai.registry.AiModelFactoryRegistry;
+import org.apache.shenyu.plugin.ai.transformer.request.cache.ChatClientCache;
+import org.apache.shenyu.plugin.base.cache.CommonHandleCache;
+import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyNoInteractions;
+
+class AiRequestTransformerPluginHandlerTest {
+
+    private AiModelFactoryRegistry aiModelFactoryRegistry;
+
+    private ChatClientCache chatClientCache;
+
+    private AiRequestTransformerPluginHandler pluginHandler;
+
+    @BeforeEach
+    void setUp() {
+        chatClientCache = ChatClientCache.getInstance();
+        aiModelFactoryRegistry = mock(AiModelFactoryRegistry.class);
+        pluginHandler = new 
AiRequestTransformerPluginHandler(aiModelFactoryRegistry);
+    }
+
+    @Test
+    void testHandlerPluginWithInvalidData() {
+
+        PluginData pluginData = new PluginData();
+        pluginData.setEnabled(true);
+        pluginData.setConfig(null);
+
+        pluginHandler.handlerPlugin(pluginData);
+
+        verifyNoInteractions(aiModelFactoryRegistry);
+    }
+
+    @Test
+    void testHandlerRule() {
+
+        RuleData ruleData = new RuleData();
+        ruleData.setId("rule1");
+        AiRequestTransformerHandle handle = new AiRequestTransformerHandle();
+        handle.setProvider("TEST_PROVIDER");
+        ruleData.setHandle(GsonUtils.getInstance().toJson(handle));
+
+        pluginHandler.handlerRule(ruleData);
+
+        CommonHandleCache<String, AiRequestTransformerHandle> cache = 
AiRequestTransformerPluginHandler.CACHED_HANDLE.get();
+        assertNotNull(cache.obtainHandle(CacheKeyUtils.INST.getKey(ruleData)));
+    }
+
+    @Test
+    void testRemoveRule() {
+
+        RuleData ruleData = new RuleData();
+        ruleData.setId("rule1");
+        AiRequestTransformerHandle handle = new AiRequestTransformerHandle();
+        handle.setProvider("TEST_PROVIDER");
+        ruleData.setHandle(GsonUtils.getInstance().toJson(handle));
+
+        pluginHandler.removeRule(ruleData);
+
+        CommonHandleCache<String, AiRequestTransformerHandle> cache = 
AiRequestTransformerPluginHandler.CACHED_HANDLE.get();
+        assertNull(cache.obtainHandle(CacheKeyUtils.INST.getKey(ruleData)));
+    }
+
+    @Test
+    void testPluginNamed() {
+        assertEquals(PluginEnum.AI_REQUEST_TRANSFORMER.getName(), 
pluginHandler.pluginNamed());
+    }
+}
diff --git 
a/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/test/java/org/apache/shenyu/plugin/ai/transformer/request/template/AiRequestTransformerTemplateTest.java
 
b/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/test/java/org/apache/shenyu/plugin/ai/transformer/request/template/AiRequestTransformerTemplateTest.java
new file mode 100644
index 0000000000..5760e6b01b
--- /dev/null
+++ 
b/shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/test/java/org/apache/shenyu/plugin/ai/transformer/request/template/AiRequestTransformerTemplateTest.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.shenyu.plugin.ai.transformer.request.template;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class AiRequestTransformerTemplateTest {
+
+    @Test
+    void testAssembleMessageWithJsonBody() {
+
+        String jsonBody = "{\"key\":\"value\"}";
+
+        ServerHttpRequest request = MockServerHttpRequest.post("/")
+                .contentType(MediaType.APPLICATION_JSON)
+                .body(jsonBody);
+
+        String userContent = "Test user content";
+        AiRequestTransformerTemplate template = new 
AiRequestTransformerTemplate(userContent, request);
+
+        Mono<String> result = template.assembleMessage();
+
+        StepVerifier.create(result)
+                .assertNext(message -> {
+                    assertNotNull(message, "Message should not be null");
+                    assertTrue(message.contains("system_prompt"), "Message 
should contain system_prompt");
+                    assertTrue(message.contains("user_prompt"), "Message 
should contain user_prompt");
+                    assertTrue(message.contains("key"), "Message should 
contain JSON body key");
+                })
+                .verifyComplete();
+    }
+
+    @Test
+    void testAssembleMessageWithFormUrlEncodedBody() {
+
+        String formBody = "key1=value1&key2=value2";
+        String userContent = "Test user content";
+        ServerHttpRequest request = MockServerHttpRequest.post("/")
+                .contentType(MediaType.APPLICATION_FORM_URLENCODED)
+                .body(formBody);
+
+        AiRequestTransformerTemplate template = new 
AiRequestTransformerTemplate(userContent, request);
+
+        Mono<String> result = template.assembleMessage();
+
+        StepVerifier.create(result)
+                .assertNext(message -> {
+                    assertNotNull(message, "Message should not be null");
+                    assertTrue(message.contains("system_prompt"), "Message 
should contain system_prompt");
+                    assertTrue(message.contains("user_prompt"), "Message 
should contain user_prompt");
+                    assertTrue(message.contains("key1"), "Message should 
contain form data key1");
+                    assertTrue(message.contains("value1"), "Message should 
contain form data value1");
+                })
+                .verifyComplete();
+    }
+
+    @Test
+    void testAssembleMessageWithEmptyBody() {
+
+        String userContent = "Test user content";
+        ServerHttpRequest request = MockServerHttpRequest.post("/")
+                .contentType(MediaType.APPLICATION_JSON)
+                .body("");
+        AiRequestTransformerTemplate template = new 
AiRequestTransformerTemplate(userContent, request);
+
+        Mono<String> result = template.assembleMessage();
+
+        StepVerifier.create(result)
+                .assertNext(message -> {
+                    assertNotNull(message, "Message should not be null");
+                    assertTrue(message.contains("system_prompt"), "Message 
should contain system_prompt");
+                    assertTrue(message.contains("user_prompt"), "Message 
should contain user_prompt");
+                })
+                .verifyComplete();
+    }
+
+    @Test
+    void testAssembleMessageWithHeaders() {
+
+        String userContent = "Test user content";
+        ServerHttpRequest request = MockServerHttpRequest.post("/")
+                .header(HttpHeaders.AUTHORIZATION, "Bearer token")
+                .header(HttpHeaders.CONTENT_TYPE, 
MediaType.APPLICATION_JSON_VALUE)
+                .body("");
+
+        AiRequestTransformerTemplate template = new 
AiRequestTransformerTemplate(userContent, request);
+
+        Mono<String> result = template.assembleMessage();
+
+        StepVerifier.create(result)
+                .assertNext(message -> {
+                    assertNotNull(message, "Message should not be null");
+                    assertTrue(message.contains("system_prompt"), "Message 
should contain system_prompt");
+                    assertTrue(message.contains("user_prompt"), "Message 
should contain user_prompt");
+                    assertTrue(message.contains("Authorization"), "Message 
should contain Authorization header");
+                    assertTrue(message.contains("Bearer token"), "Message 
should contain Authorization value");
+                })
+                .verifyComplete();
+    }
+}

Reply via email to