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.Request;
33  import com.jcabi.http.mock.MkAnswer;
34  import com.jcabi.http.mock.MkContainer;
35  import com.jcabi.http.mock.MkGrizzlyContainer;
36  import com.jcabi.http.mock.MkQuery;
37  import com.jcabi.http.request.ApacheRequest;
38  import com.jcabi.http.request.FakeRequest;
39  import java.io.IOException;
40  import java.net.HttpURLConnection;
41  import java.util.Iterator;
42  import javax.json.Json;
43  import javax.json.JsonObject;
44  import javax.json.JsonValue;
45  import javax.ws.rs.core.UriBuilder;
46  import org.hamcrest.MatcherAssert;
47  import org.hamcrest.Matchers;
48  import org.junit.Rule;
49  import org.junit.Test;
50  import org.mockito.Mockito;
51  
52  /**
53   * Test case for {@link RtRepo}.
54   *
55   * @author Giang Le (giang@vn-smartsolutions.com)
56   * @author Paulo Lobo (pauloeduardolobo@gmail.com)
57   * @version $Id: cbd03edcebb25e79e177f8a2de0d77e394a9e191 $
58   */
59  @SuppressWarnings("PMD.TooManyMethods")
60  public final class RtRepoTest {
61  
62      /**
63       * Repo user for tests.
64       */
65      private static final String TEST_USER = "testuser";
66  
67      /**
68       * Repo name for tests.
69       */
70      private static final String TEST_REPO = "testrepo";
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       * RtRepo can fetch events.
80       *
81       * @throws Exception If some problem inside
82       */
83      @Test
84      public void iteratesEvents() throws Exception {
85          try (
86              final MkContainer container = new MkGrizzlyContainer().next(
87                  new MkAnswer.Simple(
88                      HttpURLConnection.HTTP_OK,
89                      Json.createArrayBuilder()
90                          .add(event(Event.ASSIGNED))
91                          .add(event(Event.MENTIONED))
92                          .build().toString()
93                  )
94              ).start(this.resource.port())
95          ) {
96              final Repo repo = RtRepoTest.repo(
97                  new ApacheRequest(container.home())
98              );
99              MatcherAssert.assertThat(
100                 repo.issueEvents().iterate(),
101                 Matchers.<Event>iterableWithSize(2)
102             );
103             container.stop();
104         }
105     }
106 
107     /**
108      * RtRepo can fetch its labels.
109      *
110      */
111     @Test
112     public void fetchesLabels() {
113         final Repo repo = RtRepoTest.repo(
114             new FakeRequest()
115         );
116         MatcherAssert.assertThat(
117             repo.labels(),
118             Matchers.notNullValue()
119         );
120     }
121 
122     /**
123      * RtRepo can fetch its issues.
124      *
125      */
126     @Test
127     public void fetchesIssues() {
128         final Repo repo = RtRepoTest.repo(
129             new FakeRequest()
130         );
131         MatcherAssert.assertThat(
132             repo.issues(),
133             Matchers.notNullValue()
134         );
135     }
136 
137     /**
138      * RtRepo can fetch its branches.
139      *
140      */
141     @Test
142     public void fetchesBranches() {
143         final Repo repo = RtRepoTest.repo(
144             new FakeRequest()
145         );
146         MatcherAssert.assertThat(
147             repo.branches(),
148             Matchers.notNullValue()
149         );
150     }
151 
152     /**
153      * RtRepo can fetch its pulls.
154      *
155      */
156     @Test
157     public void fetchesPulls() {
158         final Repo repo = RtRepoTest.repo(
159             new FakeRequest()
160         );
161         MatcherAssert.assertThat(
162             repo.pulls(),
163             Matchers.notNullValue()
164         );
165     }
166 
167     /**
168      * RtRepo can fetch its hooks.
169      *
170      */
171     @Test
172     public void fetchHooks() {
173         final Repo repo = RtRepoTest.repo(
174             new FakeRequest()
175         );
176         MatcherAssert.assertThat(
177             repo.hooks(),
178             Matchers.notNullValue()
179         );
180     }
181 
182     /**
183      * RtRepo can fetch its keys.
184      *
185      */
186     @Test
187     public void fetchKeys() {
188         final Repo repo = RtRepoTest.repo(
189             new FakeRequest()
190         );
191         MatcherAssert.assertThat(
192             repo.keys(),
193             Matchers.notNullValue()
194         );
195     }
196 
197     /**
198      * RtRepo can fetch its releases.
199      *
200      */
201     @Test
202     public void fetchReleases() {
203         final Repo repo = RtRepoTest.repo(
204             new FakeRequest()
205         );
206         MatcherAssert.assertThat(
207             repo.releases(),
208             Matchers.notNullValue()
209         );
210     }
211 
212     /**
213      * RtRepo can fetch its contents.
214      *
215      */
216     @Test
217     public void fetchContents() {
218         final Repo repo = RtRepoTest.repo(
219             new FakeRequest()
220         );
221         MatcherAssert.assertThat(
222             repo.contents(),
223             Matchers.notNullValue()
224         );
225     }
226 
227     /**
228      * RtRepo can identify itself.
229      */
230     @Test
231     public void identifiesItself() {
232         final Coordinates coords = new Coordinates.Simple("me", "me-branch");
233         final Repo repo = new RtRepo(
234             Mockito.mock(Github.class),
235             new FakeRequest(),
236             coords
237         );
238         MatcherAssert.assertThat(
239             repo.coordinates(),
240             Matchers.sameInstance(coords)
241         );
242     }
243 
244     /**
245      * RtRepo can execute PATCH request.
246      *
247      * @throws Exception if there is any problem
248      */
249     @Test
250     public void executePatchRequest() throws Exception {
251         try (
252             final MkContainer container = new MkGrizzlyContainer().next(
253                 new MkAnswer.Simple(
254                     HttpURLConnection.HTTP_OK,
255                     event(Event.ASSIGNED).toString()
256                 )
257             ).start(this.resource.port())
258         ) {
259             final Repo repo = RtRepoTest.repo(
260                 new ApacheRequest(container.home())
261             );
262             repo.patch(RtRepoTest.event(Event.ASSIGNED));
263             MatcherAssert.assertThat(
264                 container.take().method(),
265                 Matchers.equalTo(Request.PATCH)
266             );
267             container.stop();
268         }
269     }
270 
271     /**
272      * RtRepo can describe as a JSON object.
273      *
274      * @throws Exception if there is any problem
275      */
276     @Test
277     public void describeAsJson() throws Exception {
278         final Repo repo = RtRepoTest.repo(
279             new FakeRequest().withBody(
280                 Json.createObjectBuilder()
281                     .add("full_name", "octocat/Hello-World")
282                     .add("fork", true)
283                     .build()
284                     .toString()
285             )
286         );
287         MatcherAssert.assertThat(
288             repo.json().toString(),
289             Matchers.equalTo(
290                 "{\"full_name\":\"octocat/Hello-World\",\"fork\":true}"
291             )
292         );
293     }
294 
295     /**
296      * RtRepo can fetch commits.
297      */
298     @Test
299     public void fetchCommits() {
300         final Repo repo = RtRepoTest.repo(
301             new FakeRequest()
302         );
303         MatcherAssert.assertThat(repo.commits(), Matchers.notNullValue());
304     }
305 
306     /**
307      * RtRepo can fetch Git.
308      */
309     @Test
310     public void fetchesGit() {
311         final Repo repo = RtRepoTest.repo(
312             new FakeRequest()
313         );
314         MatcherAssert.assertThat(repo.git(), Matchers.notNullValue());
315     }
316 
317     /**
318      * RtRepo can fetch stars.
319      */
320     @Test
321     public void fetchStars() {
322         final Repo repo = RtRepoTest.repo(
323             new FakeRequest()
324         );
325         MatcherAssert.assertThat(repo.stars(), Matchers.notNullValue());
326     }
327 
328     /**
329      * RtRepo can fetch its default branch.
330      *
331      * @throws IOException If some problem occurs.
332      */
333     @Test
334     public void fetchDefaultBranch() throws IOException {
335         final String expected = "main";
336         try (
337             final MkContainer container = new MkGrizzlyContainer().next(
338                 new MkAnswer.Simple(
339                     HttpURLConnection.HTTP_OK,
340                     Json.createObjectBuilder()
341                         .add("default_branch", expected)
342                         .build().toString()
343                 )
344             ).start(this.resource.port())
345         ) {
346             MatcherAssert.assertThat(
347                 RtRepoTest.repo(
348                     new ApacheRequest(container.home())
349                 ).defaultBranch().name(),
350                 Matchers.equalTo(expected)
351             );
352             container.stop();
353         }
354     }
355 
356     /**
357      * RtRepo can fetch notifications.
358      */
359     @Test
360     public void fetchNotifications() {
361         final Repo repo = RtRepoTest.repo(
362             new FakeRequest()
363         );
364         MatcherAssert.assertThat(repo.notifications(), Matchers.notNullValue());
365     }
366 
367     /**
368      * RtRepo can fetch languages.
369      * @throws Exception if a problem occurs.
370      */
371     @Test
372     public void fetchLanguages() throws Exception {
373         try (
374             final MkContainer container = new MkGrizzlyContainer().next(
375                 new MkAnswer.Simple(
376                     HttpURLConnection.HTTP_OK,
377                     Json.createObjectBuilder()
378                         .add("Ruby", 1)
379                         .build().toString()
380                 )
381             ).start(this.resource.port())
382         ) {
383             final Repo repo = RtRepoTest.repo(
384                 new ApacheRequest(container.home())
385             );
386             MatcherAssert.assertThat(repo.languages(), Matchers.notNullValue());
387             container.stop();
388         }
389     }
390 
391     /**
392      * RtRepo can iterate languages.
393      *
394      * @throws Exception If some problem inside
395      */
396     @Test
397     public void iteratesLanguages() throws Exception {
398         final String lang = "C";
399         final String other = "Java";
400         try (
401             final MkContainer container = new MkGrizzlyContainer().next(
402                 new MkAnswer.Simple(
403                     HttpURLConnection.HTTP_OK,
404                     Json.createObjectBuilder()
405                         .add(lang, 1)
406                         .add(other, 2)
407                         .build().toString()
408                 )
409             ).start(this.resource.port())
410         ) {
411             final Repo repo = RtRepoTest.repo(
412                 new ApacheRequest(container.home())
413             );
414             final Iterator<Language> iter = repo.languages().iterator();
415             MatcherAssert.assertThat(
416                 iter.hasNext(),
417                 Matchers.is(true)
418             );
419             MatcherAssert.assertThat(
420                 iter.next().name(),
421                 Matchers.is(lang)
422             );
423             MatcherAssert.assertThat(
424                 iter.hasNext(),
425                 Matchers.is(true)
426             );
427             MatcherAssert.assertThat(
428                 iter.next().name(),
429                 Matchers.is(other)
430             );
431             MatcherAssert.assertThat(
432                 iter.hasNext(),
433                 Matchers.is(false)
434             );
435             container.stop();
436         }
437     }
438 
439     /**
440      * RtStars can retrieve stargazers.
441      *
442      * @throws IOException If something goes wrong.
443      */
444     @Test
445     public void retrievesStargazers() throws IOException {
446         try (
447             final MkContainer container = new MkGrizzlyContainer()
448                 .next(
449                     new MkAnswer.Simple(
450                         HttpURLConnection.HTTP_OK,
451                         "[]"
452                     )
453                 ).start(this.resource.port())
454         ) {
455             final Repo repo = RtRepoTest.repo(
456                 new ApacheRequest(container.home())
457             );
458             final Iterable<JsonValue> stargazers = repo.stargazers()
459                 .iterable();
460             final MkQuery query = container.take();
461             MatcherAssert.assertThat(
462                 "We expect no stargazers",
463                 stargazers,
464                 Matchers.emptyIterable()
465             );
466             MatcherAssert.assertThat(
467                 "Stargazers request should be a GET request",
468                 query.method(),
469                 Matchers.equalTo(Request.GET)
470             );
471             MatcherAssert.assertThat(
472                 query.uri().getPath(),
473                 Matchers.containsString(
474                     UriBuilder.fromPath("repos")
475                         .path(RtRepoTest.TEST_USER)
476                         .path(RtRepoTest.TEST_REPO)
477                         .path("stargazers")
478                         .build()
479                         .getPath()
480                 )
481             );
482             container.stop();
483         }
484     }
485 
486     /**
487      * Create and return JsonObject to test.
488      * @param event Event type
489      * @return JsonObject
490      */
491     private static JsonObject event(final String event) {
492         return Json.createObjectBuilder()
493             .add("id", 1)
494             .add("event", event)
495             .build();
496     }
497 
498     /**
499      * Create test Repo.
500      * @param request Request
501      * @return Repo
502      */
503     private static Repo repo(final Request request) {
504         return new RtRepo(
505             Mockito.mock(Github.class),
506             request,
507             new Coordinates.Simple(RtRepoTest.TEST_USER, RtRepoTest.TEST_REPO)
508         );
509     }
510 }