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.qualityprofile.ws;
22 import java.util.List;
23 import org.junit.Rule;
24 import org.junit.Test;
25 import org.junit.rules.ExpectedException;
26 import org.sonar.api.resources.Language;
27 import org.sonar.api.resources.Languages;
28 import org.sonar.api.server.ws.Change;
29 import org.sonar.api.server.ws.WebService;
30 import org.sonar.api.utils.DateUtils;
31 import org.sonar.api.utils.System2;
32 import org.sonar.core.util.stream.MoreCollectors;
33 import org.sonar.db.DbClient;
34 import org.sonar.db.DbTester;
35 import org.sonar.db.component.ComponentDto;
36 import org.sonar.db.organization.OrganizationDto;
37 import org.sonar.db.permission.OrganizationPermission;
38 import org.sonar.db.qualityprofile.QProfileDto;
39 import org.sonar.db.qualityprofile.QualityProfileDbTester;
40 import org.sonar.db.rule.RuleDefinitionDto;
41 import org.sonar.db.user.GroupDto;
42 import org.sonar.db.user.UserDto;
43 import org.sonar.server.component.ComponentFinder;
44 import org.sonar.server.exceptions.ForbiddenException;
45 import org.sonar.server.exceptions.NotFoundException;
46 import org.sonar.server.organization.DefaultOrganizationProvider;
47 import org.sonar.server.organization.TestDefaultOrganizationProvider;
48 import org.sonar.server.tester.UserSessionRule;
49 import org.sonar.server.ws.TestRequest;
50 import org.sonar.server.ws.WsActionTester;
51 import org.sonarqube.ws.MediaTypes;
52 import org.sonarqube.ws.Qualityprofiles.SearchWsResponse;
53 import org.sonarqube.ws.Qualityprofiles.SearchWsResponse.QualityProfile;
55 import static java.lang.String.format;
56 import static java.util.stream.IntStream.range;
57 import static org.assertj.core.api.Assertions.assertThat;
58 import static org.assertj.core.api.Assertions.tuple;
59 import static org.sonar.api.rule.RuleStatus.DEPRECATED;
60 import static org.sonar.api.utils.DateUtils.parseDateTime;
61 import static org.sonar.db.component.ComponentTesting.newModuleDto;
62 import static org.sonar.db.organization.OrganizationDto.Subscription.FREE;
63 import static org.sonar.db.organization.OrganizationDto.Subscription.PAID;
64 import static org.sonar.db.qualityprofile.QualityProfileTesting.newQualityProfileDto;
65 import static org.sonar.server.language.LanguageTesting.newLanguage;
66 import static org.sonar.test.JsonAssert.assertJson;
67 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_DEFAULTS;
68 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE;
69 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_ORGANIZATION;
70 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PROJECT;
71 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_QUALITY_PROFILE;
73 public class SearchActionTest {
75 private static Language XOO1 = newLanguage("xoo1");
76 private static Language XOO2 = newLanguage("xoo2");
77 private static Languages LANGUAGES = new Languages(XOO1, XOO2);
80 public DbTester db = DbTester.create(System2.INSTANCE);
82 public UserSessionRule userSession = UserSessionRule.standalone();
84 public ExpectedException expectedException = ExpectedException.none();
85 private QualityProfileDbTester qualityProfileDb = db.qualityProfiles();
86 private DbClient dbClient = db.getDbClient();
87 private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
88 private QProfileWsSupport qProfileWsSupport = new QProfileWsSupport(dbClient, userSession, defaultOrganizationProvider);
90 private SearchAction underTest = new SearchAction(userSession, LANGUAGES, dbClient, qProfileWsSupport, new ComponentFinder(dbClient, null));
91 private WsActionTester ws = new WsActionTester(underTest);
94 public void no_profile() {
95 SearchWsResponse result = call(ws.newRequest());
97 assertThat(result.getProfilesList()).isEmpty();
101 public void empty_when_no_language_installed() {
102 WsActionTester ws = new WsActionTester(new SearchAction(userSession, new Languages(), dbClient, qProfileWsSupport, new ComponentFinder(dbClient, null)));
103 db.qualityProfiles().insert(db.getDefaultOrganization());
105 SearchWsResponse result = call(ws.newRequest());
107 assertThat(result.getProfilesList()).isEmpty();
111 public void default_organization() {
112 OrganizationDto defaultOrganization = db.getDefaultOrganization();
113 OrganizationDto anotherOrganization = db.organizations().insert();
114 QProfileDto profile1OnDefaultOrg = db.qualityProfiles().insert(defaultOrganization, p -> p.setLanguage(XOO1.getKey()));
115 QProfileDto profile2OnDefaultOrg = db.qualityProfiles().insert(defaultOrganization, p -> p.setLanguage(XOO2.getKey()));
116 QProfileDto profileOnAnotherOrg = db.qualityProfiles().insert(anotherOrganization, p -> p.setLanguage(XOO1.getKey()));
118 SearchWsResponse result = call(ws.newRequest());
120 assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
121 .containsExactlyInAnyOrder(profile1OnDefaultOrg.getKee(), profile2OnDefaultOrg.getKee())
122 .doesNotContain(profileOnAnotherOrg.getKee());
126 public void specific_organization() {
127 OrganizationDto defaultOrganization = db.getDefaultOrganization();
128 OrganizationDto specificOrganization = db.organizations().insert();
129 QProfileDto profile1OnSpecificOrg = db.qualityProfiles().insert(specificOrganization, p -> p.setLanguage(XOO1.getKey()));
130 QProfileDto profile2OnSpecificOrg = db.qualityProfiles().insert(specificOrganization, p -> p.setLanguage(XOO2.getKey()));
131 QProfileDto profileOnDefaultOrg = db.qualityProfiles().insert(defaultOrganization, p -> p.setLanguage(XOO1.getKey()));
133 SearchWsResponse result = call(ws.newRequest().setParam(PARAM_ORGANIZATION, specificOrganization.getKey()));
135 assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
136 .containsExactlyInAnyOrder(profile1OnSpecificOrg.getKee(), profile2OnSpecificOrg.getKee())
137 .doesNotContain(profileOnDefaultOrg.getKee());
141 public void filter_on_default_profile() {
142 QProfileDto defaultProfile1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO1.getKey()));
143 QProfileDto defaultProfile2 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO2.getKey()));
144 QProfileDto nonDefaultProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO1.getKey()));
145 db.qualityProfiles().setAsDefault(defaultProfile1, defaultProfile2);
147 SearchWsResponse result = call(ws.newRequest().setParam(PARAM_DEFAULTS, "true"));
149 assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
150 .containsExactlyInAnyOrder(defaultProfile1.getKee(), defaultProfile2.getKee())
151 .doesNotContain(nonDefaultProfile.getKee());
155 public void does_not_filter_when_defaults_is_false() {
156 QProfileDto defaultProfile1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO1.getKey()));
157 QProfileDto defaultProfile2 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO2.getKey()));
158 QProfileDto nonDefaultProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO1.getKey()));
159 db.qualityProfiles().setAsDefault(defaultProfile1, defaultProfile2);
161 SearchWsResponse result = call(ws.newRequest().setParam(PARAM_DEFAULTS, "false"));
163 assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
164 .containsExactlyInAnyOrder(defaultProfile1.getKee(), defaultProfile2.getKee(), nonDefaultProfile.getKee());
168 public void filter_on_language() {
169 QProfileDto profile1OnXoo1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO1.getKey()));
170 QProfileDto profile2OnXoo1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO1.getKey()));
171 QProfileDto profileOnXoo2 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO2.getKey()));
173 SearchWsResponse result = call(ws.newRequest().setParam(PARAM_LANGUAGE, XOO1.getKey()));
175 assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
176 .containsExactlyInAnyOrder(profile1OnXoo1.getKee(), profile2OnXoo1.getKee())
177 .doesNotContain(profileOnXoo2.getKee());
181 public void ignore_profiles_on_unknown_language() {
182 QProfileDto profile1OnXoo1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO1.getKey()));
183 QProfileDto profile2OnXoo1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO2.getKey()));
184 QProfileDto profileOnUnknownLanguage = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage("unknown"));
186 SearchWsResponse result = call(ws.newRequest());
188 assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
189 .containsExactlyInAnyOrder(profile1OnXoo1.getKee(), profile2OnXoo1.getKee())
190 .doesNotContain(profileOnUnknownLanguage.getKee());
194 public void filter_on_profile_name() {
195 QProfileDto sonarWayOnXoo1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setName("Sonar way").setLanguage(XOO1.getKey()));
196 QProfileDto sonarWayOnXoo2 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setName("Sonar way").setLanguage(XOO1.getKey()));
197 QProfileDto sonarWayInCamelCase = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setName("Sonar Way").setLanguage(XOO2.getKey()));
198 QProfileDto anotherProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setName("Another").setLanguage(XOO2.getKey()));
200 SearchWsResponse result = call(ws.newRequest().setParam(PARAM_QUALITY_PROFILE, "Sonar way"));
202 assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
203 .containsExactlyInAnyOrder(sonarWayOnXoo1.getKee(), sonarWayOnXoo2.getKee())
204 .doesNotContain(anotherProfile.getKee(), sonarWayInCamelCase.getKee());
208 public void filter_on_defaults_and_name() {
209 QProfileDto sonarWayOnXoo1 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setName("Sonar way").setLanguage(XOO1.getKey()));
210 QProfileDto sonarWayOnXoo2 = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setName("Sonar way").setLanguage(XOO2.getKey()));
211 QProfileDto anotherProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setName("Another").setLanguage(XOO2.getKey()));
212 db.qualityProfiles().setAsDefault(sonarWayOnXoo1, anotherProfile);
214 SearchWsResponse result = call(ws.newRequest()
215 .setParam(PARAM_DEFAULTS, "true")
216 .setParam(PARAM_QUALITY_PROFILE, "Sonar way"));
218 assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
219 .containsExactlyInAnyOrder(sonarWayOnXoo1.getKee())
220 .doesNotContain(sonarWayOnXoo2.getKee(), anotherProfile.getKee());
224 public void filter_on_project_key() {
225 ComponentDto project = db.components().insertPrivateProject();
226 QProfileDto profileOnXoo1 = db.qualityProfiles().insert(db.getDefaultOrganization(), q -> q.setLanguage(XOO1.getKey()));
227 QProfileDto defaultProfileOnXoo1 = db.qualityProfiles().insert(db.getDefaultOrganization(), q -> q.setLanguage(XOO1.getKey()));
228 QProfileDto defaultProfileOnXoo2 = db.qualityProfiles().insert(db.getDefaultOrganization(), q -> q.setLanguage(XOO2.getKey()));
229 db.qualityProfiles().associateWithProject(project, profileOnXoo1);
230 db.qualityProfiles().setAsDefault(defaultProfileOnXoo1, defaultProfileOnXoo2);
232 SearchWsResponse result = call(ws.newRequest().setParam(PARAM_PROJECT, project.getDbKey()));
234 assertThat(result.getProfilesList())
235 .extracting(QualityProfile::getKey)
236 .containsExactlyInAnyOrder(profileOnXoo1.getKee(), defaultProfileOnXoo2.getKee())
237 .doesNotContain(defaultProfileOnXoo1.getKee());
241 public void filter_on_module_key() {
242 ComponentDto project = db.components().insertPrivateProject();
243 ComponentDto module = db.components().insertComponent(newModuleDto(project));
244 QProfileDto profileOnXoo1 = db.qualityProfiles().insert(db.getDefaultOrganization(), q -> q.setLanguage(XOO1.getKey()));
245 QProfileDto defaultProfileOnXoo1 = db.qualityProfiles().insert(db.getDefaultOrganization(), q -> q.setLanguage(XOO1.getKey()));
246 QProfileDto defaultProfileOnXoo2 = db.qualityProfiles().insert(db.getDefaultOrganization(), q -> q.setLanguage(XOO2.getKey()));
247 db.qualityProfiles().associateWithProject(project, profileOnXoo1);
248 db.qualityProfiles().setAsDefault(defaultProfileOnXoo1, defaultProfileOnXoo2);
250 SearchWsResponse result = call(ws.newRequest().setParam(PARAM_PROJECT, module.getDbKey()));
252 assertThat(result.getProfilesList())
253 .extracting(QualityProfile::getKey)
254 .containsExactlyInAnyOrder(profileOnXoo1.getKee(), defaultProfileOnXoo2.getKee())
255 .doesNotContain(defaultProfileOnXoo1.getKee());
259 public void filter_on_project_key_and_default() {
260 ComponentDto project = db.components().insertPrivateProject();
261 QProfileDto profileOnXoo1 = db.qualityProfiles().insert(db.getDefaultOrganization(), q -> q.setLanguage(XOO1.getKey()));
262 QProfileDto defaultProfileOnXoo1 = db.qualityProfiles().insert(db.getDefaultOrganization(), q -> q.setLanguage(XOO1.getKey()));
263 QProfileDto defaultProfileOnXoo2 = db.qualityProfiles().insert(db.getDefaultOrganization(), q -> q.setLanguage(XOO2.getKey()));
264 db.qualityProfiles().associateWithProject(project, profileOnXoo1);
265 db.qualityProfiles().setAsDefault(defaultProfileOnXoo1, defaultProfileOnXoo2);
267 SearchWsResponse result = call(ws.newRequest()
268 .setParam(PARAM_PROJECT, project.getDbKey())
269 .setParam(PARAM_DEFAULTS, "true"));
271 assertThat(result.getProfilesList())
272 .extracting(QualityProfile::getKey)
273 .containsExactlyInAnyOrder(defaultProfileOnXoo2.getKee())
274 .doesNotContain(defaultProfileOnXoo1.getKee(), profileOnXoo1.getKee());
278 public void empty_when_filtering_on_project_and_no_language_installed() {
279 WsActionTester ws = new WsActionTester(new SearchAction(userSession, new Languages(), dbClient, qProfileWsSupport, new ComponentFinder(dbClient, null)));
280 db.qualityProfiles().insert(db.getDefaultOrganization());
281 ComponentDto project = db.components().insertPrivateProject();
282 QProfileDto profileOnXoo1 = db.qualityProfiles().insert(db.getDefaultOrganization(), q -> q.setLanguage(XOO1.getKey()));
283 db.qualityProfiles().associateWithProject(project, profileOnXoo1);
285 SearchWsResponse result = call(ws.newRequest()
286 .setParam(PARAM_PROJECT, project.getDbKey())
287 .setParam(PARAM_DEFAULTS, "true"));
289 assertThat(result.getProfilesList()).isEmpty();
293 public void actions_when_user_is_global_qprofile_administer() {
294 OrganizationDto organization = db.organizations().insert();
295 QProfileDto customProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO1.getKey()));
296 QProfileDto builtInProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO1.getKey()).setIsBuiltIn(true));
297 QProfileDto defaultProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO1.getKey()));
298 db.qualityProfiles().setAsDefault(defaultProfile);
299 UserDto user = db.users().insertUser();
300 userSession.logIn(user).addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
302 SearchWsResponse result = call(ws.newRequest()
303 .setParam(PARAM_ORGANIZATION, organization.getKey()));
305 assertThat(result.getProfilesList())
306 .extracting(QualityProfile::getKey, qp -> qp.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(),
307 qp -> qp.getActions().getDelete(), qp -> qp.getActions().getAssociateProjects())
308 .containsExactlyInAnyOrder(
309 tuple(customProfile.getKee(), true, true, true, true, true),
310 tuple(builtInProfile.getKee(), false, true, true, false, true),
311 tuple(defaultProfile.getKee(), true, true, false, false, false));
312 assertThat(result.getActions().getCreate()).isTrue();
316 public void actions_when_user_can_edit_profile() {
317 OrganizationDto organization = db.organizations().insert();
318 QProfileDto profile1 = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO1.getKey()));
319 QProfileDto profile2 = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO2.getKey()));
320 QProfileDto profile3 = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO2.getKey()));
321 QProfileDto builtInProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO2.getKey()).setIsBuiltIn(true));
322 UserDto user = db.users().insertUser();
323 GroupDto group = db.users().insertGroup(organization);
324 db.qualityProfiles().addUserPermission(profile1, user);
325 db.qualityProfiles().addGroupPermission(profile3, group);
326 userSession.logIn(user).setGroups(group);
328 SearchWsResponse result = call(ws.newRequest()
329 .setParam(PARAM_ORGANIZATION, organization.getKey()));
331 assertThat(result.getProfilesList())
332 .extracting(QualityProfile::getKey, qp -> qp.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(),
333 qp -> qp.getActions().getDelete(), qp -> qp.getActions().getAssociateProjects())
334 .containsExactlyInAnyOrder(
335 tuple(profile1.getKee(), true, false, false, true, true),
336 tuple(profile2.getKee(), false, false, false, false, false),
337 tuple(profile3.getKee(), true, false, false, true, true),
338 tuple(builtInProfile.getKee(), false, false, false, false, false));
339 assertThat(result.getActions().getCreate()).isFalse();
343 public void actions_when_not_logged_in() {
344 OrganizationDto organization = db.organizations().insert();
345 QProfileDto profile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO1.getKey()));
346 userSession.anonymous();
348 SearchWsResponse result = call(ws.newRequest()
349 .setParam(PARAM_ORGANIZATION, organization.getKey()));
351 assertThat(result.getProfilesList())
352 .extracting(QualityProfile::getKey, qp -> qp.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(),
353 qp -> qp.getActions().getDelete(), qp -> qp.getActions().getAssociateProjects())
354 .containsExactlyInAnyOrder(tuple(profile.getKee(), false, false, false, false, false));
355 assertThat(result.getActions().getCreate()).isFalse();
359 public void statistics_on_active_rules() {
360 QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(XOO1.getKey()));
361 RuleDefinitionDto rule = db.rules().insertRule(r -> r.setLanguage(XOO1.getKey())).getDefinition();
362 RuleDefinitionDto deprecatedRule1 = db.rules().insertRule(r -> r.setStatus(DEPRECATED)).getDefinition();
363 RuleDefinitionDto deprecatedRule2 = db.rules().insertRule(r -> r.setStatus(DEPRECATED)).getDefinition();
364 RuleDefinitionDto inactiveRule = db.rules().insertRule(r -> r.setLanguage(XOO1.getKey())).getDefinition();
365 db.qualityProfiles().activateRule(profile, rule);
366 db.qualityProfiles().activateRule(profile, deprecatedRule1);
367 db.qualityProfiles().activateRule(profile, deprecatedRule2);
369 SearchWsResponse result = call(ws.newRequest());
371 assertThat(result.getProfilesList())
372 .extracting(QualityProfile::getActiveRuleCount, QualityProfile::getActiveDeprecatedRuleCount)
373 .containsExactlyInAnyOrder(tuple(3L, 2L));
377 public void statistics_on_projects() {
378 ComponentDto project1 = db.components().insertPrivateProject();
379 ComponentDto project2 = db.components().insertPrivateProject();
380 QProfileDto profileOnXoo1 = db.qualityProfiles().insert(db.getDefaultOrganization(), q -> q.setLanguage(XOO1.getKey()));
381 QProfileDto defaultProfileOnXoo1 = db.qualityProfiles().insert(db.getDefaultOrganization(), q -> q.setLanguage(XOO1.getKey()));
382 db.qualityProfiles().associateWithProject(project1, profileOnXoo1);
383 db.qualityProfiles().associateWithProject(project2, profileOnXoo1);
384 db.qualityProfiles().setAsDefault(defaultProfileOnXoo1);
386 SearchWsResponse result = call(ws.newRequest());
388 assertThat(result.getProfilesList())
389 .extracting(QualityProfile::hasProjectCount, QualityProfile::getProjectCount)
390 .containsExactlyInAnyOrder(tuple(true, 2L), tuple(false, 0L));
394 public void map_dates() {
395 long time = DateUtils.parseDateTime("2016-12-22T19:10:03+0100").getTime();
396 qualityProfileDb.insert(newQualityProfileDto()
397 .setOrganizationUuid(defaultOrganizationProvider.get().getUuid())
398 .setLanguage(XOO1.getKey())
399 .setRulesUpdatedAt("2016-12-21T19:10:03+0100")
401 .setUserUpdatedAt(time));
403 SearchWsResponse result = call(ws.newRequest());
405 assertThat(result.getProfilesCount()).isEqualTo(1);
406 assertThat(result.getProfiles(0).getRulesUpdatedAt()).isEqualTo("2016-12-21T19:10:03+0100");
407 assertThat(parseDateTime(result.getProfiles(0).getLastUsed()).getTime()).isEqualTo(time);
408 assertThat(parseDateTime(result.getProfiles(0).getUserUpdatedAt()).getTime()).isEqualTo(time);
412 public void return_qprofile_on_free_organization() {
413 OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(FREE));
414 QProfileDto qProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO1.getKey()));
416 SearchWsResponse result = call(ws.newRequest().setParam(PARAM_ORGANIZATION, organization.getKey()));
418 assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
419 .containsExactlyInAnyOrder(qProfile.getKee());
423 public void return_qprofile_on_paid_organization_when_user_is_member() {
424 OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
425 QProfileDto qProfile = db.qualityProfiles().insert(organization, p -> p.setLanguage(XOO1.getKey()));
426 UserDto user = db.users().insertUser();
427 userSession.logIn(user).addMembership(organization);
429 SearchWsResponse result = call(ws.newRequest().setParam(PARAM_ORGANIZATION, organization.getKey()));
431 assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
432 .containsExactlyInAnyOrder(qProfile.getKee());
436 public void fail_if_project_does_not_exist() {
437 expectedException.expect(NotFoundException.class);
438 expectedException.expectMessage("Component key 'unknown-project' not found");
440 call(ws.newRequest().setParam(PARAM_PROJECT, "unknown-project"));
444 public void fail_if_project_of_module_does_not_exist() {
445 ComponentDto project = db.components().insertPrivateProject();
446 ComponentDto module = db.components().insertComponent(newModuleDto(project).setProjectUuid("unknown"));
448 expectedException.expect(IllegalStateException.class);
449 expectedException.expectMessage(format("Project uuid of component uuid '%s' does not exist", module.uuid()));
451 call(ws.newRequest().setParam(PARAM_PROJECT, module.getDbKey()));
455 public void fail_if_project_is_on_another_organization() {
456 OrganizationDto organization = db.organizations().insert();
457 OrganizationDto anotherOrganization = db.organizations().insert();
458 ComponentDto project = db.components().insertPrivateProject(anotherOrganization);
460 expectedException.expect(NotFoundException.class);
461 expectedException.expectMessage(format("Component key '%s' not found", project.getDbKey()));
464 .setParam(PARAM_ORGANIZATION, organization.getKey())
465 .setParam(PARAM_PROJECT, project.getDbKey()));
469 public void fail_if_organization_does_not_exist() {
470 expectedException.expect(NotFoundException.class);
471 expectedException.expectMessage("No organization with key 'unknown-organization'");
473 call(ws.newRequest().setParam(PARAM_ORGANIZATION, "unknown-organization"));
477 public void fail_on_paid_organization_when_not_member() {
478 OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
481 expectedException.expect(ForbiddenException.class);
482 expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey()));
484 call(ws.newRequest().setParam(PARAM_ORGANIZATION, organization.getKey()));
488 public void json_example() {
489 OrganizationDto organization = db.organizations().insertForKey("My Organization");
491 Language cs = newLanguage("cs", "C#");
492 Language java = newLanguage("java", "Java");
493 Language python = newLanguage("py", "Python");
495 QProfileDto sonarWayCs = db.qualityProfiles().insert(organization,
496 p -> p.setName("Sonar way").setKee("AU-TpxcA-iU5OvuD2FL3").setIsBuiltIn(true).setLanguage(cs.getKey()));
497 QProfileDto myCompanyProfile = db.qualityProfiles().insert(organization,
498 p -> p.setName("My Company Profile").setKee("iU5OvuD2FLz").setLanguage(java.getKey()));
499 QProfileDto myBuProfile = db.qualityProfiles().insert(organization,
500 p -> p.setName("My BU Profile").setKee("AU-TpxcA-iU5OvuD2FL1").setParentKee(myCompanyProfile.getKee()).setLanguage(java.getKey()));
501 QProfileDto sonarWayPython = db.qualityProfiles().insert(organization,
502 p -> p.setName("Sonar way").setKee("AU-TpxcB-iU5OvuD2FL7").setIsBuiltIn(true).setLanguage(python.getKey()));
503 db.qualityProfiles().setAsDefault(sonarWayCs, myCompanyProfile, sonarWayPython);
505 List<RuleDefinitionDto> javaRules = range(0, 10).mapToObj(i -> db.rules().insertRule(r -> r.setLanguage(java.getKey())).getDefinition())
506 .collect(MoreCollectors.toList());
507 List<RuleDefinitionDto> deprecatedJavaRules = range(0, 5)
508 .mapToObj(i -> db.rules().insertRule(r -> r.setLanguage(java.getKey()).setStatus(DEPRECATED)).getDefinition())
509 .collect(MoreCollectors.toList());
510 range(0, 7).forEach(i -> db.qualityProfiles().activateRule(myCompanyProfile, javaRules.get(i)));
511 range(0, 2).forEach(i -> db.qualityProfiles().activateRule(myCompanyProfile, deprecatedJavaRules.get(i)));
512 range(0, 10).forEach(i -> db.qualityProfiles().activateRule(myBuProfile, javaRules.get(i)));
513 range(0, 5).forEach(i -> db.qualityProfiles().activateRule(myBuProfile, deprecatedJavaRules.get(i)));
515 .mapToObj(i -> db.rules().insertRule(r -> r.setLanguage(python.getKey())).getDefinition())
516 .forEach(rule -> db.qualityProfiles().activateRule(sonarWayPython, rule));
518 .mapToObj(i -> db.rules().insertRule(r -> r.setLanguage(cs.getKey())).getDefinition())
519 .forEach(rule -> db.qualityProfiles().activateRule(sonarWayCs, rule));
522 .mapToObj(i -> db.components().insertPrivateProject(organization))
523 .forEach(project -> db.qualityProfiles().associateWithProject(project, myBuProfile));
525 UserDto user = db.users().insertUser();
526 db.qualityProfiles().addUserPermission(myCompanyProfile, user);
527 db.qualityProfiles().addUserPermission(myBuProfile, user);
528 userSession.logIn(user);
530 underTest = new SearchAction(userSession, new Languages(cs, java, python), dbClient, qProfileWsSupport, new ComponentFinder(dbClient, null));
531 ws = new WsActionTester(underTest);
532 String result = ws.newRequest().setParam(PARAM_ORGANIZATION, organization.getKey()).execute().getInput();
533 assertJson(result).ignoreFields("ruleUpdatedAt", "lastUsed", "userUpdatedAt")
534 .isSimilarTo(ws.getDef().responseExampleAsString());
538 public void definition() {
539 WebService.Action definition = ws.getDef();
541 assertThat(definition.key()).isEqualTo("search");
542 assertThat(definition.responseExampleAsString()).isNotEmpty();
543 assertThat(definition.isPost()).isFalse();
545 assertThat(definition.changelog())
546 .extracting(Change::getVersion, Change::getDescription)
547 .containsExactlyInAnyOrder(
548 tuple("6.5", "The parameters 'defaults', 'project' and 'language' can be combined without any constraint"),
549 tuple("6.6", "Add available actions 'edit', 'copy' and 'setAsDefault' and global action 'create'"),
550 tuple("7.0", "Add available actions 'delete' and 'associateProjects'"));
552 WebService.Param organization = definition.param("organization");
553 assertThat(organization).isNotNull();
554 assertThat(organization.isRequired()).isFalse();
555 assertThat(organization.isInternal()).isTrue();
556 assertThat(organization.description()).isNotEmpty();
557 assertThat(organization.since()).isEqualTo("6.4");
559 WebService.Param defaults = definition.param("defaults");
560 assertThat(defaults.defaultValue()).isEqualTo("false");
561 assertThat(defaults.description()).isEqualTo("If set to true, return only the quality profiles marked as default for each language");
563 WebService.Param projectKey = definition.param("project");
564 assertThat(projectKey.description()).isEqualTo("Project key");
566 WebService.Param language = definition.param("language");
567 assertThat(language.possibleValues()).containsExactly("xoo1", "xoo2");
568 assertThat(language.deprecatedSince()).isNull();
569 assertThat(language.description()).isEqualTo("Language key. If provided, only profiles for the given language are returned.");
571 WebService.Param profileName = definition.param("qualityProfile");
572 assertThat(profileName.deprecatedSince()).isNull();
573 assertThat(profileName.description()).isEqualTo("Quality profile name");
576 private SearchWsResponse call(TestRequest request) {
577 TestRequest wsRequest = request.setMediaType(MediaTypes.PROTOBUF);
579 return wsRequest.executeProtobuf(SearchWsResponse.class);