diff options
author | Jenkins CI <ci@sonarsource.com> | 2015-10-21 08:01:17 +0200 |
---|---|---|
committer | Jenkins CI <ci@sonarsource.com> | 2015-10-21 08:01:17 +0200 |
commit | df2b95020a82ed588d35526ff915ac2187c325da (patch) | |
tree | 965cf32dc362e2b205fd6cf7996646c332b27fa2 | |
parent | 187f501d31cba9ff220c44bbcd222768a4eee40e (diff) | |
parent | 5945ad454bcbac6bd7f1f6c9651daabeffe02f4f (diff) | |
download | sonarqube-df2b95020a82ed588d35526ff915ac2187c325da.tar.gz sonarqube-df2b95020a82ed588d35526ff915ac2187c325da.zip |
Automatic merge from branch-5.2
* origin/branch-5.2:
[maven-release-plugin] prepare for next development iteration
[maven-release-plugin] prepare release 5.2-RC3
Hack for IE - use mime type text/plain for api/qualityprofiles/create
fix quality profile deletion dialog on ie9
Fix some quality flaw
SONAR-6822 Rules search WS is not returning langName
SONAR-6822 Move search action tests to a dedicated test class
SONAR-6680 RuleRepository now load all rules at first call
SONAR-6680 add RuleDao.selectAll to be used by CE's RuleRepository
Fix quality flaws
fix select2 closing problem in the facet sidebar
42 files changed, 1078 insertions, 751 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/container/ReportComputeEngineContainerPopulator.java b/server/sonar-server/src/main/java/org/sonar/server/computation/container/ReportComputeEngineContainerPopulator.java index 1273a1e2d4e..e2118173965 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/container/ReportComputeEngineContainerPopulator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/container/ReportComputeEngineContainerPopulator.java @@ -48,7 +48,6 @@ import org.sonar.server.computation.issue.IssueVisitors; import org.sonar.server.computation.issue.LoadComponentUuidsHavingOpenIssuesVisitor; import org.sonar.server.computation.issue.NewDebtAggregator; import org.sonar.server.computation.issue.NewDebtCalculator; -import org.sonar.server.computation.issue.RuleCacheLoader; import org.sonar.server.computation.issue.RuleRepositoryImpl; import org.sonar.server.computation.issue.RuleTagsCopier; import org.sonar.server.computation.issue.ScmAccountToUser; @@ -140,7 +139,6 @@ public final class ReportComputeEngineContainerPopulator implements ContainerPop ScmInfoRepositoryImpl.class, // issues - RuleCacheLoader.class, RuleRepositoryImpl.class, ScmAccountToUserLoader.class, ScmAccountToUser.class, diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/RuleCacheLoader.java b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/RuleCacheLoader.java deleted file mode 100644 index 8f2443c5c7f..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/RuleCacheLoader.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube 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. - * - * SonarQube 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.computation.issue; - -import com.google.common.base.Optional; -import java.util.Collection; -import java.util.Map; -import org.sonar.api.rule.RuleKey; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.MyBatis; -import org.sonar.db.rule.RuleDto; -import org.sonar.server.util.cache.CacheLoader; - -public class RuleCacheLoader implements CacheLoader<RuleKey, Rule> { - - private final DbClient dbClient; - - public RuleCacheLoader(DbClient dbClient) { - this.dbClient = dbClient; - } - - @Override - public Rule load(RuleKey key) { - DbSession session = dbClient.openSession(false); - try { - Optional<RuleDto> dto = dbClient.ruleDao().selectByKey(session, key); - if (dto.isPresent()) { - return new RuleImpl(dto.get()); - } - return null; - } finally { - MyBatis.closeQuietly(session); - } - } - - @Override - public Map<RuleKey, Rule> loadAll(Collection<? extends RuleKey> keys) { - throw new UnsupportedOperationException("Not implemented yet"); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/RuleRepository.java b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/RuleRepository.java index 57bd78c1e19..be6facd2640 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/RuleRepository.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/RuleRepository.java @@ -19,11 +19,29 @@ */ package org.sonar.server.computation.issue; +import com.google.common.base.Optional; import org.sonar.api.rule.RuleKey; +/** + * Repository of every rule in DB (including manual rules) whichever their status. + */ public interface RuleRepository { + /** + * @throws NullPointerException if {@code key} is {@code null} + * @throws IllegalArgumentException when there is no Rule for the specified RuleKey in the repository + */ Rule getByKey(RuleKey key); - boolean hasKey(RuleKey key); + /** + * @throws IllegalArgumentException when there is no Rule for the specified RuleKey in the repository + */ + Rule getById(int id); + + /** + * @throws NullPointerException if {@code key} is {@code null} + */ + Optional<Rule> findByKey(RuleKey key); + + Optional<Rule> findById(int id); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/RuleRepositoryImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/RuleRepositoryImpl.java index 63c96ab24b6..dd2935e58e5 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/RuleRepositoryImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/RuleRepositoryImpl.java @@ -19,24 +19,92 @@ */ package org.sonar.server.computation.issue; +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableMap; +import java.util.Map; +import javax.annotation.CheckForNull; import org.sonar.api.rule.RuleKey; -import org.sonar.server.util.cache.MemoryCache; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.rule.RuleDto; + +import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; public class RuleRepositoryImpl implements RuleRepository { - private final MemoryCache<RuleKey, Rule> cache; + @CheckForNull + private Map<RuleKey, Rule> rulesByKey; + @CheckForNull + private Map<Integer, Rule> rulesById; + + private final DbClient dbClient; - public RuleRepositoryImpl(RuleCacheLoader cacheLoader) { - this.cache = new MemoryCache<>(cacheLoader); + public RuleRepositoryImpl(DbClient dbClient) { + this.dbClient = dbClient; } @Override public Rule getByKey(RuleKey key) { - return cache.get(key); + verifyKeyArgument(key); + + ensureInitialized(); + + Rule rule = rulesByKey.get(key); + checkArgument(rule != null, "Can not find rule for key %s. This rule does not exist in DB", key); + return rule; } @Override - public boolean hasKey(RuleKey key) { - return cache.getNullable(key) != null; + public Optional<Rule> findByKey(RuleKey key) { + verifyKeyArgument(key); + + ensureInitialized(); + + return Optional.fromNullable(rulesByKey.get(key)); } + + @Override + public Rule getById(int id) { + ensureInitialized(); + + Rule rule = rulesById.get(id); + checkArgument(rule != null, "Can not find rule for id %s. This rule does not exist in DB", id); + return rule; + } + + @Override + public Optional<Rule> findById(int id) { + ensureInitialized(); + + return Optional.fromNullable(rulesById.get(id)); + } + + private static void verifyKeyArgument(RuleKey key) { + requireNonNull(key, "RuleKey can not be null"); + } + + private void ensureInitialized() { + if (rulesByKey == null) { + DbSession dbSession = dbClient.openSession(false); + try { + loadRulesFromDb(dbSession); + } finally { + dbClient.closeSession(dbSession); + } + } + } + + private void loadRulesFromDb(DbSession dbSession) { + ImmutableMap.Builder<RuleKey, Rule> rulesByKeyBuilder = ImmutableMap.builder(); + ImmutableMap.Builder<Integer, Rule> rulesByIdBuilder = ImmutableMap.builder(); + for (RuleDto ruleDto : dbClient.ruleDao().selectAll(dbSession)) { + Rule rule = new RuleImpl(ruleDto); + rulesByKeyBuilder.put(ruleDto.getKey(), rule); + rulesByIdBuilder.put(ruleDto.getId(), rule); + } + this.rulesByKey = rulesByKeyBuilder.build(); + this.rulesById = rulesByIdBuilder.build(); + } + } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/LoadQualityProfilesStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/LoadQualityProfilesStep.java index bf19a622dda..c7b73058510 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/LoadQualityProfilesStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/LoadQualityProfilesStep.java @@ -19,6 +19,7 @@ */ package org.sonar.server.computation.step; +import com.google.common.base.Optional; import com.google.common.base.Predicate; import java.util.ArrayList; import java.util.HashMap; @@ -66,11 +67,8 @@ public class LoadQualityProfilesStep implements ComputationStep { private class IsValid implements Predicate<ActiveRule> { @Override public boolean apply(@Nonnull ActiveRule input) { - if (ruleRepository.hasKey(input.getRuleKey())) { - Rule rule = ruleRepository.getByKey(input.getRuleKey()); - return rule.getStatus() != RuleStatus.REMOVED; - } - return false; + Optional<Rule> rule = ruleRepository.findByKey(input.getRuleKey()); + return rule.isPresent() && rule.get().getStatus() != RuleStatus.REMOVED; } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/BulkIndexer.java b/server/sonar-server/src/main/java/org/sonar/server/es/BulkIndexer.java index 56352214b12..706454ed545 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/es/BulkIndexer.java +++ b/server/sonar-server/src/main/java/org/sonar/server/es/BulkIndexer.java @@ -46,6 +46,8 @@ import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; +import static java.lang.String.format; + /** * Helper to bulk requests in an efficient way : * <ul> @@ -76,7 +78,7 @@ public class BulkIndexer implements Startable { public BulkIndexer(EsClient client, String indexName) { this.client = client; this.indexName = indexName; - this.progress = new ProgressLogger(String.format("Progress[BulkIndexer[%s]]", indexName), counter, LOGGER) + this.progress = new ProgressLogger(format("Progress[BulkIndexer[%s]]", indexName), counter, LOGGER) .setPluralLabel("requests"); this.concurrentRequests = Math.max(1, Runtime.getRuntime().availableProcessors() - 1); @@ -235,11 +237,7 @@ public class BulkIndexer implements Startable { for (BulkItemResponse item : response.getItems()) { if (item.isFailed()) { - StringBuilder sb = new StringBuilder(); - String msg = sb - .append("index [").append(item.getIndex()).append("], type [").append(item.getType()).append("], id [").append(item.getId()) - .append("], message [").append(item.getFailureMessage()).append("]").toString(); - LOGGER.error(msg); + LOGGER.error("index [{}], type [{}], id [{}], message [{}]", item.getIndex(), item.getType(), item.getId(), item.getFailureMessage()); } } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java index 07b626edc24..0a40d32a3fd 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/CreateAction.java @@ -19,6 +19,8 @@ */ package org.sonar.server.qualityprofile.ws; +import java.io.InputStream; +import java.io.OutputStreamWriter; import org.sonar.api.profiles.ProfileImporter; import org.sonar.api.resources.Languages; import org.sonar.api.server.ws.Request; @@ -27,17 +29,16 @@ import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.NewAction; import org.sonar.api.utils.text.JsonWriter; import org.sonar.core.permission.GlobalPermissions; +import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.qualityprofile.QualityProfileDto; -import org.sonar.db.DbClient; +import org.sonar.server.plugins.MimeTypes; import org.sonar.server.qualityprofile.QProfileExporters; import org.sonar.server.qualityprofile.QProfileFactory; import org.sonar.server.qualityprofile.QProfileName; import org.sonar.server.qualityprofile.QProfileResult; import org.sonar.server.user.UserSession; -import java.io.InputStream; - public class CreateAction implements QProfileWsAction { private static final String PARAM_PROFILE_NAME = "name"; @@ -56,7 +57,7 @@ public class CreateAction implements QProfileWsAction { private final UserSession userSession; public CreateAction(DbClient dbClient, QProfileFactory profileFactory, QProfileExporters exporters, - Languages languages, ProfileImporter[] importers, UserSession userSession) { + Languages languages, ProfileImporter[] importers, UserSession userSession) { this.dbClient = dbClient; this.profileFactory = profileFactory; this.exporters = exporters; @@ -115,12 +116,29 @@ public class CreateAction implements QProfileWsAction { } } dbSession.commit(); - writeResult(response.newJsonWriter(), result); + + response.stream().setMediaType(guessMediaType(request)); + JsonWriter jsonWriter = JsonWriter.of(new OutputStreamWriter(response.stream().output())); + writeResult(jsonWriter, result); } finally { dbSession.close(); } } + private static String guessMediaType(Request request) { + if (request.getMediaType().contains("html")) { + // this is a hack for IE. + // The form which uploads files (for example PMD or Findbugs configuration files) opens a popup + // to download files if the response type header is application/json. Changing the response type to text/plain, + // even if response body is JSON, fixes the bug. + // This will be fixed in 5.3 when support of IE9/10 will be dropped in order to use + // more recent JS libs. + // We detect that caller is IE because it asks for application/html or text/html + return MimeTypes.TXT; + } + return request.getMediaType(); + } + private void writeResult(JsonWriter json, QProfileResult result) { String language = result.profile().getLanguage(); json.beginObject().name("profile").beginObject() @@ -151,7 +169,7 @@ public class CreateAction implements QProfileWsAction { json.endObject().close(); } - private String getBackupParamName(String importerKey) { + private static String getBackupParamName(String importerKey) { return String.format(PARAM_BACKUP_FORMAT, importerKey); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleMapping.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleMapping.java index 3e084ef6a27..449c52b7758 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleMapping.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleMapping.java @@ -21,12 +21,6 @@ package org.sonar.server.rule.ws; import com.google.common.base.Function; import com.google.common.collect.Maps; -import java.util.Collections; -import java.util.Map; -import java.util.Set; -import javax.annotation.CheckForNull; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import org.sonar.api.resources.Language; import org.sonar.api.resources.Languages; import org.sonar.api.rule.RuleKey; @@ -47,6 +41,14 @@ import org.sonar.server.user.UserSession; import org.sonarqube.ws.Common; import org.sonarqube.ws.Rules; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; + import static com.google.common.collect.FluentIterable.from; import static org.sonar.api.utils.DateUtils.formatDateTime; @@ -138,9 +140,11 @@ public class RuleMapping extends BaseMapping<RuleDoc, RuleMappingContext> { setParams(ruleResponse, ruleDoc, fieldsToReturn); setCreatedAt(ruleResponse, ruleDoc, fieldsToReturn); setDescriptionFields(ruleResponse, ruleDoc, fieldsToReturn); + setNotesFields(ruleResponse, ruleDoc, fieldsToReturn); setSeverity(ruleResponse, ruleDoc, fieldsToReturn); setInternalKey(ruleResponse, ruleDoc, fieldsToReturn); setLanguage(ruleResponse, ruleDoc, fieldsToReturn); + setLanguageName(ruleResponse, ruleDoc, fieldsToReturn); setIsTemplate(ruleResponse, ruleDoc, fieldsToReturn); setTemplateKey(ruleResponse, ruleDoc, fieldsToReturn); setDebtRemediationFunctionFields(ruleResponse, ruleDoc, fieldsToReturn); @@ -288,15 +292,18 @@ public class RuleMapping extends BaseMapping<RuleDoc, RuleMappingContext> { ruleResponse.setHtmlDesc(macroInterpreter.interpret(ruleDoc.htmlDescription())); } } + if (shouldReturnField(fieldsToReturn, RuleNormalizer.RuleField.MARKDOWN_DESCRIPTION) && ruleDoc.markdownDescription() != null) { + ruleResponse.setMdDesc(ruleDoc.markdownDescription()); + } + } + + private void setNotesFields(Rules.Rule.Builder ruleResponse, Rule ruleDoc, Set<String> fieldsToReturn) { if (shouldReturnField(fieldsToReturn, "htmlNote") && ruleDoc.markdownNote() != null) { ruleResponse.setHtmlNote(macroInterpreter.interpret(Markdown.convertToHtml(ruleDoc.markdownNote()))); } if (shouldReturnField(fieldsToReturn, "mdNote") && ruleDoc.markdownNote() != null) { ruleResponse.setMdNote(ruleDoc.markdownNote()); } - if (shouldReturnField(fieldsToReturn, RuleNormalizer.RuleField.MARKDOWN_DESCRIPTION) && ruleDoc.markdownDescription() != null) { - ruleResponse.setMdDesc(ruleDoc.markdownDescription()); - } if (shouldReturnField(fieldsToReturn, RuleNormalizer.RuleField.NOTE_LOGIN) && ruleDoc.noteLogin() != null) { ruleResponse.setNoteLogin(ruleDoc.noteLogin()); } @@ -314,13 +321,17 @@ public class RuleMapping extends BaseMapping<RuleDoc, RuleMappingContext> { } } - private void setLanguage(Rules.Rule.Builder ruleResponse, Rule ruleDoc, Set<String> fieldsToReturn) { + private static void setLanguage(Rules.Rule.Builder ruleResponse, Rule ruleDoc, Set<String> fieldsToReturn) { if (shouldReturnField(fieldsToReturn, RuleNormalizer.RuleField.LANGUAGE) && ruleDoc.language() != null) { ruleResponse.setLang(ruleDoc.language()); - Language language = languages.get(ruleDoc.language()); - if (language != null) { - ruleResponse.setLangName(language.getName()); - } + } + } + + private void setLanguageName(Rules.Rule.Builder ruleResponse, Rule ruleDoc, Set<String> fieldsToReturn) { + if (shouldReturnField(fieldsToReturn, "langName") && ruleDoc.language() != null) { + String languageKey = ruleDoc.language(); + Language language = languages.get(languageKey); + ruleResponse.setLangName(language == null ? languageKey : language.getName()); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/test/index/TestResultSetIterator.java b/server/sonar-server/src/main/java/org/sonar/server/test/index/TestResultSetIterator.java index e1ffd9d2e54..8c8316e5dbf 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/test/index/TestResultSetIterator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/test/index/TestResultSetIterator.java @@ -55,10 +55,14 @@ import static org.sonar.server.test.index.TestIndexDefinition.TYPE; /** * Scroll over table FILE_SOURCES of test type and directly parse data required to - * populate the index sourcelines + * populate the index tests/test */ public class TestResultSetIterator extends ResultSetIterator<Row> { + private TestResultSetIterator(PreparedStatement stmt) throws SQLException { + super(stmt); + } + public static TestResultSetIterator create(DbClient dbClient, DbSession session, long afterDate, @Nullable String projectUuid) { try { return new TestResultSetIterator(FileSourcesUpdaterHelper.preparedStatementToSelectFileSources(dbClient, session, FileSourceDto.Type.TEST, afterDate, projectUuid)); @@ -67,10 +71,6 @@ public class TestResultSetIterator extends ResultSetIterator<Row> { } } - private TestResultSetIterator(PreparedStatement stmt) throws SQLException { - super(stmt); - } - @Override protected Row read(ResultSet rs) throws SQLException { String projectUuid = rs.getString(1); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/DumbRule.java b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/DumbRule.java index 72e780b2298..45c340ac4c9 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/DumbRule.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/DumbRule.java @@ -39,6 +39,7 @@ public class DumbRule implements Rule { public DumbRule(RuleKey key) { this.key = key; + this.id = key.hashCode(); } @Override diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/RuleCacheLoaderTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/RuleCacheLoaderTest.java deleted file mode 100644 index fc490fa021f..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/RuleCacheLoaderTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube 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. - * - * SonarQube 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.computation.issue; - -import java.util.Collections; -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.utils.System2; -import org.sonar.db.DbTester; -import org.sonar.test.DbTests; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; - -@Category(DbTests.class) -public class RuleCacheLoaderTest { - - @org.junit.Rule - public DbTester dbTester = DbTester.create(System2.INSTANCE); - - @Before - public void setUp() { - dbTester.truncateTables(); - } - - @Test - public void load_by_key() { - dbTester.prepareDbUnit(getClass(), "shared.xml"); - RuleCacheLoader loader = new RuleCacheLoader(dbTester.getDbClient()); - - Rule javaRule = loader.load(RuleKey.of("java", "JAV01")); - assertThat(javaRule.getName()).isEqualTo("Java One"); - - Rule jsRule = loader.load(RuleKey.of("js", "JS01")); - assertThat(jsRule.getName()).isEqualTo("JS One"); - - assertThat(loader.load(RuleKey.of("java", "MISSING"))).isNull(); - } - - @Test - public void load_by_keys_is_not_supported() { - RuleCacheLoader loader = new RuleCacheLoader(dbTester.getDbClient()); - try { - loader.loadAll(Collections.<RuleKey>emptyList()); - fail(); - } catch (UnsupportedOperationException e) { - // see RuleDao#getByKeys() - } - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/RuleRepositoryImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/RuleRepositoryImplTest.java index 1497bbce6fd..5b12101525b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/RuleRepositoryImplTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/RuleRepositoryImplTest.java @@ -19,37 +19,223 @@ */ package org.sonar.server.computation.issue; +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; +import org.junit.Before; import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rule.RuleStatus; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.rule.RuleDao; +import org.sonar.db.rule.RuleDto; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.guava.api.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import static org.mockito.internal.verification.VerificationModeFactory.times; -import static org.sonar.db.rule.RuleTesting.XOO_X1; -import static org.sonar.db.rule.RuleTesting.XOO_X2; public class RuleRepositoryImplTest { - RuleCacheLoader cacheLoader = mock(RuleCacheLoader.class); - RuleRepositoryImpl underTest = new RuleRepositoryImpl(cacheLoader); + private static final RuleDto AB_RULE = createABRuleDto(); + private static final RuleKey AC_RULE_KEY = RuleKey.of("a", "c"); + private static final int AC_RULE_ID = 684; + + @org.junit.Rule + public ExpectedException expectedException = ExpectedException.none(); + + private DbClient dbClient = mock(DbClient.class); + private DbSession dbSession = mock(DbSession.class); + private RuleDao ruleDao = mock(RuleDao.class); + + RuleRepositoryImpl underTest = new RuleRepositoryImpl(dbClient); + + @Before + public void setUp() throws Exception { + when(dbClient.openSession(anyBoolean())).thenReturn(dbSession); + when(dbClient.ruleDao()).thenReturn(ruleDao); + when(ruleDao.selectAll(any(DbSession.class))).thenReturn(ImmutableList.of(AB_RULE)); + } + + @Test + public void constructor_does_not_query_DB_to_retrieve_rules() { + verifyNoMoreInteractions(dbClient); + } + + @Test + public void first_call_to_getByKey_triggers_call_to_db_and_any_subsequent_get_or_find_call_does_not() { + underTest.getByKey(AB_RULE.getKey()); + + verify(ruleDao, times(1)).selectAll(any(DbSession.class)); + + verifyNoMethodCallTriggersCallToDB(); + } + + @Test + public void first_call_to_findByKey_triggers_call_to_db_and_any_subsequent_get_or_find_call_does_not() { + underTest.findByKey(AB_RULE.getKey()); + + verify(ruleDao, times(1)).selectAll(any(DbSession.class)); + + verifyNoMethodCallTriggersCallToDB(); + } + + @Test + public void first_call_to_getById_triggers_call_to_db_and_any_subsequent_get_or_find_call_does_not() { + underTest.getById(AB_RULE.getId()); + + verify(ruleDao, times(1)).selectAll(any(DbSession.class)); + + verifyNoMethodCallTriggersCallToDB(); + } + + @Test + public void first_call_to_findById_triggers_call_to_db_and_any_subsequent_get_or_find_call_does_not() { + underTest.findById(AB_RULE.getId()); + + verify(ruleDao, times(1)).selectAll(any(DbSession.class)); + + verifyNoMethodCallTriggersCallToDB(); + } + + @Test + public void getByKey_throws_NPE_if_key_argument_is_null() { + expectNullRuleKeyNPE(); + + underTest.getByKey(null); + } + + @Test + public void getByKey_does_not_call_DB_if_key_argument_is_null() { + try { + underTest.getByKey(null); + } catch (NullPointerException e) { + assertNoCallToDb(); + } + } + + @Test + public void getByKey_returns_Rule_if_it_exists_in_DB() { + Rule rule = underTest.getByKey(AB_RULE.getKey()); + + assertIsABRule(rule); + } + + @Test + public void getByKey_throws_IAE_if_rules_does_not_exist_in_DB() { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Can not find rule for key a:c. This rule does not exist in DB"); + + underTest.getByKey(AC_RULE_KEY); + } + + @Test + public void findByKey_throws_NPE_if_key_argument_is_null() { + expectNullRuleKeyNPE(); + + underTest.findByKey(null); + } + + @Test + public void findByKey_does_not_call_DB_if_key_argument_is_null() { + try { + underTest.findByKey(null); + } catch (NullPointerException e) { + assertNoCallToDb(); + } + } + + @Test + public void findByKey_returns_absent_if_rule_does_not_exist_in_DB() { + Optional<Rule> rule = underTest.findByKey(AC_RULE_KEY); + + assertThat(rule).isAbsent(); + } + + @Test + public void findByKey_returns_Rule_if_it_exists_in_DB() { + Optional<Rule> rule = underTest.findByKey(AB_RULE.getKey()); + + assertIsABRule(rule.get()); + } + + @Test + public void getById_returns_Rule_if_it_exists_in_DB() { + Rule rule = underTest.getById(AB_RULE.getId()); + + assertIsABRule(rule); + } @Test - public void getByKey() { - when(cacheLoader.load(XOO_X1)).thenReturn(new DumbRule(XOO_X1)); + public void getById_throws_IAE_if_rules_does_not_exist_in_DB() { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Can not find rule for id " + AC_RULE_ID + ". This rule does not exist in DB"); - assertThat(underTest.getByKey(XOO_X1).getKey()).isEqualTo(XOO_X1); + underTest.getById(AC_RULE_ID); + } + + @Test + public void findById_returns_absent_if_rule_does_not_exist_in_DB() { + Optional<Rule> rule = underTest.findById(AC_RULE_ID); - // second call -> get from cache - assertThat(underTest.getByKey(XOO_X1).getKey()).isEqualTo(XOO_X1); - verify(cacheLoader, times(1)).load(XOO_X1); + assertThat(rule).isAbsent(); } @Test - public void hasKey() { - when(cacheLoader.load(XOO_X1)).thenReturn(new DumbRule(XOO_X1)); + public void findById_returns_Rule_if_it_exists_in_DB() { + Optional<Rule> rule = underTest.findById(AB_RULE.getId()); + + assertIsABRule(rule.get()); + } - assertThat(underTest.hasKey(XOO_X1)).isTrue(); - assertThat(underTest.hasKey(XOO_X2)).isFalse(); + private void expectNullRuleKeyNPE() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("RuleKey can not be null"); } + + private void verifyNoMethodCallTriggersCallToDB() { + reset(ruleDao); + underTest.getByKey(AB_RULE.getKey()); + assertNoCallToDb(); + reset(ruleDao); + underTest.findByKey(AB_RULE.getKey()); + assertNoCallToDb(); + reset(ruleDao); + underTest.getById(AB_RULE.getId()); + assertNoCallToDb(); + reset(ruleDao); + underTest.findById(AB_RULE.getId()); + assertNoCallToDb(); + } + + private void assertNoCallToDb() { + verifyNoMoreInteractions(ruleDao); + } + + private void assertIsABRule(Rule rule) { + assertThat(rule).isNotNull(); + assertThat(rule.getId()).isEqualTo(AB_RULE.getId()); + assertThat(rule.getKey()).isEqualTo(AB_RULE.getKey()); + assertThat(rule.getRemediationFunction()).isNull(); + assertThat(rule.getSubCharacteristicId()).isNull(); + assertThat(rule.getStatus()).isEqualTo(RuleStatus.REMOVED); + } + + private static RuleDto createABRuleDto() { + RuleKey ruleKey = RuleKey.of("a", "b"); + RuleDto res = new RuleDto(); + res.setId(ruleKey.hashCode()); + res.setRepositoryKey(ruleKey.repository()); + res.setRuleKey(ruleKey.rule()); + res.setStatus(RuleStatus.REMOVED); + return res; + } + } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/RuleRepositoryRule.java b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/RuleRepositoryRule.java index d50be77dafa..5cde0f10be0 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/RuleRepositoryRule.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/RuleRepositoryRule.java @@ -19,43 +19,61 @@ */ package org.sonar.server.computation.issue; +import com.google.common.base.Optional; import java.util.HashMap; import java.util.Map; import org.junit.rules.ExternalResource; import org.sonar.api.rule.RuleKey; -import org.sonar.server.exceptions.NotFoundException; + +import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; public class RuleRepositoryRule extends ExternalResource implements RuleRepository { private final Map<RuleKey, Rule> rulesByKey = new HashMap<>(); + private final Map<Integer, Rule> rulesById = new HashMap<>(); @Override protected void after() { rulesByKey.clear(); + rulesById.clear(); } @Override public Rule getByKey(RuleKey key) { - Rule rule = rulesByKey.get(key); - if (rule == null) { - throw new NotFoundException(); - } + Rule rule = rulesByKey.get(requireNonNull(key)); + checkArgument(rule != null); + return rule; + } + + @Override + public Rule getById(int id) { + Rule rule = rulesById.get(id); + checkArgument(rule != null); return rule; } @Override - public boolean hasKey(RuleKey key) { - return rulesByKey.containsKey(key); + public Optional<Rule> findByKey(RuleKey key) { + return Optional.fromNullable(rulesByKey.get(requireNonNull(key))); + } + + @Override + public Optional<Rule> findById(int id) { + return Optional.fromNullable(rulesById.get(id)); } public DumbRule add(RuleKey key) { DumbRule rule = new DumbRule(key); + rule.setId(key.hashCode()); rulesByKey.put(key, rule); + rulesById.put(rule.getId(), rule); return rule; } public RuleRepositoryRule add(DumbRule rule) { - rulesByKey.put(rule.getKey(), rule); + rulesByKey.put(requireNonNull(rule.getKey()), rule); + rulesById.put(requireNonNull(rule.getId()), rule); return this; } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistIssuesStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistIssuesStepTest.java index 344e3f0769d..53198c87543 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistIssuesStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistIssuesStepTest.java @@ -38,7 +38,6 @@ import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.server.computation.batch.BatchReportReaderRule; import org.sonar.server.computation.issue.IssueCache; -import org.sonar.server.computation.issue.RuleCacheLoader; import org.sonar.server.computation.issue.RuleRepositoryImpl; import org.sonar.server.computation.issue.UpdateConflictResolver; @@ -81,7 +80,7 @@ public class PersistIssuesStepTest extends BaseStepTest { when(system2.now()).thenReturn(NOW); reportReader.setMetadata(BatchReport.Metadata.getDefaultInstance()); - step = new PersistIssuesStep(dbClient, system2, new UpdateConflictResolver(), new RuleRepositoryImpl(new RuleCacheLoader(dbClient)), issueCache); + step = new PersistIssuesStep(dbClient, system2, new UpdateConflictResolver(), new RuleRepositoryImpl(dbClient), issueCache); } @After diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java index 84636b8ef24..eaa807efb7d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CreateActionTest.java @@ -21,16 +21,18 @@ package org.sonar.server.qualityprofile.ws; import org.junit.Rule; import org.junit.Test; -import org.sonar.api.server.ws.WebService.Action; import org.sonar.api.utils.System2; import org.sonar.core.permission.GlobalPermissions; import org.sonar.db.DbTester; import org.sonar.db.qualityprofile.QualityProfileDao; import org.sonar.server.db.DbClient; import org.sonar.server.language.LanguageTesting; +import org.sonar.server.plugins.MimeTypes; import org.sonar.server.qualityprofile.QProfileFactory; import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; +import org.sonar.server.ws.TestResponse; +import org.sonar.server.ws.WsActionTester; +import org.sonar.test.JsonAssert; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -39,25 +41,47 @@ public class CreateActionTest { @Rule public DbTester db = DbTester.create(System2.INSTANCE); + @Rule public UserSessionRule userSessionRule = UserSessionRule.standalone(); + QualityProfileDao profileDao = new QualityProfileDao(db.myBatis(), mock(System2.class)); + DbClient deprecatedDbClient = new DbClient(db.database(), db.myBatis(), profileDao); + @Test public void should_not_fail_on_no_importers() throws Exception { - QualityProfileDao profileDao = new QualityProfileDao(db.myBatis(), mock(System2.class)); - DbClient dbClient = new DbClient(db.database(), db.myBatis(), profileDao); + CreateAction underTest = new CreateAction(db.getDbClient(), new QProfileFactory(deprecatedDbClient), null, LanguageTesting.newLanguages("xoo"), userSessionRule); + WsActionTester wsTester = new WsActionTester(underTest); - String xooKey = "xoo"; - WsTester wsTester = new WsTester(new QProfilesWs( - mock(RuleActivationActions.class), mock(BulkRuleActivationActions.class), mock(ProjectAssociationActions.class), - new CreateAction(dbClient, new QProfileFactory(dbClient), null, LanguageTesting.newLanguages(xooKey), userSessionRule))); + userSessionRule.login("admin").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - Action create = wsTester.controller("api/qualityprofiles").action("create"); - assertThat(create.params()).hasSize(2); + TestResponse response = wsTester.newRequest() + .setMethod("POST") + .setMediaType(MimeTypes.JSON) + .setParam("language", "xoo") + .setParam("name", "Yeehaw!") + .execute(); + JsonAssert.assertJson(response.getInput()).isSimilarTo(getClass().getResource("CreateActionTest/create-no-importer.json")); + assertThat(response.getMediaType()).isEqualTo(MimeTypes.JSON); + } + + /** + * Do not return JSON content type header on IE. + */ + @Test + public void test_ie_hack() throws Exception { + CreateAction underTest = new CreateAction(db.getDbClient(), new QProfileFactory(deprecatedDbClient), null, LanguageTesting.newLanguages("xoo"), userSessionRule); + WsActionTester wsTester = new WsActionTester(underTest); + userSessionRule.login("admin").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - userSessionRule.login("anakin").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + TestResponse response = wsTester.newRequest() + .setMethod("POST") + // IE asks for application/html or text/html + .setMediaType("application/html") + .setParam("language", "xoo") + .setParam("name", "Yeehaw!") + .execute(); + assertThat(response.getMediaType()).isEqualTo(MimeTypes.TXT); - wsTester.newPostRequest("api/qualityprofiles", "create") - .setParam("language", xooKey).setParam("name", "Yeehaw!").execute().assertJson(getClass(), "create-no-importer.json"); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RulesWsMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RulesWsMediumTest.java index 17ba3f9495d..5574d156a75 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RulesWsMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/RulesWsMediumTest.java @@ -20,36 +20,23 @@ package org.sonar.server.rule.ws; import com.google.common.collect.ImmutableSet; -import java.util.Calendar; import java.util.Collections; -import java.util.Date; import org.junit.After; import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rule.Severity; -import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.ws.WebService; -import org.sonar.api.utils.DateUtils; import org.sonar.db.DbSession; import org.sonar.db.qualityprofile.ActiveRuleDto; -import org.sonar.db.qualityprofile.ActiveRuleParamDto; import org.sonar.db.qualityprofile.QualityProfileDao; import org.sonar.db.qualityprofile.QualityProfileDto; import org.sonar.db.rule.RuleDto; -import org.sonar.db.rule.RuleDto.Format; -import org.sonar.db.rule.RuleParamDto; -import org.sonar.db.debt.CharacteristicDto; +import org.sonar.db.rule.RuleTesting; import org.sonar.server.db.DbClient; -import org.sonar.server.debt.DebtTesting; import org.sonar.server.qualityprofile.QProfileTesting; import org.sonar.server.qualityprofile.db.ActiveRuleDao; -import org.sonar.db.rule.RuleTesting; import org.sonar.server.rule.db.RuleDao; -import org.sonar.server.rule.index.RuleNormalizer; import org.sonar.server.tester.ServerTester; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.WsTester; @@ -64,7 +51,6 @@ public class RulesWsMediumTest { public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester); private static final String API_ENDPOINT = "api/rules"; - private static final String API_SEARCH_METHOD = "search"; private static final String API_SHOW_METHOD = "show"; private static final String API_TAGS_METHOD = "tags"; @@ -72,8 +58,6 @@ public class RulesWsMediumTest { RulesWs ws; RuleDao ruleDao; DbSession session; - int softReliabilityId; - int hardReliabilityId; @Before public void setUp() { @@ -98,7 +82,7 @@ public class RulesWsMediumTest { assertThat(controller).isNotNull(); assertThat(controller.actions()).hasSize(9); - assertThat(controller.action(API_SEARCH_METHOD)).isNotNull(); + assertThat(controller.action("search")).isNotNull(); assertThat(controller.action(API_SHOW_METHOD)).isNotNull(); assertThat(controller.action(API_TAGS_METHOD)).isNotNull(); assertThat(controller.action("update")).isNotNull(); @@ -136,367 +120,6 @@ public class RulesWsMediumTest { } @Test - public void search_no_rules() throws Exception { - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.FIELDS, "actives"); - WsTester.Result result = request.execute(); - - result.assertJson(this.getClass(), "search_no_rules.json"); - } - - @Test - public void filter_by_key_rules() throws Exception { - ruleDao.insert(session, RuleTesting.newXooX1()); - ruleDao.insert(session, RuleTesting.newXooX2()); - session.commit(); - - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(SearchAction.PARAM_KEY, RuleTesting.XOO_X1.toString()); - request.setParam(WebService.Param.FIELDS, "actives"); - WsTester.Result result = request.execute(); - result.assertJson("{\"total\":1,\"p\":1,\"ps\":100,\"rules\":[{\"key\":\"xoo:x1\"}]}"); - - request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(SearchAction.PARAM_KEY, RuleKey.of("xoo", "unknown").toString()); - request.setParam(WebService.Param.FIELDS, "actives"); - result = request.execute(); - result.assertJson("{\"total\":0,\"p\":1,\"ps\":100,\"rules\":[],\"actives\":{}}"); - - } - - @Test - public void search_2_rules() throws Exception { - ruleDao.insert(session, RuleTesting.newXooX1()); - ruleDao.insert(session, RuleTesting.newXooX2()); - session.commit(); - - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - WsTester.Result result = request.execute(); - - result.assertJson(getClass(), "search_2_rules.json"); - } - - @Test - public void search_2_rules_with_field_selection() throws Exception { - ruleDao.insert(session, RuleTesting.newXooX1()); - ruleDao.insert(session, RuleTesting.newXooX2().setDescription("A *Xoo* rule").setDescriptionFormat(Format.MARKDOWN)); - session.commit(); - - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD).setParam(WebService.Param.FIELDS, "name,htmlDesc,mdDesc"); - WsTester.Result result = request.execute(); - - result.assertJson(getClass(), "search_2_rules_fields.json"); - } - - @Test - public void search_debt_rules() throws Exception { - insertDebtCharacteristics(session); - - ruleDao.insert(session, RuleTesting.newXooX1() - .setDefaultSubCharacteristicId(hardReliabilityId) - .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) - .setDefaultRemediationCoefficient("1h") - .setDefaultRemediationOffset("15min") - - .setSubCharacteristicId(null) - .setRemediationFunction(null) - .setRemediationCoefficient(null) - .setRemediationOffset(null) - ); - session.commit(); - - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.FIELDS, "debtChar,debtCharName,debtSubChar,debtSubCharName,debtRemFn,debtOverloaded,defaultDebtChar,defaultDebtSubChar,defaultDebtRemFn"); - request.setParam(WebService.Param.FACETS, "debt_characteristics"); - WsTester.Result result = request.execute(); - result.assertJson(this.getClass(), "search_debt_rule.json"); - } - - @Test - public void search_debt_rules_with_default_and_overridden_debt_values() throws Exception { - insertDebtCharacteristics(session); - - ruleDao.insert(session, RuleTesting.newXooX1() - .setDefaultSubCharacteristicId(hardReliabilityId) - .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) - .setDefaultRemediationCoefficient("1h") - .setDefaultRemediationOffset("15min") - - .setSubCharacteristicId(softReliabilityId) - .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) - .setRemediationCoefficient("2h") - .setRemediationOffset("25min") - ); - session.commit(); - - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.FIELDS, "debtChar,debtCharName,debtSubChar,debtSubCharName,debtRemFn,debtOverloaded,defaultDebtChar,defaultDebtSubChar,defaultDebtRemFn"); - WsTester.Result result = request.execute(); - result.assertJson(this.getClass(), "search_debt_rules_with_default_and_overridden_debt_values.json"); - } - - @Test - public void search_debt_rules_with_default_linear_offset_and_overridden_constant_debt() throws Exception { - insertDebtCharacteristics(session); - - ruleDao.insert(session, RuleTesting.newXooX1() - .setDefaultSubCharacteristicId(hardReliabilityId) - .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) - .setDefaultRemediationCoefficient("1h") - .setDefaultRemediationOffset("15min") - - .setSubCharacteristicId(softReliabilityId) - .setRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE.name()) - .setRemediationCoefficient(null) - .setRemediationOffset("5min") - ); - session.commit(); - - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.FIELDS, "debtChar,debtCharName,debtSubChar,debtSubCharName,debtRemFn,debtOverloaded,defaultDebtChar,defaultDebtSubChar,defaultDebtRemFn"); - WsTester.Result result = request.execute(); - result.assertJson(this.getClass(), "search_debt_rules_with_default_linear_offset_and_overridden_constant_debt.json"); - } - - @Test - public void search_debt_rules_with_default_linear_offset_and_overridden_linear_debt() throws Exception { - insertDebtCharacteristics(session); - - ruleDao.insert(session, RuleTesting.newXooX1() - .setDefaultSubCharacteristicId(hardReliabilityId) - .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) - .setDefaultRemediationCoefficient("1h") - .setDefaultRemediationOffset("15min") - - .setSubCharacteristicId(softReliabilityId) - .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.name()) - .setRemediationCoefficient("1h") - .setRemediationOffset(null) - ); - session.commit(); - - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.FIELDS, "debtChar,debtCharName,debtSubChar,debtSubCharName,debtRemFn,debtOverloaded,defaultDebtChar,defaultDebtSubChar,defaultDebtRemFn"); - WsTester.Result result = request.execute(); - result.assertJson(this.getClass(), "search_debt_rules_with_default_linear_offset_and_overridden_linear_debt.json"); - } - - @Test - public void debt_characteristics_is_sticky_facet() throws Exception { - insertDebtCharacteristics(session); - - ruleDao.insert(session, RuleTesting.newXooX1() - .setDefaultSubCharacteristicId(hardReliabilityId) - .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) - .setDefaultRemediationCoefficient("1h") - .setDefaultRemediationOffset("15min") - - .setSubCharacteristicId(null) - .setRemediationFunction(null) - .setRemediationCoefficient(null) - .setRemediationOffset(null) - ); - ruleDao.insert(session, RuleTesting.newXooX2() - .setDefaultSubCharacteristicId(hardReliabilityId) - .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) - .setDefaultRemediationCoefficient("1h") - .setDefaultRemediationOffset("15min") - - .setSubCharacteristicId(softReliabilityId) - .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) - .setRemediationCoefficient("30min") - .setRemediationOffset("5min") - ); - ruleDao.insert(session, RuleTesting.newXooX3() - .setDefaultSubCharacteristicId(null) - .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) - .setDefaultRemediationCoefficient("2min") - .setDefaultRemediationOffset("1min") - - .setSubCharacteristicId(null) - .setRemediationFunction(null) - .setRemediationCoefficient(null) - .setRemediationOffset(null) - ); - ruleDao.insert(session, RuleTesting.newDto(RuleKey.of("xoo", "x4")).setLanguage("xoo") - .setDefaultSubCharacteristicId(softReliabilityId) - .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) - .setDefaultRemediationCoefficient("2min") - .setDefaultRemediationOffset("1min") - - .setSubCharacteristicId(-1) - .setRemediationFunction(null) - .setRemediationCoefficient(null) - .setRemediationOffset(null) - ); - session.commit(); - - WsTester.Result result = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD) - .setParam(WebService.Param.FIELDS, "debtChar,debtCharName,debtSubChar,debtSubCharName,debtRemFn,debtOverloaded,defaultDebtChar,defaultDebtSubChar,defaultDebtRemFn") - .setParam("debt_characteristics", "SOFT_RELIABILITY") - .setParam(WebService.Param.FACETS, "debt_characteristics") - .execute(); - result.assertJson(this.getClass(), "search_debt_rules_sticky.json"); - } - - @Test - public void search_template_rules() throws Exception { - RuleDto templateRule = RuleTesting.newXooX1().setIsTemplate(true); - ruleDao.insert(session, templateRule); - ruleDao.insert(session, RuleTesting.newXooX2()).setTemplateId(templateRule.getId()); - session.commit(); - - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.FIELDS, "isTemplate"); - request.setParam(SearchAction.PARAM_IS_TEMPLATE, "true"); - WsTester.Result result = request.execute(); - result.assertJson(this.getClass(), "search_template_rules.json"); - } - - @Test - public void search_custom_rules_from_template_key() throws Exception { - RuleDto templateRule = RuleTesting.newXooX1().setIsTemplate(true); - ruleDao.insert(session, templateRule); - ruleDao.insert(session, RuleTesting.newXooX2()).setTemplateId(templateRule.getId()); - session.commit(); - - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.FIELDS, "templateKey"); - request.setParam(SearchAction.PARAM_TEMPLATE_KEY, "xoo:x1"); - WsTester.Result result = request.execute(); - result.assertJson(this.getClass(), "search_rules_from_template_key.json"); - } - - @Test - public void search_all_active_rules() throws Exception { - QualityProfileDto profile = QProfileTesting.newXooP1(); - tester.get(QualityProfileDao.class).insert(session, profile); - - RuleDto rule = RuleTesting.newXooX1(); - ruleDao.insert(session, rule); - - ActiveRuleDto activeRule = newActiveRule(profile, rule); - tester.get(ActiveRuleDao.class).insert(session, activeRule); - session.commit(); - - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.TEXT_QUERY, "x1"); - request.setParam(SearchAction.PARAM_ACTIVATION, "true"); - request.setParam(WebService.Param.FIELDS, ""); - WsTester.Result result = request.execute(); - - result.assertJson(this.getClass(), "search_active_rules.json"); - } - - @Test - public void search_profile_active_rules() throws Exception { - QualityProfileDto profile = QProfileTesting.newXooP1(); - tester.get(QualityProfileDao.class).insert(session, profile); - - QualityProfileDto profile2 = QProfileTesting.newXooP2(); - tester.get(QualityProfileDao.class).insert(session, profile2); - - session.commit(); - - RuleDto rule = RuleTesting.newXooX1(); - ruleDao.insert(session, rule); - - ActiveRuleDto activeRule = newActiveRule(profile, rule); - tester.get(ActiveRuleDao.class).insert(session, activeRule); - ActiveRuleDto activeRule2 = newActiveRule(profile2, rule); - tester.get(ActiveRuleDao.class).insert(session, activeRule2); - - session.commit(); - - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.TEXT_QUERY, "x1"); - request.setParam(SearchAction.PARAM_ACTIVATION, "true"); - request.setParam(SearchAction.PARAM_QPROFILE, profile2.getKey()); - request.setParam(WebService.Param.FIELDS, "actives"); - WsTester.Result result = request.execute(); - result.assertJson(this.getClass(), "search_profile_active_rules.json"); - - tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD) - .setParam(SearchAction.PARAM_ACTIVATION, "true") - .setParam(SearchAction.PARAM_QPROFILE, "unknown_profile") - .setParam(WebService.Param.FIELDS, "actives") - .execute() - .assertJson(this.getClass(), "search_no_rules.json"); - } - - @Test - public void search_profile_active_rules_with_inheritance() throws Exception { - QualityProfileDto profile = QProfileTesting.newXooP1(); - tester.get(QualityProfileDao.class).insert(session, profile); - - QualityProfileDto profile2 = QProfileTesting.newXooP2().setParentKee(profile.getKee()); - tester.get(QualityProfileDao.class).insert(session, profile2); - - session.commit(); - - RuleDto rule = RuleTesting.newXooX1(); - ruleDao.insert(session, rule); - - ActiveRuleDto activeRule = newActiveRule(profile, rule); - tester.get(ActiveRuleDao.class).insert(session, activeRule); - ActiveRuleDto activeRule2 = newActiveRule(profile2, rule).setInheritance(ActiveRuleDto.OVERRIDES).setSeverity(Severity.CRITICAL); - tester.get(ActiveRuleDao.class).insert(session, activeRule2); - - session.commit(); - - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.TEXT_QUERY, "x1"); - request.setParam(SearchAction.PARAM_ACTIVATION, "true"); - request.setParam(SearchAction.PARAM_QPROFILE, profile2.getKey()); - request.setParam(WebService.Param.FIELDS, "actives"); - WsTester.Result result = request.execute(); - result.assertJson(this.getClass(), "search_profile_active_rules_inheritance.json"); - } - - @Test - public void search_all_active_rules_params() throws Exception { - QualityProfileDto profile = QProfileTesting.newXooP1(); - tester.get(QualityProfileDao.class).insert(session, profile); - RuleDto rule = RuleTesting.newXooX1(); - ruleDao.insert(session, rule); - session.commit(); - - RuleParamDto param = RuleParamDto.createFor(rule) - .setDefaultValue("some value") - .setType("string") - .setDescription("My small description") - .setName("my_var"); - ruleDao.insertRuleParam(session, rule, param); - - RuleParamDto param2 = RuleParamDto.createFor(rule) - .setDefaultValue("other value") - .setType("integer") - .setDescription("My small description") - .setName("the_var"); - ruleDao.insertRuleParam(session, rule, param2); - - ActiveRuleDto activeRule = newActiveRule(profile, rule); - tester.get(ActiveRuleDao.class).insert(session, activeRule); - - ActiveRuleParamDto activeRuleParam = ActiveRuleParamDto.createFor(param) - .setValue("The VALUE"); - tester.get(ActiveRuleDao.class).insertParam(session, activeRule, activeRuleParam); - - ActiveRuleParamDto activeRuleParam2 = ActiveRuleParamDto.createFor(param2) - .setValue("The Other Value"); - tester.get(ActiveRuleDao.class).insertParam(session, activeRule, activeRuleParam2); - session.commit(); - - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.TEXT_QUERY, "x1"); - request.setParam(SearchAction.PARAM_ACTIVATION, "true"); - request.setParam(WebService.Param.FIELDS, "params"); - WsTester.Result result = request.execute(); - - result.assertJson(this.getClass(), "search_active_rules_params.json"); - } - - @Test public void get_tags() throws Exception { QualityProfileDto profile = QProfileTesting.newXooP1(); tester.get(QualityProfileDao.class).insert(session, profile); @@ -519,139 +142,4 @@ public class RulesWsMediumTest { .setParam("q", "ll").execute().assertJson(this.getClass(), "get_tags_filtered.json"); } - @Test - public void get_note_as_markdown_and_html() throws Exception { - QualityProfileDto profile = QProfileTesting.newXooP1(); - tester.get(QualityProfileDao.class).insert(session, profile); - RuleDto rule = RuleTesting.newXooX1().setNoteData("this is *bold*"); - ruleDao.insert(session, rule); - session.commit(); - - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.FIELDS, "htmlNote, mdNote"); - WsTester.Result result = request.execute(); - result.assertJson(this.getClass(), "get_note_as_markdown_and_html.json"); - } - - @Test - public void filter_by_tags() throws Exception { - ruleDao.insert(session, RuleTesting.newXooX1() - .setTags(Collections.<String>emptySet()) - .setSystemTags(ImmutableSet.of("tag1"))); - ruleDao.insert(session, RuleTesting.newXooX2() - .setTags(Collections.<String>emptySet()) - .setSystemTags(ImmutableSet.of("tag2"))); - session.commit(); - - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(SearchAction.PARAM_TAGS, "tag1"); - request.setParam(WebService.Param.FIELDS, "sysTags, tags"); - request.setParam(WebService.Param.FACETS, "tags"); - WsTester.Result result = request.execute(); - result.assertJson(this.getClass(), "filter_by_tags.json"); - } - - @Test - public void severities_facet_should_have_all_severities() throws Exception { - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.FACETS, "severities"); - request.execute().assertJson(this.getClass(), "severities_facet.json"); - } - - @Test - public void statuses_facet_should_have_all_statuses_except_removed() throws Exception { - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.FACETS, "statuses"); - request.execute().assertJson(this.getClass(), "statuses_facet.json"); - } - - @Test - public void statuses_facet_should_be_sticky() throws Exception { - ruleDao.insert(session, RuleTesting.newXooX1()); - ruleDao.insert(session, RuleTesting.newXooX2().setStatus(RuleStatus.BETA)); - ruleDao.insert(session, RuleTesting.newXooX3().setStatus(RuleStatus.DEPRECATED)); - session.commit(); - - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(SearchAction.PARAM_STATUSES, "DEPRECATED"); - request.setParam(WebService.Param.FACETS, "statuses"); - request.execute().assertJson(this.getClass(), "statuses_facet_sticky.json"); - } - - @Test - public void sort_by_name() throws Exception { - ruleDao.insert(session, RuleTesting.newXooX1().setName("Dodgy - Consider returning a zero length array rather than null ")); - ruleDao.insert(session, RuleTesting.newXooX2().setName("Bad practice - Creates an empty zip file entry")); - ruleDao.insert(session, RuleTesting.newXooX3().setName("XPath rule")); - session.commit(); - - // 1. Sort Name Asc - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.FIELDS, ""); - request.setParam(WebService.Param.SORT, "name"); - request.setParam(WebService.Param.ASCENDING, "true"); - - WsTester.Result result = request.execute(); - result.assertJson("{\"total\":3,\"p\":1,\"ps\":100,\"rules\":[{\"key\":\"xoo:x2\"},{\"key\":\"xoo:x1\"},{\"key\":\"xoo:x3\"}]}"); - - // 2. Sort Name DESC - request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.FIELDS, ""); - request.setParam(WebService.Param.SORT, RuleNormalizer.RuleField.NAME.field()); - request.setParam(WebService.Param.ASCENDING, "false"); - - result = request.execute(); - result.assertJson("{\"total\":3,\"p\":1,\"ps\":100,\"rules\":[{\"key\":\"xoo:x3\"},{\"key\":\"xoo:x1\"},{\"key\":\"xoo:x2\"}]}"); - - } - - @Test - public void available_since() throws Exception { - ruleDao.insert(session, RuleTesting.newXooX1()); - ruleDao.insert(session, RuleTesting.newXooX2()); - session.commit(); - session.clearCache(); - - Date since = new Date(); - - // 1. find today's rules - WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.FIELDS, ""); - request.setParam(SearchAction.PARAM_AVAILABLE_SINCE, DateUtils.formatDate(since)); - request.setParam(WebService.Param.SORT, RuleNormalizer.RuleField.KEY.field()); - WsTester.Result result = request.execute(); - result.assertJson("{\"total\":2,\"p\":1,\"ps\":100,\"rules\":[{\"key\":\"xoo:x1\"},{\"key\":\"xoo:x2\"}]}"); - - Calendar c = Calendar.getInstance(); - c.setTime(since); - c.add(Calendar.DATE, 1); // number of days to add - - // 2. no rules since tomorrow - request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); - request.setParam(WebService.Param.FIELDS, ""); - request.setParam(SearchAction.PARAM_AVAILABLE_SINCE, DateUtils.formatDate(c.getTime())); - result = request.execute(); - result.assertJson("{\"total\":0,\"p\":1,\"ps\":100,\"rules\":[]}"); - } - - private ActiveRuleDto newActiveRule(QualityProfileDto profile, RuleDto rule) { - return ActiveRuleDto.createFor(profile, rule) - .setInheritance(null) - .setSeverity("BLOCKER"); - } - - private void insertDebtCharacteristics(DbSession dbSession) { - CharacteristicDto reliability = DebtTesting.newCharacteristicDto("RELIABILITY").setName("Reliability"); - db.debtCharacteristicDao().insert(dbSession, reliability); - - CharacteristicDto softReliability = DebtTesting.newCharacteristicDto("SOFT_RELIABILITY").setName("Soft Reliability") - .setParentId(reliability.getId()); - db.debtCharacteristicDao().insert(dbSession, softReliability); - softReliabilityId = softReliability.getId(); - - CharacteristicDto hardReliability = DebtTesting.newCharacteristicDto("HARD_RELIABILITY").setName("Hard Reliability") - .setParentId(reliability.getId()); - db.debtCharacteristicDao().insert(dbSession, hardReliability); - hardReliabilityId = hardReliability.getId(); - } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/SearchActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/SearchActionMediumTest.java new file mode 100644 index 00000000000..bc2fe0be698 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/SearchActionMediumTest.java @@ -0,0 +1,627 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.rule.ws; + +import com.google.common.collect.ImmutableSet; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rule.RuleStatus; +import org.sonar.api.rule.Severity; +import org.sonar.api.server.debt.DebtRemediationFunction; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.utils.DateUtils; +import org.sonar.db.DbSession; +import org.sonar.db.debt.CharacteristicDto; +import org.sonar.db.qualityprofile.ActiveRuleDto; +import org.sonar.db.qualityprofile.ActiveRuleParamDto; +import org.sonar.db.qualityprofile.QualityProfileDao; +import org.sonar.db.qualityprofile.QualityProfileDto; +import org.sonar.db.rule.RuleDto; +import org.sonar.db.rule.RuleParamDto; +import org.sonar.db.rule.RuleTesting; +import org.sonar.server.db.DbClient; +import org.sonar.server.debt.DebtTesting; +import org.sonar.server.qualityprofile.QProfileTesting; +import org.sonar.server.qualityprofile.db.ActiveRuleDao; +import org.sonar.server.rule.db.RuleDao; +import org.sonar.server.rule.index.RuleNormalizer; +import org.sonar.server.tester.ServerTester; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsTester; + +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; + +import static org.assertj.core.api.Assertions.assertThat; + +public class SearchActionMediumTest { + + @ClassRule + public static ServerTester tester = new ServerTester().addXoo(); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester); + + private static final String API_ENDPOINT = "api/rules"; + private static final String API_SEARCH_METHOD = "search"; + + DbClient db; + RulesWs ws; + RuleDao ruleDao; + DbSession session; + int softReliabilityId; + int hardReliabilityId; + + @Before + public void setUp() { + tester.clearDbAndIndexes(); + db = tester.get(DbClient.class); + ruleDao = tester.get(RuleDao.class); + ws = tester.get(RulesWs.class); + session = tester.get(DbClient.class).openSession(false); + } + + @After + public void after() { + session.close(); + } + + @Test + public void search_no_rules() throws Exception { + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.FIELDS, "actives"); + WsTester.Result result = request.execute(); + + result.assertJson(this.getClass(), "search_no_rules.json"); + } + + @Test + public void filter_by_key_rules() throws Exception { + ruleDao.insert(session, RuleTesting.newXooX1()); + ruleDao.insert(session, RuleTesting.newXooX2()); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(SearchAction.PARAM_KEY, RuleTesting.XOO_X1.toString()); + request.setParam(WebService.Param.FIELDS, "actives"); + WsTester.Result result = request.execute(); + result.assertJson("{\"total\":1,\"p\":1,\"ps\":100,\"rules\":[{\"key\":\"xoo:x1\"}]}"); + + request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(SearchAction.PARAM_KEY, RuleKey.of("xoo", "unknown").toString()); + request.setParam(WebService.Param.FIELDS, "actives"); + result = request.execute(); + result.assertJson("{\"total\":0,\"p\":1,\"ps\":100,\"rules\":[],\"actives\":{}}"); + + } + + @Test + public void search_2_rules() throws Exception { + ruleDao.insert(session, RuleTesting.newXooX1()); + ruleDao.insert(session, RuleTesting.newXooX2()); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + WsTester.Result result = request.execute(); + + result.assertJson(getClass(), "search_2_rules.json"); + } + + @Test + public void search_2_rules_with_field_selection() throws Exception { + ruleDao.insert(session, RuleTesting.newXooX1()); + ruleDao.insert(session, RuleTesting.newXooX2().setDescription("A *Xoo* rule").setDescriptionFormat(RuleDto.Format.MARKDOWN)); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD).setParam(WebService.Param.FIELDS, "name,htmlDesc,mdDesc"); + WsTester.Result result = request.execute(); + + result.assertJson(getClass(), "search_2_rules_fields.json"); + } + + @Test + public void return_lang_field() throws Exception { + ruleDao.insert(session, RuleTesting.newXooX1()); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD).setParam(WebService.Param.FIELDS, "lang"); + WsTester.Result result = request.execute(); + + result.assertJson("{\"total\":1,\"p\":1,\"ps\":100," + + "\"rules\":[{\"key\":\"xoo:x1\",\"lang\":\"xoo\"}]}"); + assertThat(result.outputAsString()).doesNotContain("\"langName\""); + assertThat(result.outputAsString()).doesNotContain("\"name\""); + } + + @Test + public void return_lang_name_field() throws Exception { + ruleDao.insert(session, RuleTesting.newXooX1()); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD).setParam(WebService.Param.FIELDS, "langName"); + WsTester.Result result = request.execute(); + + result.assertJson("{\"total\":1,\"p\":1,\"ps\":100," + + "\"rules\":[{\"key\":\"xoo:x1\",\"langName\":\"Xoo\"}]}"); + assertThat(result.outputAsString()).doesNotContain("\"lang\""); + assertThat(result.outputAsString()).doesNotContain("\"name\""); + } + + @Test + public void return_lang_key_field_when_language_name_is_not_available() throws Exception { + ruleDao.insert(session, RuleTesting.newDto(RuleKey.of("other", "rule"))).setLanguage("unknown"); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD).setParam(WebService.Param.FIELDS, "langName"); + WsTester.Result result = request.execute(); + + result.assertJson("{\"total\":1,\"p\":1,\"ps\":100," + + "\"rules\":[{\"key\":\"other:rule\",\"langName\":\"unknown\"}]}"); + } + + @Test + public void search_debt_rules() throws Exception { + insertDebtCharacteristics(session); + + ruleDao.insert(session, RuleTesting.newXooX1() + .setDefaultSubCharacteristicId(hardReliabilityId) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) + .setDefaultRemediationCoefficient("1h") + .setDefaultRemediationOffset("15min") + + .setSubCharacteristicId(null) + .setRemediationFunction(null) + .setRemediationCoefficient(null) + .setRemediationOffset(null) + ); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.FIELDS, "debtChar,debtCharName,debtSubChar,debtSubCharName,debtRemFn,debtOverloaded,defaultDebtChar,defaultDebtSubChar,defaultDebtRemFn"); + request.setParam(WebService.Param.FACETS, "debt_characteristics"); + WsTester.Result result = request.execute(); + result.assertJson(this.getClass(), "search_debt_rule.json"); + } + + @Test + public void search_debt_rules_with_default_and_overridden_debt_values() throws Exception { + insertDebtCharacteristics(session); + + ruleDao.insert(session, RuleTesting.newXooX1() + .setDefaultSubCharacteristicId(hardReliabilityId) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) + .setDefaultRemediationCoefficient("1h") + .setDefaultRemediationOffset("15min") + + .setSubCharacteristicId(softReliabilityId) + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) + .setRemediationCoefficient("2h") + .setRemediationOffset("25min") + ); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.FIELDS, "debtChar,debtCharName,debtSubChar,debtSubCharName,debtRemFn,debtOverloaded,defaultDebtChar,defaultDebtSubChar,defaultDebtRemFn"); + WsTester.Result result = request.execute(); + result.assertJson(this.getClass(), "search_debt_rules_with_default_and_overridden_debt_values.json"); + } + + @Test + public void search_debt_rules_with_default_linear_offset_and_overridden_constant_debt() throws Exception { + insertDebtCharacteristics(session); + + ruleDao.insert(session, RuleTesting.newXooX1() + .setDefaultSubCharacteristicId(hardReliabilityId) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) + .setDefaultRemediationCoefficient("1h") + .setDefaultRemediationOffset("15min") + + .setSubCharacteristicId(softReliabilityId) + .setRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE.name()) + .setRemediationCoefficient(null) + .setRemediationOffset("5min") + ); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.FIELDS, "debtChar,debtCharName,debtSubChar,debtSubCharName,debtRemFn,debtOverloaded,defaultDebtChar,defaultDebtSubChar,defaultDebtRemFn"); + WsTester.Result result = request.execute(); + result.assertJson(this.getClass(), "search_debt_rules_with_default_linear_offset_and_overridden_constant_debt.json"); + } + + @Test + public void search_debt_rules_with_default_linear_offset_and_overridden_linear_debt() throws Exception { + insertDebtCharacteristics(session); + + ruleDao.insert(session, RuleTesting.newXooX1() + .setDefaultSubCharacteristicId(hardReliabilityId) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) + .setDefaultRemediationCoefficient("1h") + .setDefaultRemediationOffset("15min") + + .setSubCharacteristicId(softReliabilityId) + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.name()) + .setRemediationCoefficient("1h") + .setRemediationOffset(null) + ); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.FIELDS, "debtChar,debtCharName,debtSubChar,debtSubCharName,debtRemFn,debtOverloaded,defaultDebtChar,defaultDebtSubChar,defaultDebtRemFn"); + WsTester.Result result = request.execute(); + result.assertJson(this.getClass(), "search_debt_rules_with_default_linear_offset_and_overridden_linear_debt.json"); + } + + @Test + public void debt_characteristics_is_sticky_facet() throws Exception { + insertDebtCharacteristics(session); + + ruleDao.insert(session, RuleTesting.newXooX1() + .setDefaultSubCharacteristicId(hardReliabilityId) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) + .setDefaultRemediationCoefficient("1h") + .setDefaultRemediationOffset("15min") + + .setSubCharacteristicId(null) + .setRemediationFunction(null) + .setRemediationCoefficient(null) + .setRemediationOffset(null) + ); + ruleDao.insert(session, RuleTesting.newXooX2() + .setDefaultSubCharacteristicId(hardReliabilityId) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) + .setDefaultRemediationCoefficient("1h") + .setDefaultRemediationOffset("15min") + + .setSubCharacteristicId(softReliabilityId) + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) + .setRemediationCoefficient("30min") + .setRemediationOffset("5min") + ); + ruleDao.insert(session, RuleTesting.newXooX3() + .setDefaultSubCharacteristicId(null) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) + .setDefaultRemediationCoefficient("2min") + .setDefaultRemediationOffset("1min") + + .setSubCharacteristicId(null) + .setRemediationFunction(null) + .setRemediationCoefficient(null) + .setRemediationOffset(null) + ); + ruleDao.insert(session, RuleTesting.newDto(RuleKey.of("xoo", "x4")).setLanguage("xoo") + .setDefaultSubCharacteristicId(softReliabilityId) + .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.name()) + .setDefaultRemediationCoefficient("2min") + .setDefaultRemediationOffset("1min") + + .setSubCharacteristicId(-1) + .setRemediationFunction(null) + .setRemediationCoefficient(null) + .setRemediationOffset(null) + ); + session.commit(); + + WsTester.Result result = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD) + .setParam(WebService.Param.FIELDS, "debtChar,debtCharName,debtSubChar,debtSubCharName,debtRemFn,debtOverloaded,defaultDebtChar,defaultDebtSubChar,defaultDebtRemFn") + .setParam("debt_characteristics", "SOFT_RELIABILITY") + .setParam(WebService.Param.FACETS, "debt_characteristics") + .execute(); + result.assertJson(this.getClass(), "search_debt_rules_sticky.json"); + } + + @Test + public void search_template_rules() throws Exception { + RuleDto templateRule = RuleTesting.newXooX1().setIsTemplate(true); + ruleDao.insert(session, templateRule); + ruleDao.insert(session, RuleTesting.newXooX2()).setTemplateId(templateRule.getId()); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.FIELDS, "isTemplate"); + request.setParam(SearchAction.PARAM_IS_TEMPLATE, "true"); + WsTester.Result result = request.execute(); + result.assertJson(this.getClass(), "search_template_rules.json"); + } + + @Test + public void search_custom_rules_from_template_key() throws Exception { + RuleDto templateRule = RuleTesting.newXooX1().setIsTemplate(true); + ruleDao.insert(session, templateRule); + ruleDao.insert(session, RuleTesting.newXooX2()).setTemplateId(templateRule.getId()); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.FIELDS, "templateKey"); + request.setParam(SearchAction.PARAM_TEMPLATE_KEY, "xoo:x1"); + WsTester.Result result = request.execute(); + result.assertJson(this.getClass(), "search_rules_from_template_key.json"); + } + + @Test + public void search_all_active_rules() throws Exception { + QualityProfileDto profile = QProfileTesting.newXooP1(); + tester.get(QualityProfileDao.class).insert(session, profile); + + RuleDto rule = RuleTesting.newXooX1(); + ruleDao.insert(session, rule); + + ActiveRuleDto activeRule = newActiveRule(profile, rule); + tester.get(ActiveRuleDao.class).insert(session, activeRule); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.TEXT_QUERY, "x1"); + request.setParam(SearchAction.PARAM_ACTIVATION, "true"); + request.setParam(WebService.Param.FIELDS, ""); + WsTester.Result result = request.execute(); + + result.assertJson(this.getClass(), "search_active_rules.json"); + } + + @Test + public void search_profile_active_rules() throws Exception { + QualityProfileDto profile = QProfileTesting.newXooP1(); + tester.get(QualityProfileDao.class).insert(session, profile); + + QualityProfileDto profile2 = QProfileTesting.newXooP2(); + tester.get(QualityProfileDao.class).insert(session, profile2); + + session.commit(); + + RuleDto rule = RuleTesting.newXooX1(); + ruleDao.insert(session, rule); + + ActiveRuleDto activeRule = newActiveRule(profile, rule); + tester.get(ActiveRuleDao.class).insert(session, activeRule); + ActiveRuleDto activeRule2 = newActiveRule(profile2, rule); + tester.get(ActiveRuleDao.class).insert(session, activeRule2); + + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.TEXT_QUERY, "x1"); + request.setParam(SearchAction.PARAM_ACTIVATION, "true"); + request.setParam(SearchAction.PARAM_QPROFILE, profile2.getKey()); + request.setParam(WebService.Param.FIELDS, "actives"); + WsTester.Result result = request.execute(); + result.assertJson(this.getClass(), "search_profile_active_rules.json"); + + tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD) + .setParam(SearchAction.PARAM_ACTIVATION, "true") + .setParam(SearchAction.PARAM_QPROFILE, "unknown_profile") + .setParam(WebService.Param.FIELDS, "actives") + .execute() + .assertJson(this.getClass(), "search_no_rules.json"); + } + + @Test + public void search_profile_active_rules_with_inheritance() throws Exception { + QualityProfileDto profile = QProfileTesting.newXooP1(); + tester.get(QualityProfileDao.class).insert(session, profile); + + QualityProfileDto profile2 = QProfileTesting.newXooP2().setParentKee(profile.getKee()); + tester.get(QualityProfileDao.class).insert(session, profile2); + + session.commit(); + + RuleDto rule = RuleTesting.newXooX1(); + ruleDao.insert(session, rule); + + ActiveRuleDto activeRule = newActiveRule(profile, rule); + tester.get(ActiveRuleDao.class).insert(session, activeRule); + ActiveRuleDto activeRule2 = newActiveRule(profile2, rule).setInheritance(ActiveRuleDto.OVERRIDES).setSeverity(Severity.CRITICAL); + tester.get(ActiveRuleDao.class).insert(session, activeRule2); + + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.TEXT_QUERY, "x1"); + request.setParam(SearchAction.PARAM_ACTIVATION, "true"); + request.setParam(SearchAction.PARAM_QPROFILE, profile2.getKey()); + request.setParam(WebService.Param.FIELDS, "actives"); + WsTester.Result result = request.execute(); + result.assertJson(this.getClass(), "search_profile_active_rules_inheritance.json"); + } + + @Test + public void search_all_active_rules_params() throws Exception { + QualityProfileDto profile = QProfileTesting.newXooP1(); + tester.get(QualityProfileDao.class).insert(session, profile); + RuleDto rule = RuleTesting.newXooX1(); + ruleDao.insert(session, rule); + session.commit(); + + RuleParamDto param = RuleParamDto.createFor(rule) + .setDefaultValue("some value") + .setType("string") + .setDescription("My small description") + .setName("my_var"); + ruleDao.insertRuleParam(session, rule, param); + + RuleParamDto param2 = RuleParamDto.createFor(rule) + .setDefaultValue("other value") + .setType("integer") + .setDescription("My small description") + .setName("the_var"); + ruleDao.insertRuleParam(session, rule, param2); + + ActiveRuleDto activeRule = newActiveRule(profile, rule); + tester.get(ActiveRuleDao.class).insert(session, activeRule); + + ActiveRuleParamDto activeRuleParam = ActiveRuleParamDto.createFor(param) + .setValue("The VALUE"); + tester.get(ActiveRuleDao.class).insertParam(session, activeRule, activeRuleParam); + + ActiveRuleParamDto activeRuleParam2 = ActiveRuleParamDto.createFor(param2) + .setValue("The Other Value"); + tester.get(ActiveRuleDao.class).insertParam(session, activeRule, activeRuleParam2); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.TEXT_QUERY, "x1"); + request.setParam(SearchAction.PARAM_ACTIVATION, "true"); + request.setParam(WebService.Param.FIELDS, "params"); + WsTester.Result result = request.execute(); + + result.assertJson(this.getClass(), "search_active_rules_params.json"); + } + + @Test + public void get_note_as_markdown_and_html() throws Exception { + QualityProfileDto profile = QProfileTesting.newXooP1(); + tester.get(QualityProfileDao.class).insert(session, profile); + RuleDto rule = RuleTesting.newXooX1().setNoteData("this is *bold*"); + ruleDao.insert(session, rule); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.FIELDS, "htmlNote, mdNote"); + WsTester.Result result = request.execute(); + result.assertJson(this.getClass(), "get_note_as_markdown_and_html.json"); + } + + @Test + public void filter_by_tags() throws Exception { + ruleDao.insert(session, RuleTesting.newXooX1() + .setTags(Collections.<String>emptySet()) + .setSystemTags(ImmutableSet.of("tag1"))); + ruleDao.insert(session, RuleTesting.newXooX2() + .setTags(Collections.<String>emptySet()) + .setSystemTags(ImmutableSet.of("tag2"))); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(SearchAction.PARAM_TAGS, "tag1"); + request.setParam(WebService.Param.FIELDS, "sysTags, tags"); + request.setParam(WebService.Param.FACETS, "tags"); + WsTester.Result result = request.execute(); + result.assertJson(this.getClass(), "filter_by_tags.json"); + } + + @Test + public void severities_facet_should_have_all_severities() throws Exception { + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.FACETS, "severities"); + request.execute().assertJson(this.getClass(), "severities_facet.json"); + } + + @Test + public void statuses_facet_should_have_all_statuses_except_removed() throws Exception { + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.FACETS, "statuses"); + request.execute().assertJson(this.getClass(), "statuses_facet.json"); + } + + @Test + public void statuses_facet_should_be_sticky() throws Exception { + ruleDao.insert(session, RuleTesting.newXooX1()); + ruleDao.insert(session, RuleTesting.newXooX2().setStatus(RuleStatus.BETA)); + ruleDao.insert(session, RuleTesting.newXooX3().setStatus(RuleStatus.DEPRECATED)); + session.commit(); + + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(SearchAction.PARAM_STATUSES, "DEPRECATED"); + request.setParam(WebService.Param.FACETS, "statuses"); + request.execute().assertJson(this.getClass(), "statuses_facet_sticky.json"); + } + + @Test + public void sort_by_name() throws Exception { + ruleDao.insert(session, RuleTesting.newXooX1().setName("Dodgy - Consider returning a zero length array rather than null ")); + ruleDao.insert(session, RuleTesting.newXooX2().setName("Bad practice - Creates an empty zip file entry")); + ruleDao.insert(session, RuleTesting.newXooX3().setName("XPath rule")); + session.commit(); + + // 1. Sort Name Asc + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.FIELDS, ""); + request.setParam(WebService.Param.SORT, "name"); + request.setParam(WebService.Param.ASCENDING, "true"); + + WsTester.Result result = request.execute(); + result.assertJson("{\"total\":3,\"p\":1,\"ps\":100,\"rules\":[{\"key\":\"xoo:x2\"},{\"key\":\"xoo:x1\"},{\"key\":\"xoo:x3\"}]}"); + + // 2. Sort Name DESC + request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.FIELDS, ""); + request.setParam(WebService.Param.SORT, RuleNormalizer.RuleField.NAME.field()); + request.setParam(WebService.Param.ASCENDING, "false"); + + result = request.execute(); + result.assertJson("{\"total\":3,\"p\":1,\"ps\":100,\"rules\":[{\"key\":\"xoo:x3\"},{\"key\":\"xoo:x1\"},{\"key\":\"xoo:x2\"}]}"); + + } + + @Test + public void available_since() throws Exception { + ruleDao.insert(session, RuleTesting.newXooX1()); + ruleDao.insert(session, RuleTesting.newXooX2()); + session.commit(); + session.clearCache(); + + Date since = new Date(); + + // 1. find today's rules + WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.FIELDS, ""); + request.setParam(SearchAction.PARAM_AVAILABLE_SINCE, DateUtils.formatDate(since)); + request.setParam(WebService.Param.SORT, RuleNormalizer.RuleField.KEY.field()); + WsTester.Result result = request.execute(); + result.assertJson("{\"total\":2,\"p\":1,\"ps\":100,\"rules\":[{\"key\":\"xoo:x1\"},{\"key\":\"xoo:x2\"}]}"); + + Calendar c = Calendar.getInstance(); + c.setTime(since); + c.add(Calendar.DATE, 1); // number of days to add + + // 2. no rules since tomorrow + request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD); + request.setParam(WebService.Param.FIELDS, ""); + request.setParam(SearchAction.PARAM_AVAILABLE_SINCE, DateUtils.formatDate(c.getTime())); + result = request.execute(); + result.assertJson("{\"total\":0,\"p\":1,\"ps\":100,\"rules\":[]}"); + } + + private ActiveRuleDto newActiveRule(QualityProfileDto profile, RuleDto rule) { + return ActiveRuleDto.createFor(profile, rule) + .setInheritance(null) + .setSeverity("BLOCKER"); + } + + private void insertDebtCharacteristics(DbSession dbSession) { + CharacteristicDto reliability = DebtTesting.newCharacteristicDto("RELIABILITY").setName("Reliability"); + db.debtCharacteristicDao().insert(dbSession, reliability); + + CharacteristicDto softReliability = DebtTesting.newCharacteristicDto("SOFT_RELIABILITY").setName("Soft Reliability") + .setParentId(reliability.getId()); + db.debtCharacteristicDao().insert(dbSession, softReliability); + softReliabilityId = softReliability.getId(); + + CharacteristicDto hardReliability = DebtTesting.newCharacteristicDto("HARD_RELIABILITY").setName("Hard Reliability") + .setParentId(reliability.getId()); + db.debtCharacteristicDao().insert(dbSession, hardReliability); + hardReliabilityId = hardReliability.getId(); + } + +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/issue/RuleCacheLoaderTest/shared.xml b/server/sonar-server/src/test/resources/org/sonar/server/computation/issue/RuleCacheLoaderTest/shared.xml deleted file mode 100644 index 075ab07d14f..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/computation/issue/RuleCacheLoaderTest/shared.xml +++ /dev/null @@ -1,14 +0,0 @@ -<dataset> - <rules id="1" name="JS One" plugin_name="js" plugin_rule_key="JS01" - plugin_config_key="[null]" description="[null]" priority="4" - status="READY" - is_template="[false]" template_id="[null]" - tags="[null]" system_tags="[null]"/> - - <rules id="2" name="Java One" plugin_name="java" plugin_rule_key="JAV01" - plugin_config_key="[null]" description="[null]" priority="4" - status="READY" - is_template="[false]" template_id="[null]" - tags="[null]" system_tags="[null]"/> - -</dataset> diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/filter_by_tags.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/filter_by_tags.json index e109ed28cc8..e109ed28cc8 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/filter_by_tags.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/filter_by_tags.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/get_note_as_markdown_and_html.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/get_note_as_markdown_and_html.json index b4a4ecd5153..b4a4ecd5153 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/get_note_as_markdown_and_html.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/get_note_as_markdown_and_html.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_2_rules.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_2_rules.json index a3da4d33ff2..a3da4d33ff2 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_2_rules.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_2_rules.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_2_rules_fields.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_2_rules_fields.json index 0dcbe93c49f..0dcbe93c49f 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_2_rules_fields.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_2_rules_fields.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_active_rules.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_active_rules.json index 76e721d0b85..76e721d0b85 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_active_rules.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_active_rules.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_active_rules_params.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_active_rules_params.json index c8edf1ad34a..c8edf1ad34a 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_active_rules_params.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_active_rules_params.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_debt_rule.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rule.json index 0a2211290ec..0a2211290ec 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_debt_rule.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rule.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_debt_rules_sticky.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_sticky.json index 59441d3015d..59441d3015d 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_debt_rules_sticky.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_sticky.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_debt_rules_with_default_and_overridden_debt_values.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_and_overridden_debt_values.json index a3d107c3fc4..a3d107c3fc4 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_debt_rules_with_default_and_overridden_debt_values.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_and_overridden_debt_values.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_debt_rules_with_default_linear_offset_and_overridden_constant_debt.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_linear_offset_and_overridden_constant_debt.json index 0a1632920f0..0a1632920f0 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_debt_rules_with_default_linear_offset_and_overridden_constant_debt.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_linear_offset_and_overridden_constant_debt.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_debt_rules_with_default_linear_offset_and_overridden_linear_debt.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_linear_offset_and_overridden_linear_debt.json index d778dc77969..d778dc77969 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_debt_rules_with_default_linear_offset_and_overridden_linear_debt.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_debt_rules_with_default_linear_offset_and_overridden_linear_debt.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_no_rules.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_no_rules.json index 0e7286cf282..0e7286cf282 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_no_rules.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_no_rules.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_profile_active_rules.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_profile_active_rules.json index 1b7d587e7b0..ec6439cb0a7 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_profile_active_rules.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_profile_active_rules.json @@ -21,7 +21,7 @@ "XOO_P2": { "name": "P2", "lang": "xoo", - "langName": "xoo" + "langName": "Xoo" } } } diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_profile_active_rules_inheritance.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_profile_active_rules_inheritance.json index adc48218f3e..016101f2a44 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_profile_active_rules_inheritance.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_profile_active_rules_inheritance.json @@ -21,13 +21,13 @@ "XOO_P2": { "name": "P2", "lang": "xoo", - "langName": "xoo", + "langName": "Xoo", "parent": "XOO_P1" }, "XOO_P1": { "name": "P1", "lang": "xoo", - "langName": "xoo" + "langName": "Xoo" } } } diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_rules_from_template_key.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_rules_from_template_key.json index f9668593f71..f9668593f71 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_rules_from_template_key.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_rules_from_template_key.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_template_rules.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_template_rules.json index c7a449843da..c7a449843da 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/search_template_rules.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/search_template_rules.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/severities_facet.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/severities_facet.json index f2d9754809b..f2d9754809b 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/severities_facet.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/severities_facet.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/statuses_facet.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/statuses_facet.json index 4692be87efe..4692be87efe 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/statuses_facet.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/statuses_facet.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/statuses_facet_sticky.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/statuses_facet_sticky.json index a5b7a796655..a5b7a796655 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RulesWsMediumTest/statuses_facet_sticky.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/SearchActionMediumTest/statuses_facet_sticky.json diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-delete-profile.hbs b/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-delete-profile.hbs index a2635e55124..99ee29ce611 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-delete-profile.hbs +++ b/server/sonar-web/src/main/js/apps/quality-profiles/templates/quality-profiles-delete-profile.hbs @@ -1,4 +1,3 @@ -{{log this}} <form id="delete-profile-form"> <div class="modal-head"> <h2>{{t 'quality_profiles.delete_confirm_title'}}</h2> diff --git a/server/sonar-web/src/main/js/libs/third-party/select2.js b/server/sonar-web/src/main/js/libs/third-party/select2.js index 213f4cf930a..8975c0ea4c2 100644 --- a/server/sonar-web/src/main/js/libs/third-party/select2.js +++ b/server/sonar-web/src/main/js/libs/third-party/select2.js @@ -962,15 +962,17 @@ var cid = this.containerId, selector = this.containerSelector, scroll = "scroll." + cid, resize = "resize." + cid; - this.container.parents().each(function() { - $(this).bind(scroll, function() { - var s2 = $(selector); - if (s2.length == 0) { - $(this).unbind(scroll); - } - s2.select2("close"); + setTimeout(function () { + this.container.parents().each(function() { + $(this).bind(scroll, function() { + var s2 = $(selector); + if (s2.length == 0) { + $(this).unbind(scroll); + } + s2.select2("close"); + }); }); - }); + }.bind(this), 100); $(window).bind(resize, function() { var s2 = $(selector); @@ -1401,6 +1403,7 @@ // single close: function () { if (!this.opened()) return; + console.log('closing...'); this.parent.close.apply(this, arguments); this.dropdown.removeAttr("style").addClass("select2-offscreen").insertAfter(this.selection).show(); }, diff --git a/sonar-db/src/main/java/org/sonar/db/rule/RuleDao.java b/sonar-db/src/main/java/org/sonar/db/rule/RuleDao.java index cf4be7e8278..1a7026281f0 100644 --- a/sonar-db/src/main/java/org/sonar/db/rule/RuleDao.java +++ b/sonar-db/src/main/java/org/sonar/db/rule/RuleDao.java @@ -70,6 +70,10 @@ public class RuleDao implements Dao { mapper(session).selectEnabledAndNonManual(resultHandler); } + public List<RuleDto> selectAll(DbSession session) { + return mapper(session).selectAll(); + } + public void insert(DbSession session, RuleDto dto) { mapper(session).insert(dto); } diff --git a/sonar-db/src/main/java/org/sonar/db/rule/RuleMapper.java b/sonar-db/src/main/java/org/sonar/db/rule/RuleMapper.java index 833fdedf37c..e3af090fae3 100644 --- a/sonar-db/src/main/java/org/sonar/db/rule/RuleMapper.java +++ b/sonar-db/src/main/java/org/sonar/db/rule/RuleMapper.java @@ -30,6 +30,8 @@ public interface RuleMapper { List<RuleDto> selectAll(); + List<RuleDto> selectAll(ResultHandler resultHandler); + List<RuleDto> selectEnabledAndNonManual(); void selectEnabledAndNonManual(ResultHandler resultHandler); diff --git a/sonar-db/src/test/java/org/sonar/db/rule/RuleDaoTest.java b/sonar-db/src/test/java/org/sonar/db/rule/RuleDaoTest.java index 8bd207050be..b452784bddc 100644 --- a/sonar-db/src/test/java/org/sonar/db/rule/RuleDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/rule/RuleDaoTest.java @@ -129,6 +129,15 @@ public class RuleDaoTest { } @Test + public void selectAll() { + dbTester.prepareDbUnit(getClass(), "shared.xml"); + + List<RuleDto> ruleDtos = underTest.selectAll(dbTester.getSession()); + + assertThat(ruleDtos).extracting("id").containsOnly(1, 2); + } + + @Test public void insert() throws Exception { dbTester.getDbClient().ruleDao().insert(dbTester.getSession(), RuleTesting.newDto(RuleKey.of("java", "S001")).setConfigKey(null)); dbTester.getDbClient().ruleDao().insert(dbTester.getSession(), RuleTesting.newDto(RuleKey.of("java", "S002")).setConfigKey("I002")); |