]> source.dussan.org Git - sonarqube.git/blob
6af027736a736187825fe07834007c6cfd835fb1
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2019 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.projectanalysis.ws;
21
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;
28 import java.util.Map;
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;
52
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;
60
61 @RunWith(DataProviderRunner.class)
62 public class SetBaselineActionTest {
63
64   @Rule
65   public ExpectedException expectedException = ExpectedException.none();
66
67   @Rule
68   public UserSessionRule userSession = UserSessionRule.standalone();
69
70   @Rule
71   public DbTester db = DbTester.create(System2.INSTANCE);
72   private DbClient dbClient = db.getDbClient();
73   private DbSession dbSession = db.getSession();
74
75   private WsActionTester ws = new WsActionTester(new SetBaselineAction(dbClient, userSession, TestComponentFinder.from(db)));
76
77   @Test
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())
85       .setKey("master");
86     db.components().insertComponent(project);
87     db.getDbClient().branchDao().insert(dbSession, branch);
88     SnapshotDto analysis = db.components().insertSnapshot(project);
89     logInAsProjectAdministrator(project);
90
91     call(project.getKey(), branchName, analysis.getUuid());
92
93     NewCodePeriodDto loaded = dbClient.newCodePeriodDao().selectByProject(dbSession, project.uuid()).get();
94     assertThat(loaded.getValue()).isEqualTo(analysis.getUuid());
95     assertThat(loaded.getType()).isEqualTo(SPECIFIC_ANALYSIS);
96   }
97
98   @DataProvider
99   public static Object[][] nullOrEmpty() {
100     return new Object[][]{
101       {null},
102       {""},
103       {"     "},
104     };
105   }
106
107   @Test
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);
115
116     call(project.getKey(), branch.getKey(), analysis.getUuid());
117
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);
121   }
122
123   @Test
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);
130
131     expectedException.expect(ForbiddenException.class);
132     expectedException.expectMessage("Insufficient privileges");
133
134     call(project.getKey(), branch.getKey(), analysis.getUuid());
135   }
136
137   @Test
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);
142
143     call(params);
144   }
145
146   @DataProvider
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");
152
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"},
158     };
159   }
160
161   @Test
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);
170
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);
176
177     expectedException.expect(NotFoundException.class);
178     expectedException.expectMessage(regexMatcher(regex));
179
180     call(params);
181   }
182
183   @DataProvider
184   public static Object[][] nonexistentParamsAndFailureMessage() {
185     MapBuilder builder = new MapBuilder();
186
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"},
191     };
192   }
193
194   @Test
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);
202
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);
207
208     expectedException.expect(NotFoundException.class);
209     expectedException.expectMessage(String.format("Component '%s' on branch '%s' not found", project.getKey(), otherBranch.getKey()));
210
211     call(project.getKey(), otherBranch.getKey(), analysis.getUuid());
212   }
213
214   @Test
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())
221       .setKey("master");
222     db.components().insertComponent(project);
223     db.getDbClient().branchDao().insert(dbSession, branch);
224     logInAsProjectAdministrator(project);
225
226     ComponentDto otherProject = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
227     SnapshotDto otherAnalysis = db.components().insertSnapshot(otherProject);
228
229     expectedException.expect(IllegalArgumentException.class);
230     expectedException.expectMessage(String.format("Analysis '%s' does not belong to project '%s'",
231       otherAnalysis.getUuid(), project.getKey()));
232
233     call(ImmutableMap.of(PARAM_PROJECT, project.getKey(), PARAM_ANALYSIS, otherAnalysis.getUuid()));
234   }
235
236   @Test
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);
242
243     ComponentDto otherProject = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
244     SnapshotDto otherAnalysis = db.components().insertProjectAndSnapshot(otherProject);
245
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()));
249
250     call(project.getKey(), branch.getKey(), otherAnalysis.getUuid());
251   }
252
253   @Test
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);
261
262     expectedException.expect(IllegalArgumentException.class);
263     expectedException.expectMessage(String.format("Not a long-living branch: '%s'", branch.getKey()));
264
265     call(project.getKey(), branch.getKey(), analysis.getUuid());
266   }
267
268   @Test
269   public void ws_parameters() {
270     WebService.Action definition = ws.getDef();
271
272     assertThat(definition.isPost()).isTrue();
273     assertThat(definition.key()).isEqualTo("set_baseline");
274     assertThat(definition.since()).isEqualTo("7.7");
275     assertThat(definition.isInternal()).isFalse();
276   }
277
278   private void logInAsProjectAdministrator(ComponentDto project) {
279     userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
280   }
281
282   private void call(Map<String, String> params) {
283     TestRequest httpRequest = ws.newRequest().setMethod(POST.name());
284
285     for (Map.Entry<String, String> param : params.entrySet()) {
286       httpRequest.setParam(param.getKey(), param.getValue());
287     }
288
289     httpRequest.execute();
290   }
291
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));
297     } else {
298       call(ImmutableMap.of(
299         PARAM_PROJECT, projectKey,
300         PARAM_BRANCH, branchKey,
301         PARAM_ANALYSIS, analysisUuid));
302     }
303   }
304
305   private static class MapBuilder {
306     private final Map<String, String> map;
307
308     private MapBuilder() {
309       this.map = Collections.emptyMap();
310     }
311
312     private MapBuilder(Map<String, String> map) {
313       this.map = map;
314     }
315
316     public MapBuilder put(String key, @Nullable String value) {
317       Map<String, String> copy = new HashMap<>(map);
318       if (value == null) {
319         copy.remove(key);
320       } else {
321         copy.put(key, value);
322       }
323       return new MapBuilder(copy);
324     }
325   }
326 }