]> source.dussan.org Git - sonarqube.git/blob
0b68c7fd08f6f5ab51c461ec336dc72e54f4b95b
[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.qualityprofile.ws;
21
22 import java.net.HttpURLConnection;
23 import org.junit.Rule;
24 import org.junit.Test;
25 import org.junit.rules.ExpectedException;
26 import org.sonar.api.resources.Languages;
27 import org.sonar.api.server.ws.WebService;
28 import org.sonar.api.web.UserRole;
29 import org.sonar.db.DbClient;
30 import org.sonar.db.DbTester;
31 import org.sonar.db.component.ComponentDto;
32 import org.sonar.db.organization.OrganizationDto;
33 import org.sonar.db.qualityprofile.QProfileDto;
34 import org.sonar.db.user.UserDto;
35 import org.sonar.server.component.TestComponentFinder;
36 import org.sonar.server.exceptions.ForbiddenException;
37 import org.sonar.server.exceptions.NotFoundException;
38 import org.sonar.server.exceptions.UnauthorizedException;
39 import org.sonar.server.language.LanguageTesting;
40 import org.sonar.server.organization.TestDefaultOrganizationProvider;
41 import org.sonar.server.tester.UserSessionRule;
42 import org.sonar.server.ws.TestRequest;
43 import org.sonar.server.ws.TestResponse;
44 import org.sonar.server.ws.WsActionTester;
45
46 import static java.lang.String.format;
47 import static org.assertj.core.api.Assertions.assertThat;
48 import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
49
50 public class AddProjectActionTest {
51
52   private static final String LANGUAGE_1 = "xoo";
53   private static final String LANGUAGE_2 = "foo";
54
55   @Rule
56   public DbTester db = DbTester.create();
57   @Rule
58   public ExpectedException expectedException = ExpectedException.none();
59   @Rule
60   public UserSessionRule userSession = UserSessionRule.standalone();
61
62   private DbClient dbClient = db.getDbClient();
63   private Languages languages = LanguageTesting.newLanguages(LANGUAGE_1, LANGUAGE_2);
64   private QProfileWsSupport wsSupport = new QProfileWsSupport(dbClient, userSession, TestDefaultOrganizationProvider.from(db));
65   private AddProjectAction underTest = new AddProjectAction(dbClient, userSession, languages, TestComponentFinder.from(db), wsSupport);
66   private WsActionTester tester = new WsActionTester(underTest);
67
68   @Test
69   public void definition() {
70     WebService.Action definition = tester.getDef();
71     assertThat(definition.since()).isEqualTo("5.2");
72     assertThat(definition.isPost()).isTrue();
73
74     // parameters
75     assertThat(definition.params()).extracting(WebService.Param::key)
76       .containsExactlyInAnyOrder("key", "qualityProfile", "project", "language", "projectUuid", "organization");
77     WebService.Param profile = definition.param("key");
78     assertThat(profile.deprecatedKey()).isEqualTo("profileKey");
79     assertThat(profile.deprecatedSince()).isEqualTo("6.6");
80     WebService.Param languageParam = definition.param("language");
81     assertThat(languageParam.possibleValues()).containsOnly(LANGUAGE_1, LANGUAGE_2);
82     assertThat(languageParam.exampleValue()).isNull();
83     WebService.Param project = definition.param("project");
84     assertThat(project.deprecatedKey()).isEqualTo("projectKey");
85     WebService.Param projectUuid = definition.param("projectUuid");
86     assertThat(projectUuid.deprecatedSince()).isEqualTo("6.5");
87     WebService.Param organizationParam = definition.param("organization");
88     assertThat(organizationParam.since()).isEqualTo("6.4");
89     assertThat(organizationParam.isInternal()).isTrue();
90   }
91
92   @Test
93   public void add_project_on_profile_of_default_organization() {
94     logInAsProfileAdmin(db.getDefaultOrganization());
95     ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization());
96     QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization());
97
98     TestResponse response = call(project, profile);
99     assertThat(response.getStatus()).isEqualTo(HttpURLConnection.HTTP_NO_CONTENT);
100
101     assertProjectIsAssociatedToProfile(project, profile);
102   }
103
104   @Test
105   public void add_project_on_profile_of_specified_organization() {
106     OrganizationDto org1 = db.organizations().insert();
107     logInAsProfileAdmin(org1);
108     ComponentDto project = db.components().insertPrivateProject(org1);
109     QProfileDto profile = db.qualityProfiles().insert(org1, p -> p.setLanguage(LANGUAGE_1));
110
111     TestResponse response = call(org1, project, profile);
112     assertThat(response.getStatus()).isEqualTo(HttpURLConnection.HTTP_NO_CONTENT);
113
114     assertProjectIsAssociatedToProfile(project, profile);
115   }
116
117   @Test
118   public void as_qprofile_editor() {
119     OrganizationDto organization = db.organizations().insert();
120     UserDto user = db.users().insertUser();
121     QProfileDto qualityProfile = db.qualityProfiles().insert(organization, qp -> qp.setLanguage(LANGUAGE_1));
122     db.qualityProfiles().addUserPermission(qualityProfile, user);
123     ComponentDto project = db.components().insertPrivateProject(organization);
124     userSession.logIn(user);
125
126     call(organization, project, qualityProfile);
127
128     assertProjectIsAssociatedToProfile(project, qualityProfile);
129   }
130
131   @Test
132   public void fail_if_profile_and_project_are_in_different_organizations() {
133     OrganizationDto org1 = db.organizations().insert();
134     OrganizationDto org2 = db.organizations().insert();
135     logInAsProfileAdmin(org2);
136     ComponentDto project = db.components().insertPrivateProject(org1);
137     QProfileDto profileInOrg2 = db.qualityProfiles().insert(org2, p -> p.setLanguage(LANGUAGE_1));
138
139     expectedException.expect(IllegalArgumentException.class);
140     expectedException.expectMessage("Project and quality profile must have the same organization");
141
142     call(org2, project, profileInOrg2);
143   }
144
145   @Test
146   public void fail_if_profile_is_not_found_in_specified_organization() {
147     OrganizationDto org1 = db.organizations().insert();
148     OrganizationDto org2 = db.organizations().insert();
149     logInAsProfileAdmin(org1);
150     ComponentDto project = db.components().insertPrivateProject(org1);
151     QProfileDto profileInOrg2 = db.qualityProfiles().insert(org2, p -> p.setLanguage(LANGUAGE_1));
152
153     expectedException.expect(NotFoundException.class);
154     expectedException
155       .expectMessage("Quality Profile for language '" + LANGUAGE_1 + "' and name '" + profileInOrg2.getName() + "' does not exist in organization '" + org1.getKey() + "'");
156
157     call(org1, project, profileInOrg2);
158   }
159
160   @Test
161   public void change_association_in_default_organization() {
162     logInAsProfileAdmin(db.getDefaultOrganization());
163
164     ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization());
165     // two profiles on same language
166     QProfileDto profile1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(LANGUAGE_1));
167     QProfileDto profile2 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(LANGUAGE_1));
168     db.qualityProfiles().associateWithProject(project, profile1);
169
170     call(project, profile2);
171
172     assertProjectIsNotAssociatedToProfile(project, profile1);
173     assertProjectIsAssociatedToProfile(project, profile2);
174   }
175
176   @Test
177   public void changing_association_does_not_change_other_language_associations() {
178     logInAsProfileAdmin(db.getDefaultOrganization());
179     ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization());
180     QProfileDto profile1Language1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(LANGUAGE_1));
181     QProfileDto profile2Language2 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(LANGUAGE_2));
182     QProfileDto profile3Language1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(LANGUAGE_1));
183     db.qualityProfiles().associateWithProject(project, profile1Language1, profile2Language2);
184
185     call(project, profile3Language1);
186
187     assertProjectIsAssociatedToProfile(project, profile3Language1);
188     assertProjectIsAssociatedToProfile(project, profile2Language2);
189   }
190
191   @Test
192   public void project_administrator_can_change_profile() {
193     ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization());
194     QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization());
195     userSession.logIn(db.users().insertUser()).addProjectPermission(UserRole.ADMIN, project);
196
197     call(project, profile);
198
199     assertProjectIsAssociatedToProfile(project, profile);
200   }
201
202   @Test
203   public void throw_ForbiddenException_if_not_project_nor_organization_administrator() {
204     userSession.logIn(db.users().insertUser());
205     ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization());
206     QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization());
207
208     expectedException.expect(ForbiddenException.class);
209     expectedException.expectMessage("Insufficient privileges");
210
211     call(project, profile);
212   }
213
214   @Test
215   public void throw_UnauthorizedException_if_not_logged_in() {
216     userSession.anonymous();
217     ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization());
218     QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization());
219
220     expectedException.expect(UnauthorizedException.class);
221     expectedException.expectMessage("Authentication is required");
222
223     call(project, profile);
224   }
225
226   @Test
227   public void throw_NotFoundException_if_project_does_not_exist() {
228     logInAsProfileAdmin(db.getDefaultOrganization());
229     QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization());
230
231     expectedException.expect(NotFoundException.class);
232     expectedException.expectMessage("Component id 'unknown' not found");
233
234     tester.newRequest()
235       .setParam("projectUuid", "unknown")
236       .setParam("profileKey", profile.getKee())
237       .execute();
238   }
239
240   @Test
241   public void throw_NotFoundException_if_profile_does_not_exist() {
242     logInAsProfileAdmin(db.getDefaultOrganization());
243     ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization());
244
245     expectedException.expect(NotFoundException.class);
246     expectedException.expectMessage("Quality Profile with key 'unknown' does not exist");
247
248     tester.newRequest()
249       .setParam("projectUuid", project.uuid())
250       .setParam("profileKey", "unknown")
251       .execute();
252   }
253
254   @Test
255   public void fail_when_using_branch_db_key() throws Exception {
256     OrganizationDto organization = db.organizations().insert();
257     ComponentDto project = db.components().insertMainBranch(organization);
258     userSession.logIn(db.users().insertUser()).addProjectPermission(UserRole.ADMIN, project);
259     ComponentDto branch = db.components().insertProjectBranch(project);
260     QProfileDto profile = db.qualityProfiles().insert(organization);
261
262     expectedException.expect(NotFoundException.class);
263     expectedException.expectMessage(format("Component key '%s' not found", branch.getDbKey()));
264
265     tester.newRequest()
266       .setParam("project", branch.getDbKey())
267       .setParam("profileKey", profile.getKee())
268       .execute();
269   }
270
271   @Test
272   public void fail_when_using_branch_uuid() {
273     OrganizationDto organization = db.organizations().insert();
274     ComponentDto project = db.components().insertMainBranch(organization);
275     userSession.logIn(db.users().insertUser()).addProjectPermission(UserRole.ADMIN, project);
276     ComponentDto branch = db.components().insertProjectBranch(project);
277     QProfileDto profile = db.qualityProfiles().insert(organization);
278
279     expectedException.expect(NotFoundException.class);
280     expectedException.expectMessage(format("Component id '%s' not found", branch.uuid()));
281
282     tester.newRequest()
283       .setParam("projectUuid", branch.uuid())
284       .setParam("profileKey", profile.getKee())
285       .execute();
286   }
287
288   private void assertProjectIsAssociatedToProfile(ComponentDto project, QProfileDto profile) {
289     QProfileDto loaded = dbClient.qualityProfileDao().selectAssociatedToProjectAndLanguage(db.getSession(), project, profile.getLanguage());
290     assertThat(loaded.getKee()).isEqualTo(profile.getKee());
291   }
292
293   private void assertProjectIsNotAssociatedToProfile(ComponentDto project, QProfileDto profile) {
294     QProfileDto loaded = dbClient.qualityProfileDao().selectAssociatedToProjectAndLanguage(db.getSession(), project, profile.getLanguage());
295     assertThat(loaded == null || !loaded.getKee().equals(profile.getKee())).isTrue();
296   }
297
298   private void logInAsProfileAdmin(OrganizationDto organization) {
299     userSession.logIn(db.users().insertUser()).addPermission(ADMINISTER_QUALITY_PROFILES, organization);
300   }
301
302   private TestResponse call(ComponentDto project, QProfileDto qualityProfile) {
303     TestRequest request = tester.newRequest()
304       .setParam("projectUuid", project.uuid())
305       .setParam("key", qualityProfile.getKee());
306     return request.execute();
307   }
308
309   private TestResponse call(OrganizationDto organization, ComponentDto project, QProfileDto qualityProfile) {
310     TestRequest request = tester.newRequest()
311       .setParam("organization", organization.getKey())
312       .setParam("projectUuid", project.uuid())
313       .setParam("language", qualityProfile.getLanguage())
314       .setParam("qualityProfile", qualityProfile.getName());
315     return request.execute();
316   }
317 }