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 jakarta.json.Json;
8   import jakarta.json.JsonObject;
9   import java.io.IOException;
10  import org.apache.commons.codec.binary.Base64;
11  import org.apache.commons.lang3.RandomStringUtils;
12  import org.hamcrest.MatcherAssert;
13  import org.hamcrest.Matchers;
14  import org.junit.jupiter.api.Disabled;
15  import org.junit.jupiter.api.Test;
16  
17  /**
18   * Test case for {@link RtContents}.
19   * @since 0.8
20   * @checkstyle MultipleStringLiterals (500 lines)
21   */
22  @OAuthScope(OAuthScope.Scope.REPO)
23  @SuppressWarnings("PMD.AvoidDuplicateLiterals")
24  final class RtContentsITCase {
25  
26      /**
27       * RepoRule.
28       * @checkstyle VisibilityModifierCheck (3 lines)
29       */
30      public final transient RepoRule rule = new RepoRule();
31  
32      @Test
33      void canFetchReadmeFiles() throws IOException {
34          final Repos repos = GitHubIT.connect().repos();
35          final Repo repo = this.rule.repo(repos);
36          try {
37              MatcherAssert.assertThat(
38                  "Values are not equal",
39                  repos.get(repo.coordinates()).contents().readme().path(),
40                  Matchers.equalTo("README.md")
41              );
42          } finally {
43              repos.remove(repo.coordinates());
44          }
45      }
46  
47      @Test
48      void canUpdateFileContent() throws IOException {
49          final Repos repos = GitHubIT.connect().repos();
50          final Repo repo = this.rule.repo(repos);
51          final Contents contents = repos.get(repo.coordinates()).contents();
52          try {
53              final String path = RandomStringUtils.secure().nextAlphanumeric(10);
54              final String message = "commit message";
55              final Content content = contents.create(
56                  RtContentsITCase.jsonObject(
57                      path, new String(
58                          Base64.encodeBase64("init content".getBytes())
59                      ),
60                      message
61                  )
62              );
63              final String text = "new content";
64              contents.update(
65                  path,
66                  Json.createObjectBuilder()
67                      .add("path", path)
68                      .add("message", message)
69                      .add("content", Base64.encodeBase64String(text.getBytes()))
70                      .add("sha", new Content.Smart(content).sha()).build()
71              );
72              MatcherAssert.assertThat(
73                  "Values are not equal",
74                  new String(
75                      Base64.decodeBase64(
76                          new Content.Smart(
77                              contents.get(path, "master")
78                          ).content()
79                      )
80                  ),
81                  Matchers.equalTo(text)
82              );
83          } finally {
84              repos.remove(repo.coordinates());
85          }
86      }
87  
88      @Test
89      void canUpdateFileContentInSpecificBranch() throws IOException {
90          final Repos repos = GitHubIT.connect().repos();
91          final Repo repo = this.rule.repo(repos);
92          final Contents contents = repos.get(repo.coordinates()).contents();
93          try {
94              final String path = RandomStringUtils.secure().nextAlphanumeric(10);
95              final String message = "Commit message";
96              final Content content = contents.create(
97                  RtContentsITCase.jsonObject(
98                      path, new String(
99                          Base64.encodeBase64("Initial.".getBytes())
100                     ),
101                     message
102                 )
103             );
104             final String text = "Updated";
105             contents.update(
106                 path,
107                 Json.createObjectBuilder()
108                     .add("path", path)
109                     .add("message", message)
110                     .add("ref", "master")
111                     .add("content", Base64.encodeBase64String(text.getBytes()))
112                     .add("sha", new Content.Smart(content).sha()).build()
113             );
114             MatcherAssert.assertThat(
115                 "Values are not equal",
116                 new String(
117                     Base64.decodeBase64(
118                         new Content.Smart(
119                             contents.get(path, "master")
120                         ).content()
121                     )
122                 ),
123                 Matchers.equalTo(text)
124             );
125         } finally {
126             repos.remove(repo.coordinates());
127         }
128     }
129 
130     @Test
131     void throwsWhenTryingToGetAnAbsentContent() throws IOException {
132         final Repos repos = GitHubIT.connect().repos();
133         final Repo repo = this.rule.repo(repos);
134         final Contents contents = repos.get(repo.coordinates()).contents();
135         try {
136             final String path = RandomStringUtils.secure().nextAlphanumeric(10);
137             final String message = "commit message";
138             final Content content = contents.create(
139                 RtContentsITCase.jsonObject(
140                     path, new String(
141                         Base64.encodeBase64("first content".getBytes())
142                     ),
143                     message
144                 )
145             );
146             contents.remove(
147                 Json.createObjectBuilder()
148                     .add("path", path)
149                     .add("message", message)
150                     .add("sha", new Content.Smart(content).sha()).build()
151             );
152             contents.get(path, "master");
153         } finally {
154             repos.remove(repo.coordinates());
155         }
156     }
157 
158     @Test
159     void canCreateFileContent() throws IOException {
160         final Repos repos = GitHubIT.connect().repos();
161         final Repo repo = this.rule.repo(repos);
162         try {
163             final String path = RandomStringUtils.secure().nextAlphanumeric(10);
164             MatcherAssert.assertThat(
165                 "Values are not equal",
166                 repos.get(repo.coordinates()).contents().create(
167                     RtContentsITCase.jsonObject(
168                         path, new String(
169                             Base64.encodeBase64("some content".getBytes())
170                         ), "theMessage"
171                     )
172                 ).path(),
173                 Matchers.equalTo(path)
174             );
175         } finally {
176             repos.remove(repo.coordinates());
177         }
178     }
179 
180     @Test
181     void getContent() throws IOException {
182         final Repos repos = GitHubIT.connect().repos();
183         final Repo repo = this.rule.repo(repos);
184         try {
185             final String path = RandomStringUtils.secure().nextAlphanumeric(10);
186             final String message = String.format("testMessage");
187             final String cont = new String(
188                 Base64.encodeBase64(
189                     String.format("content%d", System.currentTimeMillis())
190                         .getBytes()
191                 )
192             );
193             final Contents contents = repos.get(repo.coordinates()).contents();
194             contents.create(RtContentsITCase.jsonObject(path, cont, message));
195             final Content content = contents.get(path, "master");
196             MatcherAssert.assertThat(
197                 "Values are not equal",
198                 content.path(),
199                 Matchers.equalTo(path)
200             );
201             MatcherAssert.assertThat(
202                 "Values are not equal",
203                 new Content.Smart(content).content(),
204                 Matchers.equalTo(String.format("%s\n", cont))
205             );
206             final Content other = contents.get(path);
207             MatcherAssert.assertThat(
208                 "Values are not equal", content, Matchers.equalTo(other)
209             );
210         } finally {
211             repos.remove(repo.coordinates());
212         }
213     }
214 
215     /**
216      * RtContents can iterate content.
217      * @todo #863 unignore after Contents#get is implemented for
218      *  directories (#968 and #903)
219      */
220     @Test
221     @Disabled
222     void iteratesContent() throws IOException {
223         final Repos repos = GitHubIT.connect().repos();
224         final Repo repo = this.rule.repo(repos);
225         try {
226             final String afile = RandomStringUtils.secure().nextAlphanumeric(10);
227             final String dir = RandomStringUtils.secure().nextAlphanumeric(10);
228             final String bfile = String.format(
229                 "%s/%s",
230                 dir,
231                 RandomStringUtils.secure().nextAlphanumeric(10)
232             );
233             final String message = String.format("testMessage");
234             final Contents contents = repos.get(repo.coordinates()).contents();
235             contents.create(
236                 RtContentsITCase.jsonObject(
237                     afile,
238                     new String(
239                         Base64.encodeBase64(
240                             String.format(
241                                 "content a:%d",
242                                 System.currentTimeMillis()
243                             ).getBytes()
244                         )
245                     ),
246                     message
247                 )
248             );
249             contents.create(
250                 RtContentsITCase.jsonObject(
251                     bfile,
252                     new String(
253                         Base64.encodeBase64(
254                             String.format(
255                                 "content b:%d",
256                                 System.currentTimeMillis()
257                             ).getBytes()
258                         )
259                     ),
260                     message
261                 )
262             );
263             final Iterable<Content> iterated = contents.iterate("", "master");
264             MatcherAssert.assertThat(
265                 "Collection size is incorrect",
266                 iterated,
267                 Matchers.allOf(
268                     Matchers.hasItems(contents.get(afile), contents.get(dir)),
269                     Matchers.iterableWithSize(3)
270                 )
271             );
272         } finally {
273             repos.remove(repo.coordinates());
274         }
275     }
276 
277     @Test
278     void checkExists() throws IOException {
279         final Repos repos = GitHubIT.connect().repos();
280         final Repo repo = this.rule.repo(repos);
281         try {
282             final String path = RandomStringUtils.secure().nextAlphanumeric(10);
283             final String cont = new String(
284                 Base64.encodeBase64(
285                     String.format("exist%d", System.currentTimeMillis())
286                         .getBytes()
287                 )
288             );
289             final Contents contents = repos.get(repo.coordinates()).contents();
290             contents.create(RtContentsITCase.jsonObject(path, cont, "test exist"));
291             final String branch = "master";
292             MatcherAssert.assertThat(
293                 "Values are not equal",
294                 contents.exists(path, branch),
295                 Matchers.is(true)
296             );
297             MatcherAssert.assertThat(
298                 "Values are not equal",
299                 contents.exists("content-not-exist.txt", branch),
300                 Matchers.is(false)
301             );
302         } finally {
303             repos.remove(repo.coordinates());
304         }
305     }
306 
307     /**
308      * Create and return JsonObject of content.
309      * @param path Content's path
310      * @param cont Content's Base64 string
311      * @param message Message
312      * @return JsonObject
313      */
314     private static JsonObject jsonObject(
315         final String path, final String cont, final String message
316     ) {
317         return Json.createObjectBuilder()
318             .add("path", path)
319             .add("message", message)
320             .add("content", cont)
321             .add("ref", "master")
322             .build();
323     }
324 
325 }