]> source.dussan.org Git - sonarqube.git/blob
42be74f8e87b05aef971d202f2955dc7b8e67759
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2024 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.server.almintegration.ws.gitlab;
21
22 import java.util.Arrays;
23 import java.util.LinkedList;
24 import org.junit.Rule;
25 import org.junit.Test;
26 import org.sonar.alm.client.gitlab.GitlabApplicationClient;
27 import org.sonar.alm.client.gitlab.Project;
28 import org.sonar.alm.client.gitlab.ProjectList;
29 import org.sonar.api.server.ws.WebService;
30 import org.sonar.db.DbTester;
31 import org.sonar.db.alm.pat.AlmPatDto;
32 import org.sonar.db.alm.setting.AlmSettingDto;
33 import org.sonar.db.project.ProjectDto;
34 import org.sonar.db.user.UserDto;
35 import org.sonar.server.exceptions.ForbiddenException;
36 import org.sonar.server.exceptions.NotFoundException;
37 import org.sonar.server.exceptions.UnauthorizedException;
38 import org.sonar.server.tester.UserSessionRule;
39 import org.sonar.server.ws.TestRequest;
40 import org.sonar.server.ws.WsActionTester;
41 import org.sonarqube.ws.AlmIntegrations;
42 import org.sonarqube.ws.AlmIntegrations.GitlabRepository;
43 import org.sonarqube.ws.AlmIntegrations.SearchGitlabReposWsResponse;
44
45 import static org.assertj.core.api.Assertions.assertThat;
46 import static org.assertj.core.api.Assertions.assertThatThrownBy;
47 import static org.assertj.core.api.Assertions.tuple;
48 import static org.mockito.ArgumentMatchers.any;
49 import static org.mockito.ArgumentMatchers.anyInt;
50 import static org.mockito.Mockito.mock;
51 import static org.mockito.Mockito.when;
52 import static org.sonar.db.alm.integration.pat.AlmPatsTesting.newAlmPatDto;
53 import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS;
54
55 public class SearchGitlabReposActionIT {
56
57   @Rule
58   public UserSessionRule userSession = UserSessionRule.standalone();
59   @Rule
60   public DbTester db = DbTester.create();
61
62   private final GitlabApplicationClient gitlabApplicationClient = mock(GitlabApplicationClient.class);
63   private final WsActionTester ws = new WsActionTester(new SearchGitlabReposAction(db.getDbClient(), userSession,
64     gitlabApplicationClient));
65
66   @Test
67   public void list_gitlab_repos() {
68     Project gitlabProject1 = new Project(1L, "repoName1", "repoNamePath1", "repo-slug-1", "repo-path-slug-1", "url-1");
69     Project gitlabProject2 = new Project(2L, "repoName2", "path1 / repoName2", "repo-slug-2", "path-1/repo-slug-2", "url-2");
70     Project gitlabProject3 = new Project(3L, "repoName3", "repoName3 / repoName3", "repo-slug-3", "repo-slug-3/repo-slug-3", "url-3");
71     Project gitlabProject4 = new Project(4L, "repoName4", "repoName4 / repoName4 / repoName4", "repo-slug-4", "repo-slug-4/repo-slug-4/repo-slug-4", "url-4");
72     when(gitlabApplicationClient.searchProjects(any(), any(), any(), anyInt(), anyInt()))
73       .thenReturn(
74         new ProjectList(Arrays.asList(gitlabProject1, gitlabProject2, gitlabProject3, gitlabProject4), 1, 10, 4));
75
76     UserDto user = db.users().insertUser();
77     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
78     AlmSettingDto almSetting = db.almSettings().insertGitlabAlmSetting();
79     db.almPats().insert(dto -> {
80       dto.setAlmSettingUuid(almSetting.getUuid());
81       dto.setUserUuid(user.getUuid());
82       dto.setPersonalAccessToken("some-pat");
83     });
84     ProjectDto projectDto = db.components().insertPrivateProject().getProjectDto();
85     db.almSettings().insertGitlabProjectAlmSetting(almSetting, projectDto);
86
87     AlmIntegrations.SearchGitlabReposWsResponse response = ws.newRequest()
88       .setParam("almSetting", almSetting.getKey())
89       .executeProtobuf(SearchGitlabReposWsResponse.class);
90
91     assertThat(response.getRepositoriesCount()).isEqualTo(4);
92
93     assertThat(response.getRepositoriesList())
94       .extracting(GitlabRepository::getId,
95         GitlabRepository::getName,
96         GitlabRepository::getPathName,
97         GitlabRepository::getSlug,
98         GitlabRepository::getPathSlug,
99         GitlabRepository::getUrl,
100         GitlabRepository::hasSqProjectKey,
101         GitlabRepository::hasSqProjectName)
102       .containsExactlyInAnyOrder(
103         tuple(1L, "repoName1", "repoNamePath1", "repo-slug-1", "repo-path-slug-1", "url-1", false, false),
104         tuple(2L, "repoName2", "path1", "repo-slug-2", "path-1", "url-2", false, false),
105         tuple(3L, "repoName3", "repoName3", "repo-slug-3", "repo-slug-3", "url-3", false, false),
106         tuple(4L, "repoName4", "repoName4 / repoName4", "repo-slug-4", "repo-slug-4/repo-slug-4", "url-4", false, false));
107   }
108
109   @Test
110   public void list_gitlab_repos_some_projects_already_set_up() {
111     Project gitlabProject1 = new Project(1L, "repoName1", "repoNamePath1", "repo-slug-1", "repo-path-slug-1", "url-1");
112     Project gitlabProject2 = new Project(2L, "repoName2", "path1 / repoName2", "repo-slug-2", "path-1/repo-slug-2", "url-2");
113     Project gitlabProject3 = new Project(3L, "repoName3", "repoName3 / repoName3", "repo-slug-3", "repo-slug-3/repo-slug-3", "url-3");
114     Project gitlabProject4 = new Project(4L, "repoName4", "repoName4 / repoName4 / repoName4", "repo-slug-4", "repo-slug-4/repo-slug-4/repo-slug-4", "url-4");
115     when(gitlabApplicationClient.searchProjects(any(), any(), any(), anyInt(), anyInt()))
116       .thenReturn(
117         new ProjectList(Arrays.asList(gitlabProject1, gitlabProject2, gitlabProject3, gitlabProject4), 1, 10, 4));
118
119     UserDto user = db.users().insertUser();
120     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
121     AlmSettingDto almSetting = db.almSettings().insertGitlabAlmSetting();
122     db.almPats().insert(dto -> {
123       dto.setAlmSettingUuid(almSetting.getUuid());
124       dto.setUserUuid(user.getUuid());
125       dto.setPersonalAccessToken("some-pat");
126     });
127     ProjectDto projectDto1 = db.components().insertPrivateProject(dto -> dto.setKey("proj_key_1").setName("proj_name_1")).getProjectDto();
128     db.almSettings().insertGitlabProjectAlmSetting(almSetting, projectDto1);
129
130     ProjectDto projectDto2 = db.components().insertPrivateProject(dto -> dto.setKey("proj_key_2").setName("proj_name_2")).getProjectDto();
131     db.almSettings().insertGitlabProjectAlmSetting(almSetting, projectDto2, projectAlmSettingDto -> projectAlmSettingDto.setAlmRepo("2"));
132
133     ProjectDto projectDto3 = db.components().insertPrivateProject(dto -> dto.setKey("proj_key_3").setName("proj_name_3")).getProjectDto();
134     db.almSettings().insertGitlabProjectAlmSetting(almSetting, projectDto3, projectAlmSettingDto -> projectAlmSettingDto.setAlmRepo("3"));
135
136     ProjectDto projectDto4 = db.components().insertPrivateProject(dto -> dto.setKey("proj_key_4").setName("proj_name_4")).getProjectDto();
137     db.almSettings().insertGitlabProjectAlmSetting(almSetting, projectDto4, projectAlmSettingDto -> projectAlmSettingDto.setAlmRepo("3"));
138
139     AlmIntegrations.SearchGitlabReposWsResponse response = ws.newRequest()
140       .setParam("almSetting", almSetting.getKey())
141       .executeProtobuf(SearchGitlabReposWsResponse.class);
142
143     assertThat(response.getRepositoriesCount()).isEqualTo(4);
144
145     assertThat(response.getRepositoriesList())
146       .extracting(GitlabRepository::getId,
147         GitlabRepository::getName,
148         GitlabRepository::getPathName,
149         GitlabRepository::getSlug,
150         GitlabRepository::getPathSlug,
151         GitlabRepository::getUrl,
152         GitlabRepository::getSqProjectKey,
153         GitlabRepository::getSqProjectName)
154       .containsExactlyInAnyOrder(
155         tuple(1L, "repoName1", "repoNamePath1", "repo-slug-1", "repo-path-slug-1", "url-1", "", ""),
156         tuple(2L, "repoName2", "path1", "repo-slug-2", "path-1", "url-2", projectDto2.getKey(), projectDto2.getName()),
157         tuple(3L, "repoName3", "repoName3", "repo-slug-3", "repo-slug-3", "url-3", projectDto3.getKey(), projectDto3.getName()),
158         tuple(4L, "repoName4", "repoName4 / repoName4", "repo-slug-4", "repo-slug-4/repo-slug-4", "url-4", "", ""));
159   }
160
161   @Test
162   public void return_empty_list_when_no_gitlab_projects() {
163     when(gitlabApplicationClient.searchProjects(any(), any(), any(), anyInt(), anyInt())).thenReturn(new ProjectList(new LinkedList<>(), 1, 10, 0));
164     UserDto user = db.users().insertUser();
165     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
166     AlmSettingDto almSetting = db.almSettings().insertBitbucketAlmSetting();
167     db.almPats().insert(dto -> {
168       dto.setAlmSettingUuid(almSetting.getUuid());
169       dto.setUserUuid(user.getUuid());
170     });
171     ProjectDto projectDto = db.components().insertPrivateProject().getProjectDto();
172     db.almSettings().insertGitlabProjectAlmSetting(almSetting, projectDto);
173
174     AlmIntegrations.SearchGitlabReposWsResponse response = ws.newRequest()
175       .setParam("almSetting", almSetting.getKey())
176       .executeProtobuf(SearchGitlabReposWsResponse.class);
177
178     assertThat(response.getRepositoriesList()).isEmpty();
179   }
180
181   @Test
182   public void check_pat_is_missing() {
183     UserDto user = db.users().insertUser();
184     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
185     AlmSettingDto almSetting = db.almSettings().insertGitlabAlmSetting();
186
187     TestRequest request = ws.newRequest()
188       .setParam("almSetting", almSetting.getKey());
189
190     assertThatThrownBy(request::execute)
191       .isInstanceOf(IllegalArgumentException.class)
192       .hasMessage("No personal access token found");
193   }
194
195   @Test
196   public void fail_when_alm_setting_not_found() {
197     UserDto user = db.users().insertUser();
198     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
199     AlmPatDto almPatDto = newAlmPatDto();
200     db.getDbClient().almPatDao().insert(db.getSession(), almPatDto, user.getLogin(), null);
201
202     TestRequest request = ws.newRequest()
203       .setParam("almSetting", "testKey");
204
205     assertThatThrownBy(request::execute)
206       .isInstanceOf(NotFoundException.class)
207       .hasMessage("DevOps Platform Setting 'testKey' not found");
208   }
209
210   @Test
211   public void fail_when_not_logged_in() {
212     TestRequest request = ws.newRequest()
213       .setParam("almSetting", "anyvalue");
214
215     assertThatThrownBy(request::execute)
216       .isInstanceOf(UnauthorizedException.class)
217       .hasMessage("Authentication is required");
218   }
219
220   @Test
221   public void fail_when_no_creation_project_permission() {
222     UserDto user = db.users().insertUser();
223     userSession.logIn(user);
224
225     TestRequest request = ws.newRequest()
226       .setParam("almSetting", "anyvalue");
227
228     assertThatThrownBy(request::execute)
229       .isInstanceOf(ForbiddenException.class)
230       .hasMessage("Insufficient privileges");
231   }
232
233   @Test
234   public void verify_response_example() {
235     Project gitlabProject1 = new Project(1L, "Gitlab repo name 1", "Group / Gitlab repo name 1", "gitlab-repo-name-1", "group/gitlab-repo-name-1",
236       "https://example.gitlab.com/group/gitlab-repo-name-1");
237     Project gitlabProject2 = new Project(2L, "Gitlab repo name 2", "Group / Gitlab repo name 2", "gitlab-repo-name-2", "group/gitlab-repo-name-2",
238       "https://example.gitlab.com/group/gitlab-repo-name-2");
239     Project gitlabProject3 = new Project(3L, "Gitlab repo name 3", "Group / Gitlab repo name 3", "gitlab-repo-name-3", "group/gitlab-repo-name-3",
240       "https://example.gitlab.com/group/gitlab-repo-name-3");
241     when(gitlabApplicationClient.searchProjects(any(), any(), any(), anyInt(), anyInt()))
242       .thenReturn(
243         new ProjectList(Arrays.asList(gitlabProject1, gitlabProject2, gitlabProject3), 1, 3, 10));
244
245     UserDto user = db.users().insertUser();
246     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
247     AlmSettingDto almSetting = db.almSettings().insertGitlabAlmSetting();
248     db.almPats().insert(dto -> {
249       dto.setAlmSettingUuid(almSetting.getUuid());
250       dto.setUserUuid(user.getUuid());
251       dto.setPersonalAccessToken("some-pat");
252     });
253     ProjectDto projectDto = db.components().insertPrivateProject().getProjectDto();
254     db.almSettings().insertGitlabProjectAlmSetting(almSetting, projectDto);
255
256     WebService.Action def = ws.getDef();
257     String responseExample = def.responseExampleAsString();
258
259     assertThat(responseExample).isNotBlank();
260
261     ws.newRequest()
262       .setParam("almSetting", almSetting.getKey())
263       .execute().assertJson(
264         responseExample);
265   }
266
267   @Test
268   public void definition() {
269     WebService.Action def = ws.getDef();
270
271     assertThat(def.since()).isEqualTo("8.5");
272     assertThat(def.isPost()).isFalse();
273     assertThat(def.params())
274       .extracting(WebService.Param::key, WebService.Param::isRequired)
275       .containsExactlyInAnyOrder(
276         tuple("almSetting", true),
277         tuple("p", false),
278         tuple("ps", false),
279         tuple("projectName", false));
280   }
281
282 }