]> source.dussan.org Git - sonarqube.git/blob
6f7c2edea43107605fb5c7ffaf4288ae5194500a
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2023 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.ce.ws;
21
22 import javax.annotation.Nullable;
23 import org.junit.Rule;
24 import org.junit.Test;
25 import org.sonar.api.server.ws.WebService;
26 import org.sonar.api.utils.System2;
27 import org.sonar.api.web.UserRole;
28 import org.sonar.db.DbTester;
29 import org.sonar.db.ce.CeActivityDto;
30 import org.sonar.db.ce.CeQueueDto;
31 import org.sonar.db.ce.CeTaskMessageDto;
32 import org.sonar.db.ce.CeTaskMessageType;
33 import org.sonar.db.component.ComponentDto;
34 import org.sonar.db.component.ProjectData;
35 import org.sonar.db.component.SnapshotDto;
36 import org.sonar.db.project.ProjectDto;
37 import org.sonar.db.user.UserDto;
38 import org.sonar.server.component.TestComponentFinder;
39 import org.sonar.server.exceptions.ForbiddenException;
40 import org.sonar.server.exceptions.NotFoundException;
41 import org.sonar.server.exceptions.UnauthorizedException;
42 import org.sonar.server.tester.UserSessionRule;
43 import org.sonar.server.ws.TestRequest;
44 import org.sonar.server.ws.TestResponse;
45 import org.sonar.server.ws.WsActionTester;
46
47 import static java.lang.String.format;
48 import static org.assertj.core.api.Assertions.assertThat;
49 import static org.assertj.core.api.Assertions.tuple;
50 import static org.junit.Assert.assertThrows;
51 import static org.sonar.db.ce.CeActivityDto.Status.SUCCESS;
52 import static org.sonar.db.ce.CeTaskTypes.REPORT;
53
54 public class DismissAnalysisWarningActionIT {
55   @Rule
56   public UserSessionRule userSession = UserSessionRule.standalone();
57
58   @Rule
59   public DbTester db = DbTester.create(System2.INSTANCE);
60
61   private static int counter = 1;
62
63   private final WsActionTester underTest = new WsActionTester(new DismissAnalysisWarningAction(userSession, db.getDbClient(), TestComponentFinder.from(db)));
64
65   @Test
66   public void definition() {
67     WebService.Action def = underTest.getDef();
68     assertThat(def.key()).isEqualTo("dismiss_analysis_warning");
69     assertThat(def.isInternal()).isTrue();
70     assertThat(def.isPost()).isTrue();
71     assertThat(def.params()).extracting(WebService.Param::key, WebService.Param::isRequired).containsOnly(
72       tuple("component", true),
73       tuple("warning", true));
74   }
75
76   @Test
77   public void return_401_if_user_is_not_logged_in() {
78     userSession.anonymous();
79     TestRequest request = underTest.newRequest()
80       .setParam("component", "6653f062-7c03-4b55-bcd2-0dac67640c4d")
81       .setParam("warning", "55c40b35-4145-4b78-bdf2-dfb242c25f15");
82
83     assertThrows("Authentication is required", UnauthorizedException.class, request::execute);
84   }
85
86   @Test
87   public void return_403_if_user_has_no_browse_permission_on_private_project() {
88     ProjectDto project = db.components().insertPrivateProject().getProjectDto();
89     UserDto user = db.users().insertUser();
90     userSession.logIn(user);
91
92     TestRequest request = underTest.newRequest()
93       .setParam("component", project.getKee())
94       .setParam("warning", "55c40b35-4145-4b78-bdf2-dfb242c25f15");
95
96     assertThrows("Insufficient privileges", ForbiddenException.class, request::execute);
97   }
98
99   @Test
100   public void return_204_on_success() {
101     UserDto user = db.users().insertUser();
102     ProjectData project = db.components().insertPrivateProject();
103     userSession.logIn(user).addProjectPermission(UserRole.USER, project.getProjectDto());
104     SnapshotDto analysis = db.components().insertSnapshot(project.getMainBranchComponent());
105     CeActivityDto activity = insertActivity("task-uuid" + counter++, project.getMainBranchComponent(), SUCCESS, analysis, REPORT);
106     CeTaskMessageDto taskMessageDismissible = createTaskMessage(activity, "dismissable warning", CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE);
107
108     TestResponse response = underTest.newRequest()
109       .setParam("component", project.projectKey())
110       .setParam("warning", taskMessageDismissible.getUuid())
111       .execute();
112
113     assertThat(response.getStatus()).isEqualTo(204);
114     assertThat(db.select("select * from user_dismissed_messages"))
115       .extracting("USER_UUID", "PROJECT_UUID", "MESSAGE_TYPE")
116       .containsExactly(tuple(userSession.getUuid(), project.projectUuid(), CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE.name()));
117   }
118
119   @Test
120   public void is_idempotent() {
121     UserDto user = db.users().insertUser();
122     ProjectData project = db.components().insertPrivateProject();
123     userSession.logIn(user).addProjectPermission(UserRole.USER, project.getProjectDto());
124     SnapshotDto analysis = db.components().insertSnapshot(project.getMainBranchComponent());
125     CeActivityDto activity = insertActivity("task-uuid" + counter++, project.getMainBranchComponent(), SUCCESS, analysis, REPORT);
126     CeTaskMessageDto taskMessageDismissible = createTaskMessage(activity, "dismissable warning", CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE);
127
128     underTest.newRequest()
129       .setParam("component", project.projectKey())
130       .setParam("warning", taskMessageDismissible.getUuid())
131       .execute();
132     TestResponse response = underTest.newRequest()
133       .setParam("component", project.projectKey())
134       .setParam("warning", taskMessageDismissible.getUuid())
135       .execute();
136
137     assertThat(response.getStatus()).isEqualTo(204);
138     assertThat(db.select("select * from user_dismissed_messages"))
139       .extracting("USER_UUID", "PROJECT_UUID", "MESSAGE_TYPE")
140       .containsExactly(tuple(userSession.getUuid(), project.projectUuid(), CeTaskMessageType.SUGGEST_DEVELOPER_EDITION_UPGRADE.name()));
141   }
142
143   @Test
144   public void returns_400_if_warning_is_not_dismissable() {
145     UserDto user = db.users().insertUser();
146     ProjectData project = db.components().insertPrivateProject();
147     userSession.logIn(user).addProjectPermission(UserRole.USER, project.getProjectDto());
148     SnapshotDto analysis = db.components().insertSnapshot(project.getMainBranchComponent());
149     CeActivityDto activity = insertActivity("task-uuid" + counter++, project.getMainBranchComponent(), SUCCESS, analysis, REPORT);
150     CeTaskMessageDto taskMessage = createTaskMessage(activity, "generic warning");
151
152     TestRequest request = underTest.newRequest()
153       .setParam("component", project.projectKey())
154       .setParam("warning", taskMessage.getUuid());
155
156     assertThrows(format("Message '%s' cannot be dismissed.", taskMessage.getUuid()), IllegalArgumentException.class, request::execute);
157     assertThat(db.countRowsOfTable("USER_DISMISSED_MESSAGES")).isZero();
158   }
159
160   @Test
161   public void returns_404_if_warning_does_not_exist() {
162     UserDto user = db.users().insertUser();
163     ProjectData project = db.components().insertPrivateProject();
164     userSession.logIn(user).addProjectPermission(UserRole.USER, project.getProjectDto());
165     SnapshotDto analysis = db.components().insertSnapshot(project.getMainBranchComponent());
166     insertActivity("task-uuid" + counter++, project.getMainBranchComponent(), SUCCESS, analysis, REPORT);
167     String warningUuid = "78d1e2ff-3e67-4037-ba58-0d57d5f88e44";
168
169     TestRequest request = underTest.newRequest()
170       .setParam("component", project.projectKey())
171       .setParam("warning", warningUuid);
172
173     assertThrows(format("Message '%s' not found", warningUuid), NotFoundException.class, request::execute);
174     assertThat(db.countRowsOfTable("USER_DISMISSED_MESSAGES")).isZero();
175   }
176
177   private CeTaskMessageDto createTaskMessage(CeActivityDto activity, String warning) {
178     return createTaskMessage(activity, warning, CeTaskMessageType.GENERIC);
179   }
180
181   private CeTaskMessageDto createTaskMessage(CeActivityDto activity, String warning, CeTaskMessageType messageType) {
182     CeTaskMessageDto ceTaskMessageDto = new CeTaskMessageDto()
183       .setUuid("m-uuid-" + counter++)
184       .setTaskUuid(activity.getUuid())
185       .setMessage(warning)
186       .setType(messageType)
187       .setCreatedAt(counter);
188     db.getDbClient().ceTaskMessageDao().insert(db.getSession(), ceTaskMessageDto);
189     db.commit();
190     return ceTaskMessageDto;
191   }
192
193   private CeActivityDto insertActivity(String taskUuid, ComponentDto component, CeActivityDto.Status status, @Nullable SnapshotDto analysis, String taskType) {
194     CeQueueDto queueDto = new CeQueueDto();
195     queueDto.setTaskType(taskType);
196     queueDto.setComponentUuid(component.uuid());
197     queueDto.setUuid(taskUuid);
198     CeActivityDto activityDto = new CeActivityDto(queueDto);
199     activityDto.setStatus(status);
200     activityDto.setExecutionTimeMs(500L);
201     activityDto.setAnalysisUuid(analysis == null ? null : analysis.getUuid());
202     activityDto.setExecutedAt((long) counter++);
203     activityDto.setTaskType(taskType);
204     activityDto.setComponentUuid(component.uuid());
205     db.getDbClient().ceActivityDao().insert(db.getSession(), activityDto);
206     db.getSession().commit();
207     return activityDto;
208   }
209 }