Add tests
diff --git a/src/test/java/com/googlesource/gerrit/plugins/chatgpt/PatchSetReviewerTests.java b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/PatchSetReviewerTests.java
new file mode 100644
index 0000000..4d7b7ab
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/PatchSetReviewerTests.java
@@ -0,0 +1,121 @@
+package com.googlesource.gerrit.plugins.chatgpt;
+
+import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import com.github.tomakehurst.wiremock.verification.LoggedRequest;
+import com.google.common.net.HttpHeaders;
+import com.googlesource.gerrit.plugins.chatgpt.client.GerritClient;
+import com.googlesource.gerrit.plugins.chatgpt.client.OpenAiClient;
+import com.googlesource.gerrit.plugins.chatgpt.client.UriResourceLocator;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.entity.ContentType;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Base64;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static java.net.HttpURLConnection.HTTP_OK;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+@Slf4j
+@RunWith(MockitoJUnitRunner.class)
+public class PatchSetReviewerTests {
+
+ private static final String CHANGE_ID = "myChangeId";
+
+ @Rule
+ public WireMockRule wireMockRule = new WireMockRule(9527);
+
+ private Configuration configuration;
+
+ private GerritClient gerritClient;
+
+ private OpenAiClient openAiClient;
+
+ private PatchSetReviewer patchSetReviewer;
+
+ private PatchSetCreated patchSetCreated;
+
+ @Before
+ public void before() {
+ initializePatchSetReviewer();
+ setupMockRequests();
+ }
+
+ private void initializePatchSetReviewer() {
+ configuration = Mockito.mock(Configuration.class);
+ when(configuration.getGerritAuthBaseUrl()).thenReturn("http://localhost:9527");
+ when(configuration.getGptDomain()).thenReturn("http://localhost:9527");
+ when(configuration.getMaxReviewLines()).thenReturn(500);
+
+ gerritClient = Mockito.spy(new GerritClient() {
+ @Override
+ public Configuration getConfiguration() {
+ return configuration;
+ }
+ });
+
+ openAiClient = Mockito.spy(new OpenAiClient() {
+ @Override
+ public Configuration getConfiguration() {
+ return configuration;
+ }
+ });
+
+ patchSetReviewer = new PatchSetReviewer(configuration, gerritClient, openAiClient);
+ patchSetCreated = new PatchSetCreated(patchSetReviewer);
+ }
+
+ private void setupMockRequests() {
+ // Mocks the behavior of the getPatchSet request
+ stubFor(get(urlEqualTo(URI.create(configuration.getGerritAuthBaseUrl() +
+ UriResourceLocator.gerritPatchSetUri(CHANGE_ID)).getPath()))
+ .willReturn(aResponse()
+ .withStatus(HTTP_OK)
+ .withHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())
+ .withBody(Base64.getEncoder().encodeToString("myPatch".getBytes()))));
+
+ // Mocks the behavior of the askGpt request
+ byte[] gptAnswer = Base64.getDecoder().decode("ZGF0YTogeyJpZCI6ImNoYXRjbXBsLTdSZDVOYVpEOGJNVTRkdnBVV2" +
+ "9hM3Q2RG83RkkzIiwib2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTY4NjgxOTQ1NywibW9kZWw" +
+ "iOiJncHQtMy41LXR1cmJvLTAzMDEiLCJjaG9pY2VzIjpbeyJkZWx0YSI6eyJyb2xlIjoiYXNzaXN0YW50In0sImluZGV4Ijow" +
+ "LCJmaW5pc2hfcmVhc29uIjpudWxsfV19CgpkYXRhOiB7ImlkIjoiY2hhdGNtcGwtN1JkNU5hWkQ4Yk1VNGR2cFVXb2EzdDZEb" +
+ "zdGSTMiLCJvYmplY3QiOiJjaGF0LmNvbXBsZXRpb24uY2h1bmsiLCJjcmVhdGVkIjoxNjg2ODE5NDU3LCJtb2RlbCI6ImdwdC0" +
+ "zLjUtdHVyYm8tMDMwMSIsImNob2ljZXMiOlt7ImRlbHRhIjp7ImNvbnRlbnQiOiJIZWxsbyJ9LCJpbmRleCI6MCwiZmluaXNo" +
+ "X3JlYXNvbiI6bnVsbH1dfQoKZGF0YTogeyJpZCI6ImNoYXRjbXBsLTdSZDVOYVpEOGJNVTRkdnBVV29hM3Q2RG83RkkzIiwib" +
+ "2JqZWN0IjoiY2hhdC5jb21wbGV0aW9uLmNodW5rIiwiY3JlYXRlZCI6MTY4NjgxOTQ1NywibW9kZWwiOiJncHQtMy41LXR1cm" +
+ "JvLTAzMDEiLCJjaG9pY2VzIjpbeyJkZWx0YSI6eyJjb250ZW50IjoiISJ9LCJpbmRleCI6MCwiZmluaXNoX3JlYXNvbiI" +
+ "6bnVsbH1dfQ==");
+ stubFor(post(urlEqualTo(URI.create(configuration.getGptDomain()
+ + UriResourceLocator.chatCompletionsUri()).getPath()))
+ .willReturn(aResponse()
+ .withStatus(HTTP_OK)
+ .withHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())
+ .withBody(new String(gptAnswer))));
+
+ // Mocks the behavior of the postReview request
+ stubFor(post(urlEqualTo(URI.create(configuration.getGerritAuthBaseUrl()
+ + UriResourceLocator.gerritCommentUri(CHANGE_ID)).getPath()))
+ .willReturn(aResponse()
+ .withStatus(HTTP_OK)));
+ }
+
+ @Test
+ public void review() throws IOException, InterruptedException {
+ patchSetReviewer.review(CHANGE_ID);
+
+ LoggedRequest firstMatchingRequest = findAll(postRequestedFor(urlEqualTo(UriResourceLocator
+ .gerritPatchSetUri(CHANGE_ID)))).get(0);
+ String requestBody = firstMatchingRequest.getBodyAsString();
+ assertEquals("{\"message\":\"Hello!\\n\"}", requestBody);
+
+ }
+
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/chatgpt/integration/CodeReviewPluginIT.java b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/integration/CodeReviewPluginIT.java
new file mode 100644
index 0000000..f352326
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/integration/CodeReviewPluginIT.java
@@ -0,0 +1,61 @@
+package com.googlesource.gerrit.plugins.chatgpt.integration;
+
+import com.googlesource.gerrit.plugins.chatgpt.Configuration;
+import com.googlesource.gerrit.plugins.chatgpt.client.GerritClient;
+import com.googlesource.gerrit.plugins.chatgpt.client.OpenAiClient;
+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 static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.when;
+
+//@Ignore("This test suite is designed for integration testing and is not intended to be executed during the regular build process")
+@Slf4j
+@RunWith(MockitoJUnitRunner.class)
+public class CodeReviewPluginIT {
+ @Mock
+ private Configuration configuration;
+
+ @InjectMocks
+ private GerritClient gerritClient;
+
+ @InjectMocks
+ private OpenAiClient openAiClient;
+
+ @Test
+ public void sayHelloToGPT() throws IOException, InterruptedException {
+ when(configuration.getGptToken()).thenReturn("Your GPT token");
+ when(configuration.getGptModel()).thenReturn(Configuration.DEFAULT_GPT_MODEL);
+ when(configuration.getGptPrompt()).thenReturn(Configuration.DEFAULT_GPT_PROMPT);
+
+ String answer = openAiClient.ask("hello");
+ log.info("answer: {}", answer);
+ assertNotNull(answer);
+ }
+
+ @Test
+ public void getPatchSet() throws IOException, InterruptedException {
+ when(configuration.getGerritAuthBaseUrl()).thenReturn("Your Gerrit URL");
+ when(configuration.getGerritUserName()).thenReturn("Your Gerrit username");
+ when(configuration.getGerritPassword()).thenReturn("Your Gerrit password");
+
+ String patchSet = gerritClient.getPatchSet("${changeId}");
+ log.info("patchSet: {}", patchSet);
+ assertNotNull(patchSet);
+ }
+
+ @Test
+ public void postComment() throws IOException, InterruptedException {
+ when(configuration.getGerritAuthBaseUrl()).thenReturn("Your Gerrit URL");
+ when(configuration.getGerritUserName()).thenReturn("Your Gerrit username");
+ when(configuration.getGerritPassword()).thenReturn("Your Gerrit password");
+
+ gerritClient.postComment("Your changeId", "message");
+ }
+}
diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml
new file mode 100644
index 0000000..4b12a6d
--- /dev/null
+++ b/src/test/resources/logback.xml
@@ -0,0 +1,11 @@
+<configuration>
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="debug">
+ <appender-ref ref="STDOUT"/>
+ </root>
+</configuration>
\ No newline at end of file