View Javadoc
1   /**
2    * Copyright (c) 2013-2022, 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: a0c2b71dcbe6b44fdcba23ff140e476d0bf29e85 $
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      public transient ExpectedException thrown = ExpectedException.none();
59  
60      /**
61       * Issue.Smart can fetch key properties of an Issue.
62       * @throws Exception If some problem inside
63       */
64      @Test
65      public void fetchesProperties() throws Exception {
66          final Issue issue = Mockito.mock(Issue.class);
67          Mockito.doReturn(
68              Json.createObjectBuilder()
69                  .add("title", "this is some text \u20ac")
70                  .add("body", "body of the issue")
71                  .build()
72          ).when(issue).json();
73          final Issue.Smart smart = new Issue.Smart(issue);
74          MatcherAssert.assertThat(
75              smart.title(),
76              Matchers.notNullValue()
77          );
78          MatcherAssert.assertThat(
79              smart.body(),
80              Matchers.notNullValue()
81          );
82      }
83  
84      /**
85       * Issue.Smart can detect a pull request.
86       * @throws Exception If some problem inside
87       */
88      @Test
89      public void detectsPullRequest() throws Exception {
90          final Issue issue = Mockito.mock(Issue.class);
91          Mockito.doReturn(
92              Json.createObjectBuilder().add(
93                  "pull_request",
94                  Json.createObjectBuilder().add(
95                      "html_url", "http://ibm.com/pulls/3"
96                  )
97              ).build()
98          ).when(issue).json();
99          final Pulls pulls = Mockito.mock(Pulls.class);
100         final Repo repo = Mockito.mock(Repo.class);
101         final Pull pull = Mockito.mock(Pull.class);
102         Mockito.doReturn(repo).when(issue).repo();
103         Mockito.doReturn(pulls).when(repo).pulls();
104         Mockito.when(pulls.get(Mockito.eq(Tv.THREE))).thenReturn(pull);
105         MatcherAssert.assertThat(
106             new Issue.Smart(issue).isPull(),
107             Matchers.is(true)
108         );
109         new Issue.Smart(issue).pull();
110         Mockito.verify(pulls).get(Tv.THREE);
111     }
112 
113     /**
114      * Issue.Smart can detect an absence of a pull request.
115      * @throws Exception If some problem inside
116      */
117     @Test
118     public void detectsPullRequestAbsence() throws Exception {
119         final Issue issue = Mockito.mock(Issue.class);
120         Mockito.doReturn(
121             Json.createObjectBuilder().add(
122                 "pull_request",
123                 Json.createObjectBuilder().addNull("html_url")
124             ).build()
125         ).when(issue).json();
126         MatcherAssert.assertThat(
127             new Issue.Smart(issue).isPull(),
128             Matchers.is(false)
129         );
130     }
131 
132     /**
133      * Issue.Smart can detect an full absence of a pull request.
134      * @throws Exception If some problem inside
135      */
136     @Test
137     public void detectsFullPullRequestAbsence() throws Exception {
138         final Issue issue = Mockito.mock(Issue.class);
139         Mockito.doReturn(
140             Json.createObjectBuilder().build()
141         ).when(issue).json();
142         MatcherAssert.assertThat(
143             new Issue.Smart(issue).isPull(),
144             Matchers.is(false)
145         );
146     }
147 
148     /**
149      * Issue.Smart can fetch issue's labels in read-only mode.
150      * @throws IOException If some problem inside.
151      */
152     @Test
153     public void fetchLabelsRO() throws IOException {
154         final String name = "bug";
155         final JsonObject json = Json.createObjectBuilder().add(
156             "labels",
157             Json.createArrayBuilder().add(
158                 Json.createObjectBuilder()
159                     .add("name", name)
160                     .add("color", "f29513")
161             )
162         ).build();
163         final Issue issue = new RtIssue(
164             new FakeRequest().withBody(json.toString()), this.repo(), 1
165         );
166         final IssueLabels labels = new Issue.Smart(issue).roLabels();
167         this.thrown.expect(UnsupportedOperationException.class);
168         labels.add(new ArrayList<String>(0));
169         this.thrown.expect(UnsupportedOperationException.class);
170         labels.replace(new ArrayList<String>(0));
171         this.thrown.expect(UnsupportedOperationException.class);
172         labels.remove(name);
173         this.thrown.expect(UnsupportedOperationException.class);
174         labels.clear();
175         final Label label = labels.iterate().iterator().next();
176         MatcherAssert.assertThat(label, Matchers.notNullValue());
177         this.thrown.expect(UnsupportedOperationException.class);
178         label.patch(Mockito.mock(JsonObject.class));
179     }
180 
181     /**
182      * Mock repo for GhIssue creation.
183      * @return The mock repo.
184      */
185     private Repo repo() {
186         final Repo repo = Mockito.mock(Repo.class);
187         final Coordinates coords = Mockito.mock(Coordinates.class);
188         Mockito.doReturn(coords).when(repo).coordinates();
189         Mockito.doReturn("user").when(coords).user();
190         Mockito.doReturn("repo").when(coords).repo();
191         return repo;
192     }
193 }