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.http.Request;
8   import com.jcabi.http.mock.MkAnswer;
9   import com.jcabi.http.mock.MkContainer;
10  import com.jcabi.http.mock.MkGrizzlyContainer;
11  import com.jcabi.http.mock.MkQuery;
12  import com.jcabi.http.request.ApacheRequest;
13  import com.jcabi.http.request.FakeRequest;
14  import jakarta.json.Json;
15  import jakarta.json.JsonObject;
16  import java.io.IOException;
17  import java.net.HttpURLConnection;
18  import java.util.Collection;
19  import java.util.Random;
20  import org.hamcrest.MatcherAssert;
21  import org.hamcrest.Matchers;
22  import org.junit.jupiter.api.Disabled;
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 RtPull}.
29   * @since 0.7
30   */
31  @SuppressWarnings({"PMD.TooManyMethods", "PMD.AvoidDuplicateLiterals"})
32  @ExtendWith(RandomPort.class)
33  final class RtPullTest {
34      /**
35       * Property name for ref name in pull request ref JSON object.
36       */
37      private static final String REF_PROP = "ref";
38  
39      /**
40       * Property name for commit SHA in pull request ref JSON object.
41       */
42      private static final String SHA_PROP = "sha";
43  
44      /**
45       * The rule for skipping test if there's BindException.
46       * @checkstyle VisibilityModifierCheck (3 lines)
47       */
48      @Test
49      void fetchesCommits() throws IOException {
50          try (
51              MkContainer container = new MkGrizzlyContainer().next(
52                  new MkAnswer.Simple(
53                      HttpURLConnection.HTTP_OK,
54                      "[{\"commits\":\"test\"}]"
55                  )
56              ).start(RandomPort.port())
57          ) {
58              final RtPull pull = new RtPull(
59                  new ApacheRequest(container.home()),
60                  RtPullTest.repo(),
61                  1
62              );
63              MatcherAssert.assertThat(
64                  "Value is null",
65                  pull.commits(),
66                  Matchers.notNullValue()
67              );
68              container.stop();
69          }
70      }
71  
72      @Test
73      void fetchesFiles() throws IOException {
74          try (
75              MkContainer container = new MkGrizzlyContainer().next(
76                  new MkAnswer.Simple(
77                      HttpURLConnection.HTTP_OK,
78                      "[{\"file1\":\"testFile\"}]"
79                  )
80              ).start(RandomPort.port())
81          ) {
82              final RtPull pull = new RtPull(
83                  new ApacheRequest(container.home()),
84                  RtPullTest.repo(),
85                  2
86              );
87              MatcherAssert.assertThat(
88                  "Values are not equal",
89                  pull.files().iterator().next().getString("file1"),
90                  Matchers.equalTo("testFile")
91              );
92              container.stop();
93          }
94      }
95  
96      /**
97       * RtPull can fetch its base ref.
98       * @throws IOException If some I/O problem occurs
99       */
100     @Test
101     void fetchesBase() throws IOException {
102         final String ref = "sweet-feature-branch";
103         final String sha = "e93c6a2216c69daa574abc16e7c14767fce44ad6";
104         try (
105             MkContainer container = new MkGrizzlyContainer().next(
106                 new MkAnswer.Simple(
107                     HttpURLConnection.HTTP_OK,
108                     Json.createObjectBuilder()
109                         .add(
110                             "base",
111                             Json.createObjectBuilder()
112                                 .add(RtPullTest.REF_PROP, ref)
113                                 .add(RtPullTest.SHA_PROP, sha)
114                                 .build()
115                         )
116                         .build()
117                         .toString()
118                 )
119             ).start(RandomPort.port())
120         ) {
121             final RtPull pull = new RtPull(
122                 new ApacheRequest(container.home()),
123                 RtPullTest.repo(),
124                 1
125             );
126             final PullRef base = pull.base();
127             MatcherAssert.assertThat(
128                 "Value is null",
129                 base,
130                 Matchers.notNullValue()
131             );
132             MatcherAssert.assertThat(
133                 "Values are not equal",
134                 base.ref(),
135                 Matchers.equalTo(ref)
136             );
137             MatcherAssert.assertThat(
138                 "Values are not equal",
139                 base.sha(),
140                 Matchers.equalTo(sha)
141             );
142             container.stop();
143         }
144     }
145 
146     /**
147      * RtPull can fetch its head ref.
148      * @throws IOException If some I/O problem occurs
149      */
150     @Test
151     void fetchesHead() throws IOException {
152         final String ref = "neat-other-branch";
153         final String sha = "9c717b4716e4fc4d917f546e8e6b562e810e3922";
154         try (
155             MkContainer container = new MkGrizzlyContainer().next(
156                 new MkAnswer.Simple(
157                     HttpURLConnection.HTTP_OK,
158                     RtPullTest.head(ref, sha).toString()
159                 )
160             ).start(RandomPort.port())
161         ) {
162             final RtPull pull = new RtPull(
163                 new ApacheRequest(container.home()),
164                 RtPullTest.repo(),
165                 1
166             );
167             final PullRef head = pull.head();
168             MatcherAssert.assertThat(
169                 "Value is null",
170                 head,
171                 Matchers.notNullValue()
172             );
173             MatcherAssert.assertThat(
174                 "Values are not equal",
175                 head.ref(),
176                 Matchers.equalTo(ref)
177             );
178             MatcherAssert.assertThat(
179                 "Values are not equal",
180                 head.sha(),
181                 Matchers.equalTo(sha)
182             );
183             container.stop();
184         }
185     }
186 
187     @Test
188     void executeMerge() throws IOException {
189         try (
190             MkContainer container = new MkGrizzlyContainer().next(
191                 new MkAnswer.Simple(HttpURLConnection.HTTP_OK, "testMerge")
192             ).start(RandomPort.port())
193         ) {
194             final RtPull pull = new RtPull(
195                 new ApacheRequest(container.home()),
196                 RtPullTest.repo(),
197                 3
198             );
199             pull.merge("Test commit.");
200             final MkQuery query = container.take();
201             MatcherAssert.assertThat(
202                 "Values are not equal",
203                 query.method(),
204                 Matchers.equalTo(Request.PUT)
205             );
206             MatcherAssert.assertThat(
207                 "Values are not equal",
208                 query.body(),
209                 Matchers.equalTo("{\"commit_message\":\"Test commit.\"}")
210             );
211             container.stop();
212         }
213     }
214 
215     /**
216      * RtPull should be able to fetch pull checks.
217      * @throws IOException If some I/O problem occurs.
218      */
219     @Test
220     void canFetchChecks() throws IOException {
221         try (
222             MkContainer container = new MkGrizzlyContainer()
223                 .next(
224                     new MkAnswer.Simple(
225                         HttpURLConnection.HTTP_OK,
226                         RtPullTest.head().toString()
227                     )
228                 )
229                 .next(
230                     new MkAnswer.Simple(
231                         HttpURLConnection.HTTP_OK,
232                         RtPullTest.check().toString()
233                     )
234                 )
235                 .start(RandomPort.port())
236         ) {
237             final Collection<? extends Check> all = new RtPull(
238                 new ApacheRequest(container.home()),
239                 RtPullTest.repo(),
240                 new Random().nextInt()
241             ).checks().all();
242             MatcherAssert.assertThat(
243                 "Collection size is incorrect",
244                 all,
245                 Matchers.hasSize(1)
246             );
247             MatcherAssert.assertThat(
248                 "Values are not equal",
249                 all.iterator().next().successful(),
250                 Matchers.is(true)
251             );
252             container.stop();
253         }
254     }
255 
256     @Test
257     void canCompareInstances() {
258         final RtPull less = new RtPull(new FakeRequest(), RtPullTest.repo(), 1);
259         final RtPull greater = new RtPull(new FakeRequest(), RtPullTest.repo(), 2);
260         MatcherAssert.assertThat(
261             "Value is not less than expected",
262             less.compareTo(greater), Matchers.lessThan(0)
263         );
264         MatcherAssert.assertThat(
265             "Value is not greater than expected",
266             greater.compareTo(less), Matchers.greaterThan(0)
267         );
268     }
269 
270     @Test
271     @Disabled
272     void canFetchComments() {
273         //to be implemented
274     }
275 
276     /**
277      * Mock repository for testing purposes.
278      * @return Repo the mock repository.
279      */
280     private static Repo repo() {
281         final Repo repo = Mockito.mock(Repo.class);
282         final Coordinates coords = Mockito.mock(Coordinates.class);
283         Mockito.doReturn(coords).when(repo).coordinates();
284         Mockito.doReturn("/user").when(coords).user();
285         Mockito.doReturn("/repo").when(coords).repo();
286         return repo;
287     }
288 
289     /**
290      * Check as JSON object.
291      * @return Check as JSON object.
292      */
293     private static JsonObject check() {
294         return Json.createObjectBuilder()
295             .add("total_count", Json.createValue(1))
296             .add(
297                 "check_runs",
298                 Json.createArrayBuilder()
299                     .add(
300                         Json.createObjectBuilder()
301                             .add("id", Json.createValue(new Random().nextInt()))
302                             .add("status", "completed")
303                             .add("conclusion", "success")
304                             .build()
305                     )
306             ).build();
307     }
308 
309     /**
310      * Head as JSON object.
311      * @return Head as JSON object.
312      */
313     private static JsonObject head() {
314         return RtPullTest.head(
315             "ref-ref",
316             "6d299617d9094ae6940b3958bbabab68fd1ddabb"
317         );
318     }
319 
320     /**
321      * Head as JSON object.
322      * @param ref Ref.
323      * @param sha Sha.
324      * @return Head as JSON object.
325      */
326     private static JsonObject head(final String ref, final String sha) {
327         return Json.createObjectBuilder()
328             .add(
329                 "head",
330                 Json.createObjectBuilder()
331                     .add(RtPullTest.REF_PROP, ref)
332                     .add(RtPullTest.SHA_PROP, sha)
333                     .build()
334             )
335             .build();
336     }
337 
338 }