]> source.dussan.org Git - sonarqube.git/blob
2ace97fb69e38ee257ab17c105d764f6cedde427
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2022 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.qualityprofile.ws;
21
22 import java.net.HttpURLConnection;
23 import org.junit.Rule;
24 import org.junit.Test;
25 import org.sonar.api.resources.Languages;
26 import org.sonar.api.resources.Qualifiers;
27 import org.sonar.api.server.ws.WebService;
28 import org.sonar.api.web.UserRole;
29 import org.sonar.db.DbClient;
30 import org.sonar.db.DbTester;
31 import org.sonar.db.component.ComponentDto;
32 import org.sonar.db.component.ResourceTypesRule;
33 import org.sonar.db.project.ProjectDto;
34 import org.sonar.db.qualityprofile.QProfileDto;
35 import org.sonar.db.user.UserDto;
36 import org.sonar.server.component.ComponentFinder;
37 import org.sonar.server.exceptions.ForbiddenException;
38 import org.sonar.server.exceptions.NotFoundException;
39 import org.sonar.server.exceptions.UnauthorizedException;
40 import org.sonar.server.language.LanguageTesting;
41 import org.sonar.server.tester.UserSessionRule;
42 import org.sonar.server.ws.TestRequest;
43 import org.sonar.server.ws.TestResponse;
44 import org.sonar.server.ws.WsActionTester;
45
46 import static java.lang.String.format;
47 import static org.assertj.core.api.Assertions.assertThat;
48 import static org.assertj.core.api.Assertions.assertThatThrownBy;
49 import static org.sonar.db.permission.GlobalPermission.ADMINISTER_QUALITY_PROFILES;
50
51 public class RemoveProjectActionTest {
52   private static final String LANGUAGE_1 = "xoo";
53   private static final String LANGUAGE_2 = "foo";
54
55   @Rule
56   public DbTester db = DbTester.create();
57   @Rule
58   public UserSessionRule userSession = UserSessionRule.standalone();
59
60   private final DbClient dbClient = db.getDbClient();
61   private final Languages languages = LanguageTesting.newLanguages(LANGUAGE_1, LANGUAGE_2);
62   private final QProfileWsSupport wsSupport = new QProfileWsSupport(dbClient, userSession);
63
64   private final RemoveProjectAction underTest = new RemoveProjectAction(dbClient, userSession, languages,
65     new ComponentFinder(dbClient, new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT)), wsSupport);
66   private final WsActionTester ws = new WsActionTester(underTest);
67
68   @Test
69   public void definition() {
70     WebService.Action definition = ws.getDef();
71
72     assertThat(definition.since()).isEqualTo("5.2");
73     assertThat(definition.isPost()).isTrue();
74     assertThat(definition.key()).isEqualTo("remove_project");
75
76     assertThat(definition.params()).extracting(WebService.Param::key).containsOnly("qualityProfile", "project", "language");
77     WebService.Param languageParam = definition.param("language");
78     assertThat(languageParam.possibleValues()).containsOnly(LANGUAGE_1, LANGUAGE_2);
79     assertThat(languageParam.exampleValue()).isNull();
80     assertThat(languageParam.deprecatedSince()).isNullOrEmpty();
81     WebService.Param profileName = definition.param("qualityProfile");
82     assertThat(profileName.deprecatedSince()).isNullOrEmpty();
83   }
84
85   @Test
86   public void remove_profile_from_project() {
87     logInAsProfileAdmin();
88
89     ProjectDto project = db.components().insertPrivateProjectDto();
90     QProfileDto profileLang1 = db.qualityProfiles().insert(p -> p.setLanguage(LANGUAGE_1));
91     QProfileDto profileLang2 = db.qualityProfiles().insert(p -> p.setLanguage(LANGUAGE_2));
92     db.qualityProfiles().associateWithProject(project, profileLang1);
93     db.qualityProfiles().associateWithProject(project, profileLang2);
94
95     TestResponse response = call(project, profileLang1);
96     assertThat(response.getStatus()).isEqualTo(HttpURLConnection.HTTP_NO_CONTENT);
97
98     assertProjectIsNotAssociatedToProfile(project, profileLang1);
99     assertProjectIsAssociatedToProfile(project, profileLang2);
100   }
101
102   @Test
103   public void removal_does_not_fail_if_profile_is_not_associated_to_project() {
104     logInAsProfileAdmin();
105
106     ProjectDto project = db.components().insertPrivateProjectDto();
107     QProfileDto profile = db.qualityProfiles().insert(qp -> qp.setLanguage("xoo"));
108
109     TestResponse response = call(project, profile);
110     assertThat(response.getStatus()).isEqualTo(HttpURLConnection.HTTP_NO_CONTENT);
111
112     assertProjectIsNotAssociatedToProfile(project, profile);
113   }
114
115   @Test
116   public void project_administrator_can_remove_profile() {
117     ProjectDto project = db.components().insertPrivateProjectDto();
118     QProfileDto profile = db.qualityProfiles().insert(qp -> qp.setLanguage("xoo"));
119     db.qualityProfiles().associateWithProject(project, profile);
120     userSession.logIn(db.users().insertUser()).addProjectPermission(UserRole.ADMIN, project);
121
122     call(project, profile);
123
124     assertProjectIsNotAssociatedToProfile(project, profile);
125   }
126
127   @Test
128   public void as_qprofile_editor() {
129     ProjectDto project = db.components().insertPrivateProjectDto();
130     QProfileDto profile = db.qualityProfiles().insert(p -> p.setLanguage(LANGUAGE_1));
131     db.qualityProfiles().associateWithProject(project, profile);
132     UserDto user = db.users().insertUser();
133     db.qualityProfiles().addUserPermission(profile, user);
134     userSession.logIn(user);
135
136     call(project, profile);
137
138     assertProjectIsNotAssociatedToProfile(project, profile);
139   }
140
141   @Test
142   public void fail_if_not_enough_permissions() {
143     userSession.logIn(db.users().insertUser());
144     ProjectDto project = db.components().insertPrivateProjectDto();
145     QProfileDto profile = db.qualityProfiles().insert(qp -> qp.setLanguage("xoo"));
146
147     assertThatThrownBy(() -> call(project, profile))
148       .isInstanceOf(ForbiddenException.class)
149       .hasMessage("Insufficient privileges");
150   }
151
152   @Test
153   public void fail_if_not_logged_in() {
154     userSession.anonymous();
155     ProjectDto project = db.components().insertPrivateProjectDto();
156     QProfileDto profile = db.qualityProfiles().insert();
157
158     assertThatThrownBy(() -> call(project, profile))
159       .isInstanceOf(UnauthorizedException.class)
160       .hasMessage("Authentication is required");
161   }
162
163   @Test
164   public void fail_if_project_does_not_exist() {
165     logInAsProfileAdmin();
166     QProfileDto profile = db.qualityProfiles().insert();
167
168     assertThatThrownBy(() -> {
169       ws.newRequest()
170         .setParam("project", "unknown")
171         .setParam("profileKey", profile.getKee())
172         .execute();
173     })
174       .isInstanceOf(NotFoundException.class)
175       .hasMessage("Project 'unknown' not found");
176   }
177
178   @Test
179   public void fail_if_profile_does_not_exist() {
180     logInAsProfileAdmin();
181     ComponentDto project = db.components().insertPrivateProject();
182
183     assertThatThrownBy(() -> {
184       ws.newRequest()
185         .setParam("project", project.getDbKey())
186         .setParam("language", "xoo")
187         .setParam("qualityProfile", "unknown")
188         .execute();
189     })
190       .isInstanceOf(NotFoundException.class)
191       .hasMessage("Quality Profile for language 'xoo' and name 'unknown' does not exist");
192   }
193
194   @Test
195   public void fail_when_using_branch_db_key() {
196     ComponentDto project = db.components().insertPublicProject();
197     userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
198     ComponentDto branch = db.components().insertProjectBranch(project);
199     QProfileDto profile = db.qualityProfiles().insert();
200
201     assertThatThrownBy(() -> {
202       ws.newRequest()
203         .setParam("project", branch.getDbKey())
204         .setParam("language", profile.getLanguage())
205         .setParam("qualityProfile", profile.getName())
206         .execute();
207     })
208       .isInstanceOf(NotFoundException.class)
209       .hasMessage(format("Project '%s' not found", branch.getDbKey()));
210   }
211
212   private void assertProjectIsAssociatedToProfile(ProjectDto project, QProfileDto profile) {
213     QProfileDto loaded = dbClient.qualityProfileDao().selectAssociatedToProjectAndLanguage(db.getSession(), project, profile.getLanguage());
214     assertThat(loaded.getKee()).isEqualTo(profile.getKee());
215   }
216
217   private void assertProjectIsNotAssociatedToProfile(ProjectDto project, QProfileDto profile) {
218     QProfileDto loaded = dbClient.qualityProfileDao().selectAssociatedToProjectAndLanguage(db.getSession(), project, profile.getLanguage());
219     assertThat(loaded == null || !loaded.getKee().equals(profile.getKee())).isTrue();
220   }
221
222   private void logInAsProfileAdmin() {
223     userSession.logIn(db.users().insertUser()).addPermission(ADMINISTER_QUALITY_PROFILES);
224   }
225
226   private TestResponse call(ProjectDto project, QProfileDto qualityProfile) {
227     TestRequest request = ws.newRequest()
228       .setParam("project", project.getKey())
229       .setParam("language", qualityProfile.getLanguage())
230       .setParam("qualityProfile", qualityProfile.getName());
231     return request.execute();
232   }
233 }