]> source.dussan.org Git - sonarqube.git/blob
cd800af8792b2cee6aa881bddfd2638de6f2c4cf
[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 com.google.common.collect.ImmutableMap;
23 import java.util.Arrays;
24 import java.util.Map;
25 import java.util.function.Consumer;
26 import javax.annotation.Nullable;
27 import org.junit.Rule;
28 import org.junit.Test;
29 import org.junit.rules.ExpectedException;
30 import org.sonar.api.impl.utils.TestSystem2;
31 import org.sonar.api.resources.Languages;
32 import org.sonar.api.rule.RuleKey;
33 import org.sonar.api.server.ws.WebService;
34 import org.sonar.api.utils.DateUtils;
35 import org.sonar.db.DbTester;
36 import org.sonar.db.qualityprofile.QProfileChangeDto;
37 import org.sonar.db.qualityprofile.QProfileDto;
38 import org.sonar.db.rule.RuleDefinitionDto;
39 import org.sonar.db.user.UserDto;
40 import org.sonar.server.qualityprofile.ActiveRuleChange;
41 import org.sonar.server.qualityprofile.ActiveRuleInheritance;
42 import org.sonar.server.tester.UserSessionRule;
43 import org.sonar.server.ws.WsActionTester;
44
45 import static org.assertj.core.api.Assertions.assertThat;
46 import static org.sonar.test.JsonAssert.assertJson;
47 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE;
48 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_QUALITY_PROFILE;
49 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_SINCE;
50
51 public class ChangelogActionTest {
52
53   private static final String DATE = "2011-04-25T01:15:42+0100";
54
55   private TestSystem2 system2 = new TestSystem2().setNow(DateUtils.parseDateTime(DATE).getTime());
56
57   @Rule
58   public DbTester db = DbTester.create(system2);
59   @Rule
60   public UserSessionRule userSession = UserSessionRule.standalone();
61   @Rule
62   public ExpectedException expectedException = ExpectedException.none();
63
64   private QProfileWsSupport wsSupport = new QProfileWsSupport(db.getDbClient(), userSession);
65   private WsActionTester ws = new WsActionTester(new ChangelogAction(wsSupport, new Languages(), db.getDbClient()));
66
67   @Test
68   public void return_change_with_all_fields() {
69     QProfileDto profile = db.qualityProfiles().insert();
70     UserDto user = db.users().insertUser();
71     RuleDefinitionDto rule = db.rules().insert(RuleKey.of("java", "S001"));
72     insertChange(profile, ActiveRuleChange.Type.ACTIVATED, user, ImmutableMap.of(
73       "ruleUuid", rule.getUuid(),
74       "severity", "MINOR",
75       "inheritance", ActiveRuleInheritance.INHERITED.name(),
76       "param_foo", "foo_value",
77       "param_bar", "bar_value"));
78
79     String response = ws.newRequest()
80       .setParam(PARAM_LANGUAGE, profile.getLanguage())
81       .setParam(PARAM_QUALITY_PROFILE, profile.getName())
82       .execute()
83       .getInput();
84
85     assertJson(response).isSimilarTo("{\n" +
86       "  \"total\": 1,\n" +
87       "  \"p\": 1,\n" +
88       "  \"ps\": 50,\n" +
89       "  \"events\": [\n" +
90       "    {\n" +
91       "      \"date\": \"" + DATE + "\",\n" +
92       "      \"authorLogin\": \"" + user.getLogin() + "\",\n" +
93       "      \"authorName\": \"" + user.getName() + "\",\n" +
94       "      \"action\": \"ACTIVATED\",\n" +
95       "      \"ruleKey\": \"" + rule.getKey() + "\",\n" +
96       "      \"ruleName\": \"" + rule.getName() + "\",\n" +
97       "      \"params\": {\n" +
98       "        \"severity\": \"MINOR\",\n" +
99       "        \"bar\": \"bar_value\",\n" +
100       "        \"foo\": \"foo_value\"\n" +
101       "      }\n" +
102       "    }\n" +
103       "  ]\n" +
104       "}");
105   }
106
107   @Test
108   public void find_changelog_by_profile_key() {
109     QProfileDto profile = db.qualityProfiles().insert();
110     RuleDefinitionDto rule = db.rules().insert();
111     UserDto user = db.users().insertUser();
112     insertChange(profile, ActiveRuleChange.Type.ACTIVATED, user,
113       ImmutableMap.of(
114         "ruleUuid", rule.getUuid(),
115         "severity", "MINOR"));
116
117     String response = ws.newRequest()
118       .setParam(PARAM_LANGUAGE, profile.getLanguage())
119       .setParam(PARAM_QUALITY_PROFILE, profile.getName())
120       .execute()
121       .getInput();
122
123     assertJson(response).isSimilarTo("{\n" +
124       "  \"events\": [\n" +
125       "    {\n" +
126       "      \"date\": \"" + DATE + "\",\n" +
127       "      \"authorLogin\": \"" + user.getLogin() + "\",\n" +
128       "      \"action\": \"ACTIVATED\",\n" +
129       "      \"ruleKey\": \"" + rule.getKey() + "\",\n" +
130       "      \"ruleName\": \"" + rule.getName() + "\",\n" +
131       "      \"params\": {\n" +
132       "        \"severity\": \"MINOR\"\n" +
133       "      }\n" +
134       "    }\n" +
135       "  ]\n" +
136       "}");
137   }
138
139   @Test
140   public void find_changelog_by_language_and_name() {
141     QProfileDto qualityProfile = db.qualityProfiles().insert();
142     RuleDefinitionDto rule = db.rules().insert();
143     UserDto user = db.users().insertUser();
144     insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, user,
145       ImmutableMap.of(
146         "ruleUuid", rule.getUuid(),
147         "severity", "MINOR"));
148
149     String response = ws.newRequest()
150       .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
151       .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
152       .execute()
153       .getInput();
154
155     assertJson(response).isSimilarTo("{\n" +
156       "  \"events\": [\n" +
157       "    {\n" +
158       "      \"date\": \"" + DATE + "\",\n" +
159       "      \"authorLogin\": \"" + user.getLogin() + "\",\n" +
160       "      \"action\": \"ACTIVATED\",\n" +
161       "      \"ruleKey\": \"" + rule.getKey() + "\",\n" +
162       "      \"ruleName\": \"" + rule.getName() + "\",\n" +
163       "      \"params\": {\n" +
164       "        \"severity\": \"MINOR\"\n" +
165       "      }\n" +
166       "    }\n" +
167       "  ]\n" +
168       "}");
169   }
170
171   @Test
172   public void find_changelog_by_organization_and_language_and_name() {
173     QProfileDto qualityProfile = db.qualityProfiles().insert();
174     RuleDefinitionDto rule = db.rules().insert();
175     UserDto user = db.users().insertUser();
176     insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, user,
177       ImmutableMap.of(
178         "ruleUuid", rule.getUuid(),
179         "severity", "MINOR"));
180
181     String response = ws.newRequest()
182       .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
183       .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
184       .execute()
185       .getInput();
186
187     assertJson(response).isSimilarTo("{\n" +
188       "  \"events\": [\n" +
189       "    {\n" +
190       "      \"date\": \"" + DATE + "\",\n" +
191       "      \"authorLogin\": \"" + user.getLogin() + "\",\n" +
192       "      \"action\": \"ACTIVATED\",\n" +
193       "      \"ruleKey\": \"" + rule.getKey() + "\",\n" +
194       "      \"ruleName\": \"" + rule.getName() + "\",\n" +
195       "      \"params\": {\n" +
196       "        \"severity\": \"MINOR\"\n" +
197       "      }\n" +
198       "    }\n" +
199       "  ]\n" +
200       "}");
201   }
202
203   @Test
204   public void changelog_empty() {
205     QProfileDto qualityProfile = db.qualityProfiles().insert();
206
207     String response = ws.newRequest()
208       .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
209       .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
210       .execute()
211       .getInput();
212
213     assertJson(response).isSimilarTo("{\"total\":0,\"p\":1,\"ps\":50,\"events\":[]}");
214   }
215
216   @Test
217   public void changelog_filter_by_since() {
218     QProfileDto qualityProfile = db.qualityProfiles().insert();
219     system2.setNow(DateUtils.parseDateTime("2011-04-25T01:15:42+0100").getTime());
220     RuleDefinitionDto rule = db.rules().insert();
221     UserDto user = db.users().insertUser();
222     insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, user,
223       ImmutableMap.of(
224         "ruleUuid", rule.getUuid(),
225         "severity", "MINOR"));
226
227     assertJson(ws.newRequest()
228       .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
229       .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
230       .setParam(PARAM_SINCE, "2011-04-25T01:15:42+0100")
231       .execute()
232       .getInput()).isSimilarTo("{\n" +
233         "  \"events\": [\n" +
234         "    {\n" +
235         "      \"date\": \"2011-04-25T01:15:42+0100\",\n" +
236         "      \"authorLogin\": \"" + user.getLogin() + "\",\n" +
237         "      \"action\": \"ACTIVATED\",\n" +
238         "      \"ruleKey\": \"" + rule.getKey() + "\",\n" +
239         "      \"ruleName\": \"" + rule.getName() + "\",\n" +
240         "    }\n" +
241         "  ]\n" +
242         "}");
243
244     assertJson(ws.newRequest()
245       .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
246       .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
247       .setParam(PARAM_SINCE, "2011-04-25T01:15:43+0100")
248       .execute()
249       .getInput()).isSimilarTo("{\n" +
250         "  \"events\": []\n" +
251         "}");
252   }
253
254   @Test
255   public void sort_changelog_events_in_reverse_chronological_order() {
256     QProfileDto profile = db.qualityProfiles().insert();
257     system2.setNow(DateUtils.parseDateTime("2011-04-25T01:15:42+0100").getTime());
258     RuleDefinitionDto rule1 = db.rules().insert();
259     insertChange(profile, ActiveRuleChange.Type.ACTIVATED, null,
260       ImmutableMap.of(
261         "ruleUuid", rule1.getUuid(),
262         "severity", "MINOR"));
263     system2.setNow(DateUtils.parseDateTime("2011-04-25T01:15:43+0100").getTime());
264     UserDto user = db.users().insertUser();
265     RuleDefinitionDto rule2 = db.rules().insert();
266     insertChange(profile, ActiveRuleChange.Type.DEACTIVATED, user,
267       ImmutableMap.of("ruleUuid", rule2.getUuid()));
268
269     String response = ws.newRequest()
270       .setParam(PARAM_LANGUAGE, profile.getLanguage())
271       .setParam(PARAM_QUALITY_PROFILE, profile.getName())
272       .execute()
273       .getInput();
274
275     assertJson(response).isSimilarTo("{\n" +
276       "\"events\": [\n" +
277       "    {\n" +
278       "      \"date\": \"2011-04-25T02:15:43+0200\",\n" +
279       "      \"action\": \"DEACTIVATED\",\n" +
280       "      \"authorLogin\": \"" + user.getLogin() + "\",\n" +
281       "      \"ruleKey\": \"" + rule2.getKey() + "\",\n" +
282       "      \"ruleName\": \"" + rule2.getName() + "\",\n" +
283       "      \"params\": {}\n" +
284       "    },\n" +
285       "    {\n" +
286       "      \"date\": \"2011-04-25T02:15:42+0200\",\n" +
287       "      \"action\": \"ACTIVATED\",\n" +
288       "      \"ruleKey\": \"" + rule1.getKey() + "\",\n" +
289       "      \"ruleName\": \"" + rule1.getName() + "\",\n" +
290       "      \"params\": {\n" +
291       "        \"severity\": \"MINOR\"\n" +
292       "      }\n" +
293       "    }\n" +
294       "  ]" +
295       "}");
296   }
297
298   @Test
299   public void changelog_on_no_more_existing_rule() {
300     QProfileDto qualityProfile = db.qualityProfiles().insert();
301     UserDto user = db.users().insertUser();
302     insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, user,
303       ImmutableMap.of("ruleUuid", "123"));
304
305     String response = ws.newRequest()
306       .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
307       .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
308       .execute()
309       .getInput();
310
311     assertJson(response).isSimilarTo("{\n" +
312       "  \"events\": [\n" +
313       "    {\n" +
314       "      \"date\": \"" + DATE + "\",\n" +
315       "      \"action\": \"ACTIVATED\",\n" +
316       "      \"params\": {}\n" +
317       "    }\n" +
318       "  ]\n" +
319       "}");
320     assertThat(response).doesNotContain("ruleKey", "ruleName");
321   }
322
323   @Test
324   public void changelog_on_no_more_existing_user() {
325     QProfileDto qualityProfile = db.qualityProfiles().insert();
326     RuleDefinitionDto rule = db.rules().insert();
327     insertChange(c -> c.setRulesProfileUuid(qualityProfile.getRulesProfileUuid())
328       .setUserUuid("UNKNOWN")
329       .setChangeType(ActiveRuleChange.Type.ACTIVATED.name())
330       .setData(ImmutableMap.of("ruleUuid", rule.getUuid())));
331
332     String response = ws.newRequest()
333       .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
334       .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
335       .execute()
336       .getInput();
337
338     assertJson(response).isSimilarTo("{\n" +
339       "  \"events\": [\n" +
340       "    {\n" +
341       "      \"date\": \"" + DATE + "\",\n" +
342       "      \"ruleKey\": \"" + rule.getKey() + "\",\n" +
343       "      \"ruleName\": \"" + rule.getName() + "\",\n" +
344       "      \"action\": \"ACTIVATED\",\n" +
345       "      \"params\": {}\n" +
346       "    }\n" +
347       "  ]\n" +
348       "}");
349     assertThat(response).doesNotContain("authorLogin", "authorName");
350   }
351
352   @Test
353   public void example() {
354     QProfileDto profile = db.qualityProfiles().insert();
355     String profileUuid = profile.getRulesProfileUuid();
356
357     system2.setNow(DateUtils.parseDateTime("2015-02-23T17:58:39+0100").getTime());
358     RuleDefinitionDto rule1 = db.rules().insert(RuleKey.of("squid", "S2438"), r -> r.setName("\"Threads\" should not be used where \"Runnables\" are expected"));
359     UserDto user1 = db.users().insertUser(u -> u.setLogin("anakin.skywalker").setName("Anakin Skywalker"));
360     insertChange(c -> c.setRulesProfileUuid(profileUuid)
361       .setUserUuid(user1.getUuid())
362       .setChangeType(ActiveRuleChange.Type.ACTIVATED.name())
363       .setData(ImmutableMap.of("severity", "CRITICAL", "ruleUuid", rule1.getUuid())));
364
365     system2.setNow(DateUtils.parseDateTime("2015-02-23T17:58:18+0100").getTime());
366     RuleDefinitionDto rule2 = db.rules().insert(RuleKey.of("squid", "S2162"), r -> r.setName("\"equals\" methods should be symmetric and work for subclasses"));
367     UserDto user2 = db.users().insertUser(u -> u.setLogin("padme.amidala").setName("Padme Amidala"));
368     insertChange(c -> c.setRulesProfileUuid(profileUuid)
369       .setUserUuid(user2.getUuid())
370       .setChangeType(ActiveRuleChange.Type.DEACTIVATED.name())
371       .setData(ImmutableMap.of("ruleUuid", rule2.getUuid())));
372
373     system2.setNow(DateUtils.parseDateTime("2014-09-12T15:20:46+0200").getTime());
374     RuleDefinitionDto rule3 = db.rules().insert(RuleKey.of("squid", "S00101"), r -> r.setName("Class names should comply with a naming convention"));
375     UserDto user3 = db.users().insertUser(u -> u.setLogin("obiwan.kenobi").setName("Obiwan Kenobi"));
376     insertChange(c -> c.setRulesProfileUuid(profileUuid)
377       .setUserUuid(user3.getUuid())
378       .setChangeType(ActiveRuleChange.Type.ACTIVATED.name())
379       .setData(ImmutableMap.of("severity", "MAJOR", "param_format", "^[A-Z][a-zA-Z0-9]*$", "ruleUuid", rule3.getUuid())));
380
381     String response = ws.newRequest()
382       .setMethod("GET")
383       .setParam(PARAM_LANGUAGE, profile.getLanguage())
384       .setParam(PARAM_QUALITY_PROFILE, profile.getName())
385       .setParam("ps", "10")
386       .execute()
387       .getInput();
388
389     assertJson(response).isSimilarTo(getClass().getResource("changelog-example.json"));
390   }
391
392   @Test
393   public void definition() {
394     WebService.Action definition = ws.getDef();
395
396     assertThat(definition.isPost()).isFalse();
397     assertThat(definition.responseExampleAsString()).isNotEmpty();
398     assertThat(definition.params()).extracting(WebService.Param::key)
399       .containsExactlyInAnyOrder("qualityProfile", "language", "since", "to", "p", "ps");
400     WebService.Param profileName = definition.param("qualityProfile");
401     assertThat(profileName.deprecatedSince()).isNullOrEmpty();
402     WebService.Param language = definition.param("language");
403     assertThat(language.deprecatedSince()).isNullOrEmpty();
404   }
405
406   private QProfileChangeDto insertChange(QProfileDto profile, ActiveRuleChange.Type type, @Nullable UserDto user, @Nullable Map<String, Object> data) {
407     return insertChange(c -> c.setRulesProfileUuid(profile.getRulesProfileUuid())
408       .setUserUuid(user == null ? null : user.getUuid())
409       .setChangeType(type.name())
410       .setData(data));
411   }
412
413   @SafeVarargs
414   private final QProfileChangeDto insertChange(Consumer<QProfileChangeDto>... consumers) {
415     QProfileChangeDto dto = new QProfileChangeDto();
416     Arrays.stream(consumers).forEach(c -> c.accept(dto));
417     db.getDbClient().qProfileChangeDao().insert(db.getSession(), dto);
418     db.commit();
419     return dto;
420   }
421 }