3 * Copyright (C) 2009-2021 SonarSource SA
4 * mailto:info AT sonarsource DOT com
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.
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.
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.
20 package org.sonar.alm.client.bitbucketserver;
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;
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;
34 public class BitbucketServerRestClientTest {
35 private final MockWebServer server = new MockWebServer();
36 private BitbucketServerRestClient underTest;
39 public void prepare() throws IOException {
42 underTest = new BitbucketServerRestClient(new ConstantTimeoutConfiguration(500));
46 public void stopServer() throws IOException {
51 public void get_repos() {
52 server.enqueue(new MockResponse()
53 .setHeader("Content-Type", "application/json;charset=UTF-8")
55 " \"isLastPage\": true,\n" +
58 " \"slug\": \"banana\",\n" +
60 " \"name\": \"banana\",\n" +
62 " \"key\": \"HOY\",\n" +
64 " \"name\": \"hoy\"\n" +
68 " \"slug\": \"potato\",\n" +
70 " \"name\": \"potato\",\n" +
72 " \"key\": \"HEY\",\n" +
74 " \"name\": \"hey\"\n" +
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"));
91 public void get_repo() {
92 server.enqueue(new MockResponse()
93 .setHeader("Content-Type", "application/json;charset=UTF-8")
96 " \"slug\": \"banana-slug\"," +
98 " \"name\": \"banana\"," +
100 " \"key\": \"HOY\"," +
102 " \"name\": \"hoy\"" +
106 Repository repository = underTest.getRepo(server.url("/").toString(), "token", "", "");
107 assertThat(repository.getId()).isEqualTo(2L);
108 assertThat(repository.getName()).isEqualTo("banana");
109 assertThat(repository.getSlug()).isEqualTo("banana-slug");
110 assertThat(repository.getProject())
111 .extracting(Project::getId, Project::getKey, Project::getName)
112 .contains(3L, "HOY", "hoy");
116 public void get_projects() {
117 server.enqueue(new MockResponse()
118 .setHeader("Content-Type", "application/json;charset=UTF-8")
120 " \"isLastPage\": true,\n" +
123 " \"key\": \"HEY\",\n" +
125 " \"name\": \"hey\"\n" +
128 " \"key\": \"HOY\",\n" +
130 " \"name\": \"hoy\"\n" +
135 final ProjectList gsonBBSProjectList = underTest.getProjects(server.url("/").toString(), "token");
136 assertThat(gsonBBSProjectList.getValues()).hasSize(2);
137 assertThat(gsonBBSProjectList.getValues()).extracting(Project::getId, Project::getKey, Project::getName)
138 .containsExactlyInAnyOrder(
139 tuple(1L, "HEY", "hey"),
140 tuple(2L, "HOY", "hoy"));
144 public void invalid_url() {
145 assertThatThrownBy(() -> BitbucketServerRestClient.buildUrl("file://wrong-url", ""))
146 .isInstanceOf(IllegalArgumentException.class)
147 .hasMessage("url must start with http:// or https://");
151 public void malformed_json() {
152 server.enqueue(new MockResponse()
153 .setHeader("Content-Type", "application/json;charset=UTF-8")
155 "I'm malformed JSON"));
157 String serverUrl = server.url("/").toString();
158 assertThatThrownBy(() -> underTest.getRepo(serverUrl, "token", "", ""))
159 .isInstanceOf(IllegalArgumentException.class)
160 .hasMessage("Unable to contact Bitbucket server, got an unexpected response");
164 public void error_handling() {
165 server.enqueue(new MockResponse()
166 .setHeader("Content-Type", "application/json;charset=UTF-8")
167 .setResponseCode(400)
171 " \"context\": null,\n" +
172 " \"message\": \"Bad message\",\n" +
173 " \"exceptionName\": \"com.atlassian.bitbucket.auth.BadException\"\n" +
178 String serverUrl = server.url("/").toString();
179 assertThatThrownBy(() -> underTest.getRepo(serverUrl, "token", "", ""))
180 .isInstanceOf(IllegalArgumentException.class)
181 .hasMessage("Unable to contact Bitbucket server");
185 public void unauthorized_error() {
186 server.enqueue(new MockResponse()
187 .setHeader("Content-Type", "application/json;charset=UTF-8")
188 .setResponseCode(401)
192 " \"context\": null,\n" +
193 " \"message\": \"Bad message\",\n" +
194 " \"exceptionName\": \"com.atlassian.bitbucket.auth.BadException\"\n" +
199 String serverUrl = server.url("/").toString();
200 assertThatThrownBy(() -> underTest.getRepo(serverUrl, "token", "", ""))
201 .isInstanceOf(IllegalArgumentException.class)
202 .hasMessage("Invalid personal access token");