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