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