3 * Copyright (C) 2009-2022 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.server.qualityprofile.ws;
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;
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;
51 public class RemoveProjectActionTest {
52 private static final String LANGUAGE_1 = "xoo";
53 private static final String LANGUAGE_2 = "foo";
56 public DbTester db = DbTester.create();
58 public UserSessionRule userSession = UserSessionRule.standalone();
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);
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);
69 public void definition() {
70 WebService.Action definition = ws.getDef();
72 assertThat(definition.since()).isEqualTo("5.2");
73 assertThat(definition.isPost()).isTrue();
74 assertThat(definition.key()).isEqualTo("remove_project");
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();
86 public void remove_profile_from_project() {
87 logInAsProfileAdmin();
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);
95 TestResponse response = call(project, profileLang1);
96 assertThat(response.getStatus()).isEqualTo(HttpURLConnection.HTTP_NO_CONTENT);
98 assertProjectIsNotAssociatedToProfile(project, profileLang1);
99 assertProjectIsAssociatedToProfile(project, profileLang2);
103 public void removal_does_not_fail_if_profile_is_not_associated_to_project() {
104 logInAsProfileAdmin();
106 ProjectDto project = db.components().insertPrivateProjectDto();
107 QProfileDto profile = db.qualityProfiles().insert(qp -> qp.setLanguage("xoo"));
109 TestResponse response = call(project, profile);
110 assertThat(response.getStatus()).isEqualTo(HttpURLConnection.HTTP_NO_CONTENT);
112 assertProjectIsNotAssociatedToProfile(project, profile);
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);
122 call(project, profile);
124 assertProjectIsNotAssociatedToProfile(project, profile);
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);
136 call(project, profile);
138 assertProjectIsNotAssociatedToProfile(project, profile);
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"));
147 assertThatThrownBy(() -> call(project, profile))
148 .isInstanceOf(ForbiddenException.class)
149 .hasMessage("Insufficient privileges");
153 public void fail_if_not_logged_in() {
154 userSession.anonymous();
155 ProjectDto project = db.components().insertPrivateProjectDto();
156 QProfileDto profile = db.qualityProfiles().insert();
158 assertThatThrownBy(() -> call(project, profile))
159 .isInstanceOf(UnauthorizedException.class)
160 .hasMessage("Authentication is required");
164 public void fail_if_project_does_not_exist() {
165 logInAsProfileAdmin();
166 QProfileDto profile = db.qualityProfiles().insert();
168 assertThatThrownBy(() -> {
170 .setParam("project", "unknown")
171 .setParam("profileKey", profile.getKee())
174 .isInstanceOf(NotFoundException.class)
175 .hasMessage("Project 'unknown' not found");
179 public void fail_if_profile_does_not_exist() {
180 logInAsProfileAdmin();
181 ComponentDto project = db.components().insertPrivateProject();
183 assertThatThrownBy(() -> {
185 .setParam("project", project.getDbKey())
186 .setParam("language", "xoo")
187 .setParam("qualityProfile", "unknown")
190 .isInstanceOf(NotFoundException.class)
191 .hasMessage("Quality Profile for language 'xoo' and name 'unknown' does not exist");
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();
201 assertThatThrownBy(() -> {
203 .setParam("project", branch.getDbKey())
204 .setParam("language", profile.getLanguage())
205 .setParam("qualityProfile", profile.getName())
208 .isInstanceOf(NotFoundException.class)
209 .hasMessage(format("Project '%s' not found", branch.getDbKey()));
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());
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();
222 private void logInAsProfileAdmin() {
223 userSession.logIn(db.users().insertUser()).addPermission(ADMINISTER_QUALITY_PROFILES);
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();