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.mock.MkAnswer;
8   import com.jcabi.http.mock.MkContainer;
9   import com.jcabi.http.mock.MkGrizzlyContainer;
10  import com.jcabi.http.request.JdkRequest;
11  import jakarta.json.Json;
12  import jakarta.json.JsonArrayBuilder;
13  import jakarta.json.JsonObjectBuilder;
14  import jakarta.json.JsonValue;
15  import java.io.IOException;
16  import java.net.HttpURLConnection;
17  import java.util.Arrays;
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.Test;
23  import org.junit.jupiter.api.extension.ExtendWith;
24  import org.mockito.Mockito;
25  
26  /**
27   * Test case for {@link RtChecks}.
28   *
29   * @since 1.5.0
30   */
31  @ExtendWith(RandomPort.class)
32  @SuppressWarnings("PMD.AvoidDuplicateLiterals")
33  final class RtChecksTest {
34  
35      /**
36       * Conclusion key in json check.
37       */
38      private static final String CONCLUSION_KEY = "conclusion";
39  
40      /**
41       * Status key in json check.
42       */
43      private static final String STATUS_KEY = "status";
44  
45      /**
46       * Checks whether RtChecks can get all checks.
47       * @throws IOException If some problem happens.
48       */
49      @Test
50      void getsAllChecks() throws IOException {
51          try (MkContainer container = new MkGrizzlyContainer()
52              .next(
53                  new MkAnswer.Simple(
54                      HttpURLConnection.HTTP_OK,
55                      RtChecksTest.jsonWithCheckRuns()
56                  )
57              )
58              .start(RandomPort.port())) {
59              final Checks checks = new RtChecks(
60                  new JdkRequest(container.home()),
61                  RtChecksTest.repo().pulls().get(0)
62              );
63              MatcherAssert.assertThat(
64                  "Collection size is incorrect",
65                  checks.all(),
66                  Matchers.iterableWithSize(1)
67              );
68          }
69      }
70  
71      /**
72       * Checks whether RtChecks can return empty checks if they are absent.
73       * @throws IOException If some I/O problem happens.
74       */
75      @Test
76      void returnsEmptyChecksIfTheyAreAbsent() throws IOException {
77          try (MkContainer container = new MkGrizzlyContainer()
78              .next(
79                  new MkAnswer.Simple(
80                      HttpURLConnection.HTTP_OK,
81                      RtChecksTest.empty()
82                  )
83              )
84              .start(RandomPort.port())) {
85              MatcherAssert.assertThat(
86                  "Collection size is incorrect",
87                  ((Checks) new RtChecks(
88                      new JdkRequest(container.home()),
89                      RtChecksTest.repo().pulls().get(0)
90                  )).all(),
91                  Matchers.iterableWithSize(0)
92              );
93          }
94      }
95  
96      /**
97       * Checks whether RtChecks can throw an exception
98       * if response code is not 200.
99       * @throws IOException If some I/O problem happens.
100      */
101     @Test
102     void assertsOkResponse() throws IOException {
103         try (MkContainer container = new MkGrizzlyContainer()
104             .next(
105                 new MkAnswer.Simple(
106                     HttpURLConnection.HTTP_NOT_FOUND,
107                     RtChecksTest.jsonWithCheckRuns()
108                 )
109             ).start(RandomPort.port())
110         ) {
111             final Checks checks = new RtChecks(
112                 new JdkRequest(container.home()),
113                 RtChecksTest.repo().pulls().get(0)
114             );
115             try {
116                 checks.all();
117                 MatcherAssert.assertThat(
118                     "AssertionError was expected",
119                     false,
120                     Matchers.is(true)
121                 );
122             } catch (final AssertionError ex) {
123                 MatcherAssert.assertThat(
124                     "Exception was thrown as expected",
125                     ex,
126                     Matchers.notNullValue()
127                 );
128             }
129         }
130     }
131 
132     /**
133      * Checks that library can handle unfinished checks.
134      * @throws IOException If some I/O problem happens.
135      */
136     @Test
137     void retrievesUnfinishedChecksWithoutConclusion()
138         throws IOException {
139         try (MkContainer container = new MkGrizzlyContainer()
140             .next(
141                 new MkAnswer.Simple(
142                     HttpURLConnection.HTTP_OK,
143                     RtChecksTest.jsonChecks(
144                         RtChecksTest.jsonCheck()
145                             .add(
146                                 RtChecksTest.CONCLUSION_KEY,
147                                 Check.Conclusion.SUCCESS.value()
148                             )
149                     )
150                 )
151             ).start(RandomPort.port())
152         ) {
153             final Checks checks = new RtChecks(
154                 new JdkRequest(container.home()),
155                 RtChecksTest.repo().pulls().get(0)
156             );
157             final Collection<? extends Check> all = checks.all();
158             MatcherAssert.assertThat(
159                 "Collection size is incorrect", all, Matchers.hasSize(1)
160             );
161             for (final Check check : all) {
162                 MatcherAssert.assertThat(
163                     "Values are not equal",
164                     check.successful(),
165                     Matchers.is(false)
166                 );
167             }
168         }
169     }
170 
171     /**
172      * Checks that library can handle unfinished checks.
173      * @throws IOException If some I/O problem happens.
174      */
175     @Test
176     void retrievesUnfinishedChecksWithNullableConclusion()
177         throws IOException {
178         try (MkContainer container = new MkGrizzlyContainer()
179             .next(
180                 new MkAnswer.Simple(
181                     HttpURLConnection.HTTP_OK,
182                     RtChecksTest.jsonChecks(
183                         RtChecksTest.jsonCheck()
184                             .add(
185                                 RtChecksTest.CONCLUSION_KEY,
186                                 JsonValue.NULL
187                             ).add(
188                                 RtChecksTest.STATUS_KEY,
189                                 Check.Status.QUEUED.value()
190                             )
191                     )
192                 )
193             ).start(RandomPort.port())
194         ) {
195             final Checks checks = new RtChecks(
196                 new JdkRequest(container.home()),
197                 RtChecksTest.repo().pulls().get(0)
198             );
199             final Collection<? extends Check> all = checks.all();
200             MatcherAssert.assertThat(
201                 "Collection size is incorrect", all, Matchers.hasSize(1)
202             );
203             for (final Check check : all) {
204                 MatcherAssert.assertThat(
205                     "Values are not equal",
206                     check.successful(),
207                     Matchers.is(false)
208                 );
209             }
210         }
211     }
212 
213     /**
214      * Checks that library can handle unfinished checks.
215      * @throws IOException If some I/O problem happens.
216      */
217     @Test
218     void retrievesUnfinishedChecksWithoutStatusAndConclusion()
219         throws IOException {
220         try (MkContainer container = new MkGrizzlyContainer()
221             .next(
222                 new MkAnswer.Simple(
223                     HttpURLConnection.HTTP_OK,
224                     RtChecksTest.jsonChecks(
225                         RtChecksTest.jsonCheck()
226                     )
227                 )
228             ).start(RandomPort.port())
229         ) {
230             final Checks checks = new RtChecks(
231                 new JdkRequest(container.home()),
232                 RtChecksTest.repo().pulls().get(0)
233             );
234             final Collection<? extends Check> all = checks.all();
235             MatcherAssert.assertThat(
236                 "Collection size is incorrect", all, Matchers.hasSize(1)
237             );
238             for (final Check check : all) {
239                 MatcherAssert.assertThat(
240                     "Values are not equal",
241                     check.successful(),
242                     Matchers.is(false)
243                 );
244             }
245         }
246     }
247 
248     /**
249      * Creates json response body.
250      *
251      * @return Json response body.
252      */
253     private static String jsonWithCheckRuns() {
254         return RtChecksTest.jsonChecks(
255             RtChecksTest.jsonCheck()
256                 .add(
257                     RtChecksTest.STATUS_KEY,
258                     Check.Status.COMPLETED.value()
259                 )
260                 .add(
261                     RtChecksTest.CONCLUSION_KEY,
262                     Check.Conclusion.SUCCESS.value()
263                 )
264         );
265     }
266 
267     /**
268      * Creates Json Check Builder.
269      * @return JsonObjectBuilder.
270      */
271     private static JsonObjectBuilder jsonCheck() {
272         return Json.createObjectBuilder()
273             .add("id", Json.createValue(new Random().nextInt()));
274     }
275 
276     /**
277      * Creates json checks.
278      * @param checks All checks that have to be included.
279      * @return Json.
280      */
281     private static String jsonChecks(final JsonObjectBuilder... checks) {
282         final JsonArrayBuilder all = Json.createArrayBuilder();
283         Arrays.stream(checks).map(JsonObjectBuilder::build).forEach(all::add);
284         return Json.createObjectBuilder()
285             .add("total_count", Json.createValue(1))
286             .add("check_runs", all.build())
287             .build()
288             .toString();
289     }
290 
291     /**
292      * Creates json response body without check runs.
293      * @return Json response body.
294      */
295     private static String empty() {
296         return Json.createObjectBuilder()
297             .build()
298             .toString();
299     }
300 
301     /**
302      * Create and return repo for testing.
303      * @return Repo
304      * @throws IOException If some problem happens.
305      */
306     private static Repo repo() throws IOException {
307         final Repo repo = Mockito.mock(Repo.class);
308         final Pulls pulls = Mockito.mock(Pulls.class);
309         final Pull pull = Mockito.mock(Pull.class);
310         final PullRef ref = Mockito.mock(PullRef.class);
311         Mockito.doReturn(
312             new Coordinates.Simple("volodya-lombrozo", "jtcop")
313         ).when(repo)
314             .coordinates();
315         Mockito.doReturn(pulls).when(repo).pulls();
316         Mockito.doReturn(pull).when(pulls).get(0);
317         Mockito.doReturn(repo).when(pull).repo();
318         Mockito.doReturn(ref).when(pull).head();
319         Mockito.doReturn("abcdef1").when(ref).sha();
320         return repo;
321     }
322 }