View Javadoc
1   /**
2    * Copyright (c) 2013-2022, 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.Response;
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.request.ApacheRequest;
37  import com.jcabi.http.request.FakeRequest;
38  import com.jcabi.http.response.JsonResponse;
39  import java.util.EnumMap;
40  import javax.json.Json;
41  import javax.json.JsonArrayBuilder;
42  import javax.json.JsonObject;
43  import javax.json.JsonObjectBuilder;
44  import org.hamcrest.MatcherAssert;
45  import org.hamcrest.Matchers;
46  import org.junit.Rule;
47  import org.junit.Test;
48  
49  /**
50   * Test case for {@link RtSearch}.
51   *
52   * @author Carlos Miranda (miranda.cma@gmail.com)
53   * @author Paulo Lobo (pauloeduardolobo@gmail.com)
54   * @version $Id: f12845a1cd88e4742cd2656018c453e66d8bc4e9 $
55   * @checkstyle MultipleStringLiterals (300 lines)
56   * @checkstyle ClassDataAbstractionCouplingCheck (3 lines)
57   */
58  @SuppressWarnings("PMD.AvoidDuplicateLiterals")
59  public final class RtSearchTest {
60      /**
61       * The rule for skipping test if there's BindException.
62       * @checkstyle VisibilityModifierCheck (3 lines)
63       */
64      @Rule
65      public final transient RandomPort resource = new RandomPort();
66  
67      /**
68       * RtSearch can search for repos.
69       *
70       * @throws Exception if a problem occurs
71       */
72      @Test
73      public void canSearchForRepos() throws Exception {
74          final String coords = "test-user1/test-repo1";
75          final Search search = new RtGithub(
76              new FakeRequest().withBody(
77                  RtSearchTest.search(
78                      Json.createObjectBuilder().add("full_name", coords).build()
79                  ).toString()
80              )
81          ).search();
82          MatcherAssert.assertThat(
83              search.repos("test", "stars", Search.Order.DESC).iterator().next()
84                  .coordinates().toString(),
85              Matchers.equalTo(coords)
86          );
87      }
88  
89      /**
90       * RtSearch can search for issues.
91       *
92       * @throws Exception if a problem occurs
93       */
94      @Test
95      public void canSearchForIssues() throws Exception {
96          final int number = 1;
97          final Search search = new RtGithub(
98              new FakeRequest().withBody(
99                  RtSearchTest.search(
100                     Json.createObjectBuilder().add(
101                         "url", String.format(
102                             // @checkstyle LineLength (1 line)
103                             "https://api.github.com/repos/user/repo/issues/%s",
104                             number
105                         )
106                     ).add("number", number).build()
107                 ).toString()
108             )
109         ).search();
110         MatcherAssert.assertThat(
111             search.issues(
112                 "test2",
113                 "created",
114                 Search.Order.DESC,
115                 new EnumMap<Search.Qualifier, String>(Search.Qualifier.class)
116             ).iterator().next().number(),
117             Matchers.equalTo(number)
118         );
119     }
120 
121     /**
122      * RtSearch can search for users.
123      *
124      * @throws Exception if a problem occurs
125      */
126     @Test
127     public void canSearchForUsers() throws Exception {
128         final String login = "test-user";
129         final Search search = new RtGithub(
130             new FakeRequest().withBody(
131                 RtSearchTest.search(
132                     Json.createObjectBuilder()
133                         .add("login", login).build()
134                 ).toString()
135             )
136         ).search();
137         MatcherAssert.assertThat(
138             search.users("test3", "joined", Search.Order.DESC)
139                 .iterator().next().login(),
140             Matchers.equalTo(login)
141         );
142     }
143 
144     /**
145      * RtSearch can search for contents.
146      *
147      * @throws Exception if a problem occurs
148      */
149     @Test
150     public void canSearchForContents() throws Exception {
151         final JsonObject first = RtSearchTest.content(
152             "test/unit/attributes.js",
153             "attributes.js",
154             // @checkstyle LineLength (1 line)
155             "https://api.github.com/repos/user/repo/contents/test/unit/attributes.js?ref=f3b89ba0820882bd4ce4404b7e7c819e7b506de5"
156         ).build();
157         final JsonObject second = RtSearchTest.content(
158             "src/attributes/classes.js",
159             "classes.js",
160             // @checkstyle LineLength (1 line)
161             "https://api.github.com/repos/user/repo/contents/src/attributes/classes.js?ref=f3b89ba0820882bd4ce4404b7e7c819e7b506de5"
162         ).build();
163         try (
164             final MkContainer container = new MkGrizzlyContainer().next(
165                 new MkAnswer.Simple(
166                     RtSearchTest.search(first, second).toString()
167                 )
168             ).next(new MkAnswer.Simple(first.toString()))
169                 .next(new MkAnswer.Simple(second.toString()))
170                 .start(this.resource.port())
171         ) {
172             final Search search = new RtGithub(
173                 new ApacheRequest(container.home())
174             ).search();
175             MatcherAssert.assertThat(
176                 search.codes("test4", "joined", Search.Order.DESC),
177                 Matchers.<Content>iterableWithSize(2)
178             );
179             container.stop();
180         }
181     }
182 
183     /**
184      * RtSearch can read non-unicode.
185      * @throws Exception if any problem inside
186      */
187     @Test
188     public void readNonUnicode() throws Exception {
189         final Response resp = new FakeRequest()
190             .withBody("{\"help\": \"\u001Fblah\u0001cwhoa\u0000!\"}").fetch();
191         final JsonResponse response = new JsonResponse(resp);
192         MatcherAssert.assertThat(
193             response.json().readObject().getString("help"),
194             Matchers.is("\u001Fblah\u0001cwhoa\u0000!")
195         );
196     }
197 
198     /**
199      * Create content JsonObject.
200      * @param path Content path
201      * @param name Content name
202      * @param url Content url
203      * @return JsonObjectBuilder
204      * @throws Exception If some problem inside
205      */
206     private static JsonObjectBuilder content(
207         final String path, final String name, final String url)
208         throws Exception {
209         return Json.createObjectBuilder()
210             .add("path", path)
211             .add("name", name)
212             .add("url", url);
213     }
214 
215     /**
216      * Create search response JsonObjectBuilder.
217      * @param contents Contents to add
218      * @return JsonObject
219      */
220     private static JsonObject search(
221         final JsonObject ... contents) {
222         final JsonArrayBuilder builder = Json.createArrayBuilder();
223         for (final JsonObject content : contents) {
224             builder.add(content);
225         }
226         return Json.createObjectBuilder()
227             .add("total_count", contents.length)
228             .add("items", builder).build();
229     }
230 }