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.Coordinates;
8   import com.jcabi.github.Event;
9   import com.jcabi.github.GitHub;
10  import com.jcabi.github.Issue;
11  import com.jcabi.github.Label;
12  import com.jcabi.github.Repo;
13  import java.io.IOException;
14  import java.util.Collections;
15  import java.util.Iterator;
16  import org.hamcrest.CustomMatcher;
17  import org.hamcrest.MatcherAssert;
18  import org.hamcrest.Matchers;
19  import org.junit.jupiter.api.Test;
20  import org.mockito.Mockito;
21  
22  /**
23   * Test case for {@link MkIssue}.
24   * @since 0.1
25   * @checkstyle MultipleStringLiterals (500 lines)
26   * @checkstyle ClassDataAbstractionCouplingCheck (500 lines)
27   */
28  @SuppressWarnings({"PMD.TooManyMethods", "PMD.AvoidDuplicateLiterals"})
29  final class MkIssueTest {
30  
31      /**
32       * MkIssue can open and close.
33       * @throws Exception If some problem inside
34       */
35      @Test
36      void opensAndCloses() throws Exception {
37          final Issue issue = MkIssueTest.issue();
38          MatcherAssert.assertThat(
39              "Values are not equal",
40              new Issue.Smart(issue).isOpen(),
41              Matchers.is(true)
42          );
43          new Issue.Smart(issue).close();
44          MatcherAssert.assertThat(
45              "Values are not equal",
46              new Issue.Smart(issue).isOpen(),
47              Matchers.is(false)
48          );
49      }
50  
51      /**
52       * MkIssue can point to an absent pull request.
53       * @throws Exception If some problem inside
54       */
55      @Test
56      void pointsToAnEmptyPullRequest() throws Exception {
57          final Issue issue = MkIssueTest.issue();
58          MatcherAssert.assertThat(
59              "Values are not equal",
60              new Issue.Smart(issue).isPull(),
61              Matchers.is(false)
62          );
63      }
64  
65      /**
66       * MkIssue can show an issue author.
67       * @throws Exception If some problem inside
68       */
69      @Test
70      void showsIssueAuthor() throws Exception {
71          final Issue issue = MkIssueTest.issue();
72          MatcherAssert.assertThat(
73              "Value is null",
74              new Issue.Smart(issue).author().login(),
75              Matchers.notNullValue()
76          );
77      }
78  
79      /**
80       * MkIssue can change title.
81       * @throws Exception If some problem inside
82       */
83      @Test
84      void changesTitle() throws Exception {
85          final Issue issue = MkIssueTest.issue();
86          new Issue.Smart(issue).title("hey, works?");
87          MatcherAssert.assertThat(
88              "String does not start with expected value",
89              new Issue.Smart(issue).title(),
90              Matchers.startsWith("hey, ")
91          );
92      }
93  
94      /**
95       * MkIssue can change body.
96       * @throws Exception If some problem inside
97       */
98      @Test
99      void changesBody() throws Exception {
100         final Issue issue = MkIssueTest.issue();
101         new Issue.Smart(issue).body("hey, body works?");
102         MatcherAssert.assertThat(
103             "String does not start with expected value",
104             new Issue.Smart(issue).body(),
105             Matchers.startsWith("hey, b")
106         );
107     }
108 
109     /**
110      * MkIssue can expose all properties.
111      * @throws Exception If some problem inside
112      */
113     @Test
114     void exponsesProperties() throws Exception {
115         final Issue.Smart issue = new Issue.Smart(MkIssueTest.issue());
116         MatcherAssert.assertThat(
117             "Value is null", issue.createdAt(), Matchers.notNullValue()
118         );
119         MatcherAssert.assertThat(
120             "Value is null", issue.updatedAt(), Matchers.notNullValue()
121         );
122         MatcherAssert.assertThat(
123             "Value is null", issue.htmlUrl(), Matchers.notNullValue()
124         );
125     }
126 
127     /**
128      * MkIssue can list its labels.
129      * @throws Exception If some problem inside
130      */
131     @Test
132     void listsReadOnlyLabels() throws Exception {
133         final Issue issue = MkIssueTest.issue();
134         final String tag = "test-tag";
135         issue.repo().labels().create(tag, "c0c0c0");
136         issue.labels().add(Collections.singletonList(tag));
137         MatcherAssert.assertThat(
138             "Collection does not contain expected item",
139             new Issue.Smart(issue).roLabels().iterate(),
140             Matchers.hasItem(
141                 new CustomMatcher<Label>("label just created") {
142                     @Override
143                     public boolean matches(final Object item) {
144                         return Label.class.cast(item).name().equals(tag);
145                     }
146                 }
147             )
148         );
149     }
150 
151     @Test
152     void canCompareInstances() throws IOException {
153         final MkIssue less = new MkIssue(
154             new MkStorage.InFile(),
155             "login-less",
156             Mockito.mock(Coordinates.class),
157             1
158         );
159         final MkIssue greater = new MkIssue(
160             new MkStorage.InFile(),
161             "login-greater",
162             Mockito.mock(Coordinates.class),
163             2
164         );
165         MatcherAssert.assertThat(
166             "Value is not less than expected",
167             less.compareTo(greater),
168             Matchers.lessThan(0)
169         );
170         MatcherAssert.assertThat(
171             "Value is not greater than expected",
172             greater.compareTo(less),
173             Matchers.greaterThan(0)
174         );
175     }
176 
177     /**
178      * MkIssue can remember it's author.
179      */
180     @Test
181     void canRememberItsAuthor() throws IOException {
182         final MkGitHub first = new MkGitHub("first");
183         final GitHub second = first.relogin("second");
184         final Repo repo = first.randomRepo();
185         final int number = second.repos()
186             .get(repo.coordinates())
187             .issues()
188             .create("", "")
189             .number();
190         final Issue issue = first.repos()
191             .get(repo.coordinates())
192             .issues()
193             .get(number);
194         MatcherAssert.assertThat(
195             "Values are not equal",
196             new Issue.Smart(issue).author().login(),
197             Matchers.is("second")
198         );
199     }
200 
201     /**
202      * Can check if issue exists.
203      * @throws Exception if any error occurs.
204      */
205     @Test
206     void canCheckIfIssueExists() throws Exception {
207         MatcherAssert.assertThat(
208             "Values are not equal", MkIssueTest.issue().exists(), Matchers.is(true)
209         );
210     }
211 
212     /**
213      * MkIssue.exists() return false on nonexistent issues.
214      */
215     @Test
216     void canCheckNonExistentIssue() throws IOException {
217         MatcherAssert.assertThat(
218             "Values are not equal",
219             new MkIssue(
220                 new MkStorage.InFile(),
221                 "login",
222                 new Coordinates.Simple("user", "repo"),
223                 1
224             ).exists(),
225             Matchers.is(false)
226         );
227     }
228 
229     /**
230      * MkIssue can assign a user.
231      * @throws Exception If some problem inside
232      */
233     @Test
234     void assignsUser() throws Exception {
235         final Issue.Smart issue = new Issue.Smart(MkIssueTest.issue());
236         issue.assign("walter");
237         MatcherAssert.assertThat(
238             "String does not start with expected value",
239             issue.assignee().login(),
240             Matchers.startsWith("wal")
241         );
242     }
243 
244     /**
245      * MkIssue can create a closed event when closing an issue.
246      * @throws Exception If some problem inside
247      */
248     @Test
249     void createsClosedEvent() throws Exception {
250         final Issue.Smart issue = new Issue.Smart(MkIssueTest.issue());
251         issue.close();
252         MatcherAssert.assertThat(
253             "Collection size is incorrect",
254             issue.events(),
255             Matchers.iterableWithSize(1)
256         );
257         final Event.Smart closed = new Event.Smart(
258             issue.events().iterator().next()
259         );
260         MatcherAssert.assertThat(
261             "Values are not equal",
262             closed.type(),
263             Matchers.equalTo(Event.CLOSED)
264         );
265     }
266 
267     /**
268      * MkIssue can create a reopened event when closing an issue.
269      * @throws Exception If some problem inside
270      */
271     @Test
272     void createsReopenedEvent() throws Exception {
273         final Issue.Smart issue = new Issue.Smart(MkIssueTest.issue());
274         issue.close();
275         issue.open();
276         MatcherAssert.assertThat(
277             "Collection size is incorrect",
278             issue.events(),
279             Matchers.iterableWithSize(2)
280         );
281         final Iterator<Event> events = issue.events().iterator();
282         final Event.Smart closed = new Event.Smart(events.next());
283         final Event.Smart reopened = new Event.Smart(events.next());
284         MatcherAssert.assertThat(
285             "Values are not equal",
286             closed.type(),
287             Matchers.equalTo(Event.CLOSED)
288         );
289         MatcherAssert.assertThat(
290             "Values are not equal",
291             reopened.type(),
292             Matchers.equalTo(Event.REOPENED)
293         );
294     }
295 
296     /**
297      * Create an issue to work with.
298      * @return Issue just created
299      */
300     private static Issue issue() throws IOException {
301         return new MkGitHub().randomRepo()
302             .issues().create("hey", "how are you?");
303     }
304 
305 }