View Javadoc
1   /**
2    * Copyright (c) 2013-2023, jcabi.com
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met: 1) Redistributions of source code must retain the above
8    * copyright notice, this list of conditions and the following
9    * disclaimer. 2) Redistributions in binary form must reproduce the above
10   * copyright notice, this list of conditions and the following
11   * disclaimer in the documentation and/or other materials provided
12   * with the distribution. 3) Neither the name of the jcabi.com nor
13   * the names of its contributors may be used to endorse or promote
14   * products derived from this software without specific prior written
15   * permission.
16   *
17   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
19   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21   * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28   * OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  package com.jcabi.github;
31  
32  import com.jcabi.http.mock.MkAnswer;
33  import com.jcabi.http.mock.MkContainer;
34  import com.jcabi.http.mock.MkGrizzlyContainer;
35  import com.jcabi.http.request.JdkRequest;
36  import java.io.IOException;
37  import java.net.HttpURLConnection;
38  import java.util.Arrays;
39  import java.util.Collection;
40  import java.util.Random;
41  import javax.json.Json;
42  import javax.json.JsonArrayBuilder;
43  import javax.json.JsonObjectBuilder;
44  import javax.json.JsonValue;
45  import org.hamcrest.MatcherAssert;
46  import org.hamcrest.Matchers;
47  import org.junit.Assert;
48  import org.junit.Rule;
49  import org.junit.Test;
50  import org.mockito.Mockito;
51  
52  /**
53   * Test case for {@link RtChecks}.
54   *
55   * @author Volodya Lombrozo (volodya.lombrozo@gmail.com)
56   * @version $Id: c7e5f61ae479c2337fe0a61b293681c4e1a6994b $
57   * @since 1.5.0
58   */
59  public final class RtChecksTest {
60  
61      /**
62       * Conclusion key in json check.
63       */
64      private static final String CONCLUSION_KEY = "conclusion";
65  
66      /**
67       * Status key in json check.
68       */
69      private static final String STATUS_KEY = "status";
70  
71      /**
72       * The rule for skipping test if there's BindException.
73       * @checkstyle VisibilityModifierCheck (3 lines)
74       */
75      @Rule
76      public final transient RandomPort resource = new RandomPort();
77  
78      /**
79       * Checks whether RtChecks can get all checks.
80       *
81       * @throws IOException If some problem happens.
82       */
83      @Test
84      public void getsAllChecks() throws IOException {
85          try (final MkContainer container = new MkGrizzlyContainer()
86              .next(
87                  new MkAnswer.Simple(
88                      HttpURLConnection.HTTP_OK,
89                      RtChecksTest.jsonWithCheckRuns()
90                  )
91              )
92              .start(this.resource.port())) {
93              final Checks checks = new RtChecks(
94                  new JdkRequest(container.home()),
95                  this.repo().pulls().get(0)
96              );
97              MatcherAssert.assertThat(
98                  checks.all(),
99                  Matchers.iterableWithSize(1)
100             );
101         }
102     }
103 
104     /**
105      * Checks whether RtChecks can return empty checks if they are absent.
106      *
107      * @throws IOException If some I/O problem happens.
108      */
109     @Test
110     public void returnsEmptyChecksIfTheyAreAbsent() throws IOException {
111         try (final MkContainer container = new MkGrizzlyContainer()
112             .next(
113                 new MkAnswer.Simple(
114                     HttpURLConnection.HTTP_OK,
115                     RtChecksTest.empty()
116                 )
117             )
118             .start(this.resource.port())) {
119             MatcherAssert.assertThat(
120                 ((Checks) new RtChecks(
121                     new JdkRequest(container.home()),
122                     this.repo().pulls().get(0)
123                 )).all(),
124                 Matchers.iterableWithSize(0)
125             );
126         }
127     }
128 
129     /**
130      * Checks whether RtChecks can throw an exception
131      * if response code is not 200.
132      *
133      * @throws IOException If some I/O problem happens.
134      */
135     @Test
136     public void assertsOkResponse() throws IOException {
137         try (final MkContainer container = new MkGrizzlyContainer()
138             .next(
139                 new MkAnswer.Simple(
140                     HttpURLConnection.HTTP_NOT_FOUND,
141                     RtChecksTest.jsonWithCheckRuns()
142                 )
143             ).start(this.resource.port())
144         ) {
145             final Checks checks = new RtChecks(
146                 new JdkRequest(container.home()),
147                 this.repo().pulls().get(0)
148             );
149             Assert.assertThrows(
150                 AssertionError.class,
151                 checks::all
152             );
153         }
154     }
155 
156     /**
157      * Checks that library can handle unfinished checks.
158      * @throws IOException If some I/O problem happens.
159      */
160     @Test
161     public void retrievesUnfinishedChecksWithoutConclusion()
162         throws IOException {
163         try (final MkContainer container = new MkGrizzlyContainer()
164             .next(
165                 new MkAnswer.Simple(
166                     HttpURLConnection.HTTP_OK,
167                     RtChecksTest.jsonChecks(
168                         RtChecksTest.jsonCheck()
169                             .add(
170                                 RtChecksTest.CONCLUSION_KEY,
171                                 Check.Conclusion.SUCCESS.value()
172                             )
173                     )
174                 )
175             ).start(this.resource.port())
176         ) {
177             final Checks checks = new RtChecks(
178                 new JdkRequest(container.home()),
179                 this.repo().pulls().get(0)
180             );
181             final Collection<? extends Check> all = checks.all();
182             MatcherAssert.assertThat(all, Matchers.hasSize(1));
183             for (final Check check : all) {
184                 MatcherAssert.assertThat(
185                     check.successful(),
186                     Matchers.is(false)
187                 );
188             }
189         }
190     }
191 
192     /**
193      * Checks that library can handle unfinished checks.
194      * @throws IOException If some I/O problem happens.
195      */
196     @Test
197     public void retrievesUnfinishedChecksWithNullableConclusion()
198         throws IOException {
199         try (final MkContainer container = new MkGrizzlyContainer()
200             .next(
201                 new MkAnswer.Simple(
202                     HttpURLConnection.HTTP_OK,
203                     RtChecksTest.jsonChecks(
204                         RtChecksTest.jsonCheck()
205                             .add(
206                                 RtChecksTest.CONCLUSION_KEY,
207                                 JsonValue.NULL
208                             ).add(
209                                 RtChecksTest.STATUS_KEY,
210                                 Check.Status.QUEUED.value()
211                             )
212                     )
213                 )
214             ).start(this.resource.port())
215         ) {
216             final Checks checks = new RtChecks(
217                 new JdkRequest(container.home()),
218                 this.repo().pulls().get(0)
219             );
220             final Collection<? extends Check> all = checks.all();
221             MatcherAssert.assertThat(all, Matchers.hasSize(1));
222             for (final Check check : all) {
223                 MatcherAssert.assertThat(
224                     check.successful(),
225                     Matchers.is(false)
226                 );
227             }
228         }
229     }
230 
231     /**
232      * Checks that library can handle unfinished checks.
233      * @throws IOException If some I/O problem happens.
234      */
235     @Test
236     public void retrievesUnfinishedChecksWithoutStatusAndConclusion()
237         throws IOException {
238         try (final MkContainer container = new MkGrizzlyContainer()
239             .next(
240                 new MkAnswer.Simple(
241                     HttpURLConnection.HTTP_OK,
242                     RtChecksTest.jsonChecks(
243                         RtChecksTest.jsonCheck()
244                     )
245                 )
246             ).start(this.resource.port())
247         ) {
248             final Checks checks = new RtChecks(
249                 new JdkRequest(container.home()),
250                 this.repo().pulls().get(0)
251             );
252             final Collection<? extends Check> all = checks.all();
253             MatcherAssert.assertThat(all, Matchers.hasSize(1));
254             for (final Check check : all) {
255                 MatcherAssert.assertThat(
256                     check.successful(),
257                     Matchers.is(false)
258                 );
259             }
260         }
261     }
262 
263     /**
264      * Creates json response body.
265      *
266      * @return Json response body.
267      */
268     private static String jsonWithCheckRuns() {
269         return RtChecksTest.jsonChecks(
270             RtChecksTest.jsonCheck()
271                 .add(
272                     RtChecksTest.STATUS_KEY,
273                     Check.Status.COMPLETED.value()
274                 )
275                 .add(
276                     RtChecksTest.CONCLUSION_KEY,
277                     Check.Conclusion.SUCCESS.value()
278                 )
279         );
280     }
281 
282     /**
283      * Creates Json Check Builder.
284      * @return JsonObjectBuilder.
285      */
286     private static JsonObjectBuilder jsonCheck() {
287         return Json.createObjectBuilder()
288             .add("id", Json.createValue(new Random().nextInt()));
289     }
290 
291     /**
292      * Creates json checks.
293      * @param checks All checks that have to be included.
294      * @return Json.
295      */
296     private static String jsonChecks(final JsonObjectBuilder... checks) {
297         final JsonArrayBuilder all = Json.createArrayBuilder();
298         Arrays.stream(checks).map(JsonObjectBuilder::build).forEach(all::add);
299         return Json.createObjectBuilder()
300             .add("total_count", Json.createValue(1))
301             .add("check_runs", all.build())
302             .build()
303             .toString();
304     }
305 
306     /**
307      * Creates json response body without check runs.
308      * @return Json response body.
309      */
310     private static String empty() {
311         return Json.createObjectBuilder()
312             .build()
313             .toString();
314     }
315 
316     /**
317      * Create and return repo for testing.
318      * @return Repo
319      * @throws IOException If some problem happens.
320      */
321     private Repo repo() throws IOException {
322         final Repo repo = Mockito.mock(Repo.class);
323         final Pulls pulls = Mockito.mock(Pulls.class);
324         final Pull pull = Mockito.mock(Pull.class);
325         final PullRef ref = Mockito.mock(PullRef.class);
326         Mockito.doReturn(
327                 new Coordinates.Simple("volodya-lombrozo", "jtcop")
328             ).when(repo)
329             .coordinates();
330         Mockito.doReturn(pulls).when(repo).pulls();
331         Mockito.doReturn(pull).when(pulls).get(0);
332         Mockito.doReturn(repo).when(pull).repo();
333         Mockito.doReturn(ref).when(pull).head();
334         Mockito.doReturn("abcdef1").when(ref).sha();
335         return repo;
336     }
337 }