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.projectanalysis.ws;
22 import com.google.common.collect.ImmutableMap;
23 import com.tngtech.java.junit.dataprovider.DataProvider;
24 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
25 import com.tngtech.java.junit.dataprovider.UseDataProvider;
26 import java.util.Optional;
27 import javax.annotation.Nullable;
28 import org.junit.Rule;
29 import org.junit.Test;
30 import org.junit.runner.RunWith;
31 import org.sonar.api.server.ws.WebService;
32 import org.sonar.api.utils.System2;
33 import org.sonar.api.web.UserRole;
34 import org.sonar.db.DbClient;
35 import org.sonar.db.DbSession;
36 import org.sonar.db.DbTester;
37 import org.sonar.db.component.BranchDao;
38 import org.sonar.db.component.BranchDto;
39 import org.sonar.db.component.BranchType;
40 import org.sonar.db.component.ComponentDto;
41 import org.sonar.db.component.SnapshotDto;
42 import org.sonar.db.newcodeperiod.NewCodePeriodDto;
43 import org.sonar.db.newcodeperiod.NewCodePeriodType;
44 import org.sonar.server.component.TestComponentFinder;
45 import org.sonar.server.exceptions.ForbiddenException;
46 import org.sonar.server.exceptions.NotFoundException;
47 import org.sonar.server.tester.UserSessionRule;
48 import org.sonar.server.ws.TestRequest;
49 import org.sonar.server.ws.WsActionTester;
51 import static java.util.Optional.ofNullable;
52 import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
53 import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
54 import static org.assertj.core.api.Assertions.assertThat;
55 import static org.assertj.core.api.Assertions.assertThatThrownBy;
56 import static org.sonar.server.projectanalysis.ws.ProjectAnalysesWsParameters.PARAM_BRANCH;
57 import static org.sonar.server.projectanalysis.ws.ProjectAnalysesWsParameters.PARAM_PROJECT;
58 import static org.sonarqube.ws.client.WsRequest.Method.POST;
60 @RunWith(DataProviderRunner.class)
61 public class UnsetBaselineActionTest {
65 public UserSessionRule userSession = UserSessionRule.standalone();
68 public DbTester db = DbTester.create(System2.INSTANCE);
70 private DbClient dbClient = db.getDbClient();
71 private DbSession dbSession = db.getSession();
72 private BranchDao branchDao = db.getDbClient().branchDao();
73 private WsActionTester ws = new WsActionTester(new UnsetBaselineAction(dbClient, userSession, TestComponentFinder.from(db), branchDao));
76 public void does_not_fail_and_has_no_effect_when_there_is_no_baseline_on_main_branch() {
77 ComponentDto project = db.components().insertPublicProject();
78 ComponentDto branch = db.components().insertProjectBranch(project);
79 SnapshotDto analysis = db.components().insertSnapshot(project);
80 logInAsProjectAdministrator(project);
82 call(project.getKey(), null);
84 verifyManualBaseline(project, null);
88 public void does_not_fail_and_has_no_effect_when_there_is_no_baseline_on_non_main_branch() {
89 ComponentDto project = db.components().insertPublicProject();
90 String branchName = randomAlphanumeric(248);
91 ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey(branchName));
92 SnapshotDto analysis = db.components().insertSnapshot(project);
93 logInAsProjectAdministrator(project);
95 call(project.getKey(), branchName);
97 verifyManualBaseline(branch, null);
101 public void unset_baseline_when_it_is_set_on_main_branch() {
102 ComponentDto project = db.components().insertPublicProject();
103 ComponentDto branch = db.components().insertProjectBranch(project);
104 SnapshotDto projectAnalysis = db.components().insertSnapshot(project);
105 SnapshotDto branchAnalysis = db.components().insertSnapshot(project);
106 db.newCodePeriods().insert(project.branchUuid(), NewCodePeriodType.SPECIFIC_ANALYSIS, projectAnalysis.getUuid());
107 logInAsProjectAdministrator(project);
109 call(project.getKey(), null);
111 verifyManualBaseline(project, null);
115 public void unset_baseline_when_it_is_set_non_main_branch() {
116 ComponentDto project = db.components().insertPublicProject();
117 String branchName = randomAlphanumeric(248);
118 ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey(branchName));
119 db.components().insertSnapshot(branch);
120 SnapshotDto branchAnalysis = db.components().insertSnapshot(project);
121 db.newCodePeriods().insert(project.branchUuid(), branch.uuid(), NewCodePeriodType.SPECIFIC_ANALYSIS, branchAnalysis.getUuid());
123 logInAsProjectAdministrator(project);
125 call(project.getKey(), branchName);
127 verifyManualBaseline(branch, null);
131 public void fail_when_user_is_not_admin_on_project() {
132 ComponentDto project = db.components().insertPublicProject();
133 db.components().insertProjectBranch(project);
135 assertThatThrownBy(() -> call(project.getKey(), null))
136 .isInstanceOf(ForbiddenException.class)
137 .hasMessage("Insufficient privileges");
141 public void fail_when_user_is_not_admin_on_project_of_branch() {
142 ComponentDto project = db.components().insertPublicProject();
143 String branchName = randomAlphanumeric(248);
144 db.components().insertProjectBranch(project, b -> b.setKey(branchName));
146 assertThatThrownBy(() -> call(project.getKey(), branchName))
147 .isInstanceOf(ForbiddenException.class)
148 .hasMessage("Insufficient privileges");
152 @UseDataProvider("nullOrEmptyOrValue")
153 public void fail_with_IAE_when_missing_project_parameter(@Nullable String branchParam) {
154 ComponentDto project = db.components().insertPublicProject();
155 db.components().insertProjectBranch(project);
156 logInAsProjectAdministrator(project);
158 assertThatThrownBy(() -> call(null, branchParam))
159 .isInstanceOf(IllegalArgumentException.class)
160 .hasMessage("The 'project' parameter is missing");
164 @UseDataProvider("nullOrEmptyOrValue")
165 public void fail_with_IAE_when_project_parameter_empty(@Nullable String branchParam) {
166 ComponentDto project = db.components().insertPublicProject();
167 db.components().insertProjectBranch(project);
168 logInAsProjectAdministrator(project);
170 assertThatThrownBy(() -> call("", branchParam))
171 .isInstanceOf(IllegalArgumentException.class)
172 .hasMessage("The 'project' parameter is missing");
176 public static Object[][] nullOrEmptyOrValue() {
177 return new Object[][] {
180 {randomAlphabetic(10)},
185 @UseDataProvider("nullOrEmpty")
186 public void does_not_fail_with_IAE_when_missing_branch_parameter(@Nullable String branchParam) {
187 ComponentDto project = db.components().insertPublicProject();
188 db.components().insertProjectBranch(project);
189 logInAsProjectAdministrator(project);
191 call(project.getKey(), branchParam);
195 public static Object[][] nullOrEmpty() {
196 return new Object[][] {
203 public static Object[][] nonexistentParamsAndFailureMessage() {
204 return new Object[][] {
205 {ImmutableMap.of(PARAM_PROJECT, "nonexistent"), "Component 'nonexistent' on branch .* not found"},
206 {ImmutableMap.of(PARAM_BRANCH, "nonexistent"), "Component .* on branch 'nonexistent' not found"}
211 public void fail_when_branch_does_not_belong_to_project() {
212 ComponentDto project = db.components().insertPublicProject();
213 ComponentDto branch = db.components().insertProjectBranch(project);
214 ComponentDto otherProject = db.components().insertPublicProject();
215 ComponentDto otherBranch = db.components().insertProjectBranch(otherProject);
216 logInAsProjectAdministrator(project);
218 assertThatThrownBy(() -> call(project.getKey(), otherBranch.getKey()))
219 .isInstanceOf(NotFoundException.class)
220 .hasMessage(String.format("Branch '%s' in project '%s' not found", otherBranch.getKey(), project.getKey()));
224 public void fail_with_NotFoundException_when_branch_is_pull_request() {
225 ComponentDto project = db.components().insertPrivateProject();
226 ComponentDto pullRequest = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST));
227 logInAsProjectAdministrator(project);
229 assertThatThrownBy(() -> call(project.getKey(), pullRequest.getKey()))
230 .isInstanceOf(NotFoundException.class)
231 .hasMessage(String.format("Branch '%s' in project '%s' not found", pullRequest.getKey(), project.getKey()));
235 public void verify_ws_parameters() {
236 WebService.Action definition = ws.getDef();
238 assertThat(definition.isPost()).isTrue();
239 assertThat(definition.key()).isEqualTo("unset_baseline");
240 assertThat(definition.since()).isEqualTo("7.7");
241 assertThat(definition.isInternal()).isFalse();
244 private void logInAsProjectAdministrator(ComponentDto project) {
245 userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
248 private void call(@Nullable String project, @Nullable String branchName) {
249 TestRequest httpRequest = ws.newRequest().setMethod(POST.name());
250 ofNullable(project).ifPresent(t -> httpRequest.setParam(PARAM_PROJECT, t));
251 ofNullable(branchName).ifPresent(t -> httpRequest.setParam(PARAM_BRANCH, t));
253 httpRequest.execute();
256 private void verifyManualBaseline(ComponentDto project, @Nullable SnapshotDto projectAnalysis) {
257 BranchDto branchDto = db.getDbClient().branchDao().selectByUuid(dbSession, project.uuid()).get();
258 Optional<NewCodePeriodDto> newCodePeriod = db.getDbClient().newCodePeriodDao().selectByBranch(dbSession, branchDto.getProjectUuid(), branchDto.getUuid());
259 if (projectAnalysis == null) {
260 assertThat(newCodePeriod).isNotNull();
261 assertThat(newCodePeriod).isEmpty();
263 assertThat(newCodePeriod).isNotNull();
264 assertThat(newCodePeriod).isNotEmpty();
265 assertThat(newCodePeriod.get().getValue()).isEqualTo(projectAnalysis.getUuid());