View Javadoc
1   /**
2    * Copyright (c) 2013-2023, jcabi.com
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met: 1) Redistributions of source code must retain the above
8    * copyright notice, this list of conditions and the following
9    * disclaimer. 2) Redistributions in binary form must reproduce the above
10   * copyright notice, this list of conditions and the following
11   * disclaimer in the documentation and/or other materials provided
12   * with the distribution. 3) Neither the name of the jcabi.com nor
13   * the names of its contributors may be used to endorse or promote
14   * products derived from this software without specific prior written
15   * permission.
16   *
17   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
19   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21   * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28   * OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  package com.jcabi.github;
31  
32  import com.jcabi.aspects.Tv;
33  import com.jcabi.http.request.FakeRequest;
34  import java.io.IOException;
35  import java.util.ArrayList;
36  import javax.json.Json;
37  import javax.json.JsonObject;
38  import org.hamcrest.MatcherAssert;
39  import org.hamcrest.Matchers;
40  import org.junit.Rule;
41  import org.junit.Test;
42  import org.junit.rules.ExpectedException;
43  import org.mockito.Mockito;
44  
45  /**
46   * Test case for {@link Issue}.
47   * @author Yegor Bugayenko (yegor256@gmail.com)
48   * @version $Id: bf8ceb01325ecdf4abcfc0fbc54ebeecfc1d0141 $
49   * @checkstyle MultipleStringLiterals (500 lines)
50   */
51  public final class IssueTest {
52  
53      /**
54       * Rule for checking thrown exception.
55       * @checkstyle VisibilityModifier (3 lines)
56       */
57      @Rule
58      @SuppressWarnings("deprecation")
59      public transient ExpectedException thrown = ExpectedException.none();
60  
61      /**
62       * Issue.Smart can fetch key properties of an Issue.
63       * @throws Exception If some problem inside
64       */
65      @Test
66      public void fetchesProperties() throws Exception {
67          final Issue issue = Mockito.mock(Issue.class);
68          Mockito.doReturn(
69              Json.createObjectBuilder()
70                  .add("title", "this is some text \u20ac")
71                  .add("body", "body of the issue")
72                  .build()
73          ).when(issue).json();
74          final Issue.Smart smart = new Issue.Smart(issue);
75          MatcherAssert.assertThat(
76              smart.title(),
77              Matchers.notNullValue()
78          );
79          MatcherAssert.assertThat(
80              smart.body(),
81              Matchers.notNullValue()
82          );
83      }
84  
85      /**
86       * Issue.Smart can detect a pull request.
87       * @throws Exception If some problem inside
88       */
89      @Test
90      public void detectsPullRequest() throws Exception {
91          final Issue issue = Mockito.mock(Issue.class);
92          Mockito.doReturn(
93              Json.createObjectBuilder().add(
94                  "pull_request",
95                  Json.createObjectBuilder().add(
96                      "html_url", "http://ibm.com/pulls/3"
97                  )
98              ).build()
99          ).when(issue).json();
100         final Pulls pulls = Mockito.mock(Pulls.class);
101         final Repo repo = Mockito.mock(Repo.class);
102         final Pull pull = Mockito.mock(Pull.class);
103         Mockito.doReturn(repo).when(issue).repo();
104         Mockito.doReturn(pulls).when(repo).pulls();
105         Mockito.when(pulls.get(Mockito.eq(Tv.THREE))).thenReturn(pull);
106         MatcherAssert.assertThat(
107             new Issue.Smart(issue).isPull(),
108             Matchers.is(true)
109         );
110         new Issue.Smart(issue).pull();
111         Mockito.verify(pulls).get(Tv.THREE);
112     }
113 
114     /**
115      * Issue.Smart can detect an absence of a pull request.
116      * @throws Exception If some problem inside
117      */
118     @Test
119     public void detectsPullRequestAbsence() throws Exception {
120         final Issue issue = Mockito.mock(Issue.class);
121         Mockito.doReturn(
122             Json.createObjectBuilder().add(
123                 "pull_request",
124                 Json.createObjectBuilder().addNull("html_url")
125             ).build()
126         ).when(issue).json();
127         MatcherAssert.assertThat(
128             new Issue.Smart(issue).isPull(),
129             Matchers.is(false)
130         );
131     }
132 
133     /**
134      * Issue.Smart can detect an full absence of a pull request.
135      * @throws Exception If some problem inside
136      */
137     @Test
138     public void detectsFullPullRequestAbsence() throws Exception {
139         final Issue issue = Mockito.mock(Issue.class);
140         Mockito.doReturn(
141             Json.createObjectBuilder().build()
142         ).when(issue).json();
143         MatcherAssert.assertThat(
144             new Issue.Smart(issue).isPull(),
145             Matchers.is(false)
146         );
147     }
148 
149     /**
150      * Issue.Smart can fetch issue's labels in read-only mode.
151      * @throws IOException If some problem inside.
152      */
153     @Test
154     public void fetchLabelsRO() throws IOException {
155         final String name = "bug";
156         final JsonObject json = Json.createObjectBuilder().add(
157             "labels",
158             Json.createArrayBuilder().add(
159                 Json.createObjectBuilder()
160                     .add("name", name)
161                     .add("color", "f29513")
162             )
163         ).build();
164         final Issue issue = new RtIssue(
165             new FakeRequest().withBody(json.toString()), this.repo(), 1
166         );
167         final IssueLabels labels = new Issue.Smart(issue).roLabels();
168         this.thrown.expect(UnsupportedOperationException.class);
169         labels.add(new ArrayList<>(0));
170         this.thrown.expect(UnsupportedOperationException.class);
171         labels.replace(new ArrayList<>(0));
172         this.thrown.expect(UnsupportedOperationException.class);
173         labels.remove(name);
174         this.thrown.expect(UnsupportedOperationException.class);
175         labels.clear();
176         final Label label = labels.iterate().iterator().next();
177         MatcherAssert.assertThat(label, Matchers.notNullValue());
178         this.thrown.expect(UnsupportedOperationException.class);
179         label.patch(Mockito.mock(JsonObject.class));
180     }
181 
182     /**
183      * Mock repo for GhIssue creation.
184      * @return The mock repo.
185      */
186     private Repo repo() {
187         final Repo repo = Mockito.mock(Repo.class);
188         final Coordinates coords = Mockito.mock(Coordinates.class);
189         Mockito.doReturn(coords).when(repo).coordinates();
190         Mockito.doReturn("user").when(coords).user();
191         Mockito.doReturn("repo").when(coords).repo();
192         return repo;
193     }
194 }