]> source.dussan.org Git - sonarqube.git/blob
ade503e11a1469ccd1c0f83d423981b75385f927
[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.qualityprofile.ws;
21
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.organization.OrganizationDto;
36 import org.sonar.db.permission.GlobalPermission;
37 import org.sonar.db.project.ProjectDto;
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.NotFoundException;
45 import org.sonar.server.tester.UserSessionRule;
46 import org.sonar.server.ws.TestRequest;
47 import org.sonar.server.ws.WsActionTester;
48 import org.sonarqube.ws.MediaTypes;
49 import org.sonarqube.ws.Qualityprofiles.SearchWsResponse;
50 import org.sonarqube.ws.Qualityprofiles.SearchWsResponse.QualityProfile;
51
52 import static java.util.stream.IntStream.range;
53 import static org.assertj.core.api.Assertions.assertThat;
54 import static org.assertj.core.api.Assertions.tuple;
55 import static org.sonar.api.rule.RuleStatus.DEPRECATED;
56 import static org.sonar.api.utils.DateUtils.parseDateTime;
57 import static org.sonar.db.qualityprofile.QualityProfileTesting.newQualityProfileDto;
58 import static org.sonar.server.language.LanguageTesting.newLanguage;
59 import static org.sonar.test.JsonAssert.assertJson;
60 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_DEFAULTS;
61 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE;
62 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PROJECT;
63 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PROJECT_KEY;
64 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_QUALITY_PROFILE;
65
66 public class SearchActionTest {
67
68   private static Language XOO1 = newLanguage("xoo1");
69   private static Language XOO2 = newLanguage("xoo2");
70   private static Languages LANGUAGES = new Languages(XOO1, XOO2);
71
72   @Rule
73   public DbTester db = DbTester.create(System2.INSTANCE);
74   @Rule
75   public UserSessionRule userSession = UserSessionRule.standalone();
76   @Rule
77   public ExpectedException expectedException = ExpectedException.none();
78   private QualityProfileDbTester qualityProfileDb = db.qualityProfiles();
79   private DbClient dbClient = db.getDbClient();
80
81   private SearchAction underTest = new SearchAction(userSession, LANGUAGES, dbClient, new ComponentFinder(dbClient, null));
82   private WsActionTester ws = new WsActionTester(underTest);
83
84   @Test
85   public void no_profile() {
86     SearchWsResponse result = call(ws.newRequest());
87
88     assertThat(result.getProfilesList()).isEmpty();
89   }
90
91   @Test
92   public void empty_when_no_language_installed() {
93     WsActionTester ws = new WsActionTester(new SearchAction(userSession, new Languages(), dbClient, new ComponentFinder(dbClient, null)));
94     db.qualityProfiles().insert();
95
96     SearchWsResponse result = call(ws.newRequest());
97
98     assertThat(result.getProfilesList()).isEmpty();
99   }
100
101   @Test
102   public void default_organization() {
103     QProfileDto profile1OnDefaultOrg = db.qualityProfiles().insert(p -> p.setLanguage(XOO1.getKey()));
104     QProfileDto profile2OnDefaultOrg = db.qualityProfiles().insert(p -> p.setLanguage(XOO2.getKey()));
105
106     SearchWsResponse result = call(ws.newRequest());
107
108     assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
109       .containsExactlyInAnyOrder(profile1OnDefaultOrg.getKee(), profile2OnDefaultOrg.getKee());
110   }
111
112   @Test
113   public void filter_on_default_profile() {
114     QProfileDto defaultProfile1 = db.qualityProfiles().insert(p -> p.setLanguage(XOO1.getKey()));
115     QProfileDto defaultProfile2 = db.qualityProfiles().insert(p -> p.setLanguage(XOO2.getKey()));
116     QProfileDto nonDefaultProfile = db.qualityProfiles().insert(p -> p.setLanguage(XOO1.getKey()));
117     db.qualityProfiles().setAsDefault(defaultProfile1, defaultProfile2);
118
119     SearchWsResponse result = call(ws.newRequest().setParam(PARAM_DEFAULTS, "true"));
120
121     assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
122       .containsExactlyInAnyOrder(defaultProfile1.getKee(), defaultProfile2.getKee())
123       .doesNotContain(nonDefaultProfile.getKee());
124   }
125
126   @Test
127   public void does_not_filter_when_defaults_is_false() {
128     QProfileDto defaultProfile1 = db.qualityProfiles().insert(p -> p.setLanguage(XOO1.getKey()));
129     QProfileDto defaultProfile2 = db.qualityProfiles().insert(p -> p.setLanguage(XOO2.getKey()));
130     QProfileDto nonDefaultProfile = db.qualityProfiles().insert(p -> p.setLanguage(XOO1.getKey()));
131     db.qualityProfiles().setAsDefault(defaultProfile1, defaultProfile2);
132
133     SearchWsResponse result = call(ws.newRequest().setParam(PARAM_DEFAULTS, "false"));
134
135     assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
136       .containsExactlyInAnyOrder(defaultProfile1.getKee(), defaultProfile2.getKee(), nonDefaultProfile.getKee());
137   }
138
139   @Test
140   public void filter_on_language() {
141     QProfileDto profile1OnXoo1 = db.qualityProfiles().insert(p -> p.setLanguage(XOO1.getKey()));
142     QProfileDto profile2OnXoo1 = db.qualityProfiles().insert(p -> p.setLanguage(XOO1.getKey()));
143     QProfileDto profileOnXoo2 = db.qualityProfiles().insert(p -> p.setLanguage(XOO2.getKey()));
144
145     SearchWsResponse result = call(ws.newRequest().setParam(PARAM_LANGUAGE, XOO1.getKey()));
146
147     assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
148       .containsExactlyInAnyOrder(profile1OnXoo1.getKee(), profile2OnXoo1.getKee())
149       .doesNotContain(profileOnXoo2.getKee());
150   }
151
152   @Test
153   public void ignore_profiles_on_unknown_language() {
154     QProfileDto profile1OnXoo1 = db.qualityProfiles().insert(p -> p.setLanguage(XOO1.getKey()));
155     QProfileDto profile2OnXoo1 = db.qualityProfiles().insert(p -> p.setLanguage(XOO2.getKey()));
156     QProfileDto profileOnUnknownLanguage = db.qualityProfiles().insert(p -> p.setLanguage("unknown"));
157
158     SearchWsResponse result = call(ws.newRequest());
159
160     assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
161       .containsExactlyInAnyOrder(profile1OnXoo1.getKee(), profile2OnXoo1.getKee())
162       .doesNotContain(profileOnUnknownLanguage.getKee());
163   }
164
165   @Test
166   public void filter_on_profile_name() {
167     QProfileDto sonarWayOnXoo1 = db.qualityProfiles().insert(p -> p.setName("Sonar way").setLanguage(XOO1.getKey()));
168     QProfileDto sonarWayOnXoo2 = db.qualityProfiles().insert(p -> p.setName("Sonar way").setLanguage(XOO1.getKey()));
169     QProfileDto sonarWayInCamelCase = db.qualityProfiles().insert(p -> p.setName("Sonar Way").setLanguage(XOO2.getKey()));
170     QProfileDto anotherProfile = db.qualityProfiles().insert(p -> p.setName("Another").setLanguage(XOO2.getKey()));
171
172     SearchWsResponse result = call(ws.newRequest().setParam(PARAM_QUALITY_PROFILE, "Sonar way"));
173
174     assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
175       .containsExactlyInAnyOrder(sonarWayOnXoo1.getKee(), sonarWayOnXoo2.getKee())
176       .doesNotContain(anotherProfile.getKee(), sonarWayInCamelCase.getKee());
177   }
178
179   @Test
180   public void filter_on_defaults_and_name() {
181     QProfileDto sonarWayOnXoo1 = db.qualityProfiles().insert(p -> p.setName("Sonar way").setLanguage(XOO1.getKey()));
182     QProfileDto sonarWayOnXoo2 = db.qualityProfiles().insert(p -> p.setName("Sonar way").setLanguage(XOO2.getKey()));
183     QProfileDto anotherProfile = db.qualityProfiles().insert(p -> p.setName("Another").setLanguage(XOO2.getKey()));
184     db.qualityProfiles().setAsDefault(sonarWayOnXoo1, anotherProfile);
185
186     SearchWsResponse result = call(ws.newRequest()
187       .setParam(PARAM_DEFAULTS, "true")
188       .setParam(PARAM_QUALITY_PROFILE, "Sonar way"));
189
190     assertThat(result.getProfilesList()).extracting(QualityProfile::getKey)
191       .containsExactlyInAnyOrder(sonarWayOnXoo1.getKee())
192       .doesNotContain(sonarWayOnXoo2.getKee(), anotherProfile.getKee());
193   }
194
195   @Test
196   public void filter_on_project_key() {
197     ProjectDto project = db.components().insertPrivateProjectDto();
198     QProfileDto profileOnXoo1 = db.qualityProfiles().insert(q -> q.setLanguage(XOO1.getKey()));
199     QProfileDto defaultProfileOnXoo1 = db.qualityProfiles().insert(q -> q.setLanguage(XOO1.getKey()));
200     QProfileDto defaultProfileOnXoo2 = db.qualityProfiles().insert(q -> q.setLanguage(XOO2.getKey()));
201     db.qualityProfiles().associateWithProject(project, profileOnXoo1);
202     db.qualityProfiles().setAsDefault(defaultProfileOnXoo1, defaultProfileOnXoo2);
203
204     SearchWsResponse result = call(ws.newRequest().setParam(PARAM_PROJECT, project.getKey()));
205
206     assertThat(result.getProfilesList())
207       .extracting(QualityProfile::getKey)
208       .containsExactlyInAnyOrder(profileOnXoo1.getKee(), defaultProfileOnXoo2.getKee())
209       .doesNotContain(defaultProfileOnXoo1.getKee());
210   }
211
212   @Test
213   public void filter_on_project_key_and_default() {
214     ProjectDto project = db.components().insertPrivateProjectDto();
215     QProfileDto profileOnXoo1 = db.qualityProfiles().insert(q -> q.setLanguage(XOO1.getKey()));
216     QProfileDto defaultProfileOnXoo1 = db.qualityProfiles().insert(q -> q.setLanguage(XOO1.getKey()));
217     QProfileDto defaultProfileOnXoo2 = db.qualityProfiles().insert(q -> q.setLanguage(XOO2.getKey()));
218     db.qualityProfiles().associateWithProject(project, profileOnXoo1);
219     db.qualityProfiles().setAsDefault(defaultProfileOnXoo1, defaultProfileOnXoo2);
220
221     SearchWsResponse result = call(ws.newRequest()
222       .setParam(PARAM_PROJECT, project.getKey())
223       .setParam(PARAM_DEFAULTS, "true"));
224
225     assertThat(result.getProfilesList())
226       .extracting(QualityProfile::getKey)
227       .containsExactlyInAnyOrder(defaultProfileOnXoo2.getKee())
228       .doesNotContain(defaultProfileOnXoo1.getKee(), profileOnXoo1.getKee());
229   }
230
231   @Test
232   public void filter_on_deprecated_project_key_and_default() {
233     ProjectDto project = db.components().insertPrivateProjectDto();
234     QProfileDto profileOnXoo1 = db.qualityProfiles().insert(q -> q.setLanguage(XOO1.getKey()));
235     QProfileDto defaultProfileOnXoo1 = db.qualityProfiles().insert(q -> q.setLanguage(XOO1.getKey()));
236     QProfileDto defaultProfileOnXoo2 = db.qualityProfiles().insert(q -> q.setLanguage(XOO2.getKey()));
237     db.qualityProfiles().associateWithProject(project, profileOnXoo1);
238     db.qualityProfiles().setAsDefault(defaultProfileOnXoo1, defaultProfileOnXoo2);
239
240     SearchWsResponse result = call(ws.newRequest()
241       .setParam(PARAM_PROJECT_KEY, project.getKey())
242       .setParam(PARAM_DEFAULTS, "true"));
243
244     assertThat(result.getProfilesList())
245       .extracting(QualityProfile::getKey)
246       .containsExactlyInAnyOrder(defaultProfileOnXoo2.getKee())
247       .doesNotContain(defaultProfileOnXoo1.getKee(), profileOnXoo1.getKee());
248   }
249
250   @Test
251   public void empty_when_filtering_on_project_and_no_language_installed() {
252     WsActionTester ws = new WsActionTester(new SearchAction(userSession, new Languages(), dbClient, new ComponentFinder(dbClient, null)));
253     db.qualityProfiles().insert();
254     ProjectDto project = db.components().insertPrivateProjectDto();
255     QProfileDto profileOnXoo1 = db.qualityProfiles().insert(q -> q.setLanguage(XOO1.getKey()));
256     db.qualityProfiles().associateWithProject(project, profileOnXoo1);
257
258     SearchWsResponse result = call(ws.newRequest()
259       .setParam(PARAM_PROJECT, project.getKey())
260       .setParam(PARAM_DEFAULTS, "true"));
261
262     assertThat(result.getProfilesList()).isEmpty();
263   }
264
265   @Test
266   public void actions_when_user_is_global_qprofile_administer() {
267     OrganizationDto organization = db.organizations().getDefaultOrganization();
268     QProfileDto customProfile = db.qualityProfiles().insert(p -> p.setLanguage(XOO1.getKey()));
269     QProfileDto builtInProfile = db.qualityProfiles().insert(p -> p.setLanguage(XOO1.getKey()).setIsBuiltIn(true));
270     QProfileDto defaultProfile = db.qualityProfiles().insert(p -> p.setLanguage(XOO1.getKey()));
271     db.qualityProfiles().setAsDefault(defaultProfile);
272     UserDto user = db.users().insertUser();
273     userSession.logIn(user).addPermission(GlobalPermission.ADMINISTER_QUALITY_PROFILES);
274
275     SearchWsResponse result = call(ws.newRequest());
276
277     assertThat(result.getProfilesList())
278       .extracting(QualityProfile::getKey, qp -> qp.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(),
279         qp -> qp.getActions().getDelete(), qp -> qp.getActions().getAssociateProjects())
280       .containsExactlyInAnyOrder(
281         tuple(customProfile.getKee(), true, true, true, true, true),
282         tuple(builtInProfile.getKee(), false, true, true, false, true),
283         tuple(defaultProfile.getKee(), true, true, false, false, false));
284     assertThat(result.getActions().getCreate()).isTrue();
285   }
286
287   @Test
288   public void actions_when_user_can_edit_profile() {
289     OrganizationDto organization = db.organizations().getDefaultOrganization();
290     QProfileDto profile1 = db.qualityProfiles().insert(p -> p.setLanguage(XOO1.getKey()));
291     QProfileDto profile2 = db.qualityProfiles().insert(p -> p.setLanguage(XOO2.getKey()));
292     QProfileDto profile3 = db.qualityProfiles().insert(p -> p.setLanguage(XOO2.getKey()));
293     QProfileDto builtInProfile = db.qualityProfiles().insert(p -> p.setLanguage(XOO2.getKey()).setIsBuiltIn(true));
294     UserDto user = db.users().insertUser();
295     GroupDto group = db.users().insertGroup();
296     db.qualityProfiles().addUserPermission(profile1, user);
297     db.qualityProfiles().addGroupPermission(profile3, group);
298     userSession.logIn(user).setGroups(group);
299
300     SearchWsResponse result = call(ws.newRequest());
301
302     assertThat(result.getProfilesList())
303       .extracting(QualityProfile::getKey, qp -> qp.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(),
304         qp -> qp.getActions().getDelete(), qp -> qp.getActions().getAssociateProjects())
305       .containsExactlyInAnyOrder(
306         tuple(profile1.getKee(), true, false, false, true, true),
307         tuple(profile2.getKee(), false, false, false, false, false),
308         tuple(profile3.getKee(), true, false, false, true, true),
309         tuple(builtInProfile.getKee(), false, false, false, false, false));
310     assertThat(result.getActions().getCreate()).isFalse();
311   }
312
313   @Test
314   public void actions_when_not_logged_in() {
315     QProfileDto profile = db.qualityProfiles().insert(p -> p.setLanguage(XOO1.getKey()));
316     userSession.anonymous();
317
318     SearchWsResponse result = call(ws.newRequest());
319
320     assertThat(result.getProfilesList())
321       .extracting(QualityProfile::getKey, qp -> qp.getActions().getEdit(), qp -> qp.getActions().getCopy(), qp -> qp.getActions().getSetAsDefault(),
322         qp -> qp.getActions().getDelete(), qp -> qp.getActions().getAssociateProjects())
323       .containsExactlyInAnyOrder(tuple(profile.getKee(), false, false, false, false, false));
324     assertThat(result.getActions().getCreate()).isFalse();
325   }
326
327   @Test
328   public void statistics_on_active_rules() {
329     QProfileDto profile = db.qualityProfiles().insert(p -> p.setLanguage(XOO1.getKey()));
330     RuleDefinitionDto rule = db.rules().insertRule(r -> r.setLanguage(XOO1.getKey())).getDefinition();
331     RuleDefinitionDto deprecatedRule1 = db.rules().insertRule(r -> r.setStatus(DEPRECATED)).getDefinition();
332     RuleDefinitionDto deprecatedRule2 = db.rules().insertRule(r -> r.setStatus(DEPRECATED)).getDefinition();
333     RuleDefinitionDto inactiveRule = db.rules().insertRule(r -> r.setLanguage(XOO1.getKey())).getDefinition();
334     db.qualityProfiles().activateRule(profile, rule);
335     db.qualityProfiles().activateRule(profile, deprecatedRule1);
336     db.qualityProfiles().activateRule(profile, deprecatedRule2);
337
338     SearchWsResponse result = call(ws.newRequest());
339
340     assertThat(result.getProfilesList())
341       .extracting(QualityProfile::getActiveRuleCount, QualityProfile::getActiveDeprecatedRuleCount)
342       .containsExactlyInAnyOrder(tuple(3L, 2L));
343   }
344
345   @Test
346   public void statistics_on_projects() {
347     ProjectDto project1 = db.components().insertPrivateProjectDto();
348     ProjectDto project2 = db.components().insertPrivateProjectDto();
349     QProfileDto profileOnXoo1 = db.qualityProfiles().insert(q -> q.setLanguage(XOO1.getKey()));
350     QProfileDto defaultProfileOnXoo1 = db.qualityProfiles().insert(q -> q.setLanguage(XOO1.getKey()));
351     db.qualityProfiles().associateWithProject(project1, profileOnXoo1);
352     db.qualityProfiles().associateWithProject(project2, profileOnXoo1);
353     db.qualityProfiles().setAsDefault(defaultProfileOnXoo1);
354
355     SearchWsResponse result = call(ws.newRequest());
356
357     assertThat(result.getProfilesList())
358       .extracting(QualityProfile::hasProjectCount, QualityProfile::getProjectCount)
359       .containsExactlyInAnyOrder(tuple(true, 2L), tuple(false, 0L));
360   }
361
362   @Test
363   public void map_dates() {
364     long time = DateUtils.parseDateTime("2016-12-22T19:10:03+0100").getTime();
365     qualityProfileDb.insert(newQualityProfileDto()
366       .setLanguage(XOO1.getKey())
367       .setRulesUpdatedAt("2016-12-21T19:10:03+0100")
368       .setLastUsed(time)
369       .setUserUpdatedAt(time));
370
371     SearchWsResponse result = call(ws.newRequest());
372
373     assertThat(result.getProfilesCount()).isEqualTo(1);
374     assertThat(result.getProfiles(0).getRulesUpdatedAt()).isEqualTo("2016-12-21T19:10:03+0100");
375     assertThat(parseDateTime(result.getProfiles(0).getLastUsed()).getTime()).isEqualTo(time);
376     assertThat(parseDateTime(result.getProfiles(0).getUserUpdatedAt()).getTime()).isEqualTo(time);
377   }
378
379   @Test
380   public void fail_if_project_does_not_exist() {
381     expectedException.expect(NotFoundException.class);
382     expectedException.expectMessage("Project 'unknown-project' not found");
383
384     call(ws.newRequest().setParam(PARAM_PROJECT, "unknown-project"));
385   }
386
387   @Test
388   public void json_example() {
389     // languages
390     Language cs = newLanguage("cs", "C#");
391     Language java = newLanguage("java", "Java");
392     Language python = newLanguage("py", "Python");
393     // profiles
394     QProfileDto sonarWayCs = db.qualityProfiles().insert(
395       p -> p.setName("Sonar way").setKee("AU-TpxcA-iU5OvuD2FL3").setIsBuiltIn(true).setLanguage(cs.getKey()));
396     QProfileDto myCompanyProfile = db.qualityProfiles().insert(p -> p.setName("My Company Profile").setKee("iU5OvuD2FLz").setLanguage(java.getKey()));
397     QProfileDto myBuProfile = db.qualityProfiles().insert(
398       p -> p.setName("My BU Profile").setKee("AU-TpxcA-iU5OvuD2FL1").setParentKee(myCompanyProfile.getKee()).setLanguage(java.getKey()));
399     QProfileDto sonarWayPython = db.qualityProfiles().insert(
400       p -> p.setName("Sonar way").setKee("AU-TpxcB-iU5OvuD2FL7").setIsBuiltIn(true).setLanguage(python.getKey()));
401     db.qualityProfiles().setAsDefault(sonarWayCs, myCompanyProfile, sonarWayPython);
402     // rules
403     List<RuleDefinitionDto> javaRules = range(0, 10).mapToObj(i -> db.rules().insertRule(r -> r.setLanguage(java.getKey())).getDefinition())
404       .collect(MoreCollectors.toList());
405     List<RuleDefinitionDto> deprecatedJavaRules = range(0, 5)
406       .mapToObj(i -> db.rules().insertRule(r -> r.setLanguage(java.getKey()).setStatus(DEPRECATED)).getDefinition())
407       .collect(MoreCollectors.toList());
408     range(0, 7).forEach(i -> db.qualityProfiles().activateRule(myCompanyProfile, javaRules.get(i)));
409     range(0, 2).forEach(i -> db.qualityProfiles().activateRule(myCompanyProfile, deprecatedJavaRules.get(i)));
410     range(0, 10).forEach(i -> db.qualityProfiles().activateRule(myBuProfile, javaRules.get(i)));
411     range(0, 5).forEach(i -> db.qualityProfiles().activateRule(myBuProfile, deprecatedJavaRules.get(i)));
412     range(0, 2)
413       .mapToObj(i -> db.rules().insertRule(r -> r.setLanguage(python.getKey())).getDefinition())
414       .forEach(rule -> db.qualityProfiles().activateRule(sonarWayPython, rule));
415     range(0, 3)
416       .mapToObj(i -> db.rules().insertRule(r -> r.setLanguage(cs.getKey())).getDefinition())
417       .forEach(rule -> db.qualityProfiles().activateRule(sonarWayCs, rule));
418     // project
419     range(0, 7)
420       .mapToObj(i -> db.components().insertPrivateProjectDto())
421       .forEach(project -> db.qualityProfiles().associateWithProject(project, myBuProfile));
422     // User
423     UserDto user = db.users().insertUser();
424     db.qualityProfiles().addUserPermission(myCompanyProfile, user);
425     db.qualityProfiles().addUserPermission(myBuProfile, user);
426     userSession.logIn(user);
427
428     underTest = new SearchAction(userSession, new Languages(cs, java, python), dbClient, new ComponentFinder(dbClient, null));
429     ws = new WsActionTester(underTest);
430     String result = ws.newRequest().execute().getInput();
431     assertJson(result).ignoreFields("ruleUpdatedAt", "lastUsed", "userUpdatedAt")
432       .isSimilarTo(ws.getDef().responseExampleAsString());
433   }
434
435   @Test
436   public void definition() {
437     WebService.Action definition = ws.getDef();
438
439     assertThat(definition.key()).isEqualTo("search");
440     assertThat(definition.responseExampleAsString()).isNotEmpty();
441     assertThat(definition.isPost()).isFalse();
442
443     assertThat(definition.changelog())
444       .extracting(Change::getVersion, Change::getDescription)
445       .containsExactlyInAnyOrder(
446         tuple("6.5", "The parameters 'defaults', 'project' and 'language' can be combined without any constraint"),
447         tuple("6.6", "Add available actions 'edit', 'copy' and 'setAsDefault' and global action 'create'"),
448         tuple("7.0", "Add available actions 'delete' and 'associateProjects'"));
449
450     WebService.Param defaults = definition.param("defaults");
451     assertThat(defaults.defaultValue()).isEqualTo("false");
452     assertThat(defaults.description()).isEqualTo("If set to true, return only the quality profiles marked as default for each language");
453
454     WebService.Param projectKey = definition.param("project");
455     assertThat(projectKey.description()).isEqualTo("Project key");
456     assertThat(projectKey.deprecatedKey()).isEqualTo("projectKey");
457
458     WebService.Param language = definition.param("language");
459     assertThat(language.possibleValues()).containsExactly("xoo1", "xoo2");
460     assertThat(language.deprecatedSince()).isNull();
461     assertThat(language.description()).isEqualTo("Language key. If provided, only profiles for the given language are returned.");
462
463     WebService.Param profileName = definition.param("qualityProfile");
464     assertThat(profileName.deprecatedSince()).isNull();
465     assertThat(profileName.description()).isEqualTo("Quality profile name");
466   }
467
468   private SearchWsResponse call(TestRequest request) {
469     TestRequest wsRequest = request.setMediaType(MediaTypes.PROTOBUF);
470
471     return wsRequest.executeProtobuf(SearchWsResponse.class);
472   }
473 }