View Javadoc
1   /*
2    * SPDX-FileCopyrightText: Copyright (c) 2013-2025 Yegor Bugayenko
3    * SPDX-License-Identifier: MIT
4    */
5   package com.jcabi.github;
6   
7   import com.jcabi.github.mock.MkGitHub;
8   import com.jcabi.http.Request;
9   import com.jcabi.http.mock.MkAnswer;
10  import com.jcabi.http.mock.MkContainer;
11  import com.jcabi.http.mock.MkGrizzlyContainer;
12  import com.jcabi.http.mock.MkQuery;
13  import com.jcabi.http.request.ApacheRequest;
14  import com.jcabi.http.request.FakeRequest;
15  import com.jcabi.http.request.JdkRequest;
16  import jakarta.json.Json;
17  import jakarta.json.JsonObject;
18  import java.io.IOException;
19  import java.net.HttpURLConnection;
20  import java.util.Collections;
21  import org.hamcrest.MatcherAssert;
22  import org.hamcrest.Matchers;
23  import org.junit.jupiter.api.Test;
24  import org.junit.jupiter.api.extension.ExtendWith;
25  import org.mockito.Mockito;
26  
27  /**
28   * Test case for {@link RtPullComments}.
29   * @since 0.8
30   * @checkstyle ClassDataAbstractionCoupling (500 lines)
31   */
32  @SuppressWarnings({"PMD.TooManyMethods", "PMD.AvoidDuplicateLiterals"})
33  @ExtendWith(RandomPort.class)
34  final class RtPullCommentsTest {
35  
36      /**
37       * RtPullComments can fetch a single comment.
38       *
39       * @throws Exception If something goes wrong.
40       */
41      @Test
42      void fetchesPullComment() throws Exception {
43          final Pull pull = Mockito.mock(Pull.class);
44          Mockito.doReturn(RtPullCommentsTest.repo()).when(pull).repo();
45          final RtPullComments comments =
46              new RtPullComments(new FakeRequest(), pull);
47          MatcherAssert.assertThat(
48              "Value is null",
49              comments.get(1),
50              Matchers.notNullValue()
51          );
52      }
53  
54      /**
55       * RtPullComments can fetch all pull comments for a repo.
56       *
57       * @throws Exception If something goes wrong.
58       */
59      @Test
60      void iteratesRepoPullComments() throws Exception {
61          final Pull pull = Mockito.mock(Pull.class);
62          Mockito.doReturn(RtPullCommentsTest.repo()).when(pull).repo();
63          try (
64              MkContainer container = new MkGrizzlyContainer().next(
65                  new MkAnswer.Simple(
66                      HttpURLConnection.HTTP_OK,
67                      Json.createArrayBuilder()
68                          .add(RtPullCommentsTest.comment("comment 1"))
69                          .add(RtPullCommentsTest.comment("comment 2"))
70                          .build().toString()
71                  )
72              ).start(RandomPort.port())
73          ) {
74              final RtPullComments comments = new RtPullComments(
75                  new JdkRequest(container.home()), pull
76              );
77              MatcherAssert.assertThat(
78                  "Collection size is incorrect",
79                  comments.iterate(Collections.emptyMap()),
80                  Matchers.iterableWithSize(2)
81              );
82              container.stop();
83          }
84      }
85  
86      /**
87       * RtPullComments can fetch pull comments for a pull request.
88       *
89       * @throws Exception If something goes wrong.
90       */
91      @Test
92      void iteratesPullRequestComments() throws Exception {
93          final Pull pull = Mockito.mock(Pull.class);
94          Mockito.doReturn(RtPullCommentsTest.repo()).when(pull).repo();
95          try (
96              MkContainer container = new MkGrizzlyContainer().next(
97                  new MkAnswer.Simple(
98                      HttpURLConnection.HTTP_OK,
99                      Json.createArrayBuilder()
100                         .add(RtPullCommentsTest.comment("comment 3"))
101                         .add(RtPullCommentsTest.comment("comment 4"))
102                         .build().toString()
103                 )
104             ).start(RandomPort.port())
105         ) {
106             final RtPullComments comments = new RtPullComments(
107                 new JdkRequest(container.home()), pull
108             );
109             MatcherAssert.assertThat(
110                 "Collection size is incorrect",
111                 comments.iterate(1, Collections.emptyMap()),
112                 Matchers.iterableWithSize(2)
113             );
114             container.stop();
115         }
116     }
117 
118     /**
119      * RtPullComments can post a new a pull comment.
120      *
121      * @throws Exception If something goes wrong.
122      */
123     @Test
124     void createsPullComment() throws Exception {
125         // @checkstyle MultipleStringLiterals (3 line)
126         final String body = "test-body";
127         final String commit = "test-commit-id";
128         final String path = "test-path";
129         final int position = 4;
130         final String response = RtPullCommentsTest.pulls(body, commit, path, position).toString();
131         try (
132             MkContainer container = new MkGrizzlyContainer().next(
133                 new MkAnswer.Simple(HttpURLConnection.HTTP_CREATED, response)
134             ).next(new MkAnswer.Simple(HttpURLConnection.HTTP_OK, response))
135                 .start(RandomPort.port())
136         ) {
137             final Pull pull = Mockito.mock(Pull.class);
138             Mockito.doReturn(RtPullCommentsTest.repo()).when(pull).repo();
139             final RtPullComments comments = new RtPullComments(
140                 new ApacheRequest(container.home()),
141                     pull
142             );
143             final PullComment comment = comments.post(
144                 body, commit, path, position
145             );
146             MatcherAssert.assertThat(
147                 "Values are not equal",
148                 container.take().method(),
149                 Matchers.equalTo(Request.POST)
150             );
151             MatcherAssert.assertThat(
152                 "Values are not equal",
153                 new PullComment.Smart(comment).commitId(),
154                 Matchers.equalTo(commit)
155             );
156             container.stop();
157         }
158     }
159 
160     /**
161      * RtPullComments can reply to an existing pull comment.
162      *
163      * @throws Exception If something goes wrong.
164      */
165     @Test
166     void createsPullCommentReply() throws Exception {
167         final String body = "test-body";
168         final int number = 4;
169         final String response = Json.createObjectBuilder()
170             // @checkstyle MultipleStringLiterals (2 line)
171             .add("id", 1_000_000_000)
172             .add("body", body)
173             .add("in_reply_to", number)
174             .build()
175             .toString();
176         try (
177             MkContainer container = new MkGrizzlyContainer().next(
178                 new MkAnswer.Simple(HttpURLConnection.HTTP_CREATED, response)
179             ).next(new MkAnswer.Simple(HttpURLConnection.HTTP_OK, response))
180                 .start(RandomPort.port())
181         ) {
182             final Pull pull = Mockito.mock(Pull.class);
183             Mockito.doReturn(RtPullCommentsTest.repo()).when(pull).repo();
184             final RtPullComments comments = new RtPullComments(
185                 new ApacheRequest(container.home()),
186                     pull
187             );
188             final PullComment comment = comments.reply(
189                 body, number
190             );
191             MatcherAssert.assertThat(
192                 "Values are not equal",
193                 container.take().method(),
194                 Matchers.equalTo(Request.POST)
195             );
196             MatcherAssert.assertThat(
197                 "Values are not equal",
198                 new PullComment.Smart(comment).reply(),
199                 Matchers.equalTo(number)
200             );
201             container.stop();
202         }
203     }
204 
205     /**
206      * RtPullComments can remove a pull comment.
207      *
208      * @throws Exception If something goes wrong.
209      */
210     @Test
211     void removesPullComment() throws Exception {
212         try (
213             MkContainer container = new MkGrizzlyContainer().next(
214                 new MkAnswer.Simple(HttpURLConnection.HTTP_NO_CONTENT, "")
215             ).start(RandomPort.port())
216         ) {
217             final Pull pull = Mockito.mock(Pull.class);
218             final Repo repository = RtPullCommentsTest.repo();
219             Mockito.doReturn(repository).when(pull).repo();
220             final RtPullComments comments =
221                 new RtPullComments(new ApacheRequest(container.home()), pull);
222             comments.remove(2);
223             final MkQuery query = container.take();
224             MatcherAssert.assertThat(
225                 "Values are not equal",
226                 query.method(), Matchers.equalTo(Request.DELETE)
227             );
228             MatcherAssert.assertThat(
229                 "String does not end with expected value",
230                 query.uri().toString(),
231                 Matchers.endsWith(
232                     String.format(
233                         "/repos/johnny/%s/pulls/0/comments/2",
234                         repository.coordinates().repo()
235                     )
236                 )
237             );
238             container.stop();
239         }
240     }
241 
242     /**
243      * This method returns a Repo for testing.
244      * @return Repo - a repo to be used for test.
245      */
246     private static Repo repo() throws IOException {
247         return new MkGitHub("johnny").randomRepo();
248     }
249 
250     /**
251      * Create and return JsonObject to test.
252      * @param body The body
253      * @param commit Commit
254      * @param path Path
255      * @param position Position
256      * @return JsonObject
257      * @checkstyle ParameterNumberCheck (10 lines)
258      */
259     private static JsonObject pulls(final String body, final String commit,
260         final String path, final int position) {
261         return Json.createObjectBuilder()
262             // @checkstyle MultipleStringLiterals (2 line)
263             .add("id", 1_000_000_000)
264             .add("body", body)
265             .add("commit_id", commit)
266             .add("path", path)
267             .add("position", position)
268             .build();
269     }
270 
271     /**
272      * Create and return JsonObject to test.
273      * @param bodytext Body of the comment
274      * @return JsonObject
275      */
276     private static JsonObject comment(final String bodytext) {
277         return Json.createObjectBuilder()
278             // @checkstyle MultipleStringLiterals (2 line)
279             .add("id", 1)
280             .add("body", bodytext)
281             .build();
282     }
283 
284 }