]> source.dussan.org Git - sonarqube.git/blob
ccfddb717d524f44edcff31de2cb2c1c34ee339c
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2021 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 package org.sonar.alm.client.bitbucketserver;
21
22 import java.io.IOException;
23 import okhttp3.mockwebserver.MockResponse;
24 import okhttp3.mockwebserver.MockWebServer;
25 import org.junit.After;
26 import org.junit.Before;
27 import org.junit.Test;
28 import org.sonar.alm.client.ConstantTimeoutConfiguration;
29
30 import static org.assertj.core.api.Assertions.assertThat;
31 import static org.assertj.core.api.Assertions.assertThatThrownBy;
32 import static org.assertj.core.api.Assertions.tuple;
33
34 public class BitbucketServerRestClientTest {
35   private final MockWebServer server = new MockWebServer();
36   private BitbucketServerRestClient underTest;
37
38   @Before
39   public void prepare() throws IOException {
40     server.start();
41
42     underTest = new BitbucketServerRestClient(new ConstantTimeoutConfiguration(500));
43   }
44
45   @After
46   public void stopServer() throws IOException {
47     server.shutdown();
48   }
49
50   @Test
51   public void get_repos() {
52     server.enqueue(new MockResponse()
53       .setHeader("Content-Type", "application/json;charset=UTF-8")
54       .setBody("{\n" +
55         "  \"isLastPage\": true,\n" +
56         "  \"values\": [\n" +
57         "    {\n" +
58         "      \"slug\": \"banana\",\n" +
59         "      \"id\": 2,\n" +
60         "      \"name\": \"banana\",\n" +
61         "      \"project\": {\n" +
62         "        \"key\": \"HOY\",\n" +
63         "        \"id\": 2,\n" +
64         "        \"name\": \"hoy\"\n" +
65         "      }\n" +
66         "    },\n" +
67         "    {\n" +
68         "      \"slug\": \"potato\",\n" +
69         "      \"id\": 1,\n" +
70         "      \"name\": \"potato\",\n" +
71         "      \"project\": {\n" +
72         "        \"key\": \"HEY\",\n" +
73         "        \"id\": 1,\n" +
74         "        \"name\": \"hey\"\n" +
75         "      }\n" +
76         "    }\n" +
77         "  ]\n" +
78         "}"));
79
80     RepositoryList gsonBBSRepoList = underTest.getRepos(server.url("/").toString(), "token", "", "");
81     assertThat(gsonBBSRepoList.isLastPage()).isTrue();
82     assertThat(gsonBBSRepoList.getValues()).hasSize(2);
83     assertThat(gsonBBSRepoList.getValues()).extracting(Repository::getId, Repository::getName, Repository::getSlug,
84       g -> g.getProject().getId(), g -> g.getProject().getKey(), g -> g.getProject().getName())
85       .containsExactlyInAnyOrder(
86         tuple(2L, "banana", "banana", 2L, "HOY", "hoy"),
87         tuple(1L, "potato", "potato", 1L, "HEY", "hey"));
88   }
89
90   @Test
91   public void get_recent_repos() {
92     server.enqueue(new MockResponse()
93       .setHeader("Content-Type", "application/json;charset=UTF-8")
94       .setBody("{\n" +
95         "  \"isLastPage\": true,\n" +
96         "  \"values\": [\n" +
97         "    {\n" +
98         "      \"slug\": \"banana\",\n" +
99         "      \"id\": 2,\n" +
100         "      \"name\": \"banana\",\n" +
101         "      \"project\": {\n" +
102         "        \"key\": \"HOY\",\n" +
103         "        \"id\": 2,\n" +
104         "        \"name\": \"hoy\"\n" +
105         "      }\n" +
106         "    },\n" +
107         "    {\n" +
108         "      \"slug\": \"potato\",\n" +
109         "      \"id\": 1,\n" +
110         "      \"name\": \"potato\",\n" +
111         "      \"project\": {\n" +
112         "        \"key\": \"HEY\",\n" +
113         "        \"id\": 1,\n" +
114         "        \"name\": \"hey\"\n" +
115         "      }\n" +
116         "    }\n" +
117         "  ]\n" +
118         "}"));
119
120     RepositoryList gsonBBSRepoList = underTest.getRecentRepo(server.url("/").toString(), "token");
121     assertThat(gsonBBSRepoList.isLastPage()).isTrue();
122     assertThat(gsonBBSRepoList.getValues()).hasSize(2);
123     assertThat(gsonBBSRepoList.getValues()).extracting(Repository::getId, Repository::getName, Repository::getSlug,
124       g -> g.getProject().getId(), g -> g.getProject().getKey(), g -> g.getProject().getName())
125       .containsExactlyInAnyOrder(
126         tuple(2L, "banana", "banana", 2L, "HOY", "hoy"),
127         tuple(1L, "potato", "potato", 1L, "HEY", "hey"));
128   }
129
130   @Test
131   public void get_repo() {
132     server.enqueue(new MockResponse()
133       .setHeader("Content-Type", "application/json;charset=UTF-8")
134       .setBody(
135         "    {" +
136           "      \"slug\": \"banana-slug\"," +
137           "      \"id\": 2,\n" +
138           "      \"name\": \"banana\"," +
139           "      \"project\": {\n" +
140           "        \"key\": \"HOY\"," +
141           "        \"id\": 3,\n" +
142           "        \"name\": \"hoy\"" +
143           "      }" +
144           "    }"));
145
146     Repository repository = underTest.getRepo(server.url("/").toString(), "token", "", "");
147     assertThat(repository.getId()).isEqualTo(2L);
148     assertThat(repository.getName()).isEqualTo("banana");
149     assertThat(repository.getSlug()).isEqualTo("banana-slug");
150     assertThat(repository.getProject())
151       .extracting(Project::getId, Project::getKey, Project::getName)
152       .contains(3L, "HOY", "hoy");
153   }
154
155   @Test
156   public void get_projects() {
157     server.enqueue(new MockResponse()
158         .setHeader("Content-Type", "application/json;charset=UTF-8")
159         .setBody("{\n" +
160             "  \"isLastPage\": true,\n" +
161             "  \"values\": [\n" +
162             "    {\n" +
163             "      \"key\": \"HEY\",\n" +
164             "      \"id\": 1,\n" +
165             "      \"name\": \"hey\"\n" +
166             "    },\n" +
167             "    {\n" +
168             "      \"key\": \"HOY\",\n" +
169             "      \"id\": 2,\n" +
170             "      \"name\": \"hoy\"\n" +
171             "    }\n" +
172             "  ]\n" +
173             "}"));
174
175     final ProjectList gsonBBSProjectList = underTest.getProjects(server.url("/").toString(), "token");
176     assertThat(gsonBBSProjectList.getValues()).hasSize(2);
177     assertThat(gsonBBSProjectList.getValues()).extracting(Project::getId, Project::getKey, Project::getName)
178         .containsExactlyInAnyOrder(
179             tuple(1L, "HEY", "hey"),
180             tuple(2L, "HOY", "hoy"));
181   }
182
183   @Test
184   public void getBranches_given0Branches_returnEmptyList(){
185     String bodyWith0Branches = "{\n" +
186       "  \"size\": 0,\n" +
187       "  \"limit\": 25,\n" +
188       "  \"isLastPage\": true,\n" +
189       "  \"values\": [],\n" +
190       "  \"start\": 0\n" +
191       "}";
192     server.enqueue(new MockResponse()
193       .setHeader("Content-Type", "application/json;charset=UTF-8")
194       .setBody(bodyWith0Branches));
195
196     BranchesList branches = underTest.getBranches(server.url("/").toString(), "token", "projectSlug", "repoSlug");
197
198     assertThat(branches.getBranches()).isEmpty();
199   }
200
201   @Test
202   public void getBranches_given1Branch_returnListWithOneBranch(){
203     String bodyWith1Branch = "{\n" +
204       "  \"size\": 1,\n" +
205       "  \"limit\": 25,\n" +
206       "  \"isLastPage\": true,\n" +
207       "  \"values\": [{\n" +
208       "    \"id\": \"refs/heads/demo\",\n" +
209       "    \"displayId\": \"demo\",\n" +
210       "    \"type\": \"BRANCH\",\n" +
211       "    \"latestCommit\": \"3e30a6701af6f29f976e9a6609a6076b32a69ac3\",\n" +
212       "    \"latestChangeset\": \"3e30a6701af6f29f976e9a6609a6076b32a69ac3\",\n" +
213       "    \"isDefault\": false\n" +
214       "  }],\n" +
215       "  \"start\": 0\n" +
216       "}";
217     server.enqueue(new MockResponse()
218       .setHeader("Content-Type", "application/json;charset=UTF-8")
219       .setBody(bodyWith1Branch));
220
221     BranchesList branches = underTest.getBranches(server.url("/").toString(), "token", "projectSlug", "repoSlug");
222     assertThat(branches.getBranches()).hasSize(1);
223
224     Branch branch = branches.getBranches().get(0);
225     assertThat(branch.getName()).isEqualTo("demo");
226     assertThat(branch.isDefault()).isFalse();
227
228   }
229
230   @Test
231   public void getBranches_given2Branches_returnListWithTwoBranches(){
232     String bodyWith2Branches = "{\n" +
233       "  \"size\": 2,\n" +
234       "  \"limit\": 25,\n" +
235       "  \"isLastPage\": true,\n" +
236       "  \"values\": [{\n" +
237       "    \"id\": \"refs/heads/demo\",\n" +
238       "    \"displayId\": \"demo\",\n" +
239       "    \"type\": \"BRANCH\",\n" +
240       "    \"latestCommit\": \"3e30a6701af6f29f976e9a6609a6076b32a69ac3\",\n" +
241       "    \"latestChangeset\": \"3e30a6701af6f29f976e9a6609a6076b32a69ac3\",\n" +
242       "    \"isDefault\": false\n" +
243       "  }, {\n" +
244       "    \"id\": \"refs/heads/master\",\n" +
245       "    \"displayId\": \"master\",\n" +
246       "    \"type\": \"BRANCH\",\n" +
247       "    \"latestCommit\": \"66633864d27c531ff43892f6dfea6d91632682fa\",\n" +
248       "    \"latestChangeset\": \"66633864d27c531ff43892f6dfea6d91632682fa\",\n" +
249       "    \"isDefault\": true\n" +
250       "  }],\n" +
251       "  \"start\": 0\n" +
252       "}";
253     server.enqueue(new MockResponse()
254       .setHeader("Content-Type", "application/json;charset=UTF-8")
255       .setBody(bodyWith2Branches));
256
257     BranchesList branches = underTest.getBranches(server.url("/").toString(), "token", "projectSlug", "repoSlug");
258
259     assertThat(branches.getBranches()).hasSize(2);
260   }
261
262   @Test
263   public void invalid_url() {
264     assertThatThrownBy(() -> BitbucketServerRestClient.buildUrl("file://wrong-url", ""))
265       .isInstanceOf(IllegalArgumentException.class)
266       .hasMessage("url must start with http:// or https://");
267   }
268
269   @Test
270   public void malformed_json() {
271     server.enqueue(new MockResponse()
272       .setHeader("Content-Type", "application/json;charset=UTF-8")
273       .setBody(
274         "I'm malformed JSON"));
275
276     String serverUrl = server.url("/").toString();
277     assertThatThrownBy(() -> underTest.getRepo(serverUrl, "token", "", ""))
278       .isInstanceOf(IllegalArgumentException.class)
279       .hasMessage("Unable to contact Bitbucket server, got an unexpected response");
280   }
281
282   @Test
283   public void error_handling() {
284     server.enqueue(new MockResponse()
285         .setHeader("Content-Type", "application/json;charset=UTF-8")
286         .setResponseCode(400)
287         .setBody("{\n" +
288             "  \"errors\": [\n" +
289             "    {\n" +
290             "      \"context\": null,\n" +
291             "      \"message\": \"Bad message\",\n" +
292             "      \"exceptionName\": \"com.atlassian.bitbucket.auth.BadException\"\n" +
293             "    }\n" +
294             "  ]\n" +
295             "}"));
296
297     String serverUrl = server.url("/").toString();
298     assertThatThrownBy(() -> underTest.getRepo(serverUrl, "token", "", ""))
299         .isInstanceOf(IllegalArgumentException.class)
300         .hasMessage("Unable to contact Bitbucket server");
301   }
302
303   @Test
304   public void unauthorized_error() {
305     server.enqueue(new MockResponse()
306         .setHeader("Content-Type", "application/json;charset=UTF-8")
307         .setResponseCode(401)
308         .setBody("{\n" +
309             "  \"errors\": [\n" +
310             "    {\n" +
311             "      \"context\": null,\n" +
312             "      \"message\": \"Bad message\",\n" +
313             "      \"exceptionName\": \"com.atlassian.bitbucket.auth.BadException\"\n" +
314             "    }\n" +
315             "  ]\n" +
316             "}"));
317
318     String serverUrl = server.url("/").toString();
319     assertThatThrownBy(() -> underTest.getRepo(serverUrl, "token", "", ""))
320         .isInstanceOf(IllegalArgumentException.class)
321         .hasMessage("Invalid personal access token");
322   }
323
324 }