diff --git a/xfg-dev-tech-app/src/main/resources/application-dev.yml b/xfg-dev-tech-app/src/main/resources/application-dev.yml index 3728d3ac8eb974f43809a9f824ae5c1abbc36514..c7299b802ea8d10eb8dbd978fd42a4055401f23d 100644 --- a/xfg-dev-tech-app/src/main/resources/application-dev.yml +++ b/xfg-dev-tech-app/src/main/resources/application-dev.yml @@ -8,18 +8,18 @@ chatglm: sdk: config: # 状态;true = 开启、false 关闭 - enabled: true + enabled: false # 官网地址 api-host: https://open.bigmodel.cn/ # 官网申请 https://open.bigmodel.cn/usercenter/apikeys - api-secret-key: d570f7c5d289cdac2abdfdc562e39f3f.trqz1dH8ZK6ED7Pg + api-secret-key: d570f7c5d289cdac2abdfdc562****.trqz1dH8***** # 知识星球配置信息;id -> 星球ID、user-id -> 用户ID、cookie -> 登录cookie zsxq: config: id: 28885518425541 user-id: 241858242255511 - cookie: zsxq_access_token=E0538FF2-B440-69E9-57D1-59EA37B9C0C6_9D76421394C6F474 + cookie: zsxq_access_token=E0538FF2-B440-69E9-57D1-59E****** # 日志 logging: diff --git a/xfg-dev-tech-app/src/test/java/cn/bugstack/xfg/dev/tech/infrastructure/gateway/adapter/ZSXQAdapterTest.java b/xfg-dev-tech-app/src/test/java/cn/bugstack/xfg/dev/tech/infrastructure/gateway/adapter/ZSXQAdapterTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3b9a0eb08f280f83ee6aca8a4340ddcf6b642d65 --- /dev/null +++ b/xfg-dev-tech-app/src/test/java/cn/bugstack/xfg/dev/tech/infrastructure/gateway/adapter/ZSXQAdapterTest.java @@ -0,0 +1,88 @@ +package cn.bugstack.xfg.dev.tech.infrastructure.gateway.adapter; + +import cn.bugstack.xfg.dev.tech.domain.zsxq.model.vo.TopicsItemVO; +import cn.bugstack.xfg.dev.tech.infrastructure.gateway.api.IZSXQApi; +import cn.bugstack.xfg.dev.tech.infrastructure.gateway.dto.*; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@Slf4j +@RunWith(MockitoJUnitRunner.class) +public class ZSXQAdapterTest { + + @Mock + private IZSXQApi mockZsxqApi; + + @InjectMocks + private ZSXQAdapter zsxqAdapterUnderTest; + + @Test + public void testQueryTopics() throws Exception { + // Setup + final List expectedResult = Arrays.asList(TopicsItemVO.builder() + .topicId(0L) + .talk("talk") + .showCommentsItems(Arrays.asList(TopicsItemVO.ShowCommentsItem.builder() + .userId(0L) + .build())) + .build()); + + // Configure IZSXQApi.topics(...). + final ResponseDTO responseDTO = new ResponseDTO(); + final RespData respData = new RespData(); + final TopicsItem topicsItem = new TopicsItem(); + final ShowCommentsItem showCommentsItem = new ShowCommentsItem(); + final Owner owner = new Owner(); + owner.setUserId(0L); + showCommentsItem.setOwner(owner); + topicsItem.setShowComments(Arrays.asList(showCommentsItem)); + final Talk talk = new Talk(); + talk.setText("talk"); + topicsItem.setTalk(talk); + topicsItem.setTopicId(0L); + respData.setTopics(Arrays.asList(topicsItem)); + responseDTO.setRespData(respData); + when(mockZsxqApi.topics()).thenReturn(responseDTO); + + // Run the test + final List result = zsxqAdapterUnderTest.queryTopics(); + + // Verify the results + assertEquals(expectedResult, result); + + log.info("测试结果:{}", JSON.toJSONString(result)); + } + + @Test + public void testQueryTopics_IZSXQApiThrowsIOException() throws Exception { + // Setup + when(mockZsxqApi.topics()).thenThrow(IOException.class); + + // Run the test + assertThrows(RuntimeException.class, () -> zsxqAdapterUnderTest.queryTopics()); + } + + @Test + public void testComment() { + // Setup + // Run the test + final boolean result = zsxqAdapterUnderTest.comment(0L, "content"); + + // Verify the results + assertTrue(result); + verify(mockZsxqApi).comment(0L, "content"); + } +} diff --git a/xfg-dev-tech-app/src/test/java/cn/bugstack/xfg/dev/tech/test/ApiTest.java b/xfg-dev-tech-app/src/test/java/cn/bugstack/xfg/dev/tech/test/ApiTest.java index 20a429ea3821019a08733d7c667545f7e2655e61..13523fd5b5b6c1eb8fe505a9281581592bb34d80 100644 --- a/xfg-dev-tech-app/src/test/java/cn/bugstack/xfg/dev/tech/test/ApiTest.java +++ b/xfg-dev-tech-app/src/test/java/cn/bugstack/xfg/dev/tech/test/ApiTest.java @@ -25,8 +25,6 @@ public class ApiTest { @Test public void test_IAiReply() { aiReply.doAiReply(); - - } } diff --git a/xfg-dev-tech-app/src/test/java/cn/bugstack/xfg/dev/tech/test/MockTest.java b/xfg-dev-tech-app/src/test/java/cn/bugstack/xfg/dev/tech/test/MockTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4aa07e415d6fea2c9ae30de8ea0144a41603c610 --- /dev/null +++ b/xfg-dev-tech-app/src/test/java/cn/bugstack/xfg/dev/tech/test/MockTest.java @@ -0,0 +1,61 @@ +package cn.bugstack.xfg.dev.tech.test; + +import cn.bugstack.chatglm.model.ChatCompletionRequest; +import cn.bugstack.chatglm.session.OpenAiSession; +import cn.bugstack.xfg.dev.tech.domain.zsxq.adapter.IZSXQAdapter; +import cn.bugstack.xfg.dev.tech.domain.zsxq.model.vo.TopicsItemVO; +import cn.bugstack.xfg.dev.tech.domain.zsxq.service.IAiReply; +import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.extern.slf4j.Slf4j; +import okhttp3.Request; +import okhttp3.sse.EventSource; +import okhttp3.sse.EventSourceListener; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; + +/** + * @author Fuzhengwei bugstack.cn @小傅哥 + * @description Mock 测试 + * @create 2023-10-22 11:20 + */ +@Slf4j +@RunWith(SpringRunner.class) +@SpringBootTest +public class MockTest { + + @Resource + private IAiReply aiReply; + + @MockBean + private IZSXQAdapter izsxqAdapter; + + @Test + public void test_doAiReply_() throws InterruptedException, JsonProcessingException { + Mockito.when(izsxqAdapter.queryTopics()).thenReturn(new ArrayList() {{ + TopicsItemVO topicsItemVO = new TopicsItemVO(); + topicsItemVO.setTopicId(10001L); + topicsItemVO.setTalk(" 提问 java 冒泡排序"); + add(topicsItemVO); + }}); + + Mockito.when(izsxqAdapter.comment(Mockito.anyLong(), Mockito.anyString())).thenReturn(true); + + aiReply.doAiReply(); + + // 等待;ChatGLM 异步回复 + new CountDownLatch(1).await(); + } + +} diff --git a/xfg-dev-tech-domain/src/main/java/cn/bugstack/xfg/dev/tech/domain/zsxq/adapter/IZSXQAdapter.java b/xfg-dev-tech-domain/src/main/java/cn/bugstack/xfg/dev/tech/domain/zsxq/adapter/IZSXQAdapter.java index 34b4f2fef4b2ec9857e847039a9bb6d8baaef05a..fa1e9a08a71c99e57325389bfa7cc38752084a91 100644 --- a/xfg-dev-tech-domain/src/main/java/cn/bugstack/xfg/dev/tech/domain/zsxq/adapter/IZSXQAdapter.java +++ b/xfg-dev-tech-domain/src/main/java/cn/bugstack/xfg/dev/tech/domain/zsxq/adapter/IZSXQAdapter.java @@ -13,6 +13,6 @@ public interface IZSXQAdapter { List queryTopics(); - void comment(long topicId, String content); + boolean comment(long topicId, String content); } diff --git a/xfg-dev-tech-domain/src/main/java/cn/bugstack/xfg/dev/tech/domain/zsxq/service/AiReply.java b/xfg-dev-tech-domain/src/main/java/cn/bugstack/xfg/dev/tech/domain/zsxq/service/AiReply.java index 74579b390c8890fcebeae5a663e898eed3707314..ad46606eff69abca718ff7974fae9c6296f80b96 100644 --- a/xfg-dev-tech-domain/src/main/java/cn/bugstack/xfg/dev/tech/domain/zsxq/service/AiReply.java +++ b/xfg-dev-tech-domain/src/main/java/cn/bugstack/xfg/dev/tech/domain/zsxq/service/AiReply.java @@ -38,7 +38,6 @@ public class AiReply implements IAiReply { @Value("${zsxq.config.user-id}") private Long userId; - private final String regex = " (.*)"; private volatile Set topicIds = new HashSet<>(); @Override @@ -53,6 +52,7 @@ public class AiReply implements IAiReply { String text = topicsItem.getTalk(); // " 提问 java 冒泡排序" + String regex = " (.*)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(text); @@ -65,7 +65,8 @@ public class AiReply implements IAiReply { if (null == openAiSession) { log.info("你没有开启 ChatGLM 参考yml配置文件来开启"); // 你可以使用 ChatGLM SDK 进行回答,回复问题; - zsxqAdapter.comment(topicId, "【测试,只回答圈我的帖子】对接 ChatGLM SDK https://bugstack.cn/md/project/chatgpt/sdk/chatglm-sdk-java.html 回答:" + remainingText); + boolean status = zsxqAdapter.comment(topicId, "【测试,只回答圈我的帖子】对接 ChatGLM SDK https://bugstack.cn/md/project/chatgpt/sdk/chatglm-sdk-java.html 回答:" + remainingText); + log.info("回贴完成:{}", status); } else { log.info("ChatGLM 进入回答 {} {}", topicId, remainingText); if (topicIds.contains(topicId)) { @@ -94,12 +95,12 @@ public class AiReply implements IAiReply { openAiSession.completions(request, new EventSourceListener() { @Override public void onEvent(EventSource eventSource, @Nullable String id, @Nullable String type, String data) { - ChatCompletionResponse chatCompletionResponse = com.alibaba.fastjson.JSON.parseObject(data, ChatCompletionResponse.class); + ChatCompletionResponse chatCompletionResponse = JSON.parseObject(data, ChatCompletionResponse.class); log.info("测试结果 onEvent:{}", chatCompletionResponse.getData()); // type 消息类型,add 增量,finish 结束,error 错误,interrupted 中断 if (EventType.finish.getCode().equals(type)) { - ChatCompletionResponse.Meta meta = com.alibaba.fastjson.JSON.parseObject(chatCompletionResponse.getMeta(), ChatCompletionResponse.Meta.class); - log.info("[输出结束] Tokens {}", com.alibaba.fastjson.JSON.toJSONString(meta)); + ChatCompletionResponse.Meta meta = JSON.parseObject(chatCompletionResponse.getMeta(), ChatCompletionResponse.Meta.class); + log.info("[输出结束] Tokens {}", JSON.toJSONString(meta)); } content.append(chatCompletionResponse.getData()); } @@ -121,7 +122,8 @@ public class AiReply implements IAiReply { } String subContent = contents.substring(startIndex, endIndex); - zsxqAdapter.comment(topicId, subContent); + boolean status = zsxqAdapter.comment(topicId, subContent); + log.info("回贴完成:{}", status); startIndex = endIndex; endIndex += maxLength; diff --git a/xfg-dev-tech-infrastructure/src/main/java/cn/bugstack/xfg/dev/tech/infrastructure/gateway/adapter/ZSXQAdapter.java b/xfg-dev-tech-infrastructure/src/main/java/cn/bugstack/xfg/dev/tech/infrastructure/gateway/adapter/ZSXQAdapter.java index 2a5e0ebc5723640fd6fe908715b673e19bcd3a2b..174690549ae0b7688942d9cae990732f4115ef70 100644 --- a/xfg-dev-tech-infrastructure/src/main/java/cn/bugstack/xfg/dev/tech/infrastructure/gateway/adapter/ZSXQAdapter.java +++ b/xfg-dev-tech-infrastructure/src/main/java/cn/bugstack/xfg/dev/tech/infrastructure/gateway/adapter/ZSXQAdapter.java @@ -58,8 +58,9 @@ public class ZSXQAdapter implements IZSXQAdapter { } @Override - public void comment(long topicId, String content) { + public boolean comment(long topicId, String content) { zsxqApi.comment(topicId, content); + return true; } } diff --git a/xfg-dev-tech-trigger/src/main/java/cn/bugstack/xfg/dev/tech/job/ReplyJob.java b/xfg-dev-tech-trigger/src/main/java/cn/bugstack/xfg/dev/tech/job/ReplyJob.java index 1336057526f1660122da57f763566c20af80e1a5..5f3533f128daf557fb5796eded3d038dd277326f 100644 --- a/xfg-dev-tech-trigger/src/main/java/cn/bugstack/xfg/dev/tech/job/ReplyJob.java +++ b/xfg-dev-tech-trigger/src/main/java/cn/bugstack/xfg/dev/tech/job/ReplyJob.java @@ -21,6 +21,7 @@ public class ReplyJob { @Scheduled(cron = "0/10 * * * * ?") public void exec() throws Exception { + log.info("自动回帖任务开始执行..."); aiReply.doAiReply(); }