123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500 |
- /*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
- package org.sonar.server.qualityprofile.ws;
-
- import com.google.common.collect.ImmutableMap;
- import java.util.Arrays;
- import java.util.Map;
- import java.util.function.Consumer;
- import javax.annotation.Nullable;
- import org.junit.Rule;
- import org.junit.Test;
- import org.junit.rules.ExpectedException;
- import org.sonar.api.resources.Languages;
- import org.sonar.api.rule.RuleKey;
- import org.sonar.api.server.ws.WebService;
- import org.sonar.api.utils.DateUtils;
- import org.sonar.api.utils.internal.TestSystem2;
- import org.sonar.db.DbTester;
- import org.sonar.db.organization.OrganizationDto;
- import org.sonar.db.qualityprofile.QProfileChangeDto;
- import org.sonar.db.qualityprofile.QProfileDto;
- import org.sonar.db.rule.RuleDefinitionDto;
- import org.sonar.db.user.UserDto;
- import org.sonar.server.exceptions.ForbiddenException;
- import org.sonar.server.exceptions.NotFoundException;
- import org.sonar.server.organization.TestDefaultOrganizationProvider;
- import org.sonar.server.qualityprofile.ActiveRuleChange;
- import org.sonar.server.qualityprofile.ActiveRuleInheritance;
- import org.sonar.server.tester.UserSessionRule;
- import org.sonar.server.ws.WsActionTester;
-
- import static java.lang.String.format;
- import static java.lang.String.valueOf;
- import static org.assertj.core.api.Assertions.assertThat;
- import static org.sonar.db.organization.OrganizationDto.Subscription.PAID;
- import static org.sonar.test.JsonAssert.assertJson;
- import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_KEY;
- import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE;
- import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_ORGANIZATION;
- import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_QUALITY_PROFILE;
- import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_SINCE;
-
- public class ChangelogActionTest {
-
- private static final String DATE = "2011-04-25T01:15:42+0100";
-
- private TestSystem2 system2 = new TestSystem2().setNow(DateUtils.parseDateTime(DATE).getTime());
-
- @Rule
- public DbTester db = DbTester.create(system2);
- @Rule
- public UserSessionRule userSession = UserSessionRule.standalone();
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- private QProfileWsSupport wsSupport = new QProfileWsSupport(db.getDbClient(), userSession, TestDefaultOrganizationProvider.from(db));
- private WsActionTester ws = new WsActionTester(
- new ChangelogAction(wsSupport, new Languages(), db.getDbClient()));
-
- @Test
- public void return_change_with_all_fields() {
- OrganizationDto organization = db.organizations().insert();
- QProfileDto profile = db.qualityProfiles().insert(organization);
- UserDto user = db.users().insertUser();
- RuleDefinitionDto rule = db.rules().insert(RuleKey.of("java", "S001"));
- insertChange(profile, ActiveRuleChange.Type.ACTIVATED, user, ImmutableMap.of(
- "ruleId", valueOf(rule.getId()),
- "severity", "MINOR",
- "inheritance", ActiveRuleInheritance.INHERITED.name(),
- "param_foo", "foo_value",
- "param_bar", "bar_value"));
-
- String response = ws.newRequest()
- .setParam(PARAM_KEY, profile.getKee())
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\n" +
- " \"total\": 1,\n" +
- " \"p\": 1,\n" +
- " \"ps\": 50,\n" +
- " \"events\": [\n" +
- " {\n" +
- " \"date\": \"" + DATE + "\",\n" +
- " \"authorLogin\": \"" + user.getLogin() + "\",\n" +
- " \"authorName\": \"" + user.getName() + "\",\n" +
- " \"action\": \"ACTIVATED\",\n" +
- " \"ruleKey\": \"" + rule.getKey() + "\",\n" +
- " \"ruleName\": \"" + rule.getName() + "\",\n" +
- " \"params\": {\n" +
- " \"severity\": \"MINOR\",\n" +
- " \"bar\": \"bar_value\",\n" +
- " \"foo\": \"foo_value\"\n" +
- " }\n" +
- " }\n" +
- " ]\n" +
- "}");
- }
-
- @Test
- public void find_changelog_by_profile_key() {
- OrganizationDto organization = db.organizations().insert();
- QProfileDto profile = db.qualityProfiles().insert(organization);
- RuleDefinitionDto rule = db.rules().insert();
- UserDto user = db.users().insertUser();
- insertChange(profile, ActiveRuleChange.Type.ACTIVATED, user,
- ImmutableMap.of(
- "ruleId", valueOf(rule.getId()),
- "severity", "MINOR"));
-
- String response = ws.newRequest()
- .setParam(PARAM_KEY, profile.getKee())
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\n" +
- " \"events\": [\n" +
- " {\n" +
- " \"date\": \"" + DATE + "\",\n" +
- " \"authorLogin\": \"" + user.getLogin() + "\",\n" +
- " \"action\": \"ACTIVATED\",\n" +
- " \"ruleKey\": \"" + rule.getKey() + "\",\n" +
- " \"ruleName\": \"" + rule.getName() + "\",\n" +
- " \"params\": {\n" +
- " \"severity\": \"MINOR\"\n" +
- " }\n" +
- " }\n" +
- " ]\n" +
- "}");
- }
-
- @Test
- public void find_changelog_by_language_and_name() {
- QProfileDto qualityProfile = db.qualityProfiles().insert(db.getDefaultOrganization());
- RuleDefinitionDto rule = db.rules().insert();
- UserDto user = db.users().insertUser();
- insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, user,
- ImmutableMap.of(
- "ruleId", valueOf(rule.getId()),
- "severity", "MINOR"));
-
- String response = ws.newRequest()
- .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
- .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\n" +
- " \"events\": [\n" +
- " {\n" +
- " \"date\": \"" + DATE + "\",\n" +
- " \"authorLogin\": \"" + user.getLogin() + "\",\n" +
- " \"action\": \"ACTIVATED\",\n" +
- " \"ruleKey\": \"" + rule.getKey() + "\",\n" +
- " \"ruleName\": \"" + rule.getName() + "\",\n" +
- " \"params\": {\n" +
- " \"severity\": \"MINOR\"\n" +
- " }\n" +
- " }\n" +
- " ]\n" +
- "}");
- }
-
- @Test
- public void find_changelog_by_organization_and_language_and_name() {
- OrganizationDto organization = db.organizations().insert();
- QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
- RuleDefinitionDto rule = db.rules().insert();
- UserDto user = db.users().insertUser();
- insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, user,
- ImmutableMap.of(
- "ruleId", valueOf(rule.getId()),
- "severity", "MINOR"));
-
- String response = ws.newRequest()
- .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
- .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
- .setParam(PARAM_ORGANIZATION, organization.getKey())
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\n" +
- " \"events\": [\n" +
- " {\n" +
- " \"date\": \"" + DATE + "\",\n" +
- " \"authorLogin\": \"" + user.getLogin() + "\",\n" +
- " \"action\": \"ACTIVATED\",\n" +
- " \"ruleKey\": \"" + rule.getKey() + "\",\n" +
- " \"ruleName\": \"" + rule.getName() + "\",\n" +
- " \"params\": {\n" +
- " \"severity\": \"MINOR\"\n" +
- " }\n" +
- " }\n" +
- " ]\n" +
- "}");
- }
-
- @Test
- public void changelog_empty() {
- OrganizationDto organization = db.organizations().insert();
- QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
-
- String response = ws.newRequest()
- .setParam(PARAM_KEY, qualityProfile.getKee())
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\"total\":0,\"p\":1,\"ps\":50,\"events\":[]}");
- }
-
- @Test
- public void changelog_filter_by_since() {
- OrganizationDto organization = db.organizations().insert();
- QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
- system2.setNow(DateUtils.parseDateTime("2011-04-25T01:15:42+0100").getTime());
- RuleDefinitionDto rule = db.rules().insert();
- UserDto user = db.users().insertUser();
- insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, user,
- ImmutableMap.of(
- "ruleId", valueOf(rule.getId()),
- "severity", "MINOR"));
-
- assertJson(ws.newRequest()
- .setParam(PARAM_KEY, qualityProfile.getKee())
- .setParam(PARAM_SINCE, "2011-04-25T01:15:42+0100")
- .execute()
- .getInput()).isSimilarTo("{\n" +
- " \"events\": [\n" +
- " {\n" +
- " \"date\": \"2011-04-25T01:15:42+0100\",\n" +
- " \"authorLogin\": \"" + user.getLogin() + "\",\n" +
- " \"action\": \"ACTIVATED\",\n" +
- " \"ruleKey\": \"" + rule.getKey() + "\",\n" +
- " \"ruleName\": \"" + rule.getName() + "\",\n" +
- " }\n" +
- " ]\n" +
- "}");
-
- assertJson(ws.newRequest()
- .setParam(PARAM_KEY, qualityProfile.getKee())
- .setParam(PARAM_SINCE, "2011-04-25T01:15:43+0100")
- .execute()
- .getInput()).isSimilarTo("{\n" +
- " \"events\": []\n" +
- "}");
- }
-
- @Test
- public void sort_changelog_events_in_reverse_chronological_order() {
- OrganizationDto organization = db.organizations().insert();
- QProfileDto profile = db.qualityProfiles().insert(organization);
- system2.setNow(DateUtils.parseDateTime("2011-04-25T01:15:42+0100").getTime());
- RuleDefinitionDto rule1 = db.rules().insert();
- insertChange(profile, ActiveRuleChange.Type.ACTIVATED, null,
- ImmutableMap.of(
- "ruleId", valueOf(rule1.getId()),
- "severity", "MINOR"));
- system2.setNow(DateUtils.parseDateTime("2011-04-25T01:15:43+0100").getTime());
- UserDto user = db.users().insertUser();
- RuleDefinitionDto rule2 = db.rules().insert();
- insertChange(profile, ActiveRuleChange.Type.DEACTIVATED, user,
- ImmutableMap.of("ruleId", valueOf(rule2.getId())));
-
- String response = ws.newRequest()
- .setParam(PARAM_KEY, profile.getKee())
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\n" +
- "\"events\": [\n" +
- " {\n" +
- " \"date\": \"2011-04-25T02:15:43+0200\",\n" +
- " \"action\": \"DEACTIVATED\",\n" +
- " \"authorLogin\": \"" + user.getLogin() + "\",\n" +
- " \"ruleKey\": \"" + rule2.getKey() + "\",\n" +
- " \"ruleName\": \"" + rule2.getName() + "\",\n" +
- " \"params\": {}\n" +
- " },\n" +
- " {\n" +
- " \"date\": \"2011-04-25T02:15:42+0200\",\n" +
- " \"action\": \"ACTIVATED\",\n" +
- " \"ruleKey\": \"" + rule1.getKey() + "\",\n" +
- " \"ruleName\": \"" + rule1.getName() + "\",\n" +
- " \"params\": {\n" +
- " \"severity\": \"MINOR\"\n" +
- " }\n" +
- " }\n" +
- " ]" +
- "}");
- }
-
- @Test
- public void changelog_on_no_more_existing_rule() {
- OrganizationDto organization = db.organizations().insert();
- QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
- UserDto user = db.users().insertUser();
- insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, user,
- ImmutableMap.of("ruleId", "123"));
-
- String response = ws.newRequest()
- .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
- .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
- .setParam(PARAM_ORGANIZATION, organization.getKey())
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\n" +
- " \"events\": [\n" +
- " {\n" +
- " \"date\": \"" + DATE + "\",\n" +
- " \"action\": \"ACTIVATED\",\n" +
- " \"params\": {}\n" +
- " }\n" +
- " ]\n" +
- "}");
- assertThat(response).doesNotContain("ruleKey", "ruleName");
- }
-
- @Test
- public void changelog_on_no_more_existing_user() {
- OrganizationDto organization = db.organizations().insert();
- QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
- RuleDefinitionDto rule = db.rules().insert();
- insertChange(c -> c.setRulesProfileUuid(qualityProfile.getRulesProfileUuid())
- .setUserUuid("UNKNOWN")
- .setChangeType(ActiveRuleChange.Type.ACTIVATED.name())
- .setData(ImmutableMap.of("ruleId", rule.getId())));
-
- String response = ws.newRequest()
- .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
- .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
- .setParam(PARAM_ORGANIZATION, organization.getKey())
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\n" +
- " \"events\": [\n" +
- " {\n" +
- " \"date\": \"" + DATE + "\",\n" +
- " \"ruleKey\": \"" + rule.getKey() + "\",\n" +
- " \"ruleName\": \"" + rule.getName() + "\",\n" +
- " \"action\": \"ACTIVATED\",\n" +
- " \"params\": {}\n" +
- " }\n" +
- " ]\n" +
- "}");
- assertThat(response).doesNotContain("authorLogin", "authorName");
- }
-
- @Test
- public void changelog_on_paid_organization() {
- OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addMembership(organization);
- QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
- RuleDefinitionDto rule = db.rules().insert();
- insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, db.users().insertUser(),
- ImmutableMap.of(
- "ruleId", valueOf(rule.getId()),
- "severity", "MINOR"));
-
- String response = ws.newRequest()
- .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
- .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
- .setParam(PARAM_ORGANIZATION, organization.getKey())
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo("{\n" +
- " \"events\": [\n" +
- " {\n" +
- " \"ruleKey\": \"" + rule.getKey() + "\",\n" +
- " }\n" +
- " ]\n" +
- "}");
- }
-
- @Test
- public void do_not_find_changelog_by_wrong_organization_and_language_and_name() {
- OrganizationDto organization1 = db.organizations().insert();
- OrganizationDto organization2 = db.organizations().insert();
- QProfileDto qualityProfile = db.qualityProfiles().insert(organization1);
- RuleDefinitionDto rule = db.rules().insert();
- UserDto user = db.users().insertUser();
- insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, user,
- ImmutableMap.of(
- "ruleId", valueOf(rule.getId()),
- "severity", "MINOR"));
-
- expectedException.expect(NotFoundException.class);
-
- ws.newRequest()
- .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
- .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
- .setParam(PARAM_ORGANIZATION, organization2.getKey())
- .execute();
- }
-
- @Test
- public void fail_on_paid_organization_when_not_member() {
- OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
- QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
-
- expectedException.expect(ForbiddenException.class);
- expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey()));
-
- ws.newRequest()
- .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
- .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
- .setParam(PARAM_ORGANIZATION, organization.getKey())
- .execute();
- }
-
- @Test
- public void example() {
- OrganizationDto organization = db.organizations().insert();
- QProfileDto profile = db.qualityProfiles().insert(organization);
- String profileUuid = profile.getRulesProfileUuid();
-
- system2.setNow(DateUtils.parseDateTime("2015-02-23T17:58:39+0100").getTime());
- RuleDefinitionDto rule1 = db.rules().insert(RuleKey.of("squid", "S2438"), r -> r.setName("\"Threads\" should not be used where \"Runnables\" are expected"));
- UserDto user1 = db.users().insertUser(u -> u.setLogin("anakin.skywalker").setName("Anakin Skywalker"));
- insertChange(c -> c.setRulesProfileUuid(profileUuid)
- .setUserUuid(user1.getUuid())
- .setChangeType(ActiveRuleChange.Type.ACTIVATED.name())
- .setData(ImmutableMap.of("severity", "CRITICAL", "ruleId", valueOf(rule1.getId()))));
-
- system2.setNow(DateUtils.parseDateTime("2015-02-23T17:58:18+0100").getTime());
- RuleDefinitionDto rule2 = db.rules().insert(RuleKey.of("squid", "S2162"), r -> r.setName("\"equals\" methods should be symmetric and work for subclasses"));
- UserDto user2 = db.users().insertUser(u -> u.setLogin("padme.amidala").setName("Padme Amidala"));
- QProfileChangeDto change2 = insertChange(c -> c.setRulesProfileUuid(profileUuid)
- .setUserUuid(user2.getUuid())
- .setChangeType(ActiveRuleChange.Type.DEACTIVATED.name())
- .setData(ImmutableMap.of("ruleId", valueOf(rule2.getId()))));
-
- system2.setNow(DateUtils.parseDateTime("2014-09-12T15:20:46+0200").getTime());
- RuleDefinitionDto rule3 = db.rules().insert(RuleKey.of("squid", "S00101"), r -> r.setName("Class names should comply with a naming convention"));
- UserDto user3 = db.users().insertUser(u -> u.setLogin("obiwan.kenobi").setName("Obiwan Kenobi"));
- QProfileChangeDto change3 = insertChange(c -> c.setRulesProfileUuid(profileUuid)
- .setUserUuid(user3.getUuid())
- .setChangeType(ActiveRuleChange.Type.ACTIVATED.name())
- .setData(ImmutableMap.of("severity", "MAJOR", "param_format", "^[A-Z][a-zA-Z0-9]*$", "ruleId", valueOf(rule3.getId()))));
-
- String response = ws.newRequest()
- .setMethod("GET")
- .setParam(PARAM_KEY, profile.getKee())
- .setParam("ps", "10")
- .execute()
- .getInput();
-
- assertJson(response).isSimilarTo(getClass().getResource("changelog-example.json"));
- }
-
- @Test
- public void definition() {
- WebService.Action definition = ws.getDef();
-
- assertThat(definition.isPost()).isFalse();
- assertThat(definition.responseExampleAsString()).isNotEmpty();
- assertThat(definition.params()).extracting(WebService.Param::key)
- .containsExactlyInAnyOrder("key", "qualityProfile", "language", "organization", "since", "to", "p", "ps");
- WebService.Param profileName = definition.param("qualityProfile");
- assertThat(profileName.deprecatedSince()).isNullOrEmpty();
- WebService.Param language = definition.param("language");
- assertThat(language.deprecatedSince()).isNullOrEmpty();
- }
-
- private QProfileChangeDto insertChange(QProfileDto profile, ActiveRuleChange.Type type, @Nullable UserDto user, @Nullable Map<String, Object> data) {
- return insertChange(c -> c.setRulesProfileUuid(profile.getRulesProfileUuid())
- .setUserUuid(user == null ? null : user.getUuid())
- .setChangeType(type.name())
- .setData(data));
- }
-
- @SafeVarargs
- private final QProfileChangeDto insertChange(Consumer<QProfileChangeDto>... consumers) {
- QProfileChangeDto dto = new QProfileChangeDto();
- Arrays.stream(consumers).forEach(c -> c.accept(dto));
- db.getDbClient().qProfileChangeDao().insert(db.getSession(), dto);
- db.commit();
- return dto;
- }
- }
|