]> source.dussan.org Git - sonarqube.git/blob
dec0b7937e0c194f2bd916f46136953f2f254eb5
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2020 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.qualitygate.ws;
21
22 import java.io.IOException;
23 import org.apache.commons.io.IOUtils;
24 import org.junit.Rule;
25 import org.junit.Test;
26 import org.junit.rules.ExpectedException;
27 import org.sonar.api.measures.CoreMetrics;
28 import org.sonar.api.server.ws.WebService;
29 import org.sonar.api.utils.System2;
30 import org.sonar.api.web.UserRole;
31 import org.sonar.db.DbClient;
32 import org.sonar.db.DbSession;
33 import org.sonar.db.DbTester;
34 import org.sonar.db.component.BranchType;
35 import org.sonar.db.component.ComponentDto;
36 import org.sonar.db.component.SnapshotDto;
37 import org.sonar.db.metric.MetricDto;
38 import org.sonar.db.organization.OrganizationDto;
39 import org.sonar.server.component.TestComponentFinder;
40 import org.sonar.server.exceptions.BadRequestException;
41 import org.sonar.server.exceptions.ForbiddenException;
42 import org.sonar.server.exceptions.NotFoundException;
43 import org.sonar.server.tester.UserSessionRule;
44 import org.sonar.server.ws.WsActionTester;
45 import org.sonarqube.ws.Qualitygates.ProjectStatusResponse;
46 import org.sonarqube.ws.Qualitygates.ProjectStatusResponse.Status;
47
48 import static java.lang.String.format;
49 import static org.assertj.core.api.Assertions.assertThat;
50 import static org.assertj.core.api.Assertions.tuple;
51 import static org.sonar.db.component.SnapshotTesting.newAnalysis;
52 import static org.sonar.db.measure.MeasureTesting.newLiveMeasure;
53 import static org.sonar.db.measure.MeasureTesting.newMeasureDto;
54 import static org.sonar.db.metric.MetricTesting.newMetricDto;
55 import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_ANALYSIS_ID;
56 import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_BRANCH;
57 import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_ORGANIZATION;
58 import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_PROJECT_ID;
59 import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_PROJECT_KEY;
60 import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_PULL_REQUEST;
61 import static org.sonar.test.JsonAssert.assertJson;
62
63 public class ProjectStatusActionTest {
64   private static final String ANALYSIS_ID = "task-uuid";
65
66   @Rule
67   public ExpectedException expectedException = ExpectedException.none();
68   @Rule
69   public UserSessionRule userSession = UserSessionRule.standalone();
70   @Rule
71   public DbTester db = DbTester.create(System2.INSTANCE);
72
73   private DbClient dbClient = db.getDbClient();
74   private DbSession dbSession = db.getSession();
75
76   private WsActionTester ws = new WsActionTester(new ProjectStatusAction(dbClient, TestComponentFinder.from(db), userSession));
77
78   @Test
79   public void test_definition() {
80     WebService.Action action = ws.getDef();
81     assertThat(action.params())
82       .extracting(WebService.Param::key, WebService.Param::isRequired)
83       .containsExactlyInAnyOrder(
84         tuple("analysisId", false),
85         tuple("projectKey", false),
86         tuple("projectId", false),
87         tuple("branch", false),
88         tuple("pullRequest", false));
89   }
90
91   @Test
92   public void test_json_example() throws IOException {
93     OrganizationDto organization = db.organizations().insert();
94     ComponentDto project = db.components().insertPrivateProject(organization);
95     userSession.addProjectPermission(UserRole.USER, project);
96     MetricDto gateDetailsMetric = insertGateDetailMetric();
97
98     SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(project)
99       .setPeriodMode("last_version")
100       .setPeriodParam("2015-12-07")
101       .setPeriodDate(956789123987L));
102     dbClient.measureDao().insert(dbSession,
103       newMeasureDto(gateDetailsMetric, project, snapshot)
104         .setData(IOUtils.toString(getClass().getResource("ProjectStatusActionTest/measure_data.json"))));
105     dbSession.commit();
106
107     String response = ws.newRequest()
108       .setParam("analysisId", snapshot.getUuid())
109       .execute().getInput();
110
111     assertJson(response).isSimilarTo(getClass().getResource("project_status-example.json"));
112   }
113
114   @Test
115   public void return_past_status_when_project_is_referenced_by_past_analysis_id() throws IOException {
116     OrganizationDto organization = db.organizations().insert();
117     ComponentDto project = db.components().insertPrivateProject(organization);
118     SnapshotDto pastAnalysis = dbClient.snapshotDao().insert(dbSession, newAnalysis(project)
119       .setLast(false)
120       .setPeriodMode("last_version")
121       .setPeriodParam("2015-12-07")
122       .setPeriodDate(956789123987L));
123     SnapshotDto lastAnalysis = dbClient.snapshotDao().insert(dbSession, newAnalysis(project)
124       .setLast(true)
125       .setPeriodMode("last_version")
126       .setPeriodParam("2016-12-07")
127       .setPeriodDate(1_500L));
128     MetricDto gateDetailsMetric = insertGateDetailMetric();
129     dbClient.measureDao().insert(dbSession,
130       newMeasureDto(gateDetailsMetric, project, pastAnalysis)
131         .setData(IOUtils.toString(getClass().getResource("ProjectStatusActionTest/measure_data.json"))));
132     dbClient.measureDao().insert(dbSession,
133       newMeasureDto(gateDetailsMetric, project, lastAnalysis)
134         .setData("not_used"));
135     dbSession.commit();
136     userSession.addProjectPermission(UserRole.USER, project);
137
138     String response = ws.newRequest()
139       .setParam(PARAM_ANALYSIS_ID, pastAnalysis.getUuid())
140       .execute().getInput();
141
142     assertJson(response).isSimilarTo(getClass().getResource("project_status-example.json"));
143   }
144
145   @Test
146   public void return_live_status_when_project_is_referenced_by_its_id() throws IOException {
147     OrganizationDto organization = db.organizations().insert();
148     ComponentDto project = db.components().insertPrivateProject(organization);
149     dbClient.snapshotDao().insert(dbSession, newAnalysis(project)
150       .setPeriodMode("last_version")
151       .setPeriodParam("2015-12-07")
152       .setPeriodDate(956789123987L));
153     MetricDto gateDetailsMetric = insertGateDetailMetric();
154     dbClient.liveMeasureDao().insert(dbSession,
155       newLiveMeasure(project, gateDetailsMetric)
156         .setData(IOUtils.toString(getClass().getResource("ProjectStatusActionTest/measure_data.json"))));
157     dbSession.commit();
158     userSession.addProjectPermission(UserRole.USER, project);
159
160     String response = ws.newRequest()
161       .setParam(PARAM_PROJECT_ID, project.uuid())
162       .execute().getInput();
163
164     assertJson(response).isSimilarTo(getClass().getResource("project_status-example.json"));
165   }
166
167   @Test
168   public void return_past_status_when_branch_is_referenced_by_past_analysis_id() throws IOException {
169     OrganizationDto organization = db.organizations().insert();
170     ComponentDto project = db.components().insertPrivateProject(organization);
171     ComponentDto branch = db.components().insertProjectBranch(project);
172     SnapshotDto pastAnalysis = dbClient.snapshotDao().insert(dbSession, newAnalysis(branch)
173       .setLast(false)
174       .setPeriodMode("last_version")
175       .setPeriodParam("2015-12-07")
176       .setPeriodDate(956789123987L));
177     SnapshotDto lastAnalysis = dbClient.snapshotDao().insert(dbSession, newAnalysis(branch)
178       .setLast(true)
179       .setPeriodMode("last_version")
180       .setPeriodParam("2016-12-07")
181       .setPeriodDate(1_500L));
182     MetricDto gateDetailsMetric = insertGateDetailMetric();
183     dbClient.measureDao().insert(dbSession,
184       newMeasureDto(gateDetailsMetric, branch, pastAnalysis)
185         .setData(IOUtils.toString(getClass().getResource("ProjectStatusActionTest/measure_data.json"))));
186     dbClient.measureDao().insert(dbSession,
187       newMeasureDto(gateDetailsMetric, branch, lastAnalysis)
188         .setData("not_used"));
189     dbSession.commit();
190     userSession.addProjectPermission(UserRole.USER, project);
191
192     String response = ws.newRequest()
193       .setParam(PARAM_ANALYSIS_ID, pastAnalysis.getUuid())
194       .execute().getInput();
195
196     assertJson(response).isSimilarTo(getClass().getResource("project_status-example.json"));
197   }
198
199   @Test
200   public void return_live_status_when_project_is_referenced_by_its_key() throws IOException {
201     OrganizationDto organization = db.organizations().insert();
202     ComponentDto project = db.components().insertPrivateProject(organization);
203     dbClient.snapshotDao().insert(dbSession, newAnalysis(project)
204       .setPeriodMode("last_version")
205       .setPeriodParam("2015-12-07")
206       .setPeriodDate(956789123987L));
207     MetricDto gateDetailsMetric = insertGateDetailMetric();
208     dbClient.liveMeasureDao().insert(dbSession,
209       newLiveMeasure(project, gateDetailsMetric)
210         .setData(IOUtils.toString(getClass().getResource("ProjectStatusActionTest/measure_data.json"))));
211     dbSession.commit();
212     userSession.addProjectPermission(UserRole.USER, project);
213
214     String response = ws.newRequest()
215       .setParam(PARAM_PROJECT_KEY, project.getKey())
216       .execute().getInput();
217
218     assertJson(response).isSimilarTo(getClass().getResource("project_status-example.json"));
219   }
220
221   @Test
222   public void return_live_status_when_branch_is_referenced_by_its_key() throws IOException {
223     OrganizationDto organization = db.organizations().insert();
224     ComponentDto project = db.components().insertPrivateProject(organization);
225     ComponentDto branch = db.components().insertProjectBranch(project);
226
227     dbClient.snapshotDao().insert(dbSession, newAnalysis(branch)
228       .setPeriodMode("last_version")
229       .setPeriodParam("2015-12-07")
230       .setPeriodDate(956789123987L));
231     MetricDto gateDetailsMetric = insertGateDetailMetric();
232     dbClient.liveMeasureDao().insert(dbSession,
233       newLiveMeasure(branch, gateDetailsMetric)
234         .setData(IOUtils.toString(getClass().getResource("ProjectStatusActionTest/measure_data.json"))));
235     dbSession.commit();
236     userSession.addProjectPermission(UserRole.USER, project);
237
238     String response = ws.newRequest()
239       .setParam(PARAM_PROJECT_KEY, project.getKey())
240       .setParam(PARAM_BRANCH, branch.getBranch())
241       .execute().getInput();
242
243     assertJson(response).isSimilarTo(getClass().getResource("project_status-example.json"));
244   }
245
246   @Test
247   public void return_live_status_when_pull_request_is_referenced_by_its_key() throws IOException {
248     OrganizationDto organization = db.organizations().insert();
249     ComponentDto project = db.components().insertPrivateProject(organization);
250     ComponentDto pr = db.components().insertProjectBranch(project, branch -> branch.setBranchType(BranchType.PULL_REQUEST));
251
252     dbClient.snapshotDao().insert(dbSession, newAnalysis(pr)
253       .setPeriodMode("last_version")
254       .setPeriodParam("2015-12-07")
255       .setPeriodDate(956789123987L));
256     MetricDto gateDetailsMetric = insertGateDetailMetric();
257     dbClient.liveMeasureDao().insert(dbSession,
258       newLiveMeasure(pr, gateDetailsMetric)
259         .setData(IOUtils.toString(getClass().getResource("ProjectStatusActionTest/measure_data.json"))));
260     dbSession.commit();
261     userSession.addProjectPermission(UserRole.USER, project);
262
263     String response = ws.newRequest()
264       .setParam(PARAM_PROJECT_KEY, project.getKey())
265       .setParam(PARAM_PULL_REQUEST, pr.getPullRequest())
266       .execute().getInput();
267
268     assertJson(response).isSimilarTo(getClass().getResource("project_status-example.json"));
269   }
270
271   @Test
272   public void return_undefined_status_if_specified_analysis_is_not_found() {
273     OrganizationDto organization = db.organizations().insert();
274     ComponentDto project = db.components().insertPrivateProject(organization);
275     SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(project));
276     dbSession.commit();
277     userSession.addProjectPermission(UserRole.USER, project);
278
279     ProjectStatusResponse result = ws.newRequest()
280       .setParam(PARAM_ANALYSIS_ID, snapshot.getUuid())
281       .executeProtobuf(ProjectStatusResponse.class);
282
283     assertThat(result.getProjectStatus().getStatus()).isEqualTo(Status.NONE);
284     assertThat(result.getProjectStatus().getConditionsCount()).isEqualTo(0);
285   }
286
287   @Test
288   public void return_undefined_status_if_project_is_not_analyzed() {
289     OrganizationDto organization = db.organizations().insert();
290     ComponentDto project = db.components().insertPrivateProject(organization);
291     userSession.addProjectPermission(UserRole.USER, project);
292
293     ProjectStatusResponse result = ws.newRequest()
294       .setParam(PARAM_PROJECT_ID, project.uuid())
295       .executeProtobuf(ProjectStatusResponse.class);
296
297     assertThat(result.getProjectStatus().getStatus()).isEqualTo(Status.NONE);
298     assertThat(result.getProjectStatus().getConditionsCount()).isEqualTo(0);
299   }
300
301   @Test
302   public void project_administrator_is_allowed_to_get_project_status() {
303     OrganizationDto organization = db.organizations().insert();
304     ComponentDto project = db.components().insertPrivateProject(organization);
305     SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(project));
306     dbSession.commit();
307     userSession.addProjectPermission(UserRole.ADMIN, project);
308
309     ws.newRequest()
310       .setParam(PARAM_ANALYSIS_ID, snapshot.getUuid())
311       .executeProtobuf(ProjectStatusResponse.class);
312   }
313
314   @Test
315   public void project_user_is_allowed_to_get_project_status() {
316     OrganizationDto organization = db.organizations().insert();
317     ComponentDto project = db.components().insertPrivateProject(organization);
318     SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(project));
319     dbSession.commit();
320     userSession.addProjectPermission(UserRole.USER, project);
321
322     ws.newRequest()
323       .setParam(PARAM_ANALYSIS_ID, snapshot.getUuid())
324       .executeProtobuf(ProjectStatusResponse.class);
325   }
326
327   @Test
328   public void default_organization_is_used_when_no_organization_parameter() {
329     OrganizationDto organization = db.getDefaultOrganization();
330     ComponentDto project = db.components().insertPrivateProject(organization);
331     userSession.logIn().addProjectPermission(UserRole.USER, project);
332
333     ProjectStatusResponse result = ws.newRequest()
334       .setParam(PARAM_PROJECT_ID, project.uuid())
335       .executeProtobuf(ProjectStatusResponse.class);
336
337     assertThat(result.getProjectStatus().getStatus()).isEqualTo(Status.NONE);
338   }
339
340   @Test
341   public void fail_if_no_snapshot_id_found() {
342     OrganizationDto organization = db.organizations().insert();
343     logInAsSystemAdministrator();
344
345     expectedException.expect(NotFoundException.class);
346     expectedException.expectMessage("Analysis with id 'task-uuid' is not found");
347
348     ws.newRequest()
349       .setParam(PARAM_ANALYSIS_ID, ANALYSIS_ID)
350       .executeProtobuf(ProjectStatusResponse.class);
351   }
352
353   @Test
354   public void fail_if_insufficient_privileges() {
355     OrganizationDto organization = db.organizations().insert();
356     ComponentDto project = db.components().insertPrivateProject(organization);
357     SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(project));
358     dbSession.commit();
359     userSession.logIn();
360
361     expectedException.expect(ForbiddenException.class);
362
363     ws.newRequest()
364       .setParam(PARAM_ANALYSIS_ID, snapshot.getUuid())
365       .executeProtobuf(ProjectStatusResponse.class);
366   }
367
368   @Test
369   public void fail_if_project_id_and_ce_task_id_provided() {
370     OrganizationDto organization = db.organizations().insert();
371     ComponentDto project = db.components().insertPrivateProject(organization);
372     logInAsSystemAdministrator();
373
374     expectedException.expect(BadRequestException.class);
375     expectedException.expectMessage("Either 'analysisId', 'projectId' or 'projectKey' must be provided");
376
377     ws.newRequest()
378       .setParam(PARAM_ANALYSIS_ID, "analysis-id")
379       .setParam(PARAM_PROJECT_ID, "project-uuid")
380       .setParam(PARAM_ORGANIZATION, organization.getKey())
381       .execute().getInput();
382   }
383
384   @Test
385   public void fail_if_branch_key_and_pull_request_id_provided() {
386     OrganizationDto organization = db.organizations().insert();
387     ComponentDto project = db.components().insertPrivateProject(organization);
388     logInAsSystemAdministrator();
389
390     expectedException.expect(BadRequestException.class);
391     expectedException.expectMessage("Either 'branch' or 'pullRequest' can be provided, not both");
392
393     ws.newRequest()
394       .setParam(PARAM_PROJECT_KEY, "key")
395       .setParam(PARAM_BRANCH, "branch")
396       .setParam(PARAM_PULL_REQUEST, "pr")
397       .setParam(PARAM_ORGANIZATION, organization.getKey())
398       .execute().getInput();
399   }
400
401   @Test
402   public void fail_if_no_parameter_provided() {
403     logInAsSystemAdministrator();
404
405     expectedException.expect(BadRequestException.class);
406     expectedException.expectMessage("Either 'analysisId', 'projectId' or 'projectKey' must be provided");
407
408     ws.newRequest()
409       .execute()
410       .getInput();
411   }
412
413   @Test
414   public void fail_when_using_branch_db_key() {
415     OrganizationDto organization = db.organizations().insert();
416     ComponentDto project = db.components().insertPublicProject(organization);
417     userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
418     ComponentDto branch = db.components().insertProjectBranch(project);
419     SnapshotDto snapshot = db.components().insertSnapshot(branch);
420
421     expectedException.expect(NotFoundException.class);
422     expectedException.expectMessage(format("Project '%s' not found", branch.getDbKey()));
423
424     ws.newRequest()
425       .setParam(PARAM_PROJECT_KEY, branch.getDbKey())
426       .setParam(PARAM_ORGANIZATION, organization.getKey())
427       .execute();
428   }
429
430   @Test
431   public void fail_when_using_branch_uuid() {
432     OrganizationDto organization = db.organizations().insert();
433     ComponentDto project = db.components().insertPublicProject(organization);
434     userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
435     ComponentDto branch = db.components().insertProjectBranch(project);
436     SnapshotDto snapshot = db.components().insertSnapshot(branch);
437
438     expectedException.expect(NotFoundException.class);
439     expectedException.expectMessage(format("Project '%s' not found", branch.uuid()));
440
441     ws.newRequest()
442       .setParam("projectId", branch.uuid())
443       .execute();
444   }
445
446   private void logInAsSystemAdministrator() {
447     userSession.logIn().setSystemAdministrator();
448   }
449
450   private MetricDto insertGateDetailMetric() {
451     return dbClient.metricDao().insert(dbSession, newMetricDto()
452       .setEnabled(true)
453       .setKey(CoreMetrics.QUALITY_GATE_DETAILS_KEY));
454   }
455
456 }