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.Response;
8   import com.jcabi.http.mock.MkAnswer;
9   import com.jcabi.http.mock.MkContainer;
10  import com.jcabi.http.mock.MkGrizzlyContainer;
11  import com.jcabi.http.request.ApacheRequest;
12  import com.jcabi.http.request.FakeRequest;
13  import com.jcabi.http.response.JsonResponse;
14  import jakarta.json.Json;
15  import jakarta.json.JsonArrayBuilder;
16  import jakarta.json.JsonObject;
17  import jakarta.json.JsonObjectBuilder;
18  import java.io.IOException;
19  import java.util.EnumMap;
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  
25  /**
26   * Test case for {@link RtSearch}.
27   * @since 0.1
28   * @checkstyle MultipleStringLiterals (300 lines)
29   * @checkstyle ClassDataAbstractionCouplingCheck (3 lines)
30   */
31  @SuppressWarnings("PMD.AvoidDuplicateLiterals")
32  @ExtendWith(RandomPort.class)
33  final class RtSearchTest {
34      /**
35       * The rule for skipping test if there's BindException.
36       * @checkstyle VisibilityModifierCheck (3 lines)
37       */
38      @Test
39      void canSearchForRepos() {
40          final String coords = "test-user1/test-repo1";
41          final Search search = new RtGitHub(
42              new FakeRequest().withBody(
43                  RtSearchTest.search(
44                      Json.createObjectBuilder().add("full_name", coords).build()
45                  ).toString()
46              )
47          ).search();
48          MatcherAssert.assertThat(
49              "Values are not equal",
50              search.repos("test", "stars", Search.Order.DESC).iterator().next()
51                  .coordinates().toString(),
52              Matchers.equalTo(coords)
53          );
54      }
55  
56      @Test
57      void canSearchForIssues() {
58          final int number = 1;
59          final Search search = new RtGitHub(
60              new FakeRequest().withBody(
61                  RtSearchTest.search(
62                      Json.createObjectBuilder().add(
63                          "url", String.format(
64                              // @checkstyle LineLength (1 line)
65                              "https://api.github.com/repos/user/repo/issues/%s",
66                              number
67                          )
68                      ).add("number", number).build()
69                  ).toString()
70              )
71          ).search();
72          MatcherAssert.assertThat(
73              "Values are not equal",
74              search.issues(
75                  "test2",
76                  "created",
77                  Search.Order.DESC,
78                  new EnumMap<>(Search.Qualifier.class)
79              ).iterator().next().number(),
80              Matchers.equalTo(number)
81          );
82      }
83  
84      @Test
85      void canSearchForUsers() throws IOException {
86          final String login = "test-user";
87          final Search search = new RtGitHub(
88              new FakeRequest().withBody(
89                  RtSearchTest.search(
90                      Json.createObjectBuilder()
91                          .add("login", login).build()
92                  ).toString()
93              )
94          ).search();
95          MatcherAssert.assertThat(
96              "Values are not equal",
97              search.users("test3", "joined", Search.Order.DESC)
98                  .iterator().next().login(),
99              Matchers.equalTo(login)
100         );
101     }
102 
103     @Test
104     void canSearchForContents() throws IOException {
105         final JsonObject first = RtSearchTest.content(
106             "test/unit/attributes.js",
107             "attributes.js",
108             // @checkstyle LineLength (1 line)
109             "https://api.github.com/repos/user/repo/contents/test/unit/attributes.js?ref=f3b89ba0820882bd4ce4404b7e7c819e7b506de5"
110         ).build();
111         final JsonObject second = RtSearchTest.content(
112             "src/attributes/classes.js",
113             "classes.js",
114             // @checkstyle LineLength (1 line)
115             "https://api.github.com/repos/user/repo/contents/src/attributes/classes.js?ref=f3b89ba0820882bd4ce4404b7e7c819e7b506de5"
116         ).build();
117         try (
118             MkContainer container = new MkGrizzlyContainer().next(
119                 new MkAnswer.Simple(
120                     RtSearchTest.search(first, second).toString()
121                 )
122             ).next(new MkAnswer.Simple(first.toString()))
123                 .next(new MkAnswer.Simple(second.toString()))
124                 .start(RandomPort.port())
125         ) {
126             final Search search = new RtGitHub(
127                 new ApacheRequest(container.home())
128             ).search();
129             MatcherAssert.assertThat(
130                 "Collection size is incorrect",
131                 search.codes("test4", "joined", Search.Order.DESC),
132                 Matchers.iterableWithSize(2)
133             );
134             container.stop();
135         }
136     }
137 
138     /**
139      * RtSearch can read non-unicode.
140      */
141     @Test
142     void readNonUnicode() throws IOException {
143         final Response resp = new FakeRequest()
144             .withBody("{\"help\": \"\u001Fblah\u0001cwhoa\u0000!\"}").fetch();
145         final JsonResponse response = new JsonResponse(resp);
146         MatcherAssert.assertThat(
147             "Values are not equal",
148             response.json().readObject().getString("help"),
149             Matchers.is("\u001Fblah\u0001cwhoa\u0000!")
150         );
151     }
152 
153     /**
154      * Create content JsonObject.
155      * @param path Content path
156      * @param name Content name
157      * @param url Content url
158      * @return JsonObjectBuilder
159      */
160     private static JsonObjectBuilder content(
161         final String path, final String name, final String url) {
162         return Json.createObjectBuilder()
163             .add("path", path)
164             .add("name", name)
165             .add("url", url);
166     }
167 
168     /**
169      * Create search response JsonObjectBuilder.
170      * @param contents Contents to add
171      * @return JsonObject
172      */
173     private static JsonObject search(
174         final JsonObject... contents) {
175         final JsonArrayBuilder builder = Json.createArrayBuilder();
176         for (final JsonObject content : contents) {
177             builder.add(content);
178         }
179         return Json.createObjectBuilder()
180             .add("total_count", contents.length)
181             .add("items", builder).build();
182     }
183 }