diff options
author | Fabrice Bellingard <bellingard@gmail.com> | 2012-05-13 22:41:21 +0200 |
---|---|---|
committer | Fabrice Bellingard <bellingard@gmail.com> | 2012-05-14 15:11:01 +0200 |
commit | b4d82de23fc414353dace746378fc8ec8e33b7a5 (patch) | |
tree | 69b3e363ed1cedd8924232db4af926a48ee7a265 /sonar-server | |
parent | ebab45f85888753e69b5acab3a26124cc1fc9c07 (diff) | |
download | sonarqube-b4d82de23fc414353dace746378fc8ec8e33b7a5.tar.gz sonarqube-b4d82de23fc414353dace746378fc8ec8e33b7a5.zip |
SONAR-2706 / SONAR-2541 Refactoring
Diffstat (limited to 'sonar-server')
13 files changed, 374 insertions, 194 deletions
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java index 76cb88f4c70..9c8c2b01ec0 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java @@ -72,7 +72,7 @@ import org.sonar.server.plugins.ServerExtensionInstaller; import org.sonar.server.plugins.UpdateCenterClient; import org.sonar.server.plugins.UpdateCenterMatrixFactory; import org.sonar.server.qualitymodel.DefaultModelManager; -import org.sonar.server.reviews.ReviewActionsManager; +import org.sonar.server.reviews.ReviewManager; import org.sonar.server.rules.ProfilesConsole; import org.sonar.server.rules.RulesConsole; import org.sonar.server.startup.ActivateDefaultProfiles; @@ -241,7 +241,7 @@ public final class Platform { servicesContainer.addSingleton(ReviewsNotificationManager.class); // Reviews - servicesContainer.addSingleton(ReviewActionsManager.class); + servicesContainer.addSingleton(ReviewManager.class); servicesContainer.startComponents(); } diff --git a/sonar-server/src/main/java/org/sonar/server/reviews/ReviewActionsManager.java b/sonar-server/src/main/java/org/sonar/server/reviews/ReviewActionsManager.java deleted file mode 100644 index c7090952e05..00000000000 --- a/sonar-server/src/main/java/org/sonar/server/reviews/ReviewActionsManager.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2012 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar 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. - * - * Sonar 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 Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.server.reviews; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import org.sonar.api.reviews.ReviewAction; -import org.sonar.api.utils.SonarException; - -import java.util.Collection; -import java.util.Map; - -/** - * @since 3.1 - */ -public class ReviewActionsManager { - - private Map<String, ReviewAction> idToAction = Maps.newHashMap(); - private Map<String, Collection<ReviewAction>> interfaceToAction = Maps.newHashMap(); - - public ReviewActionsManager(ReviewAction[] reviewActions) { - for (ReviewAction reviewAction : reviewActions) { - idToAction.put(reviewAction.getId(), reviewAction); - } - } - - public ReviewActionsManager() { - this(new ReviewAction[0]); - } - - public ReviewAction getAction(String actionId) { - return idToAction.get(actionId); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - public Collection<ReviewAction> getActions(String interfaceName) { - Collection<ReviewAction> result = interfaceToAction.get(interfaceName); - if (result == null) { - result = Lists.newArrayList(); - interfaceToAction.put(interfaceName, result); - try { - Class interfaceClass = Class.forName(interfaceName); - for (ReviewAction reviewAction : idToAction.values()) { - if (interfaceClass.isAssignableFrom(reviewAction.getClass())) { - result.add(reviewAction); - } - } - } catch (ClassNotFoundException e) { - throw new SonarException("The following interface for review actions does not exist: " + interfaceName); - } - - } - return result; - } - -} diff --git a/sonar-server/src/main/java/org/sonar/server/reviews/ReviewManager.java b/sonar-server/src/main/java/org/sonar/server/reviews/ReviewManager.java new file mode 100644 index 00000000000..d6ee862db3e --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/reviews/ReviewManager.java @@ -0,0 +1,97 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.server.reviews; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.reviews.ReviewAction; +import org.sonar.api.reviews.ReviewCommand; +import org.sonar.api.reviews.ReviewContext; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * @since 3.1 + */ +public class ReviewManager { + + private Map<String, ReviewCommand> idToCommand = Maps.newLinkedHashMap(); + + public ReviewManager(ReviewCommand[] reviewCommands) { + for (ReviewCommand reviewCommand : reviewCommands) { + idToCommand.put(reviewCommand.getId(), reviewCommand); + } + } + + public ReviewManager() { + this(new ReviewCommand[0]); + } + + public Collection<ReviewCommand> getAvailableCommandsFor(ReviewContext reviewContext) { + Preconditions.checkNotNull(reviewContext, "The review context must not be NULL when searching for available commands."); + List<ReviewCommand> commands = Lists.newArrayList(); + for (ReviewCommand reviewCommand : idToCommand.values()) { + if (reviewCommand.isAvailableFor(reviewContext)) { + commands.add(reviewCommand); + } + } + return commands; + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + public Collection<ReviewCommand> filterCommands(Collection<ReviewCommand> initialCommands, ReviewContext reviewContext, String interfaceName) { + Preconditions.checkNotNull(initialCommands, "The list of review commands must not be NULL when filtering commands."); + Preconditions.checkState(StringUtils.isNotBlank(interfaceName), "The interface name must not be blank when searching for available commands."); + + Class interfaceClass = null; + try { + interfaceClass = Class.forName(interfaceName); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException("The following interface for review commands does not exist: " + interfaceName); + } + + List<ReviewCommand> commands = Lists.newArrayList(); + for (ReviewCommand reviewCommand : initialCommands) { + if (interfaceClass.isAssignableFrom(reviewCommand.getClass()) && reviewCommand.isAvailableFor(reviewContext)) { + commands.add(reviewCommand); + } + } + return commands; + } + + public void executeCommandActions(String commandId, ReviewContext reviewContext) { + Preconditions.checkNotNull(reviewContext, "The review context must not be NULL when executing the actions of a command."); + ReviewCommand command = getCommand(commandId); + Preconditions.checkState(command != null, "The command with the following ID does not exist: " + commandId); + + for (ReviewAction reviewAction : command.getActions()) { + reviewAction.execute(reviewContext); + } + } + + public ReviewCommand getCommand(String commandId) { + return idToCommand.get(commandId); + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java index 5e726fbc4f3..108bf021e62 100644 --- a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java +++ b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java @@ -33,7 +33,8 @@ import org.sonar.api.profiles.ProfileImporter; import org.sonar.api.resources.Language; import org.sonar.api.resources.ResourceType; import org.sonar.api.resources.ResourceTypes; -import org.sonar.api.reviews.ReviewAction; +import org.sonar.api.reviews.ReviewCommand; +import org.sonar.api.reviews.ReviewContext; import org.sonar.api.rules.RulePriority; import org.sonar.api.rules.RuleRepository; import org.sonar.api.utils.ValidationMessages; @@ -62,7 +63,7 @@ import org.sonar.server.plugins.PluginDeployer; import org.sonar.server.plugins.PluginDownloader; import org.sonar.server.plugins.UpdateCenterMatrix; import org.sonar.server.plugins.UpdateCenterMatrixFactory; -import org.sonar.server.reviews.ReviewActionsManager; +import org.sonar.server.reviews.ReviewManager; import org.sonar.server.rules.ProfilesConsole; import org.sonar.server.rules.RulesConsole; import org.sonar.updatecenter.common.Version; @@ -73,6 +74,7 @@ import java.net.InetAddress; import java.sql.Connection; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Set; public final class JRubyFacade { @@ -478,12 +480,21 @@ public final class JRubyFacade { // REVIEWS ------------------------------------------------------------------ - public Collection<ReviewAction> getReviewActions(String interfaceName) { - return getContainer().getComponentByType(ReviewActionsManager.class).getActions(interfaceName); + public Collection<ReviewCommand> getAvailableCommandsFor(Map<String, Map<String, String>> reviewContextPropertiesMap) { + return getContainer().getComponentByType(ReviewManager.class).getAvailableCommandsFor(ReviewContext.createFromMap(reviewContextPropertiesMap)); } - public ReviewAction getReviewAction(String actionId) { - return getContainer().getComponentByType(ReviewActionsManager.class).getAction(actionId); + public Collection<ReviewCommand> filterCommands(Collection<ReviewCommand> reviewCommands, Map<String, Map<String, String>> reviewContextPropertiesMap, + String interfaceName) { + return getContainer().getComponentByType(ReviewManager.class).filterCommands(reviewCommands, ReviewContext.createFromMap(reviewContextPropertiesMap), interfaceName); + } + + public void executeCommandActions(String commandId, Map<String, Map<String, String>> reviewContextPropertiesMap) { + getContainer().getComponentByType(ReviewManager.class).executeCommandActions(commandId, ReviewContext.createFromMap(reviewContextPropertiesMap)); + } + + public ReviewCommand getCommand(String commandId) { + return getContainer().getComponentByType(ReviewManager.class).getCommand(commandId); } } diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb index 330fbeeeeb8..81f52ab562f 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb @@ -332,6 +332,7 @@ class ResourceController < ApplicationController @global_violations=[] @expandable=(@lines!=nil) @filtered=!@expanded + @review_commands= Review.available_commands_for( Api::ReviewContext.new(:project => @resource.root) ) if params[:rule].blank? metric = Metric.by_id(params[:metric]) diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/reviews_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/reviews_controller.rb index 928c04ae9ec..788ad12341c 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/reviews_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/reviews_controller.rb @@ -138,8 +138,8 @@ class ReviewsController < ApplicationController if !params[:comment_id].blank? && @violation.review @comment = @violation.review.comments.find(params[:comment_id]) end - unless params[:review_action_id].blank? - @review_action = Review.getAction(params[:review_action_id]) + unless params[:review_command_id].blank? + @review_command = Review.get_command(params[:review_command_id]) end render :partial => 'reviews/violation_comment_form' end @@ -160,11 +160,11 @@ class ReviewsController < ApplicationController :user => current_user) end - if !params[:text].blank? || !params[:review_action_id].blank? + if !params[:text].blank? || !params[:review_command_id].blank? if params[:comment_id] violation.review.edit_comment(current_user, params[:comment_id].to_i, params[:text]) else - violation.review.create_comment({:user => current_user, :text => params[:text]}, params[:review_action_id]) + violation.review.create_comment({:user => current_user, :text => params[:text]}, params[:review_command_id]) end end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/api/review_context.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/api/review_context.rb new file mode 100644 index 00000000000..cb46e1df612 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/api/review_context.rb @@ -0,0 +1,50 @@ +# +# Sonar, entreprise quality control tool. +# Copyright (C) 2008-2012 SonarSource +# mailto:contact AT sonarsource DOT com +# +# Sonar 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. +# +# Sonar 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 Sonar; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 +# + +class Api::ReviewContext + def initialize(options={}) + @review = options[:review] + @project = options[:project] + @user = options[:user] + @params = options[:params] + end + + def to_string_map + result = {} + result['review'] = create_string_map_from_attributes @review if @review + result['project'] = create_string_map_from_attributes @project if @project + result['user'] = create_string_map_from_attributes @user if @user + result['params'] = ensure_key_and_values_as_strings @params if @params + result + end + + def create_string_map_from_attributes(object) + ensure_key_and_values_as_strings(object.attributes) + end + + def ensure_key_and_values_as_strings(params) + map = {} + params.each do |key, value| + map[key.to_s] = value.to_s + end + map + end + +end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/review.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/review.rb index 2d2b148e96f..18253223c3e 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/review.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/review.rb @@ -75,14 +75,12 @@ class Review < ActiveRecord::Base # - :user # - :text # - # param review_action_id is optional (=> specifies an action to - # trigger instead of creating a simple comment) - def create_comment(comment_values={}, review_action_id=nil) - if review_action_id - action = Review.getAction(review_action_id) - if action - action.execute({"review.id" => id.to_s, "user.login" => comment_values[:user].login, "comment.text" => comment_values[:text]}) - end + # param review_command_id is optional (=> specifies which command was + # triggered instead of creating a simple comment) + def create_comment(comment_values={}, review_command_id=nil) + if review_command_id + review_context = Api::ReviewContext.new(:review => self, :user => User.new(:login => comment_values[:user].login), :params => {"comment.text" => comment_values[:text]}) + Java::OrgSonarServerUi::JRubyFacade.getInstance().executeCommandActions(review_command_id, review_context.to_string_map) else # simple comment comment = comments.create!(comment_values) @@ -263,18 +261,21 @@ class Review < ActiveRecord::Base action_plans[0] end - def self.available_link_actions(current_review=nil) - - link_actions = Java::OrgSonarServerUi::JRubyFacade.getInstance().getReviewActions("org.sonar.api.reviews.LinkReviewAction") - if current_review && current_review.data - link_actions.reject {|action| current_review.data.include? (action.getId())} - else - link_actions + def self.available_commands_for(review_context) + Java::OrgSonarServerUi::JRubyFacade.getInstance().getAvailableCommandsFor(review_context.to_string_map) + end + + def self.filter_commands(commands, violation, user=nil) + unless commands + commands= Review.available_commands_for( Api::ReviewContext.new(:project => violation.snapshot.root_project) ) end + + review_context = Api::ReviewContext.new(:review => violation.review, :user => user) + actions = Java::OrgSonarServerUi::JRubyFacade.getInstance().filterCommands(commands, review_context.to_string_map, "org.sonar.api.reviews.LinkReviewCommand") end - def self.getAction(actionId) - Java::OrgSonarServerUi::JRubyFacade.getInstance().getReviewAction(actionId) + def self.get_command(command_id) + Java::OrgSonarServerUi::JRubyFacade.getInstance().getCommand(command_id) end # diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_violation.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_violation.html.erb index 0463ec16202..11f12198248 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_violation.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_violation.html.erb @@ -130,8 +130,8 @@ <li><%= link_to_function message('reviews.change_severity'), "sCSF(#{violation.id})", :name => 'bChangeSeverity' -%></li> <li><%= link_to_function message('reviews.link_to_action_plan'), "sAPF(#{violation.id})", :name => 'bLinkActionPlan' -%></li> - <% Review.available_link_actions(violation.review).each do |action| %> - <li><%= link_to_function action.getName(), "sCF(#{violation.id}, '#{action.getId()}')", :name => 'bComment' -%></li> + <% Review.filter_commands(@review_commands, violation, current_user).each do |command| %> + <li><%= link_to_function command.getName(), "sCF(#{violation.id}, '#{command.getId()}')", :name => 'bComment' -%></li> <% end %> <% end %> diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/reviews/_violation_comment_form.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/reviews/_violation_comment_form.html.erb index 8c6c899a03c..fcf463c4d9e 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/reviews/_violation_comment_form.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/reviews/_violation_comment_form.html.erb @@ -1,6 +1,6 @@ <% - if @review_action - button_label = @review_action.getName() + if @review_command + button_label = @review_command.getName() else button_label=(@comment ? message('reviews.update_comment_submit') : message('reviews.comment_submit')) end @@ -11,15 +11,15 @@ <% if @comment %> <input type="hidden" name="comment_id" value="<%= @comment.id -%>"/> <% end %> - <% if @review_action %> - <input type="hidden" name="review_action_id" value="<%= @review_action.getId() -%>"/> + <% if @review_command %> + <input type="hidden" name="review_command_id" value="<%= @review_command.getId() -%>"/> <% end %> <table class="width100"> <tr> <td style="vertical-align:top"> <textarea id="commentText<%= params[:id] -%>" - <% unless @review_action -%> + <% unless @review_command -%> onkeyup="if (this.value=='') $('submit_btn<%= params[:id] -%>').disabled='true'; else $('submit_btn<%= params[:id] -%>').disabled='';" <% end %> rows="4" name="text" style="width: 100%"><%= @comment.text if @comment -%></textarea> @@ -36,7 +36,7 @@ <%= submit_to_remote "submit_btn"+params[:id], button_label, :url => {:action => 'violation_save_comment'}, - :html => {:id => "submit_btn"+params[:id]}.merge(@review_action ? {} : {:disabled => "true"}), + :html => {:id => "submit_btn"+params[:id]}.merge(@review_command ? {} : {:disabled => "true"}), :update => 'vId'+params[:id] -%> <%= link_to_function message('cancel'), "cancelViolationAction(#{params[:id]})" -%> diff --git a/sonar-server/src/main/webapp/javascripts/resource.js b/sonar-server/src/main/webapp/javascripts/resource.js index 7b64d3a74a3..148a9a110a3 100644 --- a/sonar-server/src/main/webapp/javascripts/resource.js +++ b/sonar-server/src/main/webapp/javascripts/resource.js @@ -40,11 +40,11 @@ function hideMoreViolationActions(violation_id) { } // show the form to comment violation -function sCF(violation_id, review_action_id) { +function sCF(violation_id, review_command_id) { hideMoreViolationActions(violation_id); new Ajax.Updater('reviewForm' + violation_id, baseUrl + '/reviews/violation_comment_form/' + violation_id - + (review_action_id==null ? "" : "?review_action_id=" + review_action_id), + + (review_command_id==null ? "" : "?review_command_id=" + review_command_id), { asynchronous:true, evalScripts:true, diff --git a/sonar-server/src/test/java/org/sonar/server/reviews/ReviewActionsManagerTest.java b/sonar-server/src/test/java/org/sonar/server/reviews/ReviewActionsManagerTest.java deleted file mode 100644 index 47148fca9bb..00000000000 --- a/sonar-server/src/test/java/org/sonar/server/reviews/ReviewActionsManagerTest.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2012 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar 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. - * - * Sonar 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 Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.server.reviews; - -import org.junit.Before; -import org.junit.Test; -import org.sonar.api.reviews.LinkReviewAction; -import org.sonar.api.reviews.ReviewAction; - -import java.util.Collection; -import java.util.Map; - -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -public class ReviewActionsManagerTest { - - private ReviewAction fakeLinkReviewAction = new FakeLinkReviewAction(); - private ReviewAction simpleReviewAction = new SimpleReviewAction(); - private ReviewActionsManager manager; - - @Before - public void init() throws Exception { - manager = new ReviewActionsManager(new ReviewAction[] {fakeLinkReviewAction, simpleReviewAction}); - } - - @Test - public void shouldReturnActionsById() throws Exception { - assertThat(manager.getAction("fake-link-review"), is(fakeLinkReviewAction)); - assertThat(manager.getAction("simple-review-action"), is(simpleReviewAction)); - } - - @Test - public void shouldReturnActionsByInterfaceName() throws Exception { - Collection<ReviewAction> reviewActions = manager.getActions("org.sonar.api.reviews.LinkReviewAction"); - assertThat(reviewActions.size(), is(1)); - assertThat(reviewActions, hasItem(fakeLinkReviewAction)); - } - - class FakeLinkReviewAction implements LinkReviewAction { - public String getId() { - return "fake-link-review"; - } - - public String getName() { - return "Fake action"; - } - - public void execute(Map<String, String> reviewContext) { - } - } - class SimpleReviewAction implements ReviewAction { - public String getId() { - return "simple-review-action"; - } - - public String getName() { - return "Simple action"; - } - - public void execute(Map<String, String> reviewContext) { - } - } -} diff --git a/sonar-server/src/test/java/org/sonar/server/reviews/ReviewManagerTest.java b/sonar-server/src/test/java/org/sonar/server/reviews/ReviewManagerTest.java new file mode 100644 index 00000000000..2d6bacfea6d --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/reviews/ReviewManagerTest.java @@ -0,0 +1,175 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.server.reviews; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.reviews.LinkReviewCommand; +import org.sonar.api.reviews.ReviewAction; +import org.sonar.api.reviews.ReviewCommand; +import org.sonar.api.reviews.ReviewContext; +import org.sonar.api.test.ReviewContextTestUtils; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +public class ReviewManagerTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private ReviewManager manager; + private ReviewAction action1; + private ReviewAction action2; + private ReviewAction action3; + private FakeLinkReviewCommand fakeLinkReviewCommand; + private SimpleReviewCommand simpleReviewCommand; + + @Before + public void init() throws Exception { + action1 = mock(ReviewAction.class); + action2 = mock(ReviewAction.class); + action3 = mock(ReviewAction.class); + fakeLinkReviewCommand = new FakeLinkReviewCommand(); + simpleReviewCommand = new SimpleReviewCommand(); + + manager = new ReviewManager(new ReviewCommand[] {fakeLinkReviewCommand, simpleReviewCommand}); + } + + @Test + public void testGetCommandById() throws Exception { + assertThat(manager.getCommand("simple-review-action"), is((ReviewCommand) simpleReviewCommand)); + } + + @Test + public void shouldGetAvailableCommandForReviewContext() throws Exception { + Map<String, String> reviewMap = Maps.newHashMap(); + reviewMap.put("fake", "bar"); + Map<String, Map<String, String>> contextMap = Maps.newHashMap(); + contextMap.put("review", reviewMap); + + ReviewContext context = ReviewContext.createFromMap(contextMap); + Collection<ReviewCommand> availableCommands = manager.getAvailableCommandsFor(context); + assertThat(availableCommands.size(), is(1)); + assertThat(availableCommands, hasItem((ReviewCommand) fakeLinkReviewCommand)); + } + + @Test + public void shouldFilterCommands() throws Exception { + ReviewContext context = ReviewContextTestUtils.createReviewContext("review={fake=bar}"); + Collection<ReviewCommand> filteredCommands = manager.filterCommands(Lists.newArrayList(fakeLinkReviewCommand, simpleReviewCommand), context, + "org.sonar.api.reviews.LinkReviewCommand"); + assertThat(filteredCommands.size(), is(1)); + assertThat(filteredCommands, hasItem((ReviewCommand) fakeLinkReviewCommand)); + } + + @Test + public void shouldFilterCommandsButNoMatch() throws Exception { + ReviewContext context = ReviewContextTestUtils.createReviewContext("review={simple=foo}"); + Collection<ReviewCommand> filteredCommands = manager.filterCommands(Lists.newArrayList(fakeLinkReviewCommand, simpleReviewCommand), context, + "org.sonar.api.reviews.LinkReviewCommand"); + assertThat(filteredCommands.size(), is(0)); + } + + @Test + public void shouldFailFilterCommandsIfUnknownInterface() throws Exception { + ReviewContext context = ReviewContextTestUtils.createReviewContext("review={fake=bar}"); + + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("The following interface for review commands does not exist: org.sonar.api.reviews.UnkonwnReviewCommand"); + + manager.filterCommands(Lists.newArrayList(fakeLinkReviewCommand, simpleReviewCommand), context, "org.sonar.api.reviews.UnkonwnReviewCommand"); + } + + @Test + public void shouldExecuteCommandActions() throws Exception { + ReviewContext reviewContext = ReviewContext.createFromMap(new HashMap<String, Map<String, String>>()); + manager.executeCommandActions("fake-link-review", reviewContext); + verify(action1).execute(reviewContext); + verify(action2).execute(reviewContext); + verify(action3, never()).execute(reviewContext); + } + + @Test + public void shouldFailExecuteCommandActionsIfCommandDoesNotExist() throws Exception { + ReviewContext reviewContext = ReviewContext.createFromMap(new HashMap<String, Map<String, String>>()); + + thrown.expect(IllegalStateException.class); + thrown.expectMessage("The command with the following ID does not exist: unexisting-command"); + + manager.executeCommandActions("unexisting-command", reviewContext); + } + + class FakeLinkReviewCommand extends ReviewCommand implements LinkReviewCommand { + @Override + public String getId() { + return "fake-link-review"; + } + + @Override + public String getName() { + return "Fake action"; + } + + @Override + public boolean isAvailableFor(ReviewContext reviewContext) { + return reviewContext.getReviewProperty("fake") != null; + } + + @Override + public Collection<ReviewAction> getActions() { + return Lists.newArrayList(action1, action2); + } + } + + class SimpleReviewCommand extends ReviewCommand { + @Override + public String getId() { + return "simple-review-action"; + } + + @Override + public String getName() { + return "Simple action"; + } + + @Override + public boolean isAvailableFor(ReviewContext reviewContext) { + return reviewContext.getReviewProperty("simple") != null; + } + + @Override + public Collection<ReviewAction> getActions() { + return Lists.newArrayList(action3); + } + } +} |