"RULES_PROFILE_UUID" VARCHAR(255) NOT NULL,
"CHANGE_TYPE" VARCHAR(20) NOT NULL,
"CREATED_AT" BIGINT NOT NULL,
- "USER_LOGIN" VARCHAR(255),
+ "USER_UUID" VARCHAR(255),
"CHANGE_DATA" CLOB
);
CREATE INDEX "QP_CHANGES_RULES_PROFILE_UUID" ON "QPROFILE_CHANGES" ("RULES_PROFILE_UUID");
private String uuid;
private String rulesProfileUuid;
private String changeType;
- private String login;
+ private String userUuid;
private String data;
private long createdAt;
}
@CheckForNull
- public String getLogin() {
- return login;
+ public String getUserUuid() {
+ return userUuid;
}
- public QProfileChangeDto setLogin(@Nullable String s) {
- this.login = s;
+ public QProfileChangeDto setUserUuid(@Nullable String s) {
+ this.userUuid = s;
return this;
}
qpc.kee as "uuid",
qpc.rules_profile_uuid as rulesProfileUuid,
qpc.created_at as createdAt,
- qpc.user_login as login,
+ qpc.user_uuid as userUuid,
qpc.change_type as changeType,
qpc.change_data as data
</sql>
kee,
rules_profile_uuid,
created_at,
- user_login,
+ user_uuid,
change_type,
change_data
) values (
#{uuid, jdbcType=VARCHAR},
#{rulesProfileUuid, jdbcType=VARCHAR},
#{createdAt, jdbcType=BIGINT},
- #{login, jdbcType=VARCHAR},
+ #{userUuid, jdbcType=VARCHAR},
#{changeType, jdbcType=VARCHAR},
#{data, jdbcType=VARCHAR}
)
</select>
<select id="selectByQuery" databaseId="oracle" resultType="org.sonar.db.qualityprofile.QProfileChangeDto">
- select "uuid", rulesProfileUuid, createdAt, login, changeType, data from (
- select rownum rnum, "uuid", rulesProfileUuid, createdAt, login, changeType, data from (
+ select "uuid", rulesProfileUuid, createdAt, userUuid, changeType, data from (
+ select rownum rnum, "uuid", rulesProfileUuid, createdAt, userUuid, changeType, data from (
select <include refid="selectColumns" />
<include refid="sqlSelectByQuery" />
order by qpc.created_at desc
@Test
public void insert() {
- QProfileChangeDto dto = insertChange("P1", "ACTIVATED", "marcel", "some_data");
+ QProfileChangeDto dto = insertChange("P1", "ACTIVATED", "marcel_uuid", "some_data");
verifyInserted(dto);
}
assertThat(reloaded.getUuid()).isEqualTo(dto.getUuid());
assertThat(reloaded.getChangeType()).isEqualTo(dto.getChangeType());
assertThat(reloaded.getData()).isEqualTo(dto.getData());
- assertThat(reloaded.getLogin()).isEqualTo(dto.getLogin());
+ assertThat(reloaded.getUserUuid()).isEqualTo(dto.getUserUuid());
assertThat(reloaded.getRulesProfileUuid()).isEqualTo(dto.getRulesProfileUuid());
assertThat(reloaded.getCreatedAt()).isPositive();
}
assertThat(result).hasSize(1);
QProfileChangeDto change = result.get(0);
assertThat(change.getRulesProfileUuid()).isEqualTo(inserted.getRulesProfileUuid());
- assertThat(change.getLogin()).isEqualTo(inserted.getLogin());
+ assertThat(change.getUserUuid()).isEqualTo(inserted.getUserUuid());
assertThat(change.getData()).isEqualTo(inserted.getData());
assertThat(change.getChangeType()).isEqualTo(inserted.getChangeType());
assertThat(change.getUuid()).isEqualTo(inserted.getUuid());
return insertChange(profile.getRulesProfileUuid(), type, login, data);
}
- private QProfileChangeDto insertChange(String rulesProfileUuid, String type, @Nullable String login, @Nullable String data) {
+ private QProfileChangeDto insertChange(String rulesProfileUuid, String type, @Nullable String userUuid, @Nullable String data) {
QProfileChangeDto dto = new QProfileChangeDto()
.setRulesProfileUuid(rulesProfileUuid)
- .setLogin(login)
+ .setUserUuid(userUuid)
.setChangeType(type)
.setData(data);
underTest.insert(dbSession, dto);
private QProfileChangeDto selectChangeByUuid(String uuid) {
Map<String, Object> map = db.selectFirst(dbSession,
- "select kee as \"uuid\", rules_profile_uuid as \"rulesProfileUuid\", created_at as \"createdAt\", user_login as \"login\", change_type as \"changeType\", change_data as \"changeData\" from qprofile_changes where kee='"
+ "select kee as \"uuid\", rules_profile_uuid as \"rulesProfileUuid\", created_at as \"createdAt\", user_uuid as \"userUuid\", change_type as \"changeType\", change_data as \"changeData\" from qprofile_changes where kee='"
+ uuid + "'");
return new QProfileChangeDto()
.setUuid((String) map.get("uuid"))
.setRulesProfileUuid((String) map.get("rulesProfileUuid"))
.setCreatedAt((long) map.get("createdAt"))
- .setLogin((String) map.get("login"))
+ .setUserUuid((String) map.get("userUuid"))
.setChangeType((String) map.get("changeType"))
.setData((String) map.get("changeData"));
}
.setRulesProfileUuid(randomAlphanumeric(40))
.setCreatedAt(nextLong())
.setChangeType("ACTIVATED")
- .setLogin(randomAlphanumeric(10));
+ .setUserUuid("userUuid_" + randomAlphanumeric(10));
}
/**
.add(2115, "Add ORGANIZATION_UUID on table users", AddOrganizationUuidToUsers.class)
.add(2116, "Populate ORGANIZATION_UUID in table users", PopulateOrganizationUuidOnUsers.class)
.add(2117, "Drop USER_ID from table organizations", DropUserIdFromOrganizations.class)
+ .add(2118, "Rename USER_LOGIN TO USER_UUID on table QPROFILE_CHANGES", RenameUserLoginToUserUuidOnTableQProfileChanges.class)
;
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.platform.db.migration.version.v72;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.sql.RenameColumnsBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class RenameUserLoginToUserUuidOnTableQProfileChanges extends DdlChange {
+
+ public RenameUserLoginToUserUuidOnTableQProfileChanges(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(new RenameColumnsBuilder(getDialect(), "qprofile_changes")
+ .renameColumn("user_login",
+ newVarcharColumnDefBuilder()
+ .setColumnName("user_uuid")
+ .setLimit(255)
+ .setIsNullable(true)
+ .build())
+ .build());
+ }
+}
@Test
public void verify_migration_count() {
- verifyMigrationCount(underTest, 18);
+ verifyMigrationCount(underTest, 19);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.platform.db.migration.version.v72;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.CoreDbTester;
+
+import static java.sql.Types.VARCHAR;
+
+public class RenameUserLoginToUserUuidOnTableQProfileChangesTest {
+
+ @Rule
+ public final CoreDbTester db = CoreDbTester.createForSchema(RenameUserLoginToUserUuidOnTableQProfileChangesTest.class, "qprofile_changes.sql");
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private RenameUserLoginToUserUuidOnTableQProfileChanges underTest = new RenameUserLoginToUserUuidOnTableQProfileChanges(db.database());
+
+ @Test
+ public void rename_column() throws SQLException {
+ underTest.execute();
+
+ db.assertColumnDefinition("qprofile_changes", "user_uuid", VARCHAR, 255, true);
+ db.assertColumnDoesNotExist("qprofile_changes", "user_login");
+ }
+
+ public void migration_is_not_reentrant() throws SQLException {
+ underTest.execute();
+
+ expectedException.expect(IllegalStateException.class);
+
+ underTest.execute();
+ }
+}
--- /dev/null
+CREATE TABLE "QPROFILE_CHANGES" (
+ "KEE" VARCHAR(40) NOT NULL PRIMARY KEY,
+ "RULES_PROFILE_UUID" VARCHAR(255) NOT NULL,
+ "CHANGE_TYPE" VARCHAR(20) NOT NULL,
+ "CREATED_AT" BIGINT NOT NULL,
+ "USER_LOGIN" VARCHAR(255),
+ "CHANGE_DATA" CLOB
+);
+CREATE INDEX "QP_CHANGES_RULES_PROFILE_UUID" ON "QPROFILE_CHANGES" ("RULES_PROFILE_UUID");
\ No newline at end of file
return this;
}
- public QProfileChangeDto toDto(@Nullable String login) {
+ public QProfileChangeDto toDto(@Nullable String userUuid) {
QProfileChangeDto dto = new QProfileChangeDto();
dto.setChangeType(type.name());
dto.setRulesProfileUuid(getKey().getRuleProfileUuid());
- dto.setLogin(login);
+ dto.setUserUuid(userUuid);
Map<String, String> data = new HashMap<>();
data.put("ruleId", String.valueOf(getRuleId()));
activeRule = doUpdate(change, context, dbSession);
}
change.setActiveRule(activeRule);
- db.qProfileChangeDao().insert(dbSession, change.toDto(userSession.getLogin()));
+ db.qProfileChangeDao().insert(dbSession, change.toDto(userSession.getUuid()));
}
private ActiveRuleDto doInsert(ActiveRuleChange change, RuleActivationContext context, DbSession dbSession) {
import java.util.List;
import java.util.Map;
import java.util.Objects;
-import java.util.Optional;
import java.util.Set;
import javax.annotation.CheckForNull;
import org.sonar.api.resources.Languages;
-import org.sonar.api.rule.RuleKey;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService.NewAction;
import static org.sonar.api.utils.DateUtils.parseEndingDateOrDateTime;
import static org.sonar.api.utils.DateUtils.parseStartingDateOrDateTime;
+import static org.sonar.core.util.stream.MoreCollectors.toSet;
+import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex;
import static org.sonar.server.es.SearchOptions.MAX_LIMIT;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_SINCE;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_TO;
int total = dbClient.qProfileChangeDao().countByQuery(dbSession, query);
List<Change> changelogs = load(dbSession, query);
- writeResponse(response.newJsonWriter(), total, page, pageSize, changelogs);
+ Map<String, UserDto> usersByUuid = getUsersByUserUuid(dbSession, changelogs);
+ Map<Integer, RuleDefinitionDto> rulesByRuleIds = getRulesByRuleIds(dbSession, changelogs);
+ writeResponse(response.newJsonWriter(), total, page, pageSize, changelogs, usersByUuid, rulesByRuleIds);
}
}
- private static void writeResponse(JsonWriter json, int total, int page, int pageSize, List<Change> changelogs) {
+ private Map<String, UserDto> getUsersByUserUuid(DbSession dbSession, List<Change> changes) {
+ Set<String> userUuids = changes.stream()
+ .map(Change::getUserUuid)
+ .filter(Objects::nonNull)
+ .collect(toSet());
+ return dbClient.userDao()
+ .selectByUuids(dbSession, userUuids)
+ .stream()
+ .collect(uniqueIndex(UserDto::getUuid));
+ }
+
+ private Map<Integer, RuleDefinitionDto> getRulesByRuleIds(DbSession dbSession, List<Change> changes) {
+ Set<Integer> ruleIds = changes.stream()
+ .map(c -> c.ruleId)
+ .filter(Objects::nonNull)
+ .collect(toSet());
+ return dbClient.ruleDao()
+ .selectDefinitionByIds(dbSession, Lists.newArrayList(ruleIds))
+ .stream()
+ .collect(uniqueIndex(RuleDefinitionDto::getId));
+ }
+
+ private static void writeResponse(JsonWriter json, int total, int page, int pageSize, List<Change> changelogs,
+ Map<String, UserDto> usersByUuid, Map<Integer, RuleDefinitionDto> rulesByRuleIds) {
json.beginObject();
json.prop("total", total);
json.prop(Param.PAGE, page);
json.prop(Param.PAGE_SIZE, pageSize);
json.name("events").beginArray();
- for (Change change : changelogs) {
- json.beginObject()
+ changelogs.forEach(change -> {
+ JsonWriter changeWriter = json.beginObject();
+ changeWriter
.prop("date", DateUtils.formatDateTime(change.getCreatedAt()))
- .prop("authorLogin", change.getUserLogin())
- .prop("authorName", change.getUserName())
- .prop("action", change.getType())
- .prop("ruleKey", change.getRuleKey().map(RuleKey::toString).orElse(null))
- .prop("ruleName", change.getRuleName().orElse(null));
+ .prop("action", change.getType());
+ UserDto user = usersByUuid.get(change.getUserUuid());
+ if (user != null) {
+ changeWriter
+ .prop("authorLogin", user.getLogin())
+ .prop("authorName", user.getName());
+ }
+ RuleDefinitionDto rule = rulesByRuleIds.get(change.getRuleId());
+ if (rule != null) {
+ changeWriter
+ .prop("ruleKey", rule.getKey().toString())
+ .prop("ruleName", rule.getName());
+ }
writeParameters(json, change);
json.endObject();
- }
+ });
json.endArray();
json.endObject().close();
}
* @return non-null list of changes, by descending order of date
*/
public List<Change> load(DbSession dbSession, QProfileChangeQuery query) {
- List<QProfileChangeDto> dtos = dbClient.qProfileChangeDao().selectByQuery(dbSession, query);
- List<Change> changes = dtos.stream()
+ List<QProfileChangeDto> changeDtos = dbClient.qProfileChangeDao().selectByQuery(dbSession, query);
+ return changeDtos.stream()
.map(Change::from)
- .collect(MoreCollectors.toList(dtos.size()));
- completeUserAndRuleNames(dbSession, changes);
- return changes;
- }
-
- private void completeUserAndRuleNames(DbSession dbSession, List<Change> changes) {
- Set<String> logins = changes.stream().filter(c -> c.userLogin != null).map(c -> c.userLogin).collect(MoreCollectors.toSet());
- Map<String, String> userNamesByLogins = dbClient.userDao()
- .selectByLogins(dbSession, logins)
- .stream()
- .collect(java.util.stream.Collectors.toMap(UserDto::getLogin, UserDto::getName));
-
- Set<Integer> ruleIds = changes.stream()
- .map(c -> c.ruleId)
- .filter(Objects::nonNull)
- .collect(MoreCollectors.toSet());
- Map<Integer, RuleDefinitionDto> ruleDefinitionsById = dbClient.ruleDao()
- .selectDefinitionByIds(dbSession, Lists.newArrayList(ruleIds))
- .stream()
- .collect(MoreCollectors.uniqueIndex(RuleDefinitionDto::getId));
-
- changes.forEach(c -> {
- c.userName = userNamesByLogins.get(c.userLogin);
- RuleDefinitionDto ruleDefinitionDto = ruleDefinitionsById.get(c.ruleId);
- if (ruleDefinitionDto != null) {
- c.ruleKey = ruleDefinitionDto.getKey();
- c.ruleName = ruleDefinitionDto.getName();
- }
- });
+ .collect(MoreCollectors.toList(changeDtos.size()));
}
static class Change {
private String type;
private long at;
private String severity;
- private String userLogin;
- private String userName;
+ private String userUuid;
private String inheritance;
private Integer ruleId;
- private RuleKey ruleKey;
- private String ruleName;
private final Map<String, String> params = new HashMap<>();
private Change() {
}
@CheckForNull
- public String getUserLogin() {
- return userLogin;
- }
-
- @CheckForNull
- public String getUserName() {
- return userName;
+ public String getUserUuid() {
+ return userUuid;
}
public String getType() {
return inheritance;
}
- public Optional<Integer> getRuleId() {
- return Optional.ofNullable(ruleId);
- }
-
- public Optional<RuleKey> getRuleKey() {
- return Optional.ofNullable(ruleKey);
- }
-
- public Optional<String> getRuleName() {
- return Optional.ofNullable(ruleName);
+ @CheckForNull
+ public Integer getRuleId() {
+ return ruleId;
}
public long getCreatedAt() {
Map<String, String> data = dto.getDataAsMap();
Change change = new Change();
change.key = dto.getUuid();
- change.userLogin = dto.getLogin();
+ change.userUuid = dto.getUserUuid();
change.type = dto.getChangeType();
change.at = dto.getCreatedAt();
// see content of data in class org.sonar.server.qualityprofile.ActiveRuleChange
public class ActiveRuleChangeTest {
- private static final String A_LOGIN = "A_LOGIN";
+ private static final String A_USER_UUID = "A_USER_UUID";
@Test
public void toDto() {
int ruleId = new Random().nextInt(963);
ActiveRuleChange underTest = new ActiveRuleChange(ACTIVATED, key, new RuleDefinitionDto().setId(ruleId));
- QProfileChangeDto result = underTest.toDto(A_LOGIN);
+ QProfileChangeDto result = underTest.toDto(A_USER_UUID);
assertThat(result.getChangeType()).isEqualTo(ACTIVATED.name());
assertThat(result.getRulesProfileUuid()).isEqualTo(profile.getRulesProfileUuid());
- assertThat(result.getLogin()).isEqualTo(A_LOGIN);
+ assertThat(result.getUserUuid()).isEqualTo(A_USER_UUID);
assertThat(result.getDataAsMap().get("ruleId")).isEqualTo(String.valueOf(ruleId));
}
}
assertThat(change.getChangeType()).isEqualTo(ActiveRuleChange.Type.ACTIVATED.name());
assertThat(change.getCreatedAt()).isPositive();
assertThat(change.getUuid()).isNotEmpty();
- assertThat(change.getLogin()).isNull();
+ assertThat(change.getUserUuid()).isNull();
assertThat(change.getRulesProfileUuid()).isEqualTo(profile.getRulesProfileUuid());
assertThat(change.getDataAsMap().get("severity")).isEqualTo(expectedSeverity);
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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;
+
+import com.google.common.collect.ImmutableMap;
+import java.util.Collections;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.qualityprofile.ActiveRuleDto;
+import org.sonar.db.qualityprofile.QProfileChangeDto;
+import org.sonar.db.qualityprofile.QProfileChangeQuery;
+import org.sonar.db.qualityprofile.QProfileDto;
+import org.sonar.db.rule.RuleDefinitionDto;
+import org.sonar.db.user.UserDto;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
+import org.sonar.server.rule.index.RuleIndex;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.util.IntegerTypeValidation;
+import org.sonar.server.util.TypeValidations;
+
+import static java.util.Collections.singleton;
+import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+
+public class QProfileRulesImplTest {
+
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+ @Rule
+ public DbTester db = DbTester.create();
+ @Rule
+ public EsTester es = EsTester.create();
+
+ private RuleIndex ruleIndex = new RuleIndex(es.client(), System2.INSTANCE);
+ private ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(db.getDbClient(), es.client());
+ private RuleActivator ruleActivator = new RuleActivator(System2.INSTANCE, db.getDbClient(), new TypeValidations(singletonList(new IntegerTypeValidation())), userSession);
+
+ private QProfileRules qProfileRules = new QProfileRulesImpl(db.getDbClient(), ruleActivator, ruleIndex, activeRuleIndexer);
+
+ @Test
+ public void activate_one_rule() {
+ OrganizationDto organization = db.organizations().insert();
+ QProfileDto qProfile = db.qualityProfiles().insert(organization);
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage(qProfile.getLanguage()));
+ RuleActivation ruleActivation = RuleActivation.create(rule.getId(), Severity.CRITICAL, Collections.emptyMap());
+
+ qProfileRules.activateAndCommit(db.getSession(), qProfile, singleton(ruleActivation));
+
+ assertThat(db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), qProfile))
+ .extracting(ActiveRuleDto::getRuleKey, ActiveRuleDto::getSeverityString)
+ .containsExactlyInAnyOrder(tuple(rule.getKey(), Severity.CRITICAL));
+ }
+
+ @Test
+ public void active_rule_change() {
+ UserDto user = db.users().insertUser();
+ userSession.logIn(user);
+ OrganizationDto organization = db.organizations().insert();
+ QProfileDto qProfile = db.qualityProfiles().insert(organization);
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage(qProfile.getLanguage()));
+ RuleActivation ruleActivation = RuleActivation.create(rule.getId(), Severity.CRITICAL, Collections.emptyMap());
+
+ qProfileRules.activateAndCommit(db.getSession(), qProfile, singleton(ruleActivation));
+
+ assertThat(db.getDbClient().qProfileChangeDao().selectByQuery(db.getSession(), new QProfileChangeQuery(qProfile.getKee())))
+ .extracting(QProfileChangeDto::getUserUuid, QProfileChangeDto::getDataAsMap)
+ .containsExactlyInAnyOrder(tuple(user.getUuid(), ImmutableMap.of("ruleId", Integer.toString(rule.getId()), "severity", Severity.CRITICAL)));
+ }
+}
import java.util.Map;
import java.util.function.Consumer;
import javax.annotation.Nullable;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.internal.TestSystem2;
-import org.sonar.db.DbSession;
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.qualityprofile.QualityProfileTesting;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.organization.DefaultOrganizationProvider;
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.TestRequest;
import org.sonar.server.ws.WsActionTester;
-import org.sonar.test.JsonAssert;
import static java.lang.String.valueOf;
import static org.assertj.core.api.Assertions.assertThat;
public class ChangelogActionTest {
- private TestSystem2 system2 = new TestSystem2().setNow(1_500_000_000_000L);
+ private static final String DATE = "2011-04-25T01:15:42+0100";
+
+ private TestSystem2 system2 = new TestSystem2().setNow(DateUtils.parseDateTime(DATE).getTime());
@Rule
- public DbTester dbTester = DbTester.create(system2);
+ public DbTester db = DbTester.create(system2);
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
@Rule
public ExpectedException thrown = ExpectedException.none();
- private WsActionTester ws;
- private QProfileWsSupport wsSupport;
- private OrganizationDto organization;
- private DefaultOrganizationProvider defaultOrganizationProvider;
-
- @Before
- public void before() {
- system2.setNow(DateUtils.parseDateTime("2011-04-25T01:15:42+0100").getTime());
- defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);
- wsSupport = new QProfileWsSupport(dbTester.getDbClient(), userSession, defaultOrganizationProvider);
- ws = new WsActionTester(
- new ChangelogAction(wsSupport, new Languages(), dbTester.getDbClient()));
- organization = dbTester.organizations().insert();
- }
+ 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 definition() {
@Test
public void example() {
- QProfileDto profile = dbTester.qualityProfiles().insert(organization);
+ 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 = dbTester.rules().insert(RuleKey.of("squid", "S2438"), r -> r.setName("\"Threads\" should not be used where \"Runnables\" are expected"));
- UserDto user1 = dbTester.users().insertUser(u -> u.setLogin("anakin.skywalker").setName("Anakin Skywalker"));
- insertChange(profile, c -> c.setRulesProfileUuid(profileUuid)
- .setLogin(user1.getLogin())
+ 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 = dbTester.rules().insert(RuleKey.of("squid", "S2162"), r -> r.setName("\"equals\" methods should be symmetric and work for subclasses"));
- UserDto user2 = dbTester.users().insertUser(u -> u.setLogin("padme.amidala").setName("Padme Amidala"));
- QProfileChangeDto change2 = insertChange(profile, c -> c.setRulesProfileUuid(profileUuid)
- .setLogin(user2.getLogin())
+ 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 = dbTester.rules().insert(RuleKey.of("squid", "S00101"), r -> r.setName("Class names should comply with a naming convention"));
- UserDto user3 = dbTester.users().insertUser(u -> u.setLogin("obiwan.kenobi").setName("Obiwan Kenobi"));
- QProfileChangeDto change3 = insertChange(profile, c -> c.setRulesProfileUuid(profileUuid)
- .setLogin(user3.getLogin())
+ 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()))));
- dbTester.commit();
-
String response = ws.newRequest()
.setMethod("GET")
.setParam(PARAM_KEY, profile.getKee())
}
@Test
- public void find_changelog_by_profile_key() {
- QProfileDto profile = dbTester.qualityProfiles().insert(organization);
+ 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()
.setMethod("GET")
.execute()
.getInput();
- assertThat(response).isNotEmpty();
+ 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_language_and_name() {
- QProfileDto qualityProfile = dbTester.qualityProfiles().insert(dbTester.getDefaultOrganization());
+ 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()
.setMethod("GET")
- .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
- .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
+ .setParam(PARAM_KEY, profile.getKee())
.execute()
.getInput();
- assertThat(response).isNotEmpty();
+ 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() {
- QProfileDto qualityProfile = dbTester.qualityProfiles().insert(organization);
+ 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()
.setMethod("GET")
.setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
.setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
- .setParam(PARAM_ORGANIZATION, organization.getKey())
.execute()
.getInput();
- assertThat(response).isNotEmpty();
+ 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 do_not_find_changelog_by_wrong_organization_and_language_and_name() {
- OrganizationDto organization1 = dbTester.organizations().insert();
- OrganizationDto organization2 = dbTester.organizations().insert();
-
- QProfileDto qualityProfile = dbTester.qualityProfiles().insert(organization1);
+ 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"));
- TestRequest request = ws.newRequest()
+ String response = ws.newRequest()
.setMethod("GET")
.setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
.setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
- .setParam(PARAM_ORGANIZATION, organization2.getKey());
-
- thrown.expect(NotFoundException.class);
-
- request.execute();
- }
-
- @Test
- public void changelog_empty() {
- QProfileDto qualityProfile = dbTester.qualityProfiles().insert(organization);
-
- String response = ws.newRequest()
- .setMethod("GET")
- .setParam(PARAM_KEY, qualityProfile.getKee())
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
.execute()
.getInput();
- assertThat(response).contains("\"total\":0");
- assertThat(response).contains("\"events\":[]");
+ 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_not_empty() {
- QProfileDto qualityProfile = dbTester.qualityProfiles().insert(organization);
- QProfileChangeDto change = QualityProfileTesting.newQProfileChangeDto()
- .setUuid(null)
- .setCreatedAt(0)
- .setRulesProfileUuid(qualityProfile.getRulesProfileUuid());
- DbSession session = dbTester.getSession();
- dbTester.getDbClient().qProfileChangeDao().insert(session, change);
- session.commit();
+ public void changelog_empty() {
+ OrganizationDto organization = db.organizations().insert();
+ QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
String response = ws.newRequest()
.setMethod("GET")
.execute()
.getInput();
- assertThat(response).contains("\"total\":1");
+ assertJson(response).isSimilarTo("{\"total\":0,\"p\":1,\"ps\":50,\"events\":[]}");
}
@Test
public void changelog_filter_by_since() {
- QProfileDto qualityProfile = dbTester.qualityProfiles().insert(organization);
+ OrganizationDto organization = db.organizations().insert();
+ QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
system2.setNow(DateUtils.parseDateTime("2011-04-25T01:15:42+0100").getTime());
- QProfileChangeDto change = QualityProfileTesting.newQProfileChangeDto()
- .setUuid(null)
- .setCreatedAt(0)
- .setRulesProfileUuid(qualityProfile.getRulesProfileUuid());
- DbSession session = dbTester.getSession();
- dbTester.getDbClient().qProfileChangeDao().insert(session, change);
- session.commit();
-
- String response = ws.newRequest()
+ 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()
.setMethod("GET")
.setParam(PARAM_KEY, qualityProfile.getKee())
.setParam(PARAM_SINCE, "2011-04-25T01:15:42+0100")
.execute()
- .getInput();
-
- assertThat(response).contains("\"total\":1");
-
- String response2 = ws.newRequest()
+ .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()
.setMethod("GET")
.setParam(PARAM_KEY, qualityProfile.getKee())
.setParam(PARAM_SINCE, "2011-04-25T01:15:43+0100")
.execute()
- .getInput();
-
- assertThat(response2).contains("\"total\":0");
+ .getInput()).isSimilarTo("{\n" +
+ " \"events\": []\n" +
+ "}");
}
@Test
public void sort_changelog_events_in_reverse_chronological_order() {
- QProfileDto profile = dbTester.qualityProfiles().insert(organization);
+ OrganizationDto organization = db.organizations().insert();
+ QProfileDto profile = db.qualityProfiles().insert(organization);
system2.setNow(DateUtils.parseDateTime("2011-04-25T01:15:42+0100").getTime());
- QProfileChangeDto change1 = insertChange(profile, ActiveRuleChange.Type.ACTIVATED, null, null);
+ 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());
- QProfileChangeDto change2 = insertChange(profile, ActiveRuleChange.Type.DEACTIVATED, "mazout", null);
- dbTester.commit();
+ 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()
.setMethod("GET")
.execute()
.getInput();
- assertThat(response).containsSubsequence("15:43", "15:42");
+ 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 return_change_with_all_fields() {
- QProfileDto profile = dbTester.qualityProfiles().insert(organization);
- RuleDefinitionDto rule1 = dbTester.rules().insert(RuleKey.of("java", "S001"));
+ 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"));
- Map<String, Object> data = ImmutableMap.of(
- "ruleId", valueOf(rule1.getId()),
- "severity", "MINOR",
- "inheritance", ActiveRuleInheritance.INHERITED.name(),
- "param_foo", "foo_value",
- "param_bar", "bar_value");
- QProfileChangeDto change = insertChange(profile, ActiveRuleChange.Type.ACTIVATED, "theLogin", data);
- dbTester.commit();
+ String response = ws.newRequest()
+ .setMethod("GET")
+ .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()
.setMethod("GET")
- .setParam(PARAM_KEY, profile.getKee())
+ .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
+ .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
+ .setParam(PARAM_ORGANIZATION, organization.getKey())
.execute()
.getInput();
- JsonAssert.assertJson(response).isSimilarTo("{\n" +
- " \"total\": 1,\n" +
- " \"p\": 1,\n" +
- " \"ps\": 50,\n" +
+ assertJson(response).isSimilarTo("{\n" +
" \"events\": [\n" +
" {\n" +
- " \"date\": \"2011-04-25T02:15:42+0200\",\n" +
- " \"authorLogin\": \"theLogin\",\n" +
+ " \"date\": \"" + DATE + "\",\n" +
+ " \"ruleKey\": \"" + rule.getKey() + "\",\n" +
+ " \"ruleName\": \"" + rule.getName() + "\",\n" +
" \"action\": \"ACTIVATED\",\n" +
- " \"ruleKey\": \"java:S001\",\n" +
- " \"params\": {\n" +
- " \"severity\": \"MINOR\",\n" +
- " \"bar\": \"bar_value\",\n" +
- " \"foo\": \"foo_value\"\n" +
- " }\n" +
+ " \"params\": {}\n" +
" }\n" +
" ]\n" +
"}");
+ assertThat(response).doesNotContain("authorLogin", "authorName");
+ }
+
+ @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"));
+
+ thrown.expect(NotFoundException.class);
+
+ ws.newRequest()
+ .setMethod("GET")
+ .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
+ .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
+ .setParam(PARAM_ORGANIZATION, organization2.getKey())
+ .execute();
}
- private QProfileChangeDto insertChange(QProfileDto profile, ActiveRuleChange.Type type, @Nullable String login, @Nullable Map<String, Object> data) {
- return insertChange(profile, c -> c.setRulesProfileUuid(profile.getRulesProfileUuid())
- .setLogin(login)
+ 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));
}
- private QProfileChangeDto insertChange(QProfileDto profile, Consumer<QProfileChangeDto>... consumers) {
+ @SafeVarargs
+ private final QProfileChangeDto insertChange(Consumer<QProfileChangeDto>... consumers) {
QProfileChangeDto dto = new QProfileChangeDto();
Arrays.stream(consumers).forEach(c -> c.accept(dto));
- dbTester.getDbClient().qProfileChangeDao().insert(dbTester.getSession(), dto);
+ db.getDbClient().qProfileChangeDao().insert(db.getSession(), dto);
+ db.commit();
return dto;
}
}
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
-import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.sonarqube.qa.util.Tester;
import org.sonarqube.tests.Category6Suite;
import org.sonarqube.ws.Qualityprofiles.ShowResponse;
import org.sonarqube.ws.Qualityprofiles.ShowResponse.CompareToSonarWay;
import org.sonarqube.ws.Qualityprofiles.ShowResponse.QualityProfile;
+import org.sonarqube.ws.Users.CreateWsResponse.User;
import org.sonarqube.ws.client.GetRequest;
import org.sonarqube.ws.client.PostRequest;
import org.sonarqube.ws.client.WsResponse;
+import org.sonarqube.ws.client.permissions.AddUserRequest;
import org.sonarqube.ws.client.qualityprofiles.ChangelogRequest;
import org.sonarqube.ws.client.qualityprofiles.SearchRequest;
import org.sonarqube.ws.client.qualityprofiles.ShowRequest;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.skyscreamer.jsonassert.JSONAssert.assertEquals;
public class QualityProfilesWsTest {
private static final String RULE_ONE_BUG_PER_LINE = "xoo:OneBugIssuePerLine";
private static final String RULE_ONE_ISSUE_PER_LINE = "xoo:OneIssuePerLine";
- private static final String EXPECTED_CHANGELOG = "{\"total\":2,\"p\":1,\"ps\":50,\"events\":[" +
- "{\"authorLogin\":\"admin\",\"authorName\":\"Administrator\",\"action\":\"ACTIVATED\",\"ruleKey\":\"xoo:OneIssuePerLine\",\"ruleName\":\"One Issue Per Line\",\"params\":{\"severity\":\"MAJOR\"}}," +
- "{\"authorLogin\":\"admin\",\"authorName\":\"Administrator\",\"action\":\"ACTIVATED\",\"ruleKey\":\"xoo:OneBugIssuePerLine\",\"ruleName\":\"One Bug Issue Per Line\",\"params\":{\"severity\":\"MAJOR\"}}" +
- "]}";
- private static final String EXPECTED_CHANGELOG_EMPTY = "{\"total\":0,\"p\":1,\"ps\":50,\"events\":[]}";
-
@ClassRule
public static Orchestrator orchestrator = Category6Suite.ORCHESTRATOR;
assertThat(tester.qProfiles().service().show(new ShowRequest()
.setKey(xooProfile.getKey())
.setCompareToSonarWay("true")).getCompareToSonarWay())
- .extracting(CompareToSonarWay::getProfile, CompareToSonarWay::getProfileName, CompareToSonarWay::getMissingRuleCount)
- .containsExactly(sonarWay.getKey(), sonarWay.getName(), 0L);
+ .extracting(CompareToSonarWay::getProfile, CompareToSonarWay::getProfileName, CompareToSonarWay::getMissingRuleCount)
+ .containsExactly(sonarWay.getKey(), sonarWay.getName(), 0L);
}
@Test
// Check 'name' parameter is taken into account
assertThat(tester.wsClient().wsConnector()
.call(new GetRequest("profiles/export?language=xoo&qualityProfile=empty&format=XooFakeExporter")).content())
- .isEqualTo("xoo -> empty -> 0");
+ .isEqualTo("xoo -> empty -> 0");
}
@Test
.setOrganization(org.getKey())
.setLanguage(profile.getLanguage())
.setQualityProfile(profile.getName()));
- JSONAssert.assertEquals(EXPECTED_CHANGELOG_EMPTY, changelog, JSONCompareMode.STRICT);
+ assertEquals("{\"total\":0,\"p\":1,\"ps\":50,\"events\":[]}",
+ changelog, JSONCompareMode.STRICT);
+ User user = tester.users().generateMember(org);
+ tester.permissions().service().addUser(new AddUserRequest().setOrganization(org.getKey()).setLogin(user.getLogin()).setPermission("profileadmin"));
+ tester.as(user.getLogin()).qProfiles().activateRule(profile, RULE_ONE_ISSUE_PER_LINE);
tester.qProfiles().activateRule(profile, RULE_ONE_BUG_PER_LINE);
- tester.qProfiles().activateRule(profile, RULE_ONE_ISSUE_PER_LINE);
String changelog2 = tester.wsClient().qualityprofiles().changelog(new ChangelogRequest()
.setOrganization(org.getKey())
.setLanguage(profile.getLanguage())
.setQualityProfile(profile.getName()));
- JSONAssert.assertEquals(EXPECTED_CHANGELOG, changelog2, JSONCompareMode.LENIENT);
+ assertEquals("{\"total\":2,\"p\":1,\"ps\":50,\"events\":[" +
+ "{\"authorLogin\":\"" + user.getLogin() + "\",\"authorName\":\"" + user.getName() + "\"," +
+ "\"action\":\"ACTIVATED\"," +
+ "\"ruleKey\":\"xoo:OneIssuePerLine\",\"ruleName\":\"One Issue Per Line\"," +
+ "\"params\":{\"severity\":\"MAJOR\"}}," +
+ "{\"authorLogin\":\"admin\",\"authorName\":\"Administrator\"," +
+ "\"action\":\"ACTIVATED\"," +
+ "\"ruleKey\":\"xoo:OneBugIssuePerLine\",\"ruleName\":\"One Bug Issue Per Line\"," +
+ "\"params\":{\"severity\":\"MAJOR\"}}" + "]}",
+ changelog2, JSONCompareMode.LENIENT);
String changelog3 = tester.wsClient().qualityprofiles().changelog(new ChangelogRequest()
.setOrganization(org.getKey())
.setLanguage(profile.getLanguage())
.setQualityProfile(profile.getName())
.setSince("2999-12-31T23:59:59+0000"));
- JSONAssert.assertEquals(EXPECTED_CHANGELOG_EMPTY, changelog3, JSONCompareMode.STRICT);
+ assertEquals("{\"total\":0,\"p\":1,\"ps\":50,\"events\":[]}",
+ changelog3, JSONCompareMode.STRICT);
}
private SearchWsResponse.QualityProfile getProfile(Organization organization, Predicate<SearchWsResponse.QualityProfile> filter) {
import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.SonarScanner;
import java.util.List;
+import org.json.JSONException;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.sonarqube.qa.util.Tester;
+import org.sonarqube.qa.util.TesterSession;
import org.sonarqube.ws.Issues;
import org.sonarqube.ws.Issues.Issue;
import org.sonarqube.ws.Organizations.Organization;
import org.sonarqube.ws.client.issues.AssignRequest;
import org.sonarqube.ws.client.organizations.AddMemberRequest;
import org.sonarqube.ws.client.organizations.SearchRequest;
+import org.sonarqube.ws.client.qualityprofiles.ChangelogRequest;
import org.sonarqube.ws.client.settings.SetRequest;
import org.sonarqube.ws.client.settings.ValuesRequest;
+import org.sonarqube.ws.client.usertokens.GenerateRequest;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.skyscreamer.jsonassert.JSONAssert.assertEquals;
import static util.ItUtils.projectDir;
public class SonarCloudUpdateLoginDuringAuthenticationTest {
.containsExactlyInAnyOrder(newLogin);
}
+ @Test
+ public void qprofile_changes_after_login_update() throws JSONException {
+ tester.settings().setGlobalSettings("sonar.organizations.anyoneCanCreate", "true");
+ String providerId = tester.users().generateProviderId();
+ String oldLogin = tester.users().generateLogin();
+ authenticate(oldLogin, providerId);
+
+ // Activate a rule on a new quality profile
+ String userToken = tester.wsClient().userTokens().generate(new GenerateRequest().setLogin(oldLogin).setName("token")).getToken();
+ TesterSession userSession = tester.as(userToken, null);
+ Organization organization = userSession.organizations().generate();
+ Qualityprofiles.CreateWsResponse.QualityProfile qProfile = userSession.qProfiles().createXooProfile(organization);
+ userSession.qProfiles().activateRule(qProfile, "xoo:OneIssuePerLine");
+
+ // Check changelog contain user login
+ String changelog = tester.qProfiles().service().changelog(new ChangelogRequest()
+ .setOrganization(organization.getKey())
+ .setQualityProfile(qProfile.getName())
+ .setLanguage(qProfile.getLanguage()));
+ assertEquals(
+ "{\n" +
+ " \"events\": [\n" +
+ " {\n" +
+ " \"ruleKey\": \"xoo:OneIssuePerLine\",\n" +
+ " \"authorLogin\": \"" + oldLogin + "\",\n" +
+ " \"action\": \"ACTIVATED\"\n" +
+ " }\n" +
+ " ]\n" +
+ "}",
+ changelog,
+ false);
+
+ // Update login during authentication, check changelog contains new user login
+ String newLogin = tester.users().generateLogin();
+ authenticate(newLogin, providerId);
+ String changelogReloaded = tester.qProfiles().service().changelog(new ChangelogRequest()
+ .setOrganization(organization.getKey())
+ .setQualityProfile(qProfile.getName())
+ .setLanguage(qProfile.getLanguage()));
+ assertEquals(
+ "{\n" +
+ " \"events\": [\n" +
+ " {\n" +
+ " \"ruleKey\": \"xoo:OneIssuePerLine\",\n" +
+ " \"authorLogin\": \"" + newLogin + "\",\n" +
+ " \"action\": \"ACTIVATED\"\n" +
+ " }\n" +
+ " ]\n" +
+ "}",
+ changelogReloaded,
+ false);
+ }
+
private void authenticate(String login, String providerId) {
tester.settings().setGlobalSettings("sonar.auth.fake-base-id-provider.user", login + "," + providerId + ",fake-" + login + ",John,john@email.com");
tester.wsClient().wsConnector().call(
// reduce memory for Elasticsearch
.setServerProperty("sonar.search.javaOpts", "-Xms128m -Xmx128m")
- .setServerProperty("sonar.web.javaAdditionalOpts", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8001")
.build();