3 * Copyright (C) 2009-2019 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.Collections;
27 import java.util.HashMap;
29 import javax.annotation.Nullable;
30 import org.junit.Rule;
31 import org.junit.Test;
32 import org.junit.rules.ExpectedException;
33 import org.junit.runner.RunWith;
34 import org.sonar.api.server.ws.WebService;
35 import org.sonar.api.utils.System2;
36 import org.sonar.api.web.UserRole;
37 import org.sonar.db.DbClient;
38 import org.sonar.db.DbSession;
39 import org.sonar.db.DbTester;
40 import org.sonar.db.component.BranchDto;
41 import org.sonar.db.component.BranchType;
42 import org.sonar.db.component.ComponentDto;
43 import org.sonar.db.component.ComponentTesting;
44 import org.sonar.db.component.SnapshotDto;
45 import org.sonar.db.newcodeperiod.NewCodePeriodDto;
46 import org.sonar.server.component.TestComponentFinder;
47 import org.sonar.server.exceptions.ForbiddenException;
48 import org.sonar.server.exceptions.NotFoundException;
49 import org.sonar.server.tester.UserSessionRule;
50 import org.sonar.server.ws.TestRequest;
51 import org.sonar.server.ws.WsActionTester;
53 import static org.assertj.core.api.Assertions.assertThat;
54 import static org.sonar.db.newcodeperiod.NewCodePeriodType.SPECIFIC_ANALYSIS;
55 import static org.sonar.server.projectanalysis.ws.ProjectAnalysesWsParameters.PARAM_ANALYSIS;
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.sonar.test.Matchers.regexMatcher;
59 import static org.sonarqube.ws.client.WsRequest.Method.POST;
61 @RunWith(DataProviderRunner.class)
62 public class SetBaselineActionTest {
65 public ExpectedException expectedException = ExpectedException.none();
68 public UserSessionRule userSession = UserSessionRule.standalone();
71 public DbTester db = DbTester.create(System2.INSTANCE);
72 private DbClient dbClient = db.getDbClient();
73 private DbSession dbSession = db.getSession();
75 private WsActionTester ws = new WsActionTester(new SetBaselineAction(dbClient, userSession, TestComponentFinder.from(db)));
78 @UseDataProvider("nullOrEmpty")
79 public void set_baseline_on_project(@Nullable String branchName) {
80 ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
81 BranchDto branch = new BranchDto()
82 .setBranchType(BranchType.LONG)
83 .setProjectUuid(project.uuid())
84 .setUuid(project.uuid())
86 db.components().insertComponent(project);
87 db.getDbClient().branchDao().insert(dbSession, branch);
88 SnapshotDto analysis = db.components().insertSnapshot(project);
89 logInAsProjectAdministrator(project);
91 call(project.getKey(), branchName, analysis.getUuid());
93 NewCodePeriodDto loaded = dbClient.newCodePeriodDao().selectByProject(dbSession, project.uuid()).get();
94 assertThat(loaded.getValue()).isEqualTo(analysis.getUuid());
95 assertThat(loaded.getType()).isEqualTo(SPECIFIC_ANALYSIS);
99 public static Object[][] nullOrEmpty() {
100 return new Object[][]{
108 public void set_baseline_on_long_living_branch() {
109 ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
110 BranchDto branch = ComponentTesting.newBranchDto(project.projectUuid(), BranchType.LONG);
111 db.components().insertProjectBranch(project, branch);
112 ComponentDto branchComponentDto = ComponentTesting.newProjectBranch(project, branch);
113 SnapshotDto analysis = db.components().insertSnapshot(branchComponentDto);
114 logInAsProjectAdministrator(project);
116 call(project.getKey(), branch.getKey(), analysis.getUuid());
118 NewCodePeriodDto loaded = dbClient.newCodePeriodDao().selectByBranch(dbSession, project.uuid(), branch.getUuid()).get();
119 assertThat(loaded.getValue()).isEqualTo(analysis.getUuid());
120 assertThat(loaded.getType()).isEqualTo(SPECIFIC_ANALYSIS);
124 public void fail_when_user_is_not_admin() {
125 ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
126 BranchDto branch = ComponentTesting.newBranchDto(project.projectUuid(), BranchType.LONG);
127 db.components().insertProjectBranch(project, branch);
128 ComponentDto branchComponentDto = ComponentTesting.newProjectBranch(project, branch);
129 SnapshotDto analysis = db.components().insertSnapshot(branchComponentDto);
131 expectedException.expect(ForbiddenException.class);
132 expectedException.expectMessage("Insufficient privileges");
134 call(project.getKey(), branch.getKey(), analysis.getUuid());
138 @UseDataProvider("missingOrEmptyParamsAndFailureMessage")
139 public void fail_with_IAE_when_required_param_missing_or_empty(Map<String, String> params, String message) {
140 expectedException.expect(IllegalArgumentException.class);
141 expectedException.expectMessage(message);
147 public static Object[][] missingOrEmptyParamsAndFailureMessage() {
148 MapBuilder builder = new MapBuilder()
149 .put(PARAM_PROJECT, "project key")
150 .put(PARAM_BRANCH, "branch key")
151 .put(PARAM_ANALYSIS, "analysis uuid");
153 return new Object[][]{
154 {builder.put(PARAM_PROJECT, null).map, "The 'project' parameter is missing"},
155 {builder.put(PARAM_PROJECT, "").map, "The 'project' parameter is missing"},
156 {builder.put(PARAM_ANALYSIS, null).map, "The 'analysis' parameter is missing"},
157 {builder.put(PARAM_ANALYSIS, "").map, "The 'analysis' parameter is missing"},
162 @UseDataProvider("nonexistentParamsAndFailureMessage")
163 public void fail_with_IAE_when_required_param_nonexistent(Map<String, String> nonexistentParams, String regex) {
164 ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
165 BranchDto branch = ComponentTesting.newBranchDto(project.projectUuid(), BranchType.LONG);
166 db.components().insertProjectBranch(project, branch);
167 ComponentDto branchComponentDto = ComponentTesting.newProjectBranch(project, branch);
168 SnapshotDto analysis = db.components().insertSnapshot(branchComponentDto);
169 logInAsProjectAdministrator(project);
171 Map<String, String> params = new HashMap<>();
172 params.put(PARAM_PROJECT, project.getKey());
173 params.put(PARAM_BRANCH, branch.getKey());
174 params.put(PARAM_ANALYSIS, analysis.getUuid());
175 params.putAll(nonexistentParams);
177 expectedException.expect(NotFoundException.class);
178 expectedException.expectMessage(regexMatcher(regex));
184 public static Object[][] nonexistentParamsAndFailureMessage() {
185 MapBuilder builder = new MapBuilder();
187 return new Object[][]{
188 {builder.put(PARAM_PROJECT, "nonexistent").map, "Component 'nonexistent' on branch .* not found"},
189 {builder.put(PARAM_BRANCH, "nonexistent").map, "Component .* on branch 'nonexistent' not found"},
190 {builder.put(PARAM_ANALYSIS, "nonexistent").map, "Analysis 'nonexistent' is not found"},
195 public void fail_when_branch_does_not_belong_to_project() {
196 ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
197 BranchDto branch = ComponentTesting.newBranchDto(project.projectUuid(), BranchType.LONG);
198 db.components().insertProjectBranch(project, branch);
199 ComponentDto branchComponentDto = ComponentTesting.newProjectBranch(project, branch);
200 SnapshotDto analysis = db.components().insertSnapshot(branchComponentDto);
201 logInAsProjectAdministrator(project);
203 ComponentDto otherProject = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
204 BranchDto otherBranch = ComponentTesting.newBranchDto(otherProject.projectUuid(), BranchType.LONG);
205 db.components().insertProjectBranch(otherProject, otherBranch);
206 ComponentTesting.newProjectBranch(otherProject, otherBranch);
208 expectedException.expect(NotFoundException.class);
209 expectedException.expectMessage(String.format("Component '%s' on branch '%s' not found", project.getKey(), otherBranch.getKey()));
211 call(project.getKey(), otherBranch.getKey(), analysis.getUuid());
215 public void fail_when_analysis_does_not_belong_to_main_branch_of_project() {
216 ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
217 BranchDto branch = new BranchDto()
218 .setBranchType(BranchType.LONG)
219 .setProjectUuid(project.uuid())
220 .setUuid(project.uuid())
222 db.components().insertComponent(project);
223 db.getDbClient().branchDao().insert(dbSession, branch);
224 logInAsProjectAdministrator(project);
226 ComponentDto otherProject = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
227 SnapshotDto otherAnalysis = db.components().insertSnapshot(otherProject);
229 expectedException.expect(IllegalArgumentException.class);
230 expectedException.expectMessage(String.format("Analysis '%s' does not belong to project '%s'",
231 otherAnalysis.getUuid(), project.getKey()));
233 call(ImmutableMap.of(PARAM_PROJECT, project.getKey(), PARAM_ANALYSIS, otherAnalysis.getUuid()));
237 public void fail_when_analysis_does_not_belong_to_non_main_branch_of_project() {
238 ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
239 BranchDto branch = ComponentTesting.newBranchDto(project.projectUuid(), BranchType.LONG);
240 db.components().insertProjectBranch(project, branch);
241 logInAsProjectAdministrator(project);
243 ComponentDto otherProject = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
244 SnapshotDto otherAnalysis = db.components().insertProjectAndSnapshot(otherProject);
246 expectedException.expect(IllegalArgumentException.class);
247 expectedException.expectMessage(String.format("Analysis '%s' does not belong to branch '%s' of project '%s'",
248 otherAnalysis.getUuid(), branch.getKey(), project.getKey()));
250 call(project.getKey(), branch.getKey(), otherAnalysis.getUuid());
254 public void fail_when_branch_is_not_long() {
255 ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
256 BranchDto branch = ComponentTesting.newBranchDto(project.projectUuid(), BranchType.SHORT);
257 db.components().insertProjectBranch(project, branch);
258 ComponentDto branchComponentDto = ComponentTesting.newProjectBranch(project, branch);
259 SnapshotDto analysis = db.components().insertSnapshot(branchComponentDto);
260 logInAsProjectAdministrator(project);
262 expectedException.expect(IllegalArgumentException.class);
263 expectedException.expectMessage(String.format("Not a long-living branch: '%s'", branch.getKey()));
265 call(project.getKey(), branch.getKey(), analysis.getUuid());
269 public void ws_parameters() {
270 WebService.Action definition = ws.getDef();
272 assertThat(definition.isPost()).isTrue();
273 assertThat(definition.key()).isEqualTo("set_baseline");
274 assertThat(definition.since()).isEqualTo("7.7");
275 assertThat(definition.isInternal()).isFalse();
278 private void logInAsProjectAdministrator(ComponentDto project) {
279 userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
282 private void call(Map<String, String> params) {
283 TestRequest httpRequest = ws.newRequest().setMethod(POST.name());
285 for (Map.Entry<String, String> param : params.entrySet()) {
286 httpRequest.setParam(param.getKey(), param.getValue());
289 httpRequest.execute();
292 private void call(String projectKey, @Nullable String branchKey, String analysisUuid) {
293 if (branchKey == null) {
294 call(ImmutableMap.of(
295 PARAM_PROJECT, projectKey,
296 PARAM_ANALYSIS, analysisUuid));
298 call(ImmutableMap.of(
299 PARAM_PROJECT, projectKey,
300 PARAM_BRANCH, branchKey,
301 PARAM_ANALYSIS, analysisUuid));
305 private static class MapBuilder {
306 private final Map<String, String> map;
308 private MapBuilder() {
309 this.map = Collections.emptyMap();
312 private MapBuilder(Map<String, String> map) {
316 public MapBuilder put(String key, @Nullable String value) {
317 Map<String, String> copy = new HashMap<>(map);
321 copy.put(key, value);
323 return new MapBuilder(copy);