Browse Source

SONAR-5007 move api/rules2 to api/rules

tags/4.4-RC1
Simon Brandhof 10 years ago
parent
commit
699ad4a425
28 changed files with 106 additions and 1120 deletions
  1. 2
    2
      sonar-server/src/main/hbs/issues/rule.hbs
  2. 0
    4
      sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
  3. 0
    4
      sonar-server/src/main/java/org/sonar/server/rule/RubyRuleService.java
  4. 0
    132
      sonar-server/src/main/java/org/sonar/server/rule/ws/RuleSearchWsHandler.java
  5. 0
    162
      sonar-server/src/main/java/org/sonar/server/rule/ws/RuleShowWsHandler.java
  6. 0
    68
      sonar-server/src/main/java/org/sonar/server/rule/ws/RulesWs.java
  7. 6
    0
      sonar-server/src/main/java/org/sonar/server/rule2/Rule.java
  8. 0
    1
      sonar-server/src/main/java/org/sonar/server/rule2/RuleService.java
  9. 16
    1
      sonar-server/src/main/java/org/sonar/server/rule2/index/RuleDoc.java
  10. 8
    12
      sonar-server/src/main/java/org/sonar/server/rule2/index/RuleIndex.java
  11. 13
    0
      sonar-server/src/main/java/org/sonar/server/rule2/index/RuleNormalizer.java
  12. 1
    1
      sonar-server/src/main/java/org/sonar/server/rule2/ws/RulesWebService.java
  13. 6
    2
      sonar-server/src/main/java/org/sonar/server/search/BaseIndex.java
  14. 0
    99
      sonar-server/src/main/webapp/WEB-INF/app/controllers/api/rules_controller.rb
  15. 1
    1
      sonar-server/src/main/webapp/WEB-INF/app/controllers/issue_controller.rb
  16. 0
    117
      sonar-server/src/main/webapp/WEB-INF/app/controllers/rules_configuration_controller.rb
  17. 1
    1
      sonar-server/src/main/webapp/WEB-INF/app/models/internal.rb
  18. 0
    28
      sonar-server/src/main/webapp/WEB-INF/app/models/rule.rb
  19. 7
    7
      sonar-server/src/main/webapp/WEB-INF/app/views/issue/_rule.html.erb
  20. 0
    42
      sonar-server/src/test/java/org/sonar/server/rule/RubyRuleServiceTest.java
  21. 0
    136
      sonar-server/src/test/java/org/sonar/server/rule/ws/RuleSearchWsHandlerTest.java
  22. 0
    206
      sonar-server/src/test/java/org/sonar/server/rule/ws/RuleShowWsHandlerTest.java
  23. 0
    71
      sonar-server/src/test/java/org/sonar/server/rule/ws/RulesWsTest.java
  24. 5
    1
      sonar-server/src/test/java/org/sonar/server/rule2/RegisterRulesTest.java
  25. 19
    3
      sonar-server/src/test/java/org/sonar/server/rule2/index/RuleFieldTest.java
  26. 13
    11
      sonar-server/src/test/java/org/sonar/server/rule2/index/RuleIndexMediumTest.java
  27. 1
    1
      sonar-server/src/test/java/org/sonar/server/rule2/ws/AppActionTest.java
  28. 7
    7
      sonar-server/src/test/java/org/sonar/server/rule2/ws/RulesWebServiceTest.java

+ 2
- 2
sonar-server/src/main/hbs/issues/rule.hbs View File

@@ -1,6 +1,6 @@
<div class="rule-desc">
<h1 class="marginbottom10">{{name}}</h1>
<div class="marginbottom10">{{{description}}}</div>
<div class="marginbottom10">{{{htmlDesc}}}</div>
</div>

<ul class="note code-issue-bar">
@@ -8,4 +8,4 @@
{{#all characteristic subCharacteristic}}
<li>{{characteristic}} > {{subCharacteristic}}{{else}}{{t 'issue.technical_debt_deleted'}}</li>
{{/all}}
</ul>
</ul>

+ 0
- 4
sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java View File

@@ -124,7 +124,6 @@ import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer;
import org.sonar.server.qualityprofile.persistence.ActiveRuleDao;
import org.sonar.server.qualityprofile.ws.*;
import org.sonar.server.rule.*;
import org.sonar.server.rule.ws.*;
import org.sonar.server.rule2.RegisterRules;
import org.sonar.server.rule2.RuleService;
import org.sonar.server.rule2.index.RuleIndex;
@@ -326,9 +325,6 @@ class ServerComponents {
pico.addSingleton(RuleRepositories.class);
pico.addSingleton(DeprecatedRulesDefinition.class);
pico.addSingleton(RuleDefinitionsLoader.class);
pico.addSingleton(RulesWs.class);
pico.addSingleton(RuleShowWsHandler.class);
pico.addSingleton(RuleSearchWsHandler.class);
pico.addSingleton(RulesDefinitionXmlLoader.class);

// experimental rules

+ 0
- 4
sonar-server/src/main/java/org/sonar/server/rule/RubyRuleService.java View File

@@ -93,10 +93,6 @@ public class RubyRuleService implements ServerComponent, Startable {
.setDebtRemediationOffset(Strings.emptyToNull((String) params.get("debtRemediationOffset"))));
}

public void updateRuleNote(int ruleId, String note) {
rules.updateRuleNote(ruleId, note);
}

public Integer createCustomRule(int ruleId, @Nullable String name, @Nullable String severity, @Nullable String description, Map<String, String> paramsByKey) {
return rules.createCustomRule(ruleId, name, severity, description, paramsByKey);
}

+ 0
- 132
sonar-server/src/main/java/org/sonar/server/rule/ws/RuleSearchWsHandler.java View File

@@ -1,132 +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.rule.ws;

import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.server.debt.DebtRemediationFunction;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.RequestHandler;
import org.sonar.api.server.ws.Response;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.server.paging.PagedResult;
import org.sonar.server.rule.Rule;
import org.sonar.server.rule.RuleQuery;
import org.sonar.server.rule.Rules;
import org.sonar.server.util.RubyUtils;

import javax.annotation.CheckForNull;

import java.util.Collection;
import java.util.Collections;

/**
* @deprecated to be dropped in 4.4
*/
@Deprecated
public class RuleSearchWsHandler implements RequestHandler {

private final Rules rules;
private final Languages languages;

public RuleSearchWsHandler(Rules rules, Languages languages) {
this.rules = rules;
this.languages = languages;
}

@Override
public void handle(Request request, Response response) {
final String ruleKeyParam = request.param("k");
Collection<Rule> foundRules = Collections.emptyList();
boolean hasMore = false;
long total = 0L;
if (ruleKeyParam == null) {
PagedResult<Rule> searchResult = rules.find(RuleQuery.builder()
.searchQuery(request.param("s"))
.languages(RubyUtils.toStrings(request.param("languages")))
.repositories(RubyUtils.toStrings(request.param("repositories")))
.severities(RubyUtils.toStrings(request.param("severities")))
.statuses(RubyUtils.toStrings(request.param("statuses")))
.tags(RubyUtils.toStrings(request.param("tags")))
.debtCharacteristics(RubyUtils.toStrings(request.param("debtCharacteristics")))
.hasDebtCharacteristic(request.paramAsBoolean("hasDebtCharacteristic"))
.pageSize(request.paramAsInt("ps"))
.pageIndex(request.paramAsInt("p"))
.build());
foundRules = searchResult.results();
hasMore = searchResult.paging().hasNextPage();
total = searchResult.paging().total();
} else {
RuleKey ruleKey = RuleKey.parse(ruleKeyParam);
Rule rule = findRule(ruleKey);
if (rule != null) {
foundRules = Collections.singleton(rule);
total = 1L;
}
hasMore = false;
}

JsonWriter json = response.newJsonWriter();
json.beginObject().name("results").beginArray();
for (Rule rule : foundRules) {
json.beginObject();
writeRule(rule, json);
json.endObject();
}
json.endArray().prop("more", hasMore).prop("total", total).endObject().close();
}

@CheckForNull
private Rule findRule(RuleKey ruleKey) {
return rules.findByKey(ruleKey);
}

private void writeRule(Rule rule, JsonWriter json) {
String languageName = null;
String languageKey = rule.language();
if (languageKey != null) {
Language language = languages.get(languageKey);
if (language != null) {
languageName = language.getName();
} else {
languageName = languageKey;
}
}
json
.prop("key", rule.ruleKey().toString())
.prop("repository", rule.ruleKey().repository())
.prop("name", rule.name())
.prop("language", languageName)
.prop("status", rule.status())
;
DebtRemediationFunction function = rule.debtRemediationFunction();
if (function != null) {
json
.prop("debtCharacteristic", rule.debtCharacteristicKey())
.prop("debtSubCharacteristic", rule.debtSubCharacteristicKey())
.prop("debtRemediationFunction", function.type().name())
.prop("debtRemediationCoefficient", function.coefficient())
.prop("debtRemediationOffset", function.offset())
;
}
}
}

+ 0
- 162
sonar-server/src/main/java/org/sonar/server/rule/ws/RuleShowWsHandler.java View File

@@ -1,162 +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.rule.ws;

import com.google.common.base.Strings;
import org.sonar.api.i18n.I18n;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.RuleFinder;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.RequestHandler;
import org.sonar.api.server.ws.Response;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.markdown.Markdown;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.rule.Rule;
import org.sonar.server.rule.RuleNote;
import org.sonar.server.rule.Rules;
import org.sonar.server.user.UserSession;

import javax.annotation.CheckForNull;
import javax.annotation.Nullable;

import java.util.Date;

/**
* @deprecated to be dropped in 4.4
*/
@Deprecated
public class RuleShowWsHandler implements RequestHandler {

private final Rules rules;
private final Languages languages;

// Only used to get manual rules
private final RuleFinder ruleFinder;
private final I18n i18n;

public RuleShowWsHandler(Rules rules, RuleFinder ruleFinder, I18n i18n, Languages languages) {
this.rules = rules;
this.ruleFinder = ruleFinder;
this.i18n = i18n;
this.languages = languages;
}

@Override
public void handle(Request request, Response response) {
final String ruleKeyParam = request.mandatoryParam("key");
RuleKey ruleKey = RuleKey.parse(ruleKeyParam);
Rule rule = findRule(ruleKey);
if (rule == null) {
throw new NotFoundException("Rule not found: " + ruleKey);
}

JsonWriter json = response.newJsonWriter();
json.beginObject().name("rule").beginObject();
writeRule(rule, json);
writeTags(rule, json);
json.endObject().endObject().close();
}

@CheckForNull
private Rule findRule(RuleKey ruleKey) {
// TODO remove this when manual rules are indexed in E/S
if (ruleKey.repository().equals(Rule.MANUAL_REPOSITORY_KEY)) {
org.sonar.api.rules.Rule rule = ruleFinder.findByKey(ruleKey);
if (rule != null) {
RulePriority severity = rule.getSeverity();
return new Rule.Builder()
.setKey(rule.getKey())
.setRepositoryKey(rule.getRepositoryKey())
.setName(rule.getName())
.setDescription(rule.getDescription())
.setSeverity(severity != null ? severity.name() : null)
.setStatus(rule.getStatus())
.setCreatedAt(rule.getCreatedAt())
.setUpdatedAt(rule.getUpdatedAt()).build();
}
return null;
} else {
return rules.findByKey(ruleKey);
}
}

private void writeRule(Rule rule, JsonWriter json) {
json
.prop("key", rule.ruleKey().toString())
.prop("name", rule.name())
.prop("description", rule.description());
addLanguage(rule, json);
addNote(rule, json);
addDate(rule.createdAt(), "createdAt", json);
addFormattedDate(rule.createdAt(), "fCreatedAt", json);
addDate(rule.updatedAt(), "updatedAt", json);
addFormattedDate(rule.updatedAt(), "fUpdatedAt", json);
}

private void addLanguage(Rule rule, JsonWriter json) {
String languageKey = rule.language();
if (languageKey != null) {
Language language = languages.get(languageKey);
json.prop("language", language == null ? languageKey : language.getName());
}
}

private void addNote(Rule rule, JsonWriter json) {
RuleNote ruleNote = rule.ruleNote();
if (ruleNote != null && !Strings.isNullOrEmpty(ruleNote.data())) {
json.prop("noteRaw", ruleNote.data())
.prop("noteHtml", Markdown.convertToHtml(ruleNote.data()));
}
}

private void writeTags(Rule rule, JsonWriter json) {
json.name("tags").beginArray();
for (String adminTag : rule.adminTags()) {
json.value(adminTag);
}
json.endArray();

json.name("sysTags").beginArray();
for (String systemTag : rule.systemTags()) {
json.value(systemTag);
}
json.endArray();
}

private void addDate(@Nullable Date date, String dateKey, JsonWriter json) {
if (date != null) {
json.prop(dateKey, DateUtils.formatDateTime(date));
}
}

private void addFormattedDate(@Nullable Date date, String dateKey, JsonWriter json) {
if (date != null) {
json.prop(dateKey, i18n.formatDateTime(UserSession.get().locale(), date));
}
}


}

+ 0
- 68
sonar-server/src/main/java/org/sonar/server/rule/ws/RulesWs.java View File

@@ -1,68 +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.rule.ws;

import org.sonar.api.server.ws.WebService;

/**
* @deprecated to be dropped in 4.4
*/
@Deprecated
public class RulesWs implements WebService {

private final RuleSearchWsHandler searchHandler;
private final RuleShowWsHandler showHandler;

public RulesWs(RuleSearchWsHandler searchHandler, RuleShowWsHandler showHandler) {
this.searchHandler = searchHandler;
this.showHandler = showHandler;
}

@Override
public void define(Context context) {
NewController controller = context.createController("api/rules")
.setDescription("Coding rules");

controller.createAction("list")
.setDescription("List rules that match the given criteria")
.setSince("4.3")
.setInternal(true)
.setHandler(searchHandler)
.createParam("s", "To return rules whose title contains this string.")
.createParam("k", "Key of the rule, for example : 'findbugs:DMI_USELESS_SUBSTRING'.")
.createParam("languages", "Comma-separated list of language keys")
.createParam("repositories", "Comma-separated list of repositories")
.createParam("severities", "Comma-separated list of severities. Possible values: INFO | MINOR | MAJOR | CRITICAL | BLOCKER.")
.createParam("statuses", "Comma-separated list of statuses. Possible values: READY | BETA | DEPRECATED.")
.createParam("tags", "Comma-separated list of tags. The rule is returned if it matches all the tags.")
.createParam("debtCharacteristics", "Comma-separated list of characteristics / sub-characteristics.")
.createParam("hasDebtCharacteristic", "Determine if returned rules should be linked to a debt characteristic or not. Possible values: true | false")
.createParam("ps", "Page size (default is 25).")
.createParam("p", "Page number (default is 1).");

controller.createAction("show")
.setDescription("Detail of rule")
.setSince("4.2")
.setHandler(showHandler)
.createParam("key", "Mandatory key of rule");

controller.done();
}
}

+ 6
- 0
sonar-server/src/main/java/org/sonar/server/rule2/Rule.java View File

@@ -81,4 +81,10 @@ public interface Rule {

@CheckForNull
String internalKey();

@CheckForNull
String noteAsMarkdown();

@CheckForNull
String noteLogin();
}

+ 0
- 1
sonar-server/src/main/java/org/sonar/server/rule2/RuleService.java View File

@@ -67,7 +67,6 @@ public class RuleService implements ServerComponent {
public RuleResult search(RuleQuery query, QueryOptions options) {
// keep only supported fields and add the fields to always return
options.filterFieldsToReturn(RuleIndex.PUBLIC_FIELDS);
options.addFieldsToReturn(RuleNormalizer.RuleField.REPOSITORY.key(), RuleNormalizer.RuleField.KEY.key());

RuleResult result = index.search(query, options);
for(Rule rule:result.getHits()){

+ 16
- 1
sonar-server/src/main/java/org/sonar/server/rule2/index/RuleDoc.java View File

@@ -153,7 +153,8 @@ class RuleDoc implements Rule {
@Override
@CheckForNull
public String debtCharacteristicKey() {
throw new UnsupportedOperationException("TODO");
// TO BE IMPLEMENTED
return null;
}

@Override
@@ -188,6 +189,20 @@ class RuleDoc implements Rule {
}
}

@Override
@CheckForNull
public String noteAsMarkdown() {
// TODO
return null;
}

@Override
@CheckForNull
public String noteLogin() {
// TODO
return null;
}

@Override
@CheckForNull
public Date createdAt() {

+ 8
- 12
sonar-server/src/main/java/org/sonar/server/rule2/index/RuleIndex.java View File

@@ -220,23 +220,19 @@ public class RuleIndex extends BaseIndex<Rule, RuleDto, RuleKey> {

/* integrate Option's Fields */
Set<String> fields = new HashSet<String>();
if (options.getFieldsToReturn() != null &&
!options.getFieldsToReturn().isEmpty()) {
for (String field : options.getFieldsToReturn()) {
fields.add(field);
}
if (options.getFieldsToReturn() != null && !options.getFieldsToReturn().isEmpty()) {
fields.addAll(options.getFieldsToReturn());
// required fields
// TODO remove REPOSITORY ? Move this list to RuleField constant ?
fields.add(RuleNormalizer.RuleField.KEY.key());
fields.add(RuleNormalizer.RuleField.REPOSITORY.key());
} else {
for (RuleNormalizer.RuleField field : RuleNormalizer.RuleField.values()) {
fields.add(field.key());
}
fields = RuleNormalizer.RuleField.ALL_KEYS;
}
//Add required fields:
fields.add(RuleNormalizer.RuleField.KEY.key());
fields.add(RuleNormalizer.RuleField.REPOSITORY.key());

//TODO limit source for available fields.
//esSearch.addFields(fields.toArray(new String[fields.size()]));
//esSearch.setSource(StringUtils.join(fields,','));
//esSearch.setSource(StringUtils.join(fields, ','));

return esSearch;
}

+ 13
- 0
sonar-server/src/main/java/org/sonar/server/rule2/index/RuleNormalizer.java View File

@@ -19,6 +19,10 @@
*/
package org.sonar.server.rule2.index;

import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import org.elasticsearch.action.update.UpdateRequest;
import org.sonar.api.rule.RuleKey;
import org.sonar.check.Cardinality;
@@ -28,9 +32,11 @@ import org.sonar.core.rule.RuleParamDto;
import org.sonar.server.db.DbClient;
import org.sonar.server.search.BaseNormalizer;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class RuleNormalizer extends BaseNormalizer<RuleDto, RuleKey> {

@@ -68,6 +74,13 @@ public class RuleNormalizer extends BaseNormalizer<RuleDto, RuleKey> {
public String toString() {
return key;
}

public static final Set<String> ALL_KEYS = ImmutableSet.copyOf(Collections2.transform(Lists.newArrayList(RuleField.values()), new Function<RuleField, String>() {
@Override
public String apply(@Nullable RuleField input) {
return input != null ? input.key : null;
}
}));
}

public static enum RuleParamField {

+ 1
- 1
sonar-server/src/main/java/org/sonar/server/rule2/ws/RulesWebService.java View File

@@ -43,7 +43,7 @@ public class RulesWebService implements WebService {
@Override
public void define(Context context) {
NewController controller = context
.createController("api/rules2")
.createController("api/rules")
.setDescription("Coding rules");

search.define(controller);

+ 6
- 2
sonar-server/src/main/java/org/sonar/server/search/BaseIndex.java View File

@@ -149,12 +149,16 @@ public abstract class BaseIndex<D, E extends Dto<K>, K extends Serializable>
public abstract D toDoc(GetResponse response);

public D getByKey(K key) {
return toDoc(getClient().prepareGet()
GetResponse response = getClient().prepareGet()
.setType(this.getIndexType())
.setIndex(this.getIndexName())
.setId(this.getKeyValue(key))
.setRouting(this.getKeyValue(key))
.get());
.get();
if (response.isExists()) {
return toDoc(response);
}
return null;
}

private void insertDocument(UpdateRequest request, K key) throws Exception {

+ 0
- 99
sonar-server/src/main/webapp/WEB-INF/app/controllers/api/rules_controller.rb View File

@@ -1,99 +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.
#
require 'fastercsv'
require "json"

class Api::RulesController < Api::RestController

def rest_call
set_backward_compatibility_params
language = params[:language] || ''
options= {}

options[:repositories]=params[:plugins].split(',') if params[:plugins]
options[:language]=language
options[:priorities]=params[:priorities].split(',') if params[:priorities]
options[:activation]=params[:status]
options[:searchtext]=params[:searchtext]
options[:include_parameters_and_notes]=true
options[:inheritance]=params[:inheritance]


if params[:profile]
profile = Profile.find_by_name_and_language(params[:profile], language)
if profile.nil?
rest_render([])
else
options[:profile]=profile
rules = Rule.search(java_facade, options)
rest_render(rules, profile)
end
else
rules = Rule.search(java_facade, options)
rest_render(rules)
end
end

def set_backward_compatibility_params
params[:plugins]=params[:plugin] if params[:plugin]
params[:priorities]=params[:levels] if params[:levels]
end


private

def rest_render(rules=[], profile=nil)
respond_to do |format|
format.json{ render :json => rest_to_json(rules, profile) }
format.xml { render :xml => rest_to_xml(rules, profile) }
format.csv {
send_data(rest_to_csv(rules, profile),
:type => 'text/csv; charset=utf-8; header=present',
:disposition => 'attachment; filename=rules.csv')
}
end
end

def rest_to_json(rules, profile)
JSON(rules.collect{|rule| rule.to_hash_json(profile)})
end

def rest_to_xml(rules, profile)
xml = Builder::XmlMarkup.new(:indent => 0)
xml.instruct!
xml.rules do
rules.each do |rule|
rule.to_xml(profile, xml)
end
end
end

def rest_to_csv(rules, profile)
FasterCSV.generate do |csv|
header = ["title", "key", "plugin"]
header.concat(["priority","status"]) if profile
csv << header
rules.each do |rule|
csv << rule.to_csv(profile)
end
end
end

end

+ 1
- 1
sonar-server/src/main/webapp/WEB-INF/app/controllers/issue_controller.rb View File

@@ -186,7 +186,7 @@ class IssueController < ApplicationController
verify_ajax_request
require_parameters :id

@rule = Internal.rules.findByKey(params[:id])
@rule = Internal.rules.getByKey(Java::OrgSonarApiRule::RuleKey.parse(params[:id]))
if @rule.debtCharacteristicKey()
@characteristic = Internal.debt.characteristicByKey(@rule.debtCharacteristicKey())
@sub_characteristic = Internal.debt.characteristicByKey(@rule.debtSubCharacteristicKey())

+ 0
- 117
sonar-server/src/main/webapp/WEB-INF/app/controllers/rules_configuration_controller.rb View File

@@ -102,30 +102,6 @@ class RulesConfigurationController < ApplicationController
@rule = Internal.quality_profiles.findByRule(params[:rule_id].to_i)
end

#
#
# POST /rules_configuration/create/<profile id>?rule_id=<rule id>&rule[name]=<new name>&...
#
#
def create
verify_post_request
require_parameters :id, :rule_id

profile_id = params[:id].to_i
rule_id = params[:rule_id].to_i
new_rule = nil
call_backend do
new_rule_id = Internal.rules.createCustomRule(rule_id, params[:rule][:name], params[:rule][:priority], params[:rule][:description], params[:rule_param])
new_rule = Internal.quality_profiles.findByRule(new_rule_id)
end

if new_rule
redirect_to :action => 'index', :id => profile_id, :searchtext => "\"#{new_rule.name()}\"", :rule_activation => 'INACTIVE', "plugins[]" => new_rule.repositoryKey()
else
redirect_to :action => 'new', :id => profile_id, :rule_id => rule_id
end
end


# deprecated since 2.3
def export
@@ -154,46 +130,6 @@ class RulesConfigurationController < ApplicationController
end
end

#
#
# POST /rules_configuration/update/<profile id>?rule_id=<rule id>&rule[name]=<new name>&...
#
#
def update
verify_post_request
require_parameters :id, :rule_id

profile_id = params[:id].to_i
rule_id = params[:rule_id].to_i
rule = nil
call_backend do
Internal.rules.updateCustomRule(rule_id, params[:rule][:name], params[:rule][:priority], params[:rule][:description], params[:rule_param])
rule = Internal.quality_profiles.findByRule(rule_id)
end

if rule
redirect_to :action => 'index', :id => profile_id, :searchtext => "\"#{rule.name()}\"", :rule_activation => '', "plugins[]" => rule.repositoryKey()
else
redirect_to :action => 'new', :id => profile_id, :rule_id => rule_id
end
end


#
#
# POST /rules_configuration/delete/<profile id>?rule_id=<rule id>
#
#
def delete
verify_post_request
require_parameters :id, :rule_id

call_backend do
Internal.rules.deleteCustomRule(params[:rule_id].to_i)
flash[:notice]=message('rules_configuration.rule_deleted')
end
redirect_to :action => 'index', :id => params[:id]
end

#
#
@@ -236,59 +172,6 @@ class RulesConfigurationController < ApplicationController
redirect_to url_parameters
end


def update_param
verify_post_request

access_denied unless has_role?(:profileadmin)
require_parameters :param_id, :active_rule_id, :profile_id

rule = nil
profile_id = params[:profile_id].to_i
active_rule_id = params[:active_rule_id].to_i
call_backend do
Internal.quality_profiles.updateActiveRuleParam(active_rule_id, params[:param_id], params[:value])
rule = Internal.quality_profiles.findByActiveRuleId(active_rule_id)
end

profile = Internal.quality_profiles.profile(profile_id)
parent_profile = Internal.quality_profiles.parent(profile)
render :partial => 'rule', :locals => {:rule => rule, :profile => profile, :parent_profile => parent_profile}
end


def update_rule_note
verify_post_request
require_parameters :rule_id, :active_rule_id

rule = nil
call_backend do
Internal.rules.updateRuleNote(params[:rule_id].to_i, params[:text])
rule = Internal.quality_profiles.findByActiveRuleId(params[:active_rule_id].to_i)
end
render :partial => 'rule_note', :locals => {:rule => rule}
end

def show_select_tags
rule = Internal.quality_profiles.findByRule(params[:rule_id].to_i)
tags = tag_selection_for_rule(rule)
render :partial => 'select_tags', :locals => { :rule => rule, :tags => tags, :profile_id => params[:profile_id] }
end

def select_tags
Internal.rules.updateRuleTags(params[:rule_id].to_i, params[:tags])
rule = Internal.quality_profiles.findByRule(params[:rule_id].to_i)
render :partial => 'rule_tags', :locals => {:rule => rule}
end

def create_tag
Internal.rule_tags.create(params[:new_tag])
rule = Internal.quality_profiles.findByRule(params[:rule_id].to_i)
tags = tag_selection_for_rule(rule)

render :partial => 'select_tags_list', :locals => {:tags => tags}
end

private

def init_params

+ 1
- 1
sonar-server/src/main/webapp/WEB-INF/app/models/internal.rb View File

@@ -79,7 +79,7 @@ class Internal
end

def self.rules
component(Java::OrgSonarServerRule::RubyRuleService.java_class)
component(Java::OrgSonarServerRule2::RuleService.java_class)
end

def self.durations

+ 0
- 28
sonar-server/src/main/webapp/WEB-INF/app/models/rule.rb View File

@@ -256,34 +256,6 @@ class Rule < ActiveRecord::Base
csv
end


# 'unused' parameter used to be available to inject java_facade, kept for compatibility w/ plugins (e.g sqale)
# options :language => nil, :repositories => [], :searchtext => '', :profile => nil, :priorities => [], :activation => '', :status => [], :sort_by => nil
def self.search(unused, options={})
# First, perform search with rule-specific criteria
java_hash = {}
options.each do |key, value|
java_hash[key.to_s] = Array(value).join("|")
end
params = java.util.HashMap.new(java_hash)

# SONAR-5048 Group results by 1000 due to fix issue on Oracle db
rules = []
matching_rule_ids = Array(Internal.rules.findIds(params))
unless matching_rule_ids.empty?
ids_grouped = matching_rule_ids.each_slice(1000).to_a
ids_condition = []
ids_grouped.each do |group|
ids_condition << 'id in (' + group.join(',') + ')'
end

includes=(options[:include_parameters_and_notes] ? [:rules_parameters] : nil)
rules = Rule.all(:include => includes, :conditions => [ids_condition.join(' or ')])
rules = Rule.sort_by(rules, options[:sort_by])
end
filter(rules, options)
end

def self.remove_blank(array)
if array
array = array - ['']

+ 7
- 7
sonar-server/src/main/webapp/WEB-INF/app/views/issue/_rule.html.erb View File

@@ -1,21 +1,21 @@
<h1 class="marginbottom10"><%= h @rule.name %></h1>
<h1 class="marginbottom10"><%= h @rule.name() -%></h1>

<div class="marginbottom10">
<% if @rule.description.strip.start_with?('<p>') %>
<%= Internal.text.interpretMacros(@rule.description) %>
<% if @rule.htmlDescription.strip.start_with?('<p>') %>
<%= Internal.text.interpretMacros(@rule.htmlDescription) %>
<% else %>
<p><%= Internal.text.interpretMacros(@rule.description) %></p>
<p><%= Internal.text.interpretMacros(@rule.htmlDescription) %></p>
<% end %>
</div>

<% if @rule.ruleNote() %>
<% if @rule.noteAsMarkdown() %>
<div class="marginbottom10">
<%= Api::Utils.markdown_to_html(@rule.ruleNote().data()) -%>
<%= Api::Utils.markdown_to_html(@rule.noteAsMarkdown()) -%>
</div>
<% end %>

<p class="note">
<span class="spacer-right"><%= h @rule.ruleKey() -%></span>
<span class="spacer-right"><%= h @rule.key() -%></span>
<%= image_tag 'sep12.png', :class => 'spacer-right' -%>
<% if @characteristic && @sub_characteristic %>
<%= @characteristic.name -%>&nbsp;&gt;&nbsp;<%= @sub_characteristic.name -%>

+ 0
- 42
sonar-server/src/test/java/org/sonar/server/rule/RubyRuleServiceTest.java View File

@@ -19,7 +19,6 @@
*/
package org.sonar.server.rule;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import org.junit.Before;
@@ -33,7 +32,6 @@ import org.sonar.api.rule.Severity;

import java.util.Map;

import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.verify;
@@ -99,12 +97,6 @@ public class RubyRuleServiceTest {
assertThat(ruleChange.debtRemediationOffset()).isEqualTo("10min");
}

@Test
public void update_rule_note() {
facade.updateRuleNote(10, "My note");
verify(rules).updateRuleNote(10, "My note");
}

@Test
public void create_custom_rule() {
facade.createCustomRule(10, "Rule name", Severity.MAJOR, "My note", ImmutableMap.of("max", "20"));
@@ -129,40 +121,6 @@ public class RubyRuleServiceTest {
verify(rules).findByKey(RuleKey.of("repo", "key"));
}

@Test
public void find_by_params() {
Map<String, Object> params = newHashMap();
params.put("searchQuery", "NPE");
params.put("key", "rule");
params.put("languages", newArrayList("java", "xoo"));
params.put("repositories", newArrayList("pmd", "checkstyle"));
params.put("severities", newArrayList("MINOR", "MAJOR"));
params.put("statuses", newArrayList("READY", "BETA"));
params.put("tags", newArrayList("has-params", "keep-enabled"));
params.put("debtCharacteristics", newArrayList("MODULARITY", "REUSABILITY"));
params.put("hasDebtCharacteristic", "true");

params.put("pageSize", 10l);
params.put("pageIndex", 50);

facade.find(params);
ArgumentCaptor<RuleQuery> ruleQueryCaptor = ArgumentCaptor.forClass(RuleQuery.class);
verify(rules).find(ruleQueryCaptor.capture());

RuleQuery query = ruleQueryCaptor.getValue();
assertThat(query.searchQuery()).isEqualTo("NPE");
assertThat(query.key()).isEqualTo("rule");
assertThat(query.languages()).containsOnly("java", "xoo");
assertThat(query.repositories()).containsOnly("pmd", "checkstyle");
assertThat(query.severities()).containsOnly("MINOR", "MAJOR");
assertThat(query.statuses()).containsOnly("READY", "BETA");
assertThat(query.tags()).containsOnly("has-params", "keep-enabled");
assertThat(query.debtCharacteristics()).containsOnly("MODULARITY", "REUSABILITY");
assertThat(query.hasDebtCharacteristic()).isTrue();
assertThat(query.pageSize()).isEqualTo(10);
assertThat(query.pageIndex()).isEqualTo(50);
}

@Test
public void just_for_fun_and_coverage() throws Exception {
facade.start();

+ 0
- 136
sonar-server/src/test/java/org/sonar/server/rule/ws/RuleSearchWsHandlerTest.java View File

@@ -1,136 +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.rule.ws;

import com.google.common.collect.ImmutableList;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.server.debt.DebtRemediationFunction;
import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction;
import org.sonar.server.ws.WsTester;
import org.sonar.server.paging.PagedResult;
import org.sonar.server.paging.PagingResult;
import org.sonar.server.rule.Rule;
import org.sonar.server.rule.RuleQuery;
import org.sonar.server.rule.Rules;
import org.sonar.server.user.MockUserSession;

import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class RuleSearchWsHandlerTest {

@Mock
Rules rules;

@Mock
Languages languages;

Rule.Builder ruleBuilder = new Rule.Builder()
.setKey("AvoidCycle")
.setRepositoryKey("squid")
.setName("Avoid cycle")
.setDescription("Avoid cycle between packages")
.setLanguage("java")
.setStatus("READY")
.setDebtCharacteristicKey("REUSABILITY")
.setDebtSubCharacteristicKey("MODULARITY")
.setDebtRemediationFunction(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "1h", "15min"));

WsTester tester;

@Before
public void setUp() throws Exception {
tester = new WsTester(new RulesWs(new RuleSearchWsHandler(rules, languages), mock(RuleShowWsHandler.class)));
}

@Test
public void search_rules() throws Exception {
final int pageSize = 10;
final int pageIndex = 2;
Rule rule = ruleBuilder.build();

when(rules.find(any(RuleQuery.class))).thenReturn(
new PagedResult<Rule>(ImmutableList.of(rule), PagingResult.create(pageSize, pageIndex, 1)));
Language lang = mock(Language.class);
when(lang.getName()).thenReturn("Java");
when(languages.get("java")).thenReturn(lang);

MockUserSession.set();
WsTester.TestRequest request = tester.newGetRequest("api/rules", "list").setParam("ps", "10").setParam("p", "2");
request.execute().assertJson(getClass(), "search_rules.json");
}

@Test
public void search_rule_by_key() throws Exception {
String ruleKey = "squid:AvoidCycle";
Rule rule = ruleBuilder.build();

when(rules.findByKey(RuleKey.parse(ruleKey))).thenReturn(rule);
Language lang = mock(Language.class);
when(lang.getName()).thenReturn("Java");
when(languages.get("java")).thenReturn(lang);

MockUserSession.set();
WsTester.TestRequest request = tester.newGetRequest("api/rules", "list").setParam("k", ruleKey);
request.execute().assertJson(getClass(), "search_rules.json");
}

@Test
public void verify_rule_query_filters() throws Exception {
Rule rule = ruleBuilder.build();

when(rules.find(any(RuleQuery.class))).thenReturn(
new PagedResult<Rule>(ImmutableList.of(rule), PagingResult.create(10, 1, 1)));

MockUserSession.set();
tester.newGetRequest("api/rules", "list")
.setParam("languages", "java,js")
.setParam("repositories", "squid,pmd")
.setParam("severities", "MAJOR,MINOR")
.setParam("statuses", "READY,BETA")
.setParam("tags", "has-params,integration-tests")
.setParam("debtCharacteristics", "MODULARITY,REUSABILITY")
.setParam("hasDebtCharacteristic", "true")
.execute();

ArgumentCaptor<RuleQuery> ruleQueryCaptor = ArgumentCaptor.forClass(RuleQuery.class);
verify(rules).find(ruleQueryCaptor.capture());

assertThat(ruleQueryCaptor.getValue().languages()).containsOnly("java", "js");
assertThat(ruleQueryCaptor.getValue().repositories()).containsOnly("squid", "pmd");
assertThat(ruleQueryCaptor.getValue().severities()).containsOnly("MAJOR", "MINOR");
assertThat(ruleQueryCaptor.getValue().statuses()).containsOnly("READY", "BETA");
assertThat(ruleQueryCaptor.getValue().tags()).containsOnly("has-params", "integration-tests");
assertThat(ruleQueryCaptor.getValue().debtCharacteristics()).containsOnly("MODULARITY", "REUSABILITY");
assertThat(ruleQueryCaptor.getValue().hasDebtCharacteristic()).isTrue();
}

}

+ 0
- 206
sonar-server/src/test/java/org/sonar/server/rule/ws/RuleShowWsHandlerTest.java View File

@@ -1,206 +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.rule.ws;

import com.google.common.collect.ImmutableList;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.sonar.api.i18n.I18n;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.RuleFinder;
import org.sonar.server.ws.WsTester;
import org.sonar.api.utils.DateUtils;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.rule.Rule;
import org.sonar.server.rule.RuleNote;
import org.sonar.server.rule.Rules;
import org.sonar.server.user.MockUserSession;

import java.util.Date;
import java.util.Locale;

import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class RuleShowWsHandlerTest {

@Mock
Rules rules;

@Mock
Languages languages;

@Mock
RuleFinder ruleFinder;

@Mock
I18n i18n;

Rule.Builder ruleBuilder = new Rule.Builder()
.setKey("AvoidCycle")
.setRepositoryKey("squid")
.setName("Avoid cycle")
.setLanguage("xoo")
.setDescription("Avoid cycle between packages");

WsTester tester;

@Before
public void setUp() throws Exception {
tester = new WsTester(new RulesWs(mock(RuleSearchWsHandler.class), new RuleShowWsHandler(rules, ruleFinder, i18n, languages)));
}

@Test
public void show_rule() throws Exception {
String ruleKey = "squid:AvoidCycle";
Rule rule = ruleBuilder.build();

when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(rule);
Language language = mock(Language.class);
when(language.getName()).thenReturn("Xoo");
when(languages.get("xoo")).thenReturn(language);

MockUserSession.set();
WsTester.TestRequest request = tester.newGetRequest("api/rules", "show").setParam("key", ruleKey);
request.execute().assertJson(getClass(), "show_rule.json");
}

@Test
public void return_not_found_on_unknown_rule() throws Exception {
String ruleKey = "squid:AvoidCycle";

when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(null);

MockUserSession.set();
WsTester.TestRequest request = tester.newGetRequest("api/rules", "show").setParam("key", ruleKey);

try {
request.execute();
fail();
} catch (Exception e) {
assertThat(e).isInstanceOf(NotFoundException.class);
}
}

@Test
public void show_rule_with_dates() throws Exception {
Date date1 = DateUtils.parseDateTime("2014-01-22T19:10:03+0100");
Date date2 = DateUtils.parseDateTime("2014-01-23T19:10:03+0100");
Rule rule = ruleBuilder
.setCreatedAt(date1)
.setUpdatedAt(date2)
.build();

when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(rule);
when(i18n.formatDateTime(any(Locale.class), eq(date1))).thenReturn("Jan 22, 2014 10:03 AM");
when(i18n.formatDateTime(any(Locale.class), eq(date2))).thenReturn("Jan 23, 2014 10:03 AM");

MockUserSession.set();
WsTester.TestRequest request = tester.newGetRequest("api/rules", "show").setParam("key", rule.ruleKey().toString());
request.execute().assertJson(getClass(), "show_rule_with_dates.json");
}

@Test
public void show_rule_with_note() throws Exception {
RuleNote note = mock(RuleNote.class);
when(note.data()).thenReturn("*Extended rule description*");
Rule rule = ruleBuilder
.setRuleNote(note)
.build();

when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(rule);

MockUserSession.set();
WsTester.TestRequest request = tester.newGetRequest("api/rules", "show").setParam("key", rule.ruleKey().toString());
request.execute().assertJson(getClass(), "show_rule_with_note.json");
}

@Test
public void show_rule_with_tags() throws Exception {
Rule rule = ruleBuilder
.setAdminTags(ImmutableList.of("complexity"))
.setSystemTags(ImmutableList.of("security"))
.build();

when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(rule);

MockUserSession.set();
WsTester.TestRequest request = tester.newGetRequest("api/rules", "show").setParam("key", rule.ruleKey().toString());
request.execute().assertJson(getClass(), "show_rule_with_tags.json");
}

@Test
public void show_manual_rule() throws Exception {
String ruleKey = "manual:api";
when(ruleFinder.findByKey(RuleKey.of("manual", "api"))).thenReturn(
org.sonar.api.rules.Rule.create("manual", "api", "API").setDescription("API rule description"));

MockUserSession.set();
WsTester.TestRequest request = tester.newGetRequest("api/rules", "show").setParam("key", ruleKey);
request.execute();
request.execute().assertJson(getClass(), "show_manuel_rule.json");
}

@Test
public void show_manual_rule_without_severity() throws Exception {
String ruleKey = "manual:api";
org.sonar.api.rules.Rule rule = mock(org.sonar.api.rules.Rule.class);
when(rule.getKey()).thenReturn("api");
when(rule.getRepositoryKey()).thenReturn("manual");
when(rule.getName()).thenReturn("API");
when(rule.getDescription()).thenReturn("API rule description");
when(rule.getSeverity()).thenReturn(null);
when(ruleFinder.findByKey(RuleKey.of("manual", "api"))).thenReturn(rule);

MockUserSession.set();
WsTester.TestRequest request = tester.newGetRequest("api/rules", "show").setParam("key", ruleKey);
request.execute();
request.execute().assertJson(getClass(), "show_manuel_rule.json");
}

@Test
public void return_not_found_on_unknown_manual_rule() throws Exception {
String ruleKey = "manual:api";

when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(null);

MockUserSession.set();
WsTester.TestRequest request = tester.newGetRequest("api/rules", "show").setParam("key", ruleKey);

try {
request.execute();
fail();
} catch (Exception e) {
assertThat(e).isInstanceOf(NotFoundException.class);
}
}

}

+ 0
- 71
sonar-server/src/test/java/org/sonar/server/rule/ws/RulesWsTest.java View File

@@ -1,71 +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.rule.ws;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.sonar.api.server.ws.WebService;
import org.sonar.server.ws.WsTester;

import static org.fest.assertions.Assertions.assertThat;

@RunWith(MockitoJUnitRunner.class)
public class RulesWsTest {

@Mock
RuleSearchWsHandler searchHandler;

@Mock
RuleShowWsHandler showHandler;

WsTester tester;

@Before
public void setUp() {
tester = new WsTester(new RulesWs(searchHandler, showHandler));
}

@Test
public void define_ws() throws Exception {
WebService.Controller controller = tester.controller("api/rules");
assertThat(controller).isNotNull();
assertThat(controller.path()).isEqualTo("api/rules");
assertThat(controller.description()).isNotEmpty();
assertThat(controller.actions()).hasSize(2);

WebService.Action list = controller.action("list");
assertThat(list).isNotNull();
assertThat(list.handler()).isNotNull();
assertThat(list.since()).isEqualTo("4.3");
assertThat(list.isPost()).isFalse();
assertThat(list.isInternal()).isTrue();
assertThat(list.params()).hasSize(11);

WebService.Action show = controller.action("show");
assertThat(show).isNotNull();
assertThat(show.handler()).isNotNull();
assertThat(show.since()).isEqualTo("4.2");
assertThat(show.isPost()).isFalse();
assertThat(show.isInternal()).isFalse();
}
}

+ 5
- 1
sonar-server/src/test/java/org/sonar/server/rule2/RegisterRulesTest.java View File

@@ -123,10 +123,12 @@ public class RegisterRulesTest extends AbstractDaoTestCase {
execute(new FakeRepositoryV1());
assertThat(dbClient.ruleDao().findAll(dbSession)).hasSize(2);

// user adds tags
// user adds tags and sets markdown note
RuleKey ruleKey1 = RuleKey.of("fake", "rule1");
RuleDto rule1 = dbClient.ruleDao().getByKey(ruleKey1, dbSession);
rule1.setTags(Sets.newHashSet("usertag1", "usertag2"));
rule1.setNoteData("user *note*");
rule1.setNoteUserLogin("marius");
dbClient.ruleDao().update(rule1, dbSession);
dbSession.commit();

@@ -141,6 +143,8 @@ public class RegisterRulesTest extends AbstractDaoTestCase {
assertThat(rule1.getTags()).containsOnly("usertag1", "usertag2");
assertThat(rule1.getSystemTags()).containsOnly("tag1", "tag4");
assertThat(rule1.getConfigKey()).isEqualTo("config1 v2");
assertThat(rule1.getNoteData()).isEqualTo("user *note*");
assertThat(rule1.getNoteUserLogin()).isEqualTo("marius");
assertThat(rule1.getStatus()).isEqualTo(RuleStatus.READY.toString());
assertThat(rule1.getCreatedAt()).isEqualTo(DATE1);
assertThat(rule1.getUpdatedAt()).isEqualTo(DATE2);

sonar-server/src/main/java/org/sonar/server/rule/ws/package-info.java → sonar-server/src/test/java/org/sonar/server/rule2/index/RuleFieldTest.java View File

@@ -17,7 +17,23 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@ParametersAreNonnullByDefault
package org.sonar.server.rule.ws;
package org.sonar.server.rule2.index;

import javax.annotation.ParametersAreNonnullByDefault;
import org.junit.Test;

import static org.fest.assertions.Assertions.assertThat;

public class RuleFieldTest {

@Test
public void all_rule_fields() throws Exception {
assertThat(RuleNormalizer.RuleField.ALL_KEYS).contains(
RuleNormalizer.RuleField.KEY.key(), RuleNormalizer.RuleField.REPOSITORY.key(), RuleNormalizer.RuleField.TAGS.key(),
RuleNormalizer.RuleField.CREATED_AT.key());
}

@Test
public void key_of_rule_field() throws Exception {
assertThat(RuleNormalizer.RuleField.INTERNAL_KEY.key()).isEqualTo("internalKey");
}
}

+ 13
- 11
sonar-server/src/test/java/org/sonar/server/rule2/index/RuleIndexMediumTest.java View File

@@ -21,6 +21,7 @@ package org.sonar.server.rule2.index;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
@@ -66,7 +67,7 @@ public class RuleIndexMediumTest {
}

@Test
public void insert_rule() throws InterruptedException {
public void getByKey() throws InterruptedException {
RuleDto ruleDto = newRuleDto(RuleKey.of("javascript", "S001"));
dao.insert(ruleDto, dbSession);
dbSession.commit();
@@ -78,21 +79,23 @@ public class RuleIndexMediumTest {

assertThat(rule.htmlDescription()).isEqualTo(ruleDto.getDescription());
assertThat(rule.key()).isEqualTo(ruleDto.getKey());
//
// assertThat(rule.debtSubCharacteristicKey())
// .isEqualTo(ruleDto.getDefaultSubCharacteristicId().toString());
assertThat(rule.debtRemediationFunction().type().name())
.isEqualTo(ruleDto.getRemediationFunction());

assertThat(Sets.newHashSet(rule.tags())).isEqualTo(ruleDto.getTags());
assertThat(Sets.newHashSet(rule.systemTags())).isEqualTo(ruleDto.getSystemTags());
}

//
// assertThat(rule.tags()).containsExactly(ruleDto.getTags());
// assertThat(rule.systemTags()).containsExactly(ruleDto.getSystemTags());

@Test
public void getByKey_null_if_not_found() throws InterruptedException {
Rule rule = index.getByKey(RuleKey.of("javascript", "unknown"));

assertThat(rule).isNull();
}


@Test
public void facet_test_with_repository() {
dao.insert(newRuleDto(RuleKey.of("javascript", "S001")).setRuleKey("X001"), dbSession);
@@ -135,7 +138,6 @@ public class RuleIndexMediumTest {

@Test
@Ignore
//TODO discuss if enforced in WS only.
public void select_doc_fields_to_return() {
dao.insert(newRuleDto(RuleKey.of("javascript", "S001")), dbSession);
dbSession.commit();
@@ -367,7 +369,7 @@ public class RuleIndexMediumTest {
// tag1 in query
query = new RuleQuery().setQueryText("tag1");
assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1);
assertThat(Iterables.getFirst(index.search(query, new QueryOptions()).getHits(),null).tags()).containsExactly("tag1");
assertThat(Iterables.getFirst(index.search(query, new QueryOptions()).getHits(), null).tags()).containsExactly("tag1");

// tag1 and tag2 in query
query = new RuleQuery().setQueryText("tag1 tag2");
@@ -376,7 +378,7 @@ public class RuleIndexMediumTest {
// tag2 in filter
query = new RuleQuery().setTags(ImmutableSet.of("tag2"));
assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1);
assertThat(Iterables.getFirst(index.search(query, new QueryOptions()).getHits(),null).tags()).containsExactly("tag2");
assertThat(Iterables.getFirst(index.search(query, new QueryOptions()).getHits(), null).tags()).containsExactly("tag2");

// tag2 in filter and tag1 tag2 in query
query = new RuleQuery().setTags(ImmutableSet.of("tag2")).setQueryText("tag1");
@@ -385,7 +387,7 @@ public class RuleIndexMediumTest {
// tag2 in filter and tag1 in query
query = new RuleQuery().setTags(ImmutableSet.of("tag2")).setQueryText("tag1 tag2");
assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1);
assertThat(Iterables.getFirst(index.search(query, new QueryOptions()).getHits(),null).tags()).containsExactly("tag2");
assertThat(Iterables.getFirst(index.search(query, new QueryOptions()).getHits(), null).tags()).containsExactly("tag2");

// null list => no filter
query = new RuleQuery().setTags(Collections.<String>emptySet());

+ 1
- 1
sonar-server/src/test/java/org/sonar/server/rule2/ws/AppActionTest.java View File

@@ -105,6 +105,6 @@ public class AppActionTest {
char2.setId(24).setParentId(parentId).setKey("MODULARITY").setName("Modularity");
when(debtModel.allCharacteristics()).thenReturn(ImmutableList.<DebtCharacteristic>of(char1, char2));

tester.newGetRequest("api/rules2", "app").execute().assertJson(this.getClass(), "app.json");
tester.newGetRequest("api/rules", "app").execute().assertJson(this.getClass(), "app.json");
}
}

+ 7
- 7
sonar-server/src/test/java/org/sonar/server/rule2/ws/RulesWebServiceTest.java View File

@@ -83,7 +83,7 @@ public class RulesWebServiceTest {
WebService.Context context = new WebService.Context();
ws.define(context);

WebService.Controller controller = context.controller("api/rules2");
WebService.Controller controller = context.controller("api/rules");

assertThat(controller).isNotNull();
assertThat(controller.actions()).hasSize(6);
@@ -99,7 +99,7 @@ public class RulesWebServiceTest {
public void search_no_rules() throws Exception {

MockUserSession.set();
WsTester.TestRequest request = wsTester.newGetRequest("api/rules2", "search");
WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "search");

WsTester.Result result = request.execute();

@@ -115,7 +115,7 @@ public class RulesWebServiceTest {
tester.get(RuleService.class).refresh();

MockUserSession.set();
WsTester.TestRequest request = wsTester.newGetRequest("api/rules2", "search");
WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "search");
WsTester.Result result = request.execute();

String json = result.outputAsString();
@@ -137,7 +137,7 @@ public class RulesWebServiceTest {
tester.get(RuleService.class).refresh();

MockUserSession.set();
WsTester.TestRequest request = wsTester.newGetRequest("api/rules2", "search");
WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "search");
WsTester.Result result = request.execute();

result.assertJson(this.getClass(),"search_debt_rule.json");
@@ -161,7 +161,7 @@ public class RulesWebServiceTest {


MockUserSession.set();
WsTester.TestRequest request = wsTester.newGetRequest("api/rules2", "search");
WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "search");
request.setParam("q","S001");
WsTester.Result result = request.execute();

@@ -208,7 +208,7 @@ public class RulesWebServiceTest {
tester.get(RuleService.class).refresh();

MockUserSession.set();
WsTester.TestRequest request = wsTester.newGetRequest("api/rules2", "search");
WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "search");
request.setParam("q", "S001");
WsTester.Result result = request.execute();

@@ -236,7 +236,7 @@ public class RulesWebServiceTest {


MockUserSession.set();
WsTester.TestRequest request = wsTester.newGetRequest("api/rules2", "tags");
WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "tags");
WsTester.Result result = request.execute();

result.assertJson(this.getClass(),"get_tags.json");

Loading…
Cancel
Save