View Javadoc
1   /*
2    * SPDX-FileCopyrightText: Copyright (c) 2013-2025 Yegor Bugayenko
3    * SPDX-License-Identifier: MIT
4    */
5   package com.jcabi.github.mock;
6   
7   import com.jcabi.github.Content;
8   import com.jcabi.github.Contents;
9   import com.jcabi.github.Repo;
10  import com.jcabi.github.RepoCommit;
11  import jakarta.json.Json;
12  import jakarta.json.JsonObject;
13  import jakarta.json.JsonObjectBuilder;
14  import java.io.IOException;
15  import org.hamcrest.MatcherAssert;
16  import org.hamcrest.Matchers;
17  import org.junit.jupiter.api.Test;
18  
19  /**
20   * Test case for {@link MkContents}.
21   * @since 0.8
22   * @checkstyle MultipleStringLiterals (500 lines)
23   */
24  @SuppressWarnings({ "PMD.TooManyMethods", "PMD.AvoidDuplicateLiterals" })
25  final class MkContentsTest {
26      @Test
27      void canFetchReadmeFile() throws IOException {
28          final Contents contents = new MkGitHub().randomRepo().contents();
29          final String body = "Readme On Master";
30          // @checkstyle MultipleStringLiterals (6 lines)
31          contents.create(
32              MkContentsTest.content("README.md", "readme on master", body).build()
33          );
34          MatcherAssert.assertThat(
35              "Values are not equal",
36              contents.readme().json().getString("content"),
37              Matchers.is(body)
38          );
39      }
40  
41      @Test
42      void canFetchReadmeFromBranch() throws IOException {
43          final String branch = "branch-1";
44          final Contents contents = new MkGitHub().randomRepo().contents();
45          final String body = "Readme On Branch";
46          contents.create(
47              MkContentsTest.content("README.md", "readme on branch", body)
48                  .add("ref", branch)
49                  .build()
50          );
51          MatcherAssert.assertThat(
52              "Values are not equal",
53              contents.readme(branch).json().getString("content"),
54              Matchers.is(body)
55          );
56      }
57  
58      /**
59       * MkContents should be able to create new files.
60       * @throws Exception if some problem inside
61       */
62      @Test
63      void canCreateFile() throws Exception {
64          final String path = "file.txt";
65          final Content.Smart content = new Content.Smart(
66              MkContentsTest.createFile(new MkGitHub().randomRepo(), path)
67          );
68          MatcherAssert.assertThat(
69              "Values are not equal",
70              content.path(),
71              Matchers.is(path)
72          );
73          MatcherAssert.assertThat(
74              "Values are not equal",
75              content.name(),
76              Matchers.is(path)
77          );
78          MatcherAssert.assertThat(
79              "Values are not equal",
80              content.sha(),
81              Matchers.not(Matchers.is(Matchers.emptyOrNullString()))
82          );
83      }
84  
85      @Test
86      void canCreateFileInSomeBranch() throws IOException {
87          final String path = "file-in-branch.txt";
88          final String branch = "branch-2";
89          final String body = "some file";
90          final Content.Smart content = new Content.Smart(
91              new MkGitHub().randomRepo().contents().create(
92                  MkContentsTest.content(path, "some file", body)
93                      .add("ref", branch)
94                      .build()
95              )
96          );
97          MatcherAssert.assertThat(
98              "Values are not equal",
99              content.path(),
100             Matchers.is(path)
101         );
102         MatcherAssert.assertThat(
103             "Values are not equal",
104             content.name(),
105             Matchers.is(path)
106         );
107         MatcherAssert.assertThat(
108             "Values are not equal",
109             content.sha(),
110             Matchers.not(Matchers.is(Matchers.emptyOrNullString()))
111         );
112         MatcherAssert.assertThat(
113             "Values are not equal",
114             content.content(),
115             Matchers.is(body)
116         );
117     }
118 
119     /**
120      * MkContents should be able to create new files.
121      * @throws Exception if some problem inside
122      */
123     @Test
124     void canRemoveFile() throws Exception {
125         final Repo repo = new MkGitHub().randomRepo();
126         final String path = "removeme.txt";
127         MkContentsTest.createFile(repo, path);
128         final JsonObject json = MkContentsTest
129             .content(path, "theDeleteMessage")
130             .add("committer", MkContentsTest.committer())
131             .build();
132         final RepoCommit commit = repo.contents().remove(json);
133         MatcherAssert.assertThat(
134             "Value is null", commit, Matchers.notNullValue()
135         );
136         MatcherAssert.assertThat(
137             "Values are not equal",
138             commit.json().getString("message"),
139             Matchers.equalTo("theDeleteMessage")
140         );
141     }
142 
143     /**
144      * MkContents should be able to remove files from from non-default branches.
145      * @throws Exception if some problem inside
146      */
147     @Test
148     void canRemoveFileFromBranch() throws Exception {
149         final Repo repo = new MkGitHub().randomRepo();
150         final String path = "removeme.txt";
151         MkContentsTest.createFile(repo, path);
152         final String branch = "branch-1";
153         final JsonObject json = MkContentsTest
154             .content(path, "theDeleteMessage")
155             .add("ref", branch)
156             .add("committer", MkContentsTest.committer())
157             .build();
158         final RepoCommit commit = repo.contents().remove(json);
159         MatcherAssert.assertThat(
160             "Value is null", commit, Matchers.notNullValue()
161         );
162         MatcherAssert.assertThat(
163             "Values are not equal",
164             commit.json().getString("message"),
165             Matchers.equalTo("theDeleteMessage")
166         );
167     }
168 
169     @Test
170     void updatesFile() throws IOException {
171         final String path = "file.txt";
172         final String message = "content message";
173         final String initial = "initial text";
174         final String cont = "content";
175         final Contents contents = new MkGitHub().randomRepo().contents();
176         MatcherAssert.assertThat(
177             "Values are not equal",
178             contents.create(
179                 MkContentsTest.content(path, message, initial).build()
180             ).json().getString(cont),
181             Matchers.is(initial)
182         );
183         final String updated = "updated text";
184         contents.update(
185             path, MkContentsTest.content(path, message, updated).build()
186         );
187         MatcherAssert.assertThat(
188             "Values are not equal",
189             contents.get(path, "master").json().getString(cont),
190             Matchers.is(updated)
191         );
192     }
193 
194     @Test
195     void updatesFileCreateCommit() throws IOException {
196         final MkStorage storage = new MkStorage.InFile();
197         final Contents contents = MkContentsTest.repo(storage).contents();
198         final String path = "file.txt";
199         final JsonObject json = MkContentsTest
200             .content(path, "theCreateMessage", "newContent")
201             .add("committer", MkContentsTest.committer())
202             .build();
203         contents.create(json);
204         final String xpath = "/github/repos/repo/commits/commit";
205         MatcherAssert.assertThat(
206             "Collection size is incorrect",
207             storage.xml().nodes(xpath),
208             Matchers.iterableWithSize(1)
209         );
210         final JsonObject update = MkContentsTest
211             .content(path, "theMessage", "blah")
212             .build();
213         MatcherAssert.assertThat(
214             "Values are not equal",
215             new RepoCommit.Smart(contents.update(path, update)).sha(),
216             Matchers.not(Matchers.is(Matchers.emptyOrNullString()))
217         );
218         MatcherAssert.assertThat(
219             "Values are not equal",
220             new Content.Smart(contents.get(path, "master")).path(),
221             Matchers.is(path)
222         );
223         MatcherAssert.assertThat(
224             "Collection size is incorrect",
225             storage.xml().nodes(xpath),
226             Matchers.iterableWithSize(2)
227         );
228     }
229 
230     @Test
231     void updateContent() throws IOException {
232         final String path = "content-to-update.txt";
233         final String message = "commit message";
234         final String initial = "Hello World!";
235         final String branch = "master";
236         final Contents contents = new MkGitHub().randomRepo().contents();
237         final JsonObject content = MkContentsTest
238             .content(path, message, initial)
239             .add("ref", branch)
240             .build();
241         MatcherAssert.assertThat(
242             "Values are not equal",
243             new Content.Smart(contents.create(content)).content(),
244             Matchers.is(initial)
245         );
246         final String updated = "update content";
247         contents.update(
248             path, MkContentsTest.content(path, message, updated)
249                 .add("ref", branch).build()
250         );
251         MatcherAssert.assertThat(
252             "Values are not equal",
253             new Content.Smart(contents.get(path, branch)).content(),
254             Matchers.is(updated)
255         );
256     }
257 
258     @Test
259     void checkExists() throws IOException {
260         final String path = "content-exist.txt";
261         final String branch = "rel.08";
262         final Contents contents = new MkGitHub().randomRepo().contents();
263         contents.create(
264             MkContentsTest.content(path, "commit", "content exists")
265                 .add("ref", branch)
266                 .build()
267         );
268         MatcherAssert.assertThat(
269             "Values are not equal",
270             contents.exists(path, branch),
271             Matchers.is(true)
272         );
273         MatcherAssert.assertThat(
274             "Values are not equal",
275             contents.exists("content-not-exist.txt", branch),
276             Matchers.is(false)
277         );
278     }
279 
280     @Test
281     void getContentFromDefaultBranch() throws IOException {
282         final String path = "content-default-branch.txt";
283         final String message = "content default branch created";
284         final String text = "I'm content of default branch";
285         final Contents contents = new MkGitHub().randomRepo().contents();
286         final JsonObject content = MkContentsTest
287             .content(path, message, text)
288             .build();
289         MatcherAssert.assertThat(
290             "Values are not equal",
291             new Content.Smart(contents.create(content)).content(),
292             Matchers.is(text)
293         );
294         MatcherAssert.assertThat(
295             "Values are not equal",
296             new Content.Smart(contents.get(path)).content(),
297             Matchers.is(text)
298         );
299     }
300 
301     /**
302      * Tests if MkContents is iterable by path.
303      * @throws IOException if any error occurs.
304      */
305     @Test
306     void canIterate() throws IOException {
307         final MkStorage storage = new MkStorage.InFile();
308         final Repo repo = MkContentsTest.repo(storage);
309         final Content[] correct = MkContentsTest.addContent(
310             repo, "foo/bar/1", "foo/bar/2"
311         );
312         MkContentsTest.addContent(repo, "foo/baz", "foo/boo");
313         MatcherAssert.assertThat(
314             "Assertion failed",
315             repo.contents().iterate("foo/bar", "ref-1"),
316             Matchers.contains(correct)
317         );
318     }
319 
320     /**
321      * Adds collection of test content items.
322      * @param repo The repo.
323      * @param paths Test items to be created inside the repo.
324      * @return Iterable with created items.
325      * @throws IOException If any I/O error occurs.
326      */
327     private static Content[] addContent(final Repo repo,
328         final String... paths) throws IOException {
329         final Content[] result = new Content[paths.length];
330         int index = 0;
331         for (final String path : paths) {
332             result[index] = repo.contents().create(
333                 Json.createObjectBuilder().add("ref", "ref-1")
334                     .add("path", path).add("content", path)
335                     .add("message", "msg").build()
336             );
337             index += 1;
338         }
339         return result;
340     }
341 
342     /**
343      * Creates a new file.
344      * @param repo The repository
345      * @param path Content path
346      * @return Created content
347      */
348     private static Content createFile(
349         final Repo repo, final String path) throws IOException {
350         final Contents contents = repo.contents();
351         final JsonObject json = MkContentsTest
352             .content(path, "theCreateMessage", "newContent")
353             .add("committer", MkContentsTest.committer())
354             .build();
355         return contents.create(json);
356     }
357 
358     /**
359      * Create content JsonObjectBuilder.
360      * @param path Content path
361      * @param message Commit message
362      * @return JsonObjectBuilder
363      */
364     private static JsonObjectBuilder content(
365         final String path, final String message) {
366         return Json.createObjectBuilder()
367             .add("path", path)
368             .add("message", message);
369     }
370 
371     /**
372      * Create content JsonObjectBuilder.
373      * @param path Content path
374      * @param message Commit message
375      * @param content Base64 encoded content
376      * @return JsonObjectBuilder
377      */
378     private static JsonObjectBuilder content(
379         final String path, final String message, final String content) {
380         return Json.createObjectBuilder()
381             .add("path", path)
382             .add("message", message)
383             .add("content", content);
384     }
385 
386     /**
387      * Creates default committer.
388      * @return JsonObjectBuilder
389      */
390     private static JsonObjectBuilder committer() {
391         return Json.createObjectBuilder()
392             .add("name", "joe")
393             .add("email", "joe@contents.com");
394     }
395 
396     /**
397      * Create a test repo with custom {@code MkStorage}.
398      * @param storage The storage
399      * @return Test repo
400      * @throws IOException If any I/O error occurs.
401      */
402     private static Repo repo(
403         final MkStorage storage) throws IOException {
404         final String login = "test";
405         return new MkGitHub(storage, login).randomRepo();
406     }
407 
408 }