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.log.Logger;
8   import java.io.IOException;
9   import java.util.Date;
10  import org.hamcrest.MatcherAssert;
11  import org.hamcrest.Matchers;
12  import org.hamcrest.core.IsEqual;
13  import org.junit.jupiter.api.AfterAll;
14  import org.junit.jupiter.api.Assumptions;
15  import org.junit.jupiter.api.BeforeAll;
16  import org.junit.jupiter.api.Disabled;
17  import org.junit.jupiter.api.Test;
18  
19  /**
20   * Integration case for {@link Issue}.
21   * @since 0.1
22   * @checkstyle ClassDataAbstractionCoupling (500 lines)
23   */
24  @OAuthScope(OAuthScope.Scope.REPO)
25  @SuppressWarnings({"PMD.AvoidDuplicateLiterals", "PMD.TooManyMethods"})
26  final class RtIssueITCase {
27      /**
28       * Test repos.
29       */
30      private static Repos repos;
31  
32      /**
33       * Test repo.
34       */
35      private static Repo repo;
36  
37      /**
38       * Set up test fixtures.
39       */
40      @BeforeAll
41      static void setUp() throws IOException {
42          final GitHub github = GitHubIT.connect();
43          RtIssueITCase.repos = github.repos();
44          RtIssueITCase.repo = new RepoRule().repo(RtIssueITCase.repos);
45      }
46  
47      /**
48       * Tear down test fixtures.
49       */
50      @AfterAll
51      static void tearDown() throws IOException {
52          if (RtIssueITCase.repos != null && RtIssueITCase.repo != null) {
53              RtIssueITCase.repos.remove(RtIssueITCase.repo.coordinates());
54          }
55      }
56  
57      /**
58       * RtIssue can talk in github. This test is ignored because of bug
59       * https://github.com/jcabi/jcabi-github/issues/1178.
60       * @throws Exception If some problem inside
61       */
62      @Disabled
63      @Test
64      void talksInGitHubProject() throws Exception {
65          final Issue issue = RtIssueITCase.issue();
66          final Comment comment = issue.comments().post("hey, works?");
67          MatcherAssert.assertThat(
68              "String does not start with expected value",
69              new Comment.Smart(comment).body(),
70              Matchers.startsWith("hey, ")
71          );
72          MatcherAssert.assertThat(
73              "Collection size is incorrect",
74              issue.comments().iterate(new Date(0L)),
75              Matchers.iterableWithSize(1)
76          );
77          final User.Smart author = new User.Smart(
78              new Comment.Smart(comment)
79                  .author()
80          );
81          final User.Smart self = new User.Smart(
82              issue.repo().github().users().self()
83          );
84          if (author.hasName() && self.hasName()) {
85              MatcherAssert.assertThat(
86                  "Values are not equal",
87                  author.name(),
88                  Matchers.equalTo(
89                      self.name()
90                  )
91              );
92          }
93          comment.remove();
94      }
95  
96      /**
97       * RtIssue can change title and body.
98       * @throws Exception If some problem inside
99       */
100     @Test
101     void changesTitleAndBody() throws Exception {
102         final Issue issue = RtIssueITCase.issue();
103         new Issue.Smart(issue).title("test one more time");
104         MatcherAssert.assertThat(
105             "String does not start with expected value",
106             new Issue.Smart(issue).title(),
107             Matchers.startsWith("test o")
108         );
109         new Issue.Smart(issue).body("some new body of the issue");
110         MatcherAssert.assertThat(
111             "String does not start with expected value",
112             new Issue.Smart(issue).body(),
113             Matchers.startsWith("some new ")
114         );
115     }
116 
117     /**
118      * RtIssue can change issue state.
119      * @throws Exception If some problem inside
120      */
121     @Test
122     void changesIssueState() throws Exception {
123         final Issue issue = RtIssueITCase.issue();
124         new Issue.Smart(issue).close();
125         MatcherAssert.assertThat(
126             "Values are not equal",
127             new Issue.Smart(issue).isOpen(),
128             Matchers.is(false)
129         );
130         new Issue.Smart(issue).open();
131         MatcherAssert.assertThat(
132             "Values are not equal",
133             new Issue.Smart(issue).isOpen(),
134             Matchers.is(true)
135         );
136     }
137 
138     /**
139      * RtIssue can fetch assignee.
140      *
141      * <p> If you get AssertionError during this test execution and test was
142      *  ignored it means that something happened with account that you try to
143      *  edit with Issue.assign(). We had this problem when our account was
144      *  flagged as suspicious by GitHub. In this case you should contact GitHub
145      *  support and ask them to unblock account you use.
146      * @throws Exception if any problem inside.
147      * @see <a href="https://github.com/jcabi/jcabi-github/issues/810">Why test is ignored?</a>
148      */
149     @Test
150     void identifyAssignee() throws Exception {
151         final Issue issue = RtIssueITCase.issue();
152         final String login = issue.repo().github().users().self().login();
153         try {
154             new Issue.Smart(issue).assign(login);
155         } catch (final AssertionError error) {
156             Logger.warn(this, "Test failed with error: %s", error.getMessage());
157             Assumptions.assumeFalse(
158                 true,
159                 "Something wrong with your test account. Read test's java-doc."
160             );
161         }
162         final User assignee = new Issue.Smart(issue).assignee();
163         MatcherAssert.assertThat(
164             "Values are not equal",
165             assignee.login(),
166             Matchers.equalTo(login)
167         );
168     }
169 
170     /**
171      * RtIssue can check whether it is a pull request.
172      * @throws Exception If some problem inside
173      */
174     @Test
175     void checksForPullRequest() throws Exception {
176         final Issue issue = RtIssueITCase.issue();
177         MatcherAssert.assertThat(
178             "Values are not equal",
179             new Issue.Smart(issue).isPull(),
180             Matchers.is(false)
181         );
182     }
183 
184     /**
185      * GhIssue can list issue events.
186      * @throws Exception If some problem inside
187      */
188     @Test
189     void listsIssueEvents() throws Exception {
190         final Issue issue = RtIssueITCase.issue();
191         new Issue.Smart(issue).close();
192         MatcherAssert.assertThat(
193             "Values are not equal",
194             new Event.Smart(issue.events().iterator().next()).type(),
195             Matchers.equalTo(Event.CLOSED)
196         );
197     }
198 
199     /**
200      * Issue.Smart can find the latest event.
201      * @throws Exception If some problem inside
202      */
203     @Test
204     void findsLatestEvent() throws Exception {
205         final Issue.Smart issue = new Issue.Smart(RtIssueITCase.issue());
206         issue.close();
207         MatcherAssert.assertThat(
208             "Values are not equal",
209             new Event.Smart(
210                 new Issue.Smart(issue).latestEvent(Event.CLOSED)
211             ).author().login(),
212             Matchers.equalTo(issue.author().login())
213         );
214     }
215 
216     /**
217      * RtIssue always exists in GitHub.
218      *
219      * @throws Exception when a problem occurs.
220      */
221     @Test
222     void issueAlwaysExistsInGitHub() throws Exception {
223         MatcherAssert.assertThat(
224             "Values are not equal",
225             new Issue.Smart(RtIssueITCase.issue()).exists(), Matchers.is(true)
226         );
227     }
228 
229     /**
230      * RtIssue can lock conversation.
231      * @throws Exception If some problem inside
232      */
233     @Test
234     void locks() throws Exception {
235         final Issue issue = new Issue.Smart(RtIssueITCase.issue());
236         issue.lock("off-topic");
237         MatcherAssert.assertThat(
238             "Assertion failed",
239             issue.isLocked(),
240             new IsEqual<>(true)
241         );
242     }
243 
244     /**
245      * RtIssue can unlock conversation.
246      * @throws Exception If some problem inside
247      */
248     @Test
249     void unlocks() throws Exception {
250         final Issue issue = new Issue.Smart(RtIssueITCase.issue());
251         issue.lock("too heated");
252         issue.unlock();
253         MatcherAssert.assertThat(
254             "Assertion failed",
255             issue.isLocked(),
256             new IsEqual<>(false)
257         );
258     }
259 
260     /**
261      * Create and return issue to test.
262      * @return Issue
263      */
264     private static Issue issue() throws IOException {
265         return RtIssueITCase.repo.issues().create("test issue title", "test issue body");
266     }
267 
268 }