* SONAR-10597 Update RULES_METADATA#NOTE_USER_LOGIN to NOTE_USER_UUD in DB * SONAR-10597 Update rules ws to use user note uuid * SONAR-10597 Add ITs to check rule note after login updatetags/7.5
@@ -206,7 +206,7 @@ CREATE TABLE "RULES_METADATA" ( | |||
"RULE_ID" INTEGER NOT NULL, | |||
"ORGANIZATION_UUID" VARCHAR(40) NOT NULL, | |||
"NOTE_DATA" CLOB, | |||
"NOTE_USER_LOGIN" VARCHAR(255), | |||
"NOTE_USER_UUID" VARCHAR(255), | |||
"NOTE_CREATED_AT" BIGINT, | |||
"NOTE_UPDATED_AT" BIGINT, | |||
"REMEDIATION_FUNCTION" VARCHAR(20), |
@@ -361,12 +361,12 @@ public class RuleDto { | |||
} | |||
@CheckForNull | |||
public String getNoteUserLogin() { | |||
return metadata.getNoteUserLogin(); | |||
public String getNoteUserUuid() { | |||
return metadata.getNoteUserUuid(); | |||
} | |||
public RuleDto setNoteUserLogin(@Nullable String noteUserLogin) { | |||
metadata.setNoteUserLogin(noteUserLogin); | |||
public RuleDto setNoteUserUuid(@Nullable String noteUserUuid) { | |||
metadata.setNoteUserUuid(noteUserUuid); | |||
return this; | |||
} | |||
@@ -33,7 +33,7 @@ public class RuleMetadataDto { | |||
private int ruleId; | |||
private String organizationUuid; | |||
private String noteData; | |||
private String noteUserLogin; | |||
private String noteUserUuid; | |||
private Long noteCreatedAt; | |||
private Long noteUpdatedAt; | |||
private String remediationFunction; | |||
@@ -72,12 +72,12 @@ public class RuleMetadataDto { | |||
} | |||
@CheckForNull | |||
public String getNoteUserLogin() { | |||
return noteUserLogin; | |||
public String getNoteUserUuid() { | |||
return noteUserUuid; | |||
} | |||
public RuleMetadataDto setNoteUserLogin(@Nullable String noteUserLogin) { | |||
this.noteUserLogin = noteUserLogin; | |||
public RuleMetadataDto setNoteUserUuid(@Nullable String noteUserUuid) { | |||
this.noteUserUuid = noteUserUuid; | |||
return this; | |||
} | |||
@@ -178,7 +178,7 @@ public class RuleMetadataDto { | |||
"ruleId=" + ruleId + | |||
", organizationUuid='" + organizationUuid + '\'' + | |||
", noteData='" + noteData + '\'' + | |||
", noteUserLogin='" + noteUserLogin + '\'' + | |||
", noteUserUuid='" + noteUserUuid + '\'' + | |||
", noteCreatedAt=" + noteCreatedAt + | |||
", noteUpdatedAt=" + noteUpdatedAt + | |||
", remediationFunction='" + remediationFunction + '\'' + |
@@ -38,7 +38,7 @@ | |||
r.created_at as "createdAtFromDefinition", | |||
r.updated_at as "updatedAtFromDefinition", | |||
rm.note_data as "noteData", | |||
rm.note_user_login as "noteUserLogin", | |||
rm.note_user_uuid as "noteUserUuid", | |||
rm.note_created_at as "noteCreatedAt", | |||
rm.note_updated_at as "noteUpdatedAt", | |||
rm.remediation_function as "remediationFunction", | |||
@@ -187,7 +187,7 @@ | |||
rm.rule_id as "ruleId", | |||
rm.organization_uuid as "organizationUuid", | |||
rm.note_data as "noteData", | |||
rm.note_user_login as "noteUserLogin", | |||
rm.note_user_uuid as "noteUserUuid", | |||
rm.note_created_at as "noteCreatedAt", | |||
rm.note_updated_at as "noteUpdatedAt", | |||
rm.remediation_function as "remediationFunction", | |||
@@ -378,7 +378,7 @@ | |||
rule_id, | |||
organization_uuid, | |||
note_data, | |||
note_user_login, | |||
note_user_uuid, | |||
note_created_at, | |||
note_updated_at, | |||
remediation_function, | |||
@@ -392,7 +392,7 @@ | |||
#{ruleId,jdbcType=INTEGER}, | |||
#{organizationUuid,jdbcType=VARCHAR}, | |||
#{noteData,jdbcType=CLOB}, | |||
#{noteUserLogin,jdbcType=VARCHAR}, | |||
#{noteUserUuid,jdbcType=VARCHAR}, | |||
#{noteCreatedAt,jdbcType=BIGINT}, | |||
#{noteUpdatedAt,jdbcType=BIGINT}, | |||
#{remediationFunction,jdbcType=VARCHAR}, | |||
@@ -407,7 +407,7 @@ | |||
<update id="updateMetadata" parameterType="org.sonar.db.rule.RuleMetadataDto"> | |||
update rules_metadata set | |||
note_data=#{noteData,jdbcType=CLOB}, | |||
note_user_login=#{noteUserLogin,jdbcType=VARCHAR}, | |||
note_user_uuid=#{noteUserUuid,jdbcType=VARCHAR}, | |||
note_created_at=#{noteCreatedAt,jdbcType=BIGINT}, | |||
note_updated_at=#{noteUpdatedAt,jdbcType=BIGINT}, | |||
remediation_function=#{remediationFunction,jdbcType=VARCHAR}, |
@@ -584,7 +584,7 @@ public class RuleDaoTest { | |||
.setRuleId(1) | |||
.setOrganizationUuid(organizationUuid) | |||
.setNoteData("My note") | |||
.setNoteUserLogin("admin") | |||
.setNoteUserUuid("admin") | |||
.setNoteCreatedAt(DateUtils.parseDate("2013-12-19").getTime()) | |||
.setNoteUpdatedAt(DateUtils.parseDate("2013-12-20").getTime()) | |||
.setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) | |||
@@ -611,7 +611,7 @@ public class RuleDaoTest { | |||
assertThat(ruleDto.isTemplate()).isFalse(); | |||
assertThat(ruleDto.getTemplateId()).isNull(); | |||
assertThat(ruleDto.getNoteData()).isEqualTo("My note"); | |||
assertThat(ruleDto.getNoteUserLogin()).isEqualTo("admin"); | |||
assertThat(ruleDto.getNoteUserUuid()).isEqualTo("admin"); | |||
assertThat(ruleDto.getNoteCreatedAt()).isNotNull(); | |||
assertThat(ruleDto.getNoteUpdatedAt()).isNotNull(); | |||
assertThat(ruleDto.getRemediationFunction()).isEqualTo("LINEAR"); | |||
@@ -642,7 +642,7 @@ public class RuleDaoTest { | |||
.setRuleId(1) | |||
.setOrganizationUuid(organizationUuid) | |||
.setNoteData("My note") | |||
.setNoteUserLogin("admin") | |||
.setNoteUserUuid("admin") | |||
.setNoteCreatedAt(DateUtils.parseDate("2013-12-19").getTime()) | |||
.setNoteUpdatedAt(DateUtils.parseDate("2013-12-20").getTime()) | |||
.setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) | |||
@@ -669,7 +669,7 @@ public class RuleDaoTest { | |||
assertThat(ruleDto.isTemplate()).isFalse(); | |||
assertThat(ruleDto.getTemplateId()).isNull(); | |||
assertThat(ruleDto.getNoteData()).isNull(); | |||
assertThat(ruleDto.getNoteUserLogin()).isNull(); | |||
assertThat(ruleDto.getNoteUserUuid()).isNull(); | |||
assertThat(ruleDto.getNoteCreatedAt()).isNull(); | |||
assertThat(ruleDto.getNoteUpdatedAt()).isNull(); | |||
assertThat(ruleDto.getRemediationFunction()).isNull(); | |||
@@ -701,7 +701,7 @@ public class RuleDaoTest { | |||
assertThat(ruleDto.isTemplate()).isFalse(); | |||
assertThat(ruleDto.getTemplateId()).isNull(); | |||
assertThat(ruleDto.getNoteData()).isEqualTo("My note"); | |||
assertThat(ruleDto.getNoteUserLogin()).isEqualTo("admin"); | |||
assertThat(ruleDto.getNoteUserUuid()).isEqualTo("admin"); | |||
assertThat(ruleDto.getNoteCreatedAt()).isNotNull(); | |||
assertThat(ruleDto.getNoteUpdatedAt()).isNotNull(); | |||
assertThat(ruleDto.getRemediationFunction()).isEqualTo("LINEAR"); |
@@ -24,6 +24,7 @@ import org.sonar.api.rule.RuleKey; | |||
import org.sonar.api.server.rule.RuleParamType; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.user.UserDto; | |||
import static java.util.Arrays.asList; | |||
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; | |||
@@ -79,6 +80,13 @@ public class RuleDbTester { | |||
return insertOrUpdateMetadata(dto); | |||
} | |||
@SafeVarargs | |||
public final RuleMetadataDto insertOrUpdateMetadata(RuleDefinitionDto rule, UserDto noteUser, OrganizationDto organization, Consumer<RuleMetadataDto>... populaters) { | |||
RuleMetadataDto dto = RuleTesting.newRuleMetadata(rule, noteUser, organization); | |||
asList(populaters).forEach(populater -> populater.accept(dto)); | |||
return insertOrUpdateMetadata(dto); | |||
} | |||
public RuleMetadataDto insertOrUpdateMetadata(RuleMetadataDto metadata) { | |||
db.getDbClient().ruleDao().insertOrUpdate(db.getSession(), metadata); | |||
db.commit(); |
@@ -33,6 +33,7 @@ import org.sonar.core.util.UuidFactoryFast; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.rule.RuleDto.Format; | |||
import org.sonar.db.rule.RuleDto.Scope; | |||
import org.sonar.db.user.UserDto; | |||
import static com.google.common.base.Preconditions.checkNotNull; | |||
import static com.google.common.collect.ImmutableSet.copyOf; | |||
@@ -96,7 +97,7 @@ public class RuleTesting { | |||
.setRemediationFunction("LINEAR_OFFSET") | |||
.setTags(newHashSet("tag_" + randomAlphanumeric(5), "tag_" + randomAlphanumeric(5))) | |||
.setNoteData("noteData_" + randomAlphanumeric(5)) | |||
.setNoteUserLogin("noteLogin_" + randomAlphanumeric(5)) | |||
.setNoteUserUuid("noteUserUuid_" + randomAlphanumeric(5)) | |||
.setNoteCreatedAt(System.currentTimeMillis() - 200) | |||
.setNoteUpdatedAt(System.currentTimeMillis() - 150) | |||
.setCreatedAt(System.currentTimeMillis() - 100) | |||
@@ -109,6 +110,11 @@ public class RuleTesting { | |||
.setOrganizationUuid(organization.getUuid()); | |||
} | |||
public static RuleMetadataDto newRuleMetadata(RuleDefinitionDto rule, UserDto noteUser, OrganizationDto organization) { | |||
return newRuleMetadata(rule, organization) | |||
.setNoteUserUuid(noteUser.getUuid()); | |||
} | |||
public static RuleParamDto newRuleParam(RuleDefinitionDto rule) { | |||
return new RuleParamDto() | |||
.setRuleId(rule.getId()) |
@@ -47,7 +47,8 @@ public class DbVersion72 implements DbVersion { | |||
.add(2117, "Drop USER_ID from table organizations", DropUserIdFromOrganizations.class) | |||
.add(2118, "Rename USER_LOGIN TO USER_UUID on table QPROFILE_CHANGES", RenameUserLoginToUserUuidOnTableQProfileChanges.class) | |||
.add(2119, "Rename LOGIN TO USER_UUID on table USER_TOKENS", RenameLoginToUserUuidOnTableUserTokens.class) | |||
.add(2120, "Rename USER_LOGIN TO USER_UUID on table MANUAL_MEASURES", RenameUserLoginToUserUuidOnTableManualMeasures.class); | |||
.add(2120, "Rename USER_LOGIN TO USER_UUID on table MANUAL_MEASURES", RenameUserLoginToUserUuidOnTableManualMeasures.class) | |||
.add(2121, "Rename NOTE_USER_LOGIN TO NOTE_USER_UUID on table RULES_METADATA", RenameNoteUserLoginToNoteUserUuidOnTableRulesMetadata.class) | |||
; | |||
} | |||
} |
@@ -0,0 +1,48 @@ | |||
/* | |||
* 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 RenameNoteUserLoginToNoteUserUuidOnTableRulesMetadata extends DdlChange { | |||
private static final String TABLE = "rules_metadata"; | |||
public RenameNoteUserLoginToNoteUserUuidOnTableRulesMetadata(Database db) { | |||
super(db); | |||
} | |||
@Override | |||
public void execute(Context context) throws SQLException { | |||
context.execute(new RenameColumnsBuilder(getDialect(), TABLE) | |||
.renameColumn("note_user_login", | |||
newVarcharColumnDefBuilder() | |||
.setColumnName("note_user_uuid") | |||
.setLimit(255) | |||
.setIsNullable(true) | |||
.build()) | |||
.build()); | |||
} | |||
} |
@@ -34,7 +34,7 @@ public class DbVersion72Test { | |||
@Test | |||
public void verify_migration_count() { | |||
verifyMigrationCount(underTest, 21); | |||
verifyMigrationCount(underTest, 22); | |||
} | |||
} |
@@ -0,0 +1,57 @@ | |||
/* | |||
* 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 RenameNoteUserLoginToNoteUserUuidOnTableRulesMetadataTest { | |||
@Rule | |||
public final CoreDbTester db = CoreDbTester.createForSchema(RenameNoteUserLoginToNoteUserUuidOnTableRulesMetadataTest.class, "rules_metadata.sql"); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
private RenameNoteUserLoginToNoteUserUuidOnTableRulesMetadata underTest = new RenameNoteUserLoginToNoteUserUuidOnTableRulesMetadata(db.database()); | |||
@Test | |||
public void rename_column() throws SQLException { | |||
underTest.execute(); | |||
db.assertColumnDefinition("rules_metadata", "note_user_uuid", VARCHAR, 255, true); | |||
db.assertColumnDoesNotExist("rules_metadata", "note_user_login"); | |||
} | |||
public void migration_is_not_reentrant() throws SQLException { | |||
underTest.execute(); | |||
expectedException.expect(IllegalStateException.class); | |||
underTest.execute(); | |||
} | |||
} |
@@ -0,0 +1,15 @@ | |||
CREATE TABLE "RULES_METADATA" ( | |||
"RULE_ID" INTEGER NOT NULL, | |||
"ORGANIZATION_UUID" VARCHAR(40) NOT NULL, | |||
"NOTE_DATA" CLOB, | |||
"NOTE_USER_LOGIN" VARCHAR(255), | |||
"NOTE_CREATED_AT" BIGINT, | |||
"NOTE_UPDATED_AT" BIGINT, | |||
"REMEDIATION_FUNCTION" VARCHAR(20), | |||
"REMEDIATION_GAP_MULT" VARCHAR(20), | |||
"REMEDIATION_BASE_EFFORT" VARCHAR(20), | |||
"TAGS" VARCHAR(4000), | |||
"CREATED_AT" BIGINT NOT NULL, | |||
"UPDATED_AT" BIGINT NOT NULL, | |||
CONSTRAINT PK_RULES_METADATA PRIMARY KEY (RULE_ID,ORGANIZATION_UUID) | |||
); |
@@ -191,13 +191,13 @@ public class RuleUpdater { | |||
rule.setNoteData(null); | |||
rule.setNoteCreatedAt(null); | |||
rule.setNoteUpdatedAt(null); | |||
rule.setNoteUserLogin(null); | |||
rule.setNoteUserUuid(null); | |||
} else { | |||
long now = system.now(); | |||
rule.setNoteData(update.getMarkdownNote()); | |||
rule.setNoteCreatedAt(rule.getNoteCreatedAt() != null ? rule.getNoteCreatedAt() : now); | |||
rule.setNoteUpdatedAt(now); | |||
rule.setNoteUserLogin(userSession.getLogin()); | |||
rule.setNoteUserUuid(userSession.getUuid()); | |||
} | |||
} | |||
@@ -23,6 +23,7 @@ import com.google.common.base.Function; | |||
import com.google.common.collect.FluentIterable; | |||
import java.util.List; | |||
import java.util.Locale; | |||
import java.util.Map; | |||
import java.util.Set; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nonnull; | |||
@@ -34,6 +35,7 @@ import org.sonar.db.rule.RuleDefinitionDto; | |||
import org.sonar.db.rule.RuleDto.Scope; | |||
import org.sonar.db.rule.RuleMetadataDto; | |||
import org.sonar.db.rule.RuleParamDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.markdown.Markdown; | |||
import org.sonar.server.rule.ws.SearchAction.SearchResult; | |||
import org.sonar.server.text.MacroInterpreter; | |||
@@ -63,10 +65,10 @@ import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_PARAMS; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_REM_FUNCTION; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_REM_FUNCTION_OVERLOADED; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_REPO; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_SCOPE; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_SEVERITY; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_STATUS; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_SYSTEM_TAGS; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_SCOPE; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_TAGS; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_TEMPLATE_KEY; | |||
@@ -89,10 +91,10 @@ public class RuleMapper { | |||
return ruleResponse.build(); | |||
} | |||
public Rules.Rule toWsRule(RuleDefinitionDto ruleDefinitionDto, SearchResult result, Set<String> fieldsToReturn, RuleMetadataDto metadata) { | |||
public Rules.Rule toWsRule(RuleDefinitionDto ruleDefinitionDto, SearchResult result, Set<String> fieldsToReturn, RuleMetadataDto metadata, Map<String, UserDto> usersByUuid) { | |||
Rules.Rule.Builder ruleResponse = Rules.Rule.newBuilder(); | |||
applyRuleDefinition(ruleResponse, ruleDefinitionDto, result, fieldsToReturn); | |||
applyRuleMetadata(ruleResponse, metadata, fieldsToReturn); | |||
applyRuleMetadata(ruleResponse, metadata, usersByUuid, fieldsToReturn); | |||
setDebtRemediationFunctionFields(ruleResponse, ruleDefinitionDto, metadata, fieldsToReturn); | |||
return ruleResponse.build(); | |||
} | |||
@@ -101,7 +103,7 @@ public class RuleMapper { | |||
// Mandatory fields | |||
ruleResponse.setKey(ruleDefinitionDto.getKey().toString()); | |||
ruleResponse.setType(Common.RuleType.valueOf(ruleDefinitionDto.getType())); | |||
ruleResponse.setType(Common.RuleType.forNumber(ruleDefinitionDto.getType())); | |||
// Optional fields | |||
setRepository(ruleResponse, ruleDefinitionDto, fieldsToReturn); | |||
@@ -124,9 +126,9 @@ public class RuleMapper { | |||
return ruleResponse; | |||
} | |||
private void applyRuleMetadata(Rules.Rule.Builder ruleResponse, RuleMetadataDto metadata, Set<String> fieldsToReturn) { | |||
private void applyRuleMetadata(Rules.Rule.Builder ruleResponse, RuleMetadataDto metadata, Map<String, UserDto> usersByUuid, Set<String> fieldsToReturn) { | |||
setTags(ruleResponse, metadata, fieldsToReturn); | |||
setNotesFields(ruleResponse, metadata, fieldsToReturn); | |||
setNotesFields(ruleResponse, metadata, usersByUuid, fieldsToReturn); | |||
setIsRemediationFunctionOverloaded(ruleResponse, metadata, fieldsToReturn); | |||
} | |||
@@ -282,21 +284,24 @@ public class RuleMapper { | |||
} | |||
} | |||
private void setNotesFields(Rules.Rule.Builder ruleResponse, RuleMetadataDto ruleDto, Set<String> fieldsToReturn) { | |||
if (shouldReturnField(fieldsToReturn, "htmlNote") && ruleDto.getNoteData() != null) { | |||
ruleResponse.setHtmlNote(macroInterpreter.interpret(Markdown.convertToHtml(ruleDto.getNoteData()))); | |||
private void setNotesFields(Rules.Rule.Builder ruleResponse, RuleMetadataDto ruleDto, Map<String, UserDto> usersByUuid, Set<String> fieldsToReturn) { | |||
String noteData = ruleDto.getNoteData(); | |||
if (shouldReturnField(fieldsToReturn, "htmlNote") && noteData != null) { | |||
ruleResponse.setHtmlNote(macroInterpreter.interpret(Markdown.convertToHtml(noteData))); | |||
} | |||
if (shouldReturnField(fieldsToReturn, "mdNote") && ruleDto.getNoteData() != null) { | |||
ruleResponse.setMdNote(ruleDto.getNoteData()); | |||
if (shouldReturnField(fieldsToReturn, "mdNote") && noteData != null) { | |||
ruleResponse.setMdNote(noteData); | |||
} | |||
if (shouldReturnField(fieldsToReturn, FIELD_NOTE_LOGIN) && ruleDto.getNoteUserLogin() != null) { | |||
ruleResponse.setNoteLogin(ruleDto.getNoteUserLogin()); | |||
String userUuid = ruleDto.getNoteUserUuid(); | |||
if (shouldReturnField(fieldsToReturn, FIELD_NOTE_LOGIN) && userUuid != null) { | |||
ruleResponse.setNoteLogin(usersByUuid.get(userUuid).getLogin()); | |||
} | |||
} | |||
private static void setSeverity(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, Set<String> fieldsToReturn) { | |||
if (shouldReturnField(fieldsToReturn, FIELD_SEVERITY) && ruleDto.getSeverityString() != null) { | |||
ruleResponse.setSeverity(ruleDto.getSeverityString()); | |||
String severity = ruleDto.getSeverityString(); | |||
if (shouldReturnField(fieldsToReturn, FIELD_SEVERITY) && severity != null) { | |||
ruleResponse.setSeverity(severity); | |||
} | |||
} | |||
@@ -307,8 +312,9 @@ public class RuleMapper { | |||
} | |||
private static void setLanguage(Rules.Rule.Builder ruleResponse, RuleDefinitionDto ruleDto, Set<String> fieldsToReturn) { | |||
if (shouldReturnField(fieldsToReturn, FIELD_LANGUAGE) && ruleDto.getLanguage() != null) { | |||
ruleResponse.setLang(ruleDto.getLanguage()); | |||
String language = ruleDto.getLanguage(); | |||
if (shouldReturnField(fieldsToReturn, FIELD_LANGUAGE) && language != null) { | |||
ruleResponse.setLang(language); | |||
} | |||
} | |||
@@ -385,8 +391,9 @@ public class RuleMapper { | |||
if (param.getDescription() != null) { | |||
paramResponse.setHtmlDesc(Markdown.convertToHtml(param.getDescription())); | |||
} | |||
if (param.getDefaultValue() != null) { | |||
paramResponse.setDefaultValue(param.getDefaultValue()); | |||
String defaultValue = param.getDefaultValue(); | |||
if (defaultValue != null) { | |||
paramResponse.setDefaultValue(defaultValue); | |||
} | |||
if (param.getType() != null) { | |||
paramResponse.setType(param.getType()); |
@@ -19,16 +19,24 @@ | |||
*/ | |||
package org.sonar.server.rule.ws; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Objects; | |||
import java.util.Optional; | |||
import java.util.Set; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.server.ServerSide; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.rule.RuleDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonar.server.ws.WsUtils; | |||
import static org.sonar.core.util.stream.MoreCollectors.toSet; | |||
import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex; | |||
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES; | |||
@ServerSide | |||
@@ -58,4 +66,9 @@ public class RuleWsSupport { | |||
"No organization with key '%s'", organizationOrDefaultKey); | |||
} | |||
Map<String, UserDto> getUsersByUuid(DbSession dbSession, List<RuleDto> rules) { | |||
Set<String> userUuids = rules.stream().map(RuleDto::getNoteUserUuid).filter(Objects::nonNull).collect(toSet()); | |||
return dbClient.userDao().selectByUuids(dbSession, userUuids).stream().collect(uniqueIndex(UserDto::getUuid)); | |||
} | |||
} |
@@ -49,6 +49,7 @@ import org.sonar.db.DbSession; | |||
import org.sonar.db.rule.RuleDefinitionDto; | |||
import org.sonar.db.rule.RuleDto; | |||
import org.sonar.db.rule.RuleParamDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.es.Facets; | |||
import org.sonar.server.es.SearchIdResult; | |||
import org.sonar.server.es.SearchOptions; | |||
@@ -118,13 +119,16 @@ public class SearchAction implements RulesWsAction { | |||
private final RuleIndex ruleIndex; | |||
private final ActiveRuleCompleter activeRuleCompleter; | |||
private final RuleMapper mapper; | |||
private final RuleWsSupport ruleWsSupport; | |||
public SearchAction(RuleIndex ruleIndex, ActiveRuleCompleter activeRuleCompleter, RuleQueryFactory ruleQueryFactory, DbClient dbClient, RuleMapper mapper) { | |||
public SearchAction(RuleIndex ruleIndex, ActiveRuleCompleter activeRuleCompleter, RuleQueryFactory ruleQueryFactory, DbClient dbClient, RuleMapper mapper, | |||
RuleWsSupport ruleWsSupport) { | |||
this.ruleIndex = ruleIndex; | |||
this.activeRuleCompleter = activeRuleCompleter; | |||
this.ruleQueryFactory = ruleQueryFactory; | |||
this.dbClient = dbClient; | |||
this.mapper = mapper; | |||
this.ruleWsSupport = ruleWsSupport; | |||
} | |||
@Override | |||
@@ -330,10 +334,9 @@ public class SearchAction implements RulesWsAction { | |||
.setSince("6.4"); | |||
} | |||
private void writeRules(SearchResponse.Builder response, SearchResult result, SearchOptions context) { | |||
for (RuleDto rule : result.rules) { | |||
response.addRules(mapper.toWsRule(rule.getDefinition(), result, context.getFields(), rule.getMetadata())); | |||
} | |||
private void writeRules(DbSession dbSession, SearchResponse.Builder response, SearchResult result, SearchOptions context) { | |||
Map<String, UserDto> usersByUuid = ruleWsSupport.getUsersByUuid(dbSession, result.rules); | |||
result.rules.forEach(rule -> response.addRules(mapper.toWsRule(rule.getDefinition(), result, context.getFields(), rule.getMetadata(), usersByUuid))); | |||
} | |||
private static SearchOptions buildSearchOptions(SearchRequest request) { | |||
@@ -392,7 +395,7 @@ public class SearchAction implements RulesWsAction { | |||
private void doContextResponse(DbSession dbSession, SearchRequest request, SearchResult result, SearchResponse.Builder response, RuleQuery query) { | |||
SearchOptions contextForResponse = loadCommonContext(request); | |||
writeRules(response, result, contextForResponse); | |||
writeRules(dbSession, response, result, contextForResponse); | |||
if (contextForResponse.getFields().contains("actives")) { | |||
activeRuleCompleter.completeSearch(dbSession, query, result.rules, response); | |||
} |
@@ -33,8 +33,6 @@ import org.sonar.db.rule.RuleDefinitionDto; | |||
import org.sonar.db.rule.RuleDto; | |||
import org.sonar.db.rule.RuleParamDto; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import org.sonar.server.ws.WsUtils; | |||
import org.sonarqube.ws.Rules.ShowResponse; | |||
import static java.util.Collections.singletonList; | |||
@@ -53,13 +51,13 @@ public class ShowAction implements RulesWsAction { | |||
private final DbClient dbClient; | |||
private final RuleMapper mapper; | |||
private final ActiveRuleCompleter activeRuleCompleter; | |||
private final DefaultOrganizationProvider defaultOrganizationProvider; | |||
private final RuleWsSupport ruleWsSupport; | |||
public ShowAction(DbClient dbClient, RuleMapper mapper, ActiveRuleCompleter activeRuleCompleter, DefaultOrganizationProvider defaultOrganizationProvider) { | |||
public ShowAction(DbClient dbClient, RuleMapper mapper, ActiveRuleCompleter activeRuleCompleter, RuleWsSupport ruleWsSupport) { | |||
this.dbClient = dbClient; | |||
this.activeRuleCompleter = activeRuleCompleter; | |||
this.mapper = mapper; | |||
this.defaultOrganizationProvider = defaultOrganizationProvider; | |||
this.ruleWsSupport = ruleWsSupport; | |||
} | |||
@Override | |||
@@ -105,7 +103,7 @@ public class ShowAction implements RulesWsAction { | |||
public void handle(Request request, Response response) throws Exception { | |||
RuleKey key = RuleKey.parse(request.mandatoryParam(PARAM_KEY)); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
OrganizationDto organization = getOrganization(request, dbSession); | |||
OrganizationDto organization = ruleWsSupport.getOrganizationByKey(dbSession, request.param(PARAM_ORGANIZATION)); | |||
RuleDto rule = dbClient.ruleDao().selectByKey(dbSession, organization, key) | |||
.orElseThrow(() -> new NotFoundException(String.format("Rule not found: %s", key))); | |||
@@ -124,24 +122,15 @@ public class ShowAction implements RulesWsAction { | |||
} | |||
} | |||
private OrganizationDto getOrganization(Request request, DbSession dbSession) { | |||
String organizationKey = ofNullable(request.param(PARAM_ORGANIZATION)) | |||
.orElseGet(() -> defaultOrganizationProvider.get().getKey()); | |||
return WsUtils.checkFoundWithOptional( | |||
dbClient.organizationDao().selectByKey(dbSession, organizationKey), | |||
"No organization with key '%s'", organizationKey); | |||
} | |||
private ShowResponse buildResponse(DbSession dbSession, OrganizationDto organization, Request request, SearchAction.SearchResult searchResult) { | |||
ShowResponse.Builder responseBuilder = ShowResponse.newBuilder(); | |||
RuleDto rule = searchResult.getRules().get(0); | |||
responseBuilder.setRule(mapper.toWsRule(rule.getDefinition(), searchResult, Collections.emptySet(), rule.getMetadata())); | |||
responseBuilder.setRule(mapper.toWsRule(rule.getDefinition(), searchResult, Collections.emptySet(), rule.getMetadata(), | |||
ruleWsSupport.getUsersByUuid(dbSession, searchResult.getRules()))); | |||
if (request.mandatoryParamAsBoolean(PARAM_ACTIVES)) { | |||
activeRuleCompleter.completeShow(dbSession, organization, rule.getDefinition()).stream() | |||
.forEach(responseBuilder::addActives); | |||
activeRuleCompleter.completeShow(dbSession, organization, rule.getDefinition()).forEach(responseBuilder::addActives); | |||
} | |||
return responseBuilder.build(); | |||
} | |||
} |
@@ -40,11 +40,9 @@ import org.sonar.db.rule.RuleDefinitionDto; | |||
import org.sonar.db.rule.RuleDto; | |||
import org.sonar.db.rule.RuleParamDto; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import org.sonar.server.rule.RuleUpdate; | |||
import org.sonar.server.rule.RuleUpdater; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonar.server.ws.WsUtils; | |||
import org.sonarqube.ws.Rules.UpdateResponse; | |||
import static com.google.common.collect.Sets.newHashSet; | |||
@@ -79,15 +77,14 @@ public class UpdateAction implements RulesWsAction { | |||
private final RuleUpdater ruleUpdater; | |||
private final RuleMapper mapper; | |||
private final UserSession userSession; | |||
private final DefaultOrganizationProvider defaultOrganizationProvider; | |||
private final RuleWsSupport ruleWsSupport; | |||
public UpdateAction(DbClient dbClient, RuleUpdater ruleUpdater, RuleMapper mapper, UserSession userSession, | |||
DefaultOrganizationProvider defaultOrganizationProvider) { | |||
public UpdateAction(DbClient dbClient, RuleUpdater ruleUpdater, RuleMapper mapper, UserSession userSession, RuleWsSupport ruleWsSupport) { | |||
this.dbClient = dbClient; | |||
this.ruleUpdater = ruleUpdater; | |||
this.mapper = mapper; | |||
this.userSession = userSession; | |||
this.defaultOrganizationProvider = defaultOrganizationProvider; | |||
this.ruleWsSupport = ruleWsSupport; | |||
} | |||
@Override | |||
@@ -181,7 +178,7 @@ public class UpdateAction implements RulesWsAction { | |||
public void handle(Request request, Response response) throws Exception { | |||
userSession.checkLoggedIn(); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
OrganizationDto organization = getOrganization(request, dbSession); | |||
OrganizationDto organization = ruleWsSupport.getOrganizationByKey(dbSession, request.param(PARAM_ORGANIZATION)); | |||
userSession.checkPermission(ADMINISTER_QUALITY_PROFILES, organization); | |||
RuleUpdate update = readRequest(dbSession, request, organization); | |||
ruleUpdater.update(dbSession, update, organization, userSession); | |||
@@ -191,14 +188,6 @@ public class UpdateAction implements RulesWsAction { | |||
} | |||
} | |||
private OrganizationDto getOrganization(Request request, DbSession dbSession) { | |||
String organizationKey = ofNullable(request.param(PARAM_ORGANIZATION)) | |||
.orElseGet(() -> defaultOrganizationProvider.get().getKey()); | |||
return WsUtils.checkFoundWithOptional( | |||
dbClient.organizationDao().selectByKey(dbSession, organizationKey), | |||
"No organization with key '%s'", organizationKey); | |||
} | |||
private RuleUpdate readRequest(DbSession dbSession, Request request, OrganizationDto organization) { | |||
RuleKey key = RuleKey.parse(request.mandatoryParam(PARAM_KEY)); | |||
RuleUpdate update = createRuleUpdate(dbSession, key, organization); | |||
@@ -289,7 +278,8 @@ public class UpdateAction implements RulesWsAction { | |||
.setTemplateRules(templateRules) | |||
.setRuleParameters(ruleParameters) | |||
.setTotal(1L); | |||
responseBuilder.setRule(mapper.toWsRule(rule.getDefinition(), searchResult, Collections.emptySet(), rule.getMetadata())); | |||
responseBuilder | |||
.setRule(mapper.toWsRule(rule.getDefinition(), searchResult, Collections.emptySet(), rule.getMetadata(), ruleWsSupport.getUsersByUuid(dbSession, singletonList(rule)))); | |||
return responseBuilder.build(); | |||
} |
@@ -269,7 +269,7 @@ public class RegisterRulesTest { | |||
// user adds tags and sets markdown note | |||
rule1.setTags(newHashSet("usertag1", "usertag2")); | |||
rule1.setNoteData("user *note*"); | |||
rule1.setNoteUserLogin("marius"); | |||
rule1.setNoteUserUuid("marius"); | |||
dbClient.ruleDao().insertOrUpdate(dbTester.getSession(), rule1.getMetadata()); | |||
dbTester.getSession().commit(); | |||
@@ -285,7 +285,7 @@ public class RegisterRulesTest { | |||
assertThat(rule1.getSystemTags()).containsOnly("tag1", "tag4"); | |||
assertThat(rule1.getConfigKey()).isEqualTo("config1 v2"); | |||
assertThat(rule1.getNoteData()).isEqualTo("user *note*"); | |||
assertThat(rule1.getNoteUserLogin()).isEqualTo("marius"); | |||
assertThat(rule1.getNoteUserUuid()).isEqualTo("marius"); | |||
assertThat(rule1.getStatus()).isEqualTo(RuleStatus.READY); | |||
assertThat(rule1.getType()).isEqualTo(RuleType.BUG.getDbConstant()); | |||
assertThat(rule1.getCreatedAt()).isEqualTo(DATE1.getTime()); |
@@ -46,6 +46,7 @@ import org.sonar.db.rule.RuleDefinitionDto; | |||
import org.sonar.db.rule.RuleDto; | |||
import org.sonar.db.rule.RuleParamDto; | |||
import org.sonar.db.rule.RuleTesting; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.es.EsTester; | |||
import org.sonar.server.es.SearchOptions; | |||
import org.sonar.server.qualityprofile.QProfileTesting; | |||
@@ -105,7 +106,7 @@ public class RuleUpdaterTest { | |||
RuleDto ruleDto = RuleTesting.newDto(RULE_KEY, db.getDefaultOrganization()) | |||
// the following fields are not supposed to be updated | |||
.setNoteData("my *note*") | |||
.setNoteUserLogin("me") | |||
.setNoteUserUuid("me") | |||
.setTags(ImmutableSet.of("tag1")) | |||
.setRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE.name()) | |||
.setRemediationGapMultiplier("1d") | |||
@@ -121,7 +122,7 @@ public class RuleUpdaterTest { | |||
dbSession.clearCache(); | |||
RuleDto rule = db.getDbClient().ruleDao().selectOrFailByKey(dbSession, db.getDefaultOrganization(), RULE_KEY); | |||
assertThat(rule.getNoteData()).isEqualTo("my *note*"); | |||
assertThat(rule.getNoteUserLogin()).isEqualTo("me"); | |||
assertThat(rule.getNoteUserUuid()).isEqualTo("me"); | |||
assertThat(rule.getTags()).containsOnly("tag1"); | |||
assertThat(rule.getRemediationFunction()).isEqualTo(DebtRemediationFunction.Type.CONSTANT_ISSUE.name()); | |||
assertThat(rule.getRemediationGapMultiplier()).isEqualTo("1d"); | |||
@@ -130,11 +131,12 @@ public class RuleUpdaterTest { | |||
@Test | |||
public void set_markdown_note() { | |||
userSessionRule.logIn("me"); | |||
UserDto user = db.users().insertUser(); | |||
userSessionRule.logIn(user); | |||
RuleDto ruleDto = RuleTesting.newDto(RULE_KEY, db.getDefaultOrganization()) | |||
.setNoteData(null) | |||
.setNoteUserLogin(null) | |||
.setNoteUserUuid(null) | |||
// the following fields are not supposed to be updated | |||
.setTags(ImmutableSet.of("tag1")) | |||
@@ -153,7 +155,7 @@ public class RuleUpdaterTest { | |||
dbSession.clearCache(); | |||
RuleDto rule = db.getDbClient().ruleDao().selectOrFailByKey(dbSession, db.getDefaultOrganization(), RULE_KEY); | |||
assertThat(rule.getNoteData()).isEqualTo("my *note*"); | |||
assertThat(rule.getNoteUserLogin()).isEqualTo("me"); | |||
assertThat(rule.getNoteUserUuid()).isEqualTo(user.getUuid()); | |||
assertThat(rule.getNoteCreatedAt()).isNotNull(); | |||
assertThat(rule.getNoteUpdatedAt()).isNotNull(); | |||
// no other changes | |||
@@ -167,7 +169,7 @@ public class RuleUpdaterTest { | |||
public void remove_markdown_note() { | |||
RuleDto ruleDto = RuleTesting.newDto(RULE_KEY, db.getDefaultOrganization()) | |||
.setNoteData("my *note*") | |||
.setNoteUserLogin("me"); | |||
.setNoteUserUuid("me"); | |||
db.rules().insert(ruleDto.getDefinition()); | |||
db.rules().insertOrUpdateMetadata(ruleDto.getMetadata().setRuleId(ruleDto.getId())); | |||
dbSession.commit(); | |||
@@ -180,7 +182,7 @@ public class RuleUpdaterTest { | |||
dbSession.clearCache(); | |||
RuleDto rule = db.getDbClient().ruleDao().selectOrFailByKey(dbSession, db.getDefaultOrganization(), RULE_KEY); | |||
assertThat(rule.getNoteData()).isNull(); | |||
assertThat(rule.getNoteUserLogin()).isNull(); | |||
assertThat(rule.getNoteUserUuid()).isNull(); | |||
assertThat(rule.getNoteCreatedAt()).isNull(); | |||
assertThat(rule.getNoteUpdatedAt()).isNull(); | |||
} |
@@ -43,6 +43,7 @@ import org.sonar.db.qualityprofile.QProfileDto; | |||
import org.sonar.db.rule.RuleDefinitionDto; | |||
import org.sonar.db.rule.RuleMetadataDto; | |||
import org.sonar.db.rule.RuleParamDto; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.es.EsTester; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.language.LanguageTesting; | |||
@@ -113,7 +114,8 @@ public class SearchActionTest { | |||
private RuleQueryFactory ruleQueryFactory = new RuleQueryFactory(db.getDbClient(), wsSupport); | |||
private MacroInterpreter macroInterpreter = mock(MacroInterpreter.class); | |||
private RuleMapper ruleMapper = new RuleMapper(languages, macroInterpreter); | |||
private SearchAction underTest = new SearchAction(ruleIndex, activeRuleCompleter, ruleQueryFactory, db.getDbClient(), ruleMapper); | |||
private SearchAction underTest = new SearchAction(ruleIndex, activeRuleCompleter, ruleQueryFactory, db.getDbClient(), ruleMapper, | |||
new RuleWsSupport(db.getDbClient(), userSession, defaultOrganizationProvider)); | |||
private TypeValidations typeValidations = new TypeValidations(asList(new StringTypeValidation(), new IntegerTypeValidation())); | |||
private RuleActivator ruleActivator = new RuleActivator(System2.INSTANCE, db.getDbClient(), typeValidations, userSession); | |||
private QProfileRules qProfileRules = new QProfileRulesImpl(db.getDbClient(), ruleActivator, ruleIndex, activeRuleIndexer); | |||
@@ -162,6 +164,29 @@ public class SearchActionTest { | |||
}, rule1, rule2); | |||
} | |||
@Test | |||
public void return_note_login() { | |||
OrganizationDto organization = db.organizations().insert(); | |||
UserDto user1 = db.users().insertUser(); | |||
RuleDefinitionDto rule1 = db.rules().insert(); | |||
db.rules().insertOrUpdateMetadata(rule1, user1, organization); | |||
UserDto disableUser = db.users().insertDisabledUser(); | |||
RuleDefinitionDto rule2 = db.rules().insert(); | |||
db.rules().insertOrUpdateMetadata(rule2, disableUser, organization); | |||
indexRules(); | |||
SearchResponse result = ws.newRequest() | |||
.setParam("f", "noteLogin") | |||
.setParam("organization", organization.getKey()) | |||
.executeProtobuf(SearchResponse.class); | |||
assertThat(result.getRulesList()) | |||
.extracting(Rule::getKey, Rule::getNoteLogin) | |||
.containsExactlyInAnyOrder( | |||
tuple(rule1.getKey().toString(), user1.getLogin()), | |||
tuple(rule2.getKey().toString(), disableUser.getLogin())); | |||
} | |||
@Test | |||
public void filter_by_rule_key() { | |||
RuleDefinitionDto rule1 = createJavaRule(); | |||
@@ -324,6 +349,7 @@ public class SearchActionTest { | |||
indexRules(); | |||
SearchResponse result = ws.newRequest() | |||
.setParam("f", "repo,name") | |||
.setParam("facets", "tags") | |||
.setParam("organization", organization.getKey()) | |||
.executeProtobuf(SearchResponse.class); | |||
@@ -341,6 +367,7 @@ public class SearchActionTest { | |||
indexRules(); | |||
SearchResponse result = ws.newRequest() | |||
.setParam("f", "repo,name") | |||
.setParam("facets", "tags") | |||
.setParam("organization", organization.getKey()) | |||
.executeProtobuf(SearchResponse.class); | |||
@@ -409,8 +436,7 @@ public class SearchActionTest { | |||
.extracting(v -> tuple(v.getVal(), v.getCount())) | |||
.containsExactly( | |||
tuple("system1", 1L), | |||
tuple("system2", 1L) | |||
); | |||
tuple("system2", 1L)); | |||
} | |||
@Test | |||
@@ -455,11 +481,10 @@ public class SearchActionTest { | |||
@Test | |||
public void search_debt_rules_with_default_and_overridden_debt_values() { | |||
RuleDefinitionDto rule = db.rules().insert(r -> | |||
r.setLanguage("java") | |||
.setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) | |||
.setDefRemediationGapMultiplier("1h") | |||
.setDefRemediationBaseEffort("15min")); | |||
RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("java") | |||
.setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) | |||
.setDefRemediationGapMultiplier("1h") | |||
.setDefRemediationBaseEffort("15min")); | |||
RuleMetadataDto metadata = insertMetadata(db.getDefaultOrganization(), rule, | |||
r -> r.setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) | |||
@@ -490,11 +515,10 @@ public class SearchActionTest { | |||
@Test | |||
public void search_debt_rules_with_default_linear_offset_and_overridden_constant_debt() { | |||
RuleDefinitionDto rule = db.rules().insert(r -> | |||
r.setLanguage("java") | |||
.setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) | |||
.setDefRemediationGapMultiplier("1h") | |||
.setDefRemediationBaseEffort("15min")); | |||
RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("java") | |||
.setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) | |||
.setDefRemediationGapMultiplier("1h") | |||
.setDefRemediationBaseEffort("15min")); | |||
RuleMetadataDto metadata = insertMetadata(db.getDefaultOrganization(), rule, | |||
r -> r.setRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE.name()) | |||
@@ -525,11 +549,10 @@ public class SearchActionTest { | |||
@Test | |||
public void search_debt_rules_with_default_linear_offset_and_overridden_linear_debt() { | |||
RuleDefinitionDto rule = db.rules().insert(r -> | |||
r.setLanguage("java") | |||
.setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) | |||
.setDefRemediationGapMultiplier("1h") | |||
.setDefRemediationBaseEffort("15min")); | |||
RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("java") | |||
.setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) | |||
.setDefRemediationGapMultiplier("1h") | |||
.setDefRemediationBaseEffort("15min")); | |||
RuleMetadataDto metadata = insertMetadata(db.getDefaultOrganization(), rule, | |||
r -> r.setRemediationFunction(DebtRemediationFunction.Type.LINEAR.name()) | |||
@@ -560,12 +583,10 @@ public class SearchActionTest { | |||
@Test | |||
public void search_template_rules() { | |||
RuleDefinitionDto templateRule = db.rules().insert(r -> | |||
r.setLanguage("java") | |||
.setIsTemplate(true)); | |||
RuleDefinitionDto rule = db.rules().insert(r -> | |||
r.setLanguage("java") | |||
.setTemplateId(templateRule.getId())); | |||
RuleDefinitionDto templateRule = db.rules().insert(r -> r.setLanguage("java") | |||
.setIsTemplate(true)); | |||
RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("java") | |||
.setTemplateId(templateRule.getId())); | |||
indexRules(); | |||
@@ -584,12 +605,10 @@ public class SearchActionTest { | |||
@Test | |||
public void search_custom_rules_from_template_key() { | |||
RuleDefinitionDto templateRule = db.rules().insert(r -> | |||
r.setLanguage("java") | |||
.setIsTemplate(true)); | |||
RuleDefinitionDto rule = db.rules().insert(r -> | |||
r.setLanguage("java") | |||
.setTemplateId(templateRule.getId())); | |||
RuleDefinitionDto templateRule = db.rules().insert(r -> r.setLanguage("java") | |||
.setIsTemplate(true)); | |||
RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("java") | |||
.setTemplateId(templateRule.getId())); | |||
indexRules(); | |||
@@ -639,24 +658,21 @@ public class SearchActionTest { | |||
RuleDefinitionDto rule = createJavaRule(); | |||
RuleParamDto ruleParam1 = db.rules().insertRuleParam(rule, p -> | |||
p.setDefaultValue("some value") | |||
.setType("STRING") | |||
.setDescription("My small description") | |||
.setName("my_var")); | |||
RuleParamDto ruleParam1 = db.rules().insertRuleParam(rule, p -> p.setDefaultValue("some value") | |||
.setType("STRING") | |||
.setDescription("My small description") | |||
.setName("my_var")); | |||
RuleParamDto ruleParam2 = db.rules().insertRuleParam(rule, p -> | |||
p.setDefaultValue("1") | |||
.setType("INTEGER") | |||
.setDescription("My small description") | |||
.setName("the_var")); | |||
RuleParamDto ruleParam2 = db.rules().insertRuleParam(rule, p -> p.setDefaultValue("1") | |||
.setType("INTEGER") | |||
.setDescription("My small description") | |||
.setName("the_var")); | |||
// SONAR-7083 | |||
RuleParamDto ruleParam3 = db.rules().insertRuleParam(rule, p -> | |||
p.setDefaultValue(null) | |||
.setType("STRING") | |||
.setDescription("Empty Param") | |||
.setName("empty_var")); | |||
RuleParamDto ruleParam3 = db.rules().insertRuleParam(rule, p -> p.setDefaultValue(null) | |||
.setType("STRING") | |||
.setDescription("Empty Param") | |||
.setName("empty_var")); | |||
RuleActivation activation = RuleActivation.create(rule.getId()); | |||
List<ActiveRuleChange> activeRuleChanges1 = qProfileRules.activateAndCommit(db.getSession(), profile, singleton(activation)); | |||
@@ -688,8 +704,7 @@ public class SearchActionTest { | |||
assertThat(activeList.getParamsCount()).isEqualTo(2); | |||
assertThat(activeList.getParamsList()).extracting("key", "value").containsExactlyInAnyOrder( | |||
tuple(ruleParam1.getName(), ruleParam1.getDefaultValue()), | |||
tuple(ruleParam2.getName(), ruleParam2.getDefaultValue()) | |||
); | |||
tuple(ruleParam2.getName(), ruleParam2.getDefaultValue())); | |||
String unknownProfile = "unknown_profile" + randomAlphanumeric(5); | |||
expectedException.expect(NotFoundException.class); | |||
@@ -708,11 +723,10 @@ public class SearchActionTest { | |||
RuleDefinitionDto rule = createJavaRule(); | |||
RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> | |||
p.setDefaultValue("some value") | |||
.setType("STRING") | |||
.setDescription("My small description") | |||
.setName("my_var")); | |||
RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setDefaultValue("some value") | |||
.setType("STRING") | |||
.setDescription("My small description") | |||
.setName("my_var")); | |||
RuleActivation activation = RuleActivation.create(rule.getId()); | |||
List<ActiveRuleChange> activeRuleChanges = qProfileRules.activateAndCommit(db.getSession(), profile, singleton(activation)); | |||
@@ -744,8 +758,7 @@ public class SearchActionTest { | |||
assertThat(activeList.getParamsCount()).isEqualTo(2); | |||
assertThat(activeList.getParamsList()).extracting("key", "value").containsExactlyInAnyOrder( | |||
tuple(ruleParam.getName(), ruleParam.getDefaultValue()), | |||
tuple(activeRuleParam.getKey(), "") | |||
); | |||
tuple(activeRuleParam.getKey(), "")); | |||
} | |||
/** | |||
@@ -757,8 +770,7 @@ public class SearchActionTest { | |||
OrganizationDto organization = db.organizations().insert(); | |||
QProfileDto profile = db.qualityProfiles().insert(organization, q -> q | |||
.setLanguage("language1") | |||
); | |||
.setLanguage("language1")); | |||
// on same language, not activated => match | |||
RuleDefinitionDto rule1 = db.rules().insert(r -> r | |||
@@ -811,51 +823,45 @@ public class SearchActionTest { | |||
tuple(rule1.getLanguage(), 1L), | |||
// known limitation: irrelevant languages are shown in this case (SONAR-9683) | |||
tuple(rule3.getLanguage(), 1L) | |||
); | |||
tuple(rule3.getLanguage(), 1L)); | |||
assertThat(result.getFacets().getFacetsList().stream().filter(f -> "tags".equals(f.getProperty())).findAny().get().getValuesList()) | |||
.extracting(Common.FacetValue::getVal, Common.FacetValue::getCount) | |||
.as("Facet tags") | |||
.containsExactlyInAnyOrder( | |||
tuple(rule1.getSystemTags().iterator().next(), 1L) | |||
); | |||
tuple(rule1.getSystemTags().iterator().next(), 1L)); | |||
assertThat(result.getFacets().getFacetsList().stream().filter(f -> "repositories".equals(f.getProperty())).findAny().get().getValuesList()) | |||
.extracting(Common.FacetValue::getVal, Common.FacetValue::getCount) | |||
.as("Facet repositories") | |||
.containsExactlyInAnyOrder( | |||
tuple(rule1.getRepositoryKey(), 1L) | |||
); | |||
tuple(rule1.getRepositoryKey(), 1L)); | |||
assertThat(result.getFacets().getFacetsList().stream().filter(f -> "severities".equals(f.getProperty())).findAny().get().getValuesList()) | |||
.extracting(Common.FacetValue::getVal, Common.FacetValue::getCount) | |||
.as("Facet severities") | |||
.containsExactlyInAnyOrder( | |||
tuple("BLOCKER" /*rule2*/, 0L), | |||
tuple("CRITICAL"/*rule1*/, 1L), | |||
tuple("BLOCKER" /* rule2 */, 0L), | |||
tuple("CRITICAL"/* rule1 */, 1L), | |||
tuple("MAJOR", 0L), | |||
tuple("MINOR", 0L), | |||
tuple("INFO", 0L) | |||
); | |||
tuple("INFO", 0L)); | |||
assertThat(result.getFacets().getFacetsList().stream().filter(f -> "statuses".equals(f.getProperty())).findAny().get().getValuesList()) | |||
.extracting(Common.FacetValue::getVal, Common.FacetValue::getCount) | |||
.as("Facet statuses") | |||
.containsExactlyInAnyOrder( | |||
tuple("READY"/*rule2*/, 0L), | |||
tuple("BETA" /*rule1*/, 1L), | |||
tuple("DEPRECATED", 0L) | |||
); | |||
tuple("READY"/* rule2 */, 0L), | |||
tuple("BETA" /* rule1 */, 1L), | |||
tuple("DEPRECATED", 0L)); | |||
assertThat(result.getFacets().getFacetsList().stream().filter(f -> "types".equals(f.getProperty())).findAny().get().getValuesList()) | |||
.extracting(Common.FacetValue::getVal, Common.FacetValue::getCount) | |||
.as("Facet types") | |||
.containsExactlyInAnyOrder( | |||
tuple("BUG" /*rule2*/, 0L), | |||
tuple("CODE_SMELL"/*rule1*/, 1L), | |||
tuple("VULNERABILITY", 0L) | |||
); | |||
tuple("BUG" /* rule2 */, 0L), | |||
tuple("CODE_SMELL"/* rule1 */, 1L), | |||
tuple("VULNERABILITY", 0L)); | |||
} | |||
@Test | |||
@@ -875,8 +881,7 @@ public class SearchActionTest { | |||
assertThat(result.getRulesList()).extracting("key", "status.name").containsExactlyInAnyOrder( | |||
tuple(rule1.getKey().toString(), rule1.getStatus().name()), | |||
tuple(rule2.getKey().toString(), rule2.getStatus().name()), | |||
tuple(rule3.getKey().toString(), rule3.getStatus().name()) | |||
); | |||
tuple(rule3.getKey().toString(), rule3.getStatus().name())); | |||
} | |||
@Test |
@@ -47,6 +47,7 @@ import org.sonar.db.rule.RuleDto.Scope; | |||
import org.sonar.db.rule.RuleMetadataDto; | |||
import org.sonar.db.rule.RuleParamDto; | |||
import org.sonar.db.rule.RuleTesting; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.es.EsClient; | |||
import org.sonar.server.es.EsTester; | |||
import org.sonar.server.es.StartupIndexer; | |||
@@ -59,6 +60,7 @@ import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; | |||
import org.sonar.server.rule.NewCustomRule; | |||
import org.sonar.server.rule.RuleCreator; | |||
import org.sonar.server.rule.index.RuleIndexer; | |||
import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.text.MacroInterpreter; | |||
import org.sonar.server.util.TypeValidations; | |||
import org.sonar.server.ws.TestResponse; | |||
@@ -87,21 +89,23 @@ public class ShowActionTest { | |||
private static final String INTERPRETED = "interpreted"; | |||
@org.junit.Rule | |||
public DbTester dbTester = DbTester.create(); | |||
public UserSessionRule userSession = UserSessionRule.standalone(); | |||
@org.junit.Rule | |||
public DbTester db = DbTester.create(); | |||
@org.junit.Rule | |||
public EsTester es = EsTester.create(); | |||
@org.junit.Rule | |||
public ExpectedException thrown = ExpectedException.none(); | |||
private DbClient dbClient = dbTester.getDbClient(); | |||
private DbClient dbClient = db.getDbClient(); | |||
private EsClient esClient = es.client(); | |||
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester); | |||
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); | |||
private MacroInterpreter macroInterpreter = mock(MacroInterpreter.class); | |||
private Languages languages = new Languages(LanguageTesting.newLanguage("xoo", "Xoo")); | |||
private RuleMapper mapper = new RuleMapper(languages, macroInterpreter); | |||
private ActiveRuleCompleter activeRuleCompleter = mock(ActiveRuleCompleter.class); | |||
private WsAction underTest = new ShowAction(dbClient, mapper, activeRuleCompleter, defaultOrganizationProvider); | |||
private WsAction underTest = new ShowAction(dbClient, mapper, activeRuleCompleter, new RuleWsSupport(db.getDbClient(), userSession, defaultOrganizationProvider)); | |||
private WsActionTester actionTester = new WsActionTester(underTest); | |||
private RuleIndexer ruleIndexer = new RuleIndexer(esClient, dbClient); | |||
@@ -124,7 +128,7 @@ public class ShowActionTest { | |||
@Test | |||
public void should_show_rule_tags_in_default_organization() { | |||
RuleDefinitionDto rule = insertRule(); | |||
RuleMetadataDto metadata = insertMetadata(dbTester.getDefaultOrganization(), rule, setTags("tag1", "tag2")); | |||
RuleMetadataDto metadata = insertMetadata(db.getDefaultOrganization(), rule, setTags("tag1", "tag2"), m -> m.setNoteData(null).setNoteUserUuid(null)); | |||
Rules.ShowResponse result = actionTester.newRequest() | |||
.setParam(PARAM_KEY, rule.getKey().toString()) | |||
@@ -136,8 +140,8 @@ public class ShowActionTest { | |||
@Test | |||
public void should_show_rule_tags_in_specific_organization() { | |||
RuleDefinitionDto rule = insertRule(); | |||
OrganizationDto organization = dbTester.organizations().insert(); | |||
RuleMetadataDto metadata = insertMetadata(organization, rule, setTags("tag1", "tag2")); | |||
OrganizationDto organization = db.organizations().insert(); | |||
RuleMetadataDto metadata = insertMetadata(organization, rule, setTags("tag1", "tag2"), m -> m.setNoteData(null).setNoteUserUuid(null)); | |||
Rules.ShowResponse result = actionTester.newRequest() | |||
.setParam(PARAM_KEY, rule.getKey().toString()) | |||
@@ -149,14 +153,13 @@ public class ShowActionTest { | |||
@Test | |||
public void show_rule_with_activation() { | |||
OrganizationDto organization = dbTester.organizations().insert(); | |||
OrganizationDto organization = db.organizations().insert(); | |||
QProfileDto profile = QProfileTesting.newXooP1(organization); | |||
dbClient.qualityProfileDao().insert(dbTester.getSession(), profile); | |||
dbTester.commit(); | |||
dbClient.qualityProfileDao().insert(db.getSession(), profile); | |||
db.commit(); | |||
RuleDefinitionDto rule = insertRule(); | |||
RuleMetadataDto ruleMetadata = dbTester.rules().insertOrUpdateMetadata(rule, organization); | |||
RuleMetadataDto ruleMetadata = db.rules().insertOrUpdateMetadata(rule, organization, m -> m.setNoteData(null).setNoteUserUuid(null)); | |||
ArgumentCaptor<OrganizationDto> orgCaptor = ArgumentCaptor.forClass(OrganizationDto.class); | |||
ArgumentCaptor<RuleDefinitionDto> ruleCaptor = ArgumentCaptor.forClass(RuleDefinitionDto.class); | |||
@@ -192,16 +195,16 @@ public class ShowActionTest { | |||
@Test | |||
public void show_rule_without_activation() { | |||
OrganizationDto organization = dbTester.organizations().insert(); | |||
OrganizationDto organization = db.organizations().insert(); | |||
QProfileDto profile = QProfileTesting.newXooP1(organization); | |||
dbClient.qualityProfileDao().insert(dbTester.getSession(), profile); | |||
dbTester.commit(); | |||
dbClient.qualityProfileDao().insert(db.getSession(), profile); | |||
db.commit(); | |||
RuleDefinitionDto rule = insertRule(); | |||
RuleMetadataDto ruleMetadata = dbTester.rules().insertOrUpdateMetadata(rule, organization); | |||
RuleMetadataDto ruleMetadata = db.rules().insertOrUpdateMetadata(rule, organization, m -> m.setNoteData(null).setNoteUserUuid(null)); | |||
dbTester.qualityProfiles().activateRule(profile, rule, a -> a.setSeverity("BLOCKER")); | |||
db.qualityProfiles().activateRule(profile, rule, a -> a.setSeverity("BLOCKER")); | |||
ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(dbClient, esClient); | |||
activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes()); | |||
@@ -221,7 +224,7 @@ public class ShowActionTest { | |||
@Test | |||
public void throw_NotFoundException_if_organization_cannot_be_found() { | |||
RuleDefinitionDto rule = dbTester.rules().insert(); | |||
RuleDefinitionDto rule = db.rules().insert(); | |||
thrown.expect(NotFoundException.class); | |||
@@ -232,8 +235,8 @@ public class ShowActionTest { | |||
} | |||
@Test | |||
public void show_rule() throws Exception { | |||
RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), dbTester.getDefaultOrganization()) | |||
public void show_rule() { | |||
RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), db.getDefaultOrganization()) | |||
.setName("Rule S001") | |||
.setDescription("Rule S001 <b>description</b>") | |||
.setDescriptionFormat(Format.HTML) | |||
@@ -247,7 +250,7 @@ public class ShowActionTest { | |||
.setScope(Scope.ALL); | |||
RuleDefinitionDto definition = ruleDto.getDefinition(); | |||
RuleDao ruleDao = dbClient.ruleDao(); | |||
DbSession session = dbTester.getSession(); | |||
DbSession session = db.getSession(); | |||
ruleDao.insert(session, definition); | |||
ruleDao.insertOrUpdate(session, ruleDto.getMetadata().setRuleId(ruleDto.getId())); | |||
RuleParamDto param = RuleParamDto.createFor(definition).setName("regex").setType("STRING").setDescription("Reg *exp*").setDefaultValue(".*"); | |||
@@ -261,8 +264,8 @@ public class ShowActionTest { | |||
} | |||
@Test | |||
public void show_rule_with_default_debt_infos() throws Exception { | |||
RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), dbTester.getDefaultOrganization()) | |||
public void show_rule_with_default_debt_infos() { | |||
RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), db.getDefaultOrganization()) | |||
.setName("Rule S001") | |||
.setDescription("Rule S001 <b>description</b>") | |||
.setSeverity(MINOR) | |||
@@ -277,7 +280,7 @@ public class ShowActionTest { | |||
.setRemediationBaseEffort(null) | |||
.setScope(Scope.ALL); | |||
RuleDao ruleDao = dbClient.ruleDao(); | |||
DbSession session = dbTester.getSession(); | |||
DbSession session = db.getSession(); | |||
ruleDao.insert(session, ruleDto.getDefinition()); | |||
ruleDao.insertOrUpdate(session, ruleDto.getMetadata()); | |||
session.commit(); | |||
@@ -290,8 +293,8 @@ public class ShowActionTest { | |||
} | |||
@Test | |||
public void show_rule_with_overridden_debt() throws Exception { | |||
RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), dbTester.getDefaultOrganization()) | |||
public void show_rule_with_overridden_debt() { | |||
RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), db.getDefaultOrganization()) | |||
.setName("Rule S001") | |||
.setDescription("Rule S001 <b>description</b>") | |||
.setSeverity(MINOR) | |||
@@ -306,7 +309,7 @@ public class ShowActionTest { | |||
.setRemediationBaseEffort("10h") | |||
.setScope(Scope.ALL); | |||
RuleDao ruleDao = dbClient.ruleDao(); | |||
DbSession session = dbTester.getSession(); | |||
DbSession session = db.getSession(); | |||
ruleDao.insert(session, ruleDto.getDefinition()); | |||
ruleDao.insertOrUpdate(session, ruleDto.getMetadata().setRuleId(ruleDto.getId())); | |||
session.commit(); | |||
@@ -318,8 +321,8 @@ public class ShowActionTest { | |||
} | |||
@Test | |||
public void show_rule_with_default_and_overridden_debt_infos() throws Exception { | |||
RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), dbTester.getDefaultOrganization()) | |||
public void show_rule_with_default_and_overridden_debt_infos() { | |||
RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), db.getDefaultOrganization()) | |||
.setName("Rule S001") | |||
.setDescription("Rule S001 <b>description</b>") | |||
.setSeverity(MINOR) | |||
@@ -334,7 +337,7 @@ public class ShowActionTest { | |||
.setRemediationBaseEffort("10h") | |||
.setScope(Scope.ALL); | |||
RuleDao ruleDao = dbClient.ruleDao(); | |||
DbSession session = dbTester.getSession(); | |||
DbSession session = db.getSession(); | |||
ruleDao.insert(session, ruleDto.getDefinition()); | |||
ruleDao.insertOrUpdate(session, ruleDto.getMetadata().setRuleId(ruleDto.getId())); | |||
session.commit(); | |||
@@ -346,7 +349,7 @@ public class ShowActionTest { | |||
} | |||
@Test | |||
public void show_rule_with_no_default_and_no_overridden_debt() throws Exception { | |||
public void show_rule_with_no_default_and_no_overridden_debt() { | |||
RuleDefinitionDto ruleDto = RuleTesting.newRule(RuleKey.of("java", "S001")) | |||
.setName("Rule S001") | |||
.setDescription("Rule S001 <b>description</b>") | |||
@@ -360,7 +363,7 @@ public class ShowActionTest { | |||
.setDefRemediationBaseEffort(null) | |||
.setScope(Scope.ALL); | |||
RuleDao ruleDao = dbClient.ruleDao(); | |||
DbSession session = dbTester.getSession(); | |||
DbSession session = db.getSession(); | |||
ruleDao.insert(session, ruleDto); | |||
session.commit(); | |||
session.clearCache(); | |||
@@ -375,7 +378,7 @@ public class ShowActionTest { | |||
// Template rule | |||
RuleDto templateRule = RuleTesting.newTemplateRule(RuleKey.of("java", "S001")); | |||
RuleDao ruleDao = dbClient.ruleDao(); | |||
DbSession session = dbTester.getSession(); | |||
DbSession session = db.getSession(); | |||
ruleDao.insert(session, templateRule.getDefinition()); | |||
session.commit(); | |||
@@ -385,7 +388,7 @@ public class ShowActionTest { | |||
.setSeverity(MINOR) | |||
.setStatus(RuleStatus.READY) | |||
.setMarkdownDescription("<div>line1\nline2</div>"); | |||
RuleKey customRuleKey = new RuleCreator(System2.INSTANCE, ruleIndexer, dbClient, new TypeValidations(asList()), TestDefaultOrganizationProvider.from(dbTester)).create(session, customRule); | |||
RuleKey customRuleKey = new RuleCreator(System2.INSTANCE, ruleIndexer, dbClient, new TypeValidations(asList()), TestDefaultOrganizationProvider.from(db)).create(session, customRule); | |||
session.clearCache(); | |||
doReturn("<div>line1<br/>line2</div>").when(macroInterpreter).interpret("<div>line1\nline2</div>"); | |||
@@ -402,8 +405,8 @@ public class ShowActionTest { | |||
} | |||
@Test | |||
public void show_deprecated_rule_rem_function_fields() throws Exception { | |||
RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), dbTester.getDefaultOrganization()) | |||
public void show_deprecated_rule_rem_function_fields() { | |||
RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), db.getDefaultOrganization()) | |||
.setName("Rule S001") | |||
.setDescription("Rule S001 <b>description</b>") | |||
.setSeverity(MINOR) | |||
@@ -418,7 +421,7 @@ public class ShowActionTest { | |||
.setRemediationBaseEffort("10h") | |||
.setScope(Scope.ALL); | |||
RuleDao ruleDao = dbClient.ruleDao(); | |||
DbSession session = dbTester.getSession(); | |||
DbSession session = db.getSession(); | |||
ruleDao.insert(session, ruleDto.getDefinition()); | |||
ruleDao.insertOrUpdate(session, ruleDto.getMetadata().setRuleId(ruleDto.getId())); | |||
session.commit(); | |||
@@ -429,7 +432,7 @@ public class ShowActionTest { | |||
} | |||
@Test | |||
public void show_rule_when_activated() throws Exception { | |||
public void show_rule_when_activated() { | |||
RuleDefinitionDto ruleDto = RuleTesting.newRule(RuleKey.of("java", "S001")) | |||
.setName("Rule S001") | |||
.setDescription("Rule S001 <b>description</b>") | |||
@@ -442,7 +445,7 @@ public class ShowActionTest { | |||
.setUpdatedAt(new Date().getTime()) | |||
.setScope(Scope.ALL); | |||
RuleDao ruleDao = dbClient.ruleDao(); | |||
DbSession session = dbTester.getSession(); | |||
DbSession session = db.getSession(); | |||
ruleDao.insert(session, ruleDto); | |||
session.commit(); | |||
ruleIndexer.commitAndIndex(session, ruleDto.getId()); | |||
@@ -473,7 +476,7 @@ public class ShowActionTest { | |||
activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes()); | |||
ActiveRuleCompleter activeRuleCompleter = new ActiveRuleCompleter(dbClient, languages); | |||
WsAction underTest = new ShowAction(dbClient, mapper, activeRuleCompleter, defaultOrganizationProvider); | |||
WsAction underTest = new ShowAction(dbClient, mapper, activeRuleCompleter, new RuleWsSupport(db.getDbClient(), userSession, defaultOrganizationProvider)); | |||
WsActionTester actionTester = new WsActionTester(underTest); | |||
actionTester.newRequest() | |||
@@ -482,6 +485,22 @@ public class ShowActionTest { | |||
.execute().assertJson(getClass(), "show_rule_when_activated.json"); | |||
} | |||
@Test | |||
public void show_rule_with_note_login() { | |||
RuleDefinitionDto rule = insertRule(); | |||
UserDto user = db.users().insertUser(); | |||
OrganizationDto organization = db.organizations().insert(); | |||
db.rules().insertOrUpdateMetadata(rule, user, organization); | |||
ruleIndexer.commitAndIndex(db.getSession(), rule.getId(), organization); | |||
Rules.ShowResponse result = actionTester.newRequest() | |||
.setParam(PARAM_KEY, rule.getKey().toString()) | |||
.setParam(PARAM_ORGANIZATION, organization.getKey()) | |||
.executeProtobuf(Rules.ShowResponse.class); | |||
assertThat(result.getRule().getNoteLogin()).isEqualTo(user.getLogin()); | |||
} | |||
private void assertEqual(RuleDefinitionDto rule, RuleMetadataDto ruleMetadata, Rule resultRule) { | |||
assertThat(resultRule.getKey()).isEqualTo(rule.getKey().toString()); | |||
assertThat(resultRule.getRepo()).isEqualTo(rule.getRepositoryKey()); | |||
@@ -497,15 +516,15 @@ public class ShowActionTest { | |||
} | |||
private RuleDefinitionDto insertRule() { | |||
RuleDefinitionDto rule = dbTester.rules().insert(); | |||
ruleIndexer.commitAndIndex(dbTester.getSession(), rule.getId()); | |||
RuleDefinitionDto rule = db.rules().insert(); | |||
ruleIndexer.commitAndIndex(db.getSession(), rule.getId()); | |||
return rule; | |||
} | |||
@SafeVarargs | |||
private final RuleMetadataDto insertMetadata(OrganizationDto organization, RuleDefinitionDto rule, Consumer<RuleMetadataDto>... populaters) { | |||
RuleMetadataDto metadata = dbTester.rules().insertOrUpdateMetadata(rule, organization, populaters); | |||
ruleIndexer.commitAndIndex(dbTester.getSession(), rule.getId(), organization); | |||
RuleMetadataDto metadata = db.rules().insertOrUpdateMetadata(rule, organization, populaters); | |||
ruleIndexer.commitAndIndex(db.getSession(), rule.getId(), organization); | |||
return metadata; | |||
} | |||
} |
@@ -33,6 +33,7 @@ import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.rule.RuleDefinitionDto; | |||
import org.sonar.db.rule.RuleMetadataDto; | |||
import org.sonar.db.rule.RuleTesting; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.server.es.EsClient; | |||
import org.sonar.server.es.EsTester; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
@@ -63,6 +64,7 @@ import static org.sonar.server.rule.ws.UpdateAction.DEPRECATED_PARAM_REMEDIATION | |||
import static org.sonar.server.rule.ws.UpdateAction.DEPRECATED_PARAM_REMEDIATION_FN_OFFSET; | |||
import static org.sonar.server.rule.ws.UpdateAction.DEPRECATED_PARAM_REMEDIATION_FN_TYPE; | |||
import static org.sonar.server.rule.ws.UpdateAction.PARAM_KEY; | |||
import static org.sonar.server.rule.ws.UpdateAction.PARAM_MARKDOWN_NOTE; | |||
import static org.sonar.server.rule.ws.UpdateAction.PARAM_ORGANIZATION; | |||
import static org.sonar.server.rule.ws.UpdateAction.PARAM_REMEDIATION_FN_BASE_EFFORT; | |||
import static org.sonar.server.rule.ws.UpdateAction.PARAM_REMEDIATION_FN_GAP_MULTIPLIER; | |||
@@ -94,7 +96,7 @@ public class UpdateActionTest { | |||
private RuleMapper mapper = new RuleMapper(languages, createMacroInterpreter()); | |||
private RuleIndexer ruleIndexer = new RuleIndexer(esClient, dbClient); | |||
private RuleUpdater ruleUpdater = new RuleUpdater(dbClient, ruleIndexer, System2.INSTANCE); | |||
private WsAction underTest = new UpdateAction(dbClient, ruleUpdater, mapper, userSession, defaultOrganizationProvider); | |||
private WsAction underTest = new UpdateAction(dbClient, ruleUpdater, mapper, userSession, new RuleWsSupport(db.getDbClient(), userSession, defaultOrganizationProvider)); | |||
private WsActionTester ws = new WsActionTester(underTest); | |||
@Test | |||
@@ -153,7 +155,7 @@ public class UpdateActionTest { | |||
logInAsQProfileAdministrator(); | |||
RuleDefinitionDto rule = db.rules().insert(setSystemTags("stag1", "stag2")); | |||
db.rules().insertOrUpdateMetadata(rule, db.getDefaultOrganization(), setTags("tag1", "tag2")); | |||
db.rules().insertOrUpdateMetadata(rule, db.getDefaultOrganization(), setTags("tag1", "tag2"), m -> m.setNoteData(null).setNoteUserUuid(null)); | |||
Rules.UpdateResponse result = ws.newRequest().setMethod("POST") | |||
.setParam(PARAM_KEY, rule.getKey().toString()) | |||
@@ -174,7 +176,7 @@ public class UpdateActionTest { | |||
logInAsQProfileAdministrator(organization.getUuid()); | |||
RuleDefinitionDto rule = db.rules().insert(setSystemTags("stag1", "stag2")); | |||
db.rules().insertOrUpdateMetadata(rule, organization, setTags("tagAlt1", "tagAlt2")); | |||
db.rules().insertOrUpdateMetadata(rule, organization, setTags("tagAlt1", "tagAlt2"), m -> m.setNoteData(null).setNoteUserUuid(null)); | |||
Rules.UpdateResponse result = ws.newRequest().setMethod("POST") | |||
.setParam(PARAM_KEY, rule.getKey().toString()) | |||
@@ -279,6 +281,33 @@ public class UpdateActionTest { | |||
assertThat(updatedRule.getGapDescription()).isEqualTo(rule.getGapDescription()); | |||
} | |||
@Test | |||
public void update_note() { | |||
OrganizationDto organization = db.organizations().insert(); | |||
RuleDefinitionDto rule = db.rules().insert(); | |||
UserDto userHavingUpdatingNote = db.users().insertUser(); | |||
db.rules().insertOrUpdateMetadata(rule, userHavingUpdatingNote, organization, m -> m.setNoteData("old data")); | |||
UserDto userAuthenticated = db.users().insertUser(); | |||
userSession.logIn(userAuthenticated).addPermission(ADMINISTER_QUALITY_PROFILES, organization); | |||
Rules.UpdateResponse result = ws.newRequest().setMethod("POST") | |||
.setParam(PARAM_KEY, rule.getKey().toString()) | |||
.setParam(PARAM_MARKDOWN_NOTE, "new data") | |||
.setParam(PARAM_ORGANIZATION, organization.getKey()) | |||
.executeProtobuf(Rules.UpdateResponse.class); | |||
Rules.Rule updatedRule = result.getRule(); | |||
// check response | |||
assertThat(updatedRule.getMdNote()).isEqualTo("new data"); | |||
assertThat(updatedRule.getNoteLogin()).isEqualTo(userAuthenticated.getLogin()); | |||
// check database | |||
RuleMetadataDto metadataOfSpecificOrg = db.getDbClient().ruleDao().selectMetadataByKey(db.getSession(), rule.getKey(), organization).get(); | |||
assertThat(metadataOfSpecificOrg.getNoteData()).isEqualTo("new data"); | |||
assertThat(metadataOfSpecificOrg.getNoteUserUuid()).isEqualTo(userAuthenticated.getUuid()); | |||
} | |||
@Test | |||
public void fail_to_update_custom_when_description_is_empty() { | |||
logInAsQProfileAdministrator(); |
@@ -36,6 +36,7 @@ import org.sonarqube.ws.Organizations.Organization; | |||
import org.sonarqube.ws.Projects; | |||
import org.sonarqube.ws.Projects.CreateWsResponse.Project; | |||
import org.sonarqube.ws.Qualityprofiles; | |||
import org.sonarqube.ws.Rules; | |||
import org.sonarqube.ws.Settings; | |||
import org.sonarqube.ws.UserTokens; | |||
import org.sonarqube.ws.Users; | |||
@@ -47,6 +48,7 @@ import org.sonarqube.ws.client.organizations.AddMemberRequest; | |||
import org.sonarqube.ws.client.organizations.SearchRequest; | |||
import org.sonarqube.ws.client.permissions.AddUserRequest; | |||
import org.sonarqube.ws.client.qualityprofiles.ChangelogRequest; | |||
import org.sonarqube.ws.client.rules.UpdateRequest; | |||
import org.sonarqube.ws.client.settings.SetRequest; | |||
import org.sonarqube.ws.client.settings.ValuesRequest; | |||
import org.sonarqube.ws.client.usertokens.GenerateRequest; | |||
@@ -54,6 +56,7 @@ import org.sonarqube.ws.client.usertokens.GenerateRequest; | |||
import static java.util.Collections.singletonList; | |||
import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.assertj.core.api.Assertions.tuple; | |||
import static org.skyscreamer.jsonassert.JSONAssert.assertEquals; | |||
import static util.ItUtils.projectDir; | |||
@@ -326,6 +329,38 @@ public class SonarCloudUpdateLoginDuringAuthenticationTest { | |||
false); | |||
} | |||
@Test | |||
public void rule_note_login_after_login_update() { | |||
tester.settings().setGlobalSettings("sonar.organizations.anyoneCanCreate", "true"); | |||
String providerId = tester.users().generateProviderId(); | |||
String oldLogin = tester.users().generateLogin(); | |||
// Create user using authentication | |||
authenticate(oldLogin, providerId); | |||
String userToken = tester.wsClient().userTokens().generate(new GenerateRequest().setLogin(oldLogin).setName("token")).getToken(); | |||
WsClient userWsClient = tester.as(userToken, null).wsClient(); | |||
// Grant user the qprofile admin permission on the organization | |||
Organization organization = tester.organizations().generate(); | |||
tester.organizations().service().addMember(new AddMemberRequest().setOrganization(organization.getKey()).setLogin(oldLogin)); | |||
tester.wsClient().permissions().addUser(new AddUserRequest().setLogin(oldLogin).setOrganization(organization.getKey()).setPermission("profileadmin")); | |||
// Add a note on a rule | |||
userWsClient.rules().update(new UpdateRequest().setOrganization(organization.getKey()).setKey("xoo:OneIssuePerLine").setMarkdownNote("A user note")); | |||
assertThat( | |||
tester.wsClient().rules().search(new org.sonarqube.ws.client.rules.SearchRequest().setOrganization(organization.getKey()).setRuleKey("xoo:OneIssuePerLine")).getRulesList()) | |||
.extracting(Rules.Rule::getKey, Rules.Rule::getNoteLogin, Rules.Rule::getMdNote) | |||
.containsExactlyInAnyOrder(tuple("xoo:OneIssuePerLine", oldLogin, "A user note")); | |||
// Update login during authentication, check rule note contains new user login | |||
String newLogin = tester.users().generateLogin(); | |||
authenticate(newLogin, providerId); | |||
assertThat( | |||
tester.wsClient().rules().search(new org.sonarqube.ws.client.rules.SearchRequest().setOrganization(organization.getKey()).setRuleKey("xoo:OneIssuePerLine")).getRulesList()) | |||
.extracting(Rules.Rule::getKey, Rules.Rule::getNoteLogin, Rules.Rule::getMdNote) | |||
.containsExactlyInAnyOrder(tuple("xoo:OneIssuePerLine", newLogin, "A user note")); | |||
} | |||
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( |