import org.sonar.api.issue.Issue;
import org.sonar.api.issue.condition.Condition;
import org.sonar.api.issue.internal.IssueChangeContext;
-import org.sonar.core.issue.IssueUpdater;
import org.sonar.server.user.UserSession;
import java.util.List;
interface Context {
Issue issue();
- IssueUpdater issueUpdater();
-
IssueChangeContext issueChangeContext();
}
package org.sonar.server.issue;
+import com.google.common.base.Strings;
import org.sonar.api.ServerComponent;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.condition.IsUnResolved;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.user.UserFinder;
+import org.sonar.core.issue.IssueUpdater;
import org.sonar.server.user.UserSession;
import java.util.List;
public static final String ASSIGN_ACTION_KEY = "assign";
private final UserFinder userFinder;
+ private final IssueUpdater issueUpdater;
- public AssignAction(UserFinder userFinder) {
+ public AssignAction(UserFinder userFinder, IssueUpdater issueUpdater) {
super(ASSIGN_ACTION_KEY);
this.userFinder = userFinder;
+ this.issueUpdater = issueUpdater;
super.setConditions(new IsUnResolved());
}
@Override
public boolean verify(Map<String, Object> properties, List<Issue> issues, UserSession userSession){
String assignee = assignee(properties);
- if (assignee != null && userFinder.findByLogin(assignee) == null) {
+ if (!Strings.isNullOrEmpty(assignee) && userFinder.findByLogin(assignee) == null) {
throw new IllegalArgumentException("Unknown user: " + assignee);
}
return true;
@Override
public boolean execute(Map<String, Object> properties, Context context) {
- return context.issueUpdater().assign((DefaultIssue) context.issue(), assignee(properties), context.issueChangeContext());
+ return issueUpdater.assign((DefaultIssue) context.issue(), assignee(properties), context.issueChangeContext());
}
private String assignee(Map<String, Object> properties){
import org.sonar.api.ServerComponent;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.IssueUpdater;
import org.sonar.server.user.UserSession;
import java.util.List;
public static final String COMMENT_ACTION_KEY = "comment";
public static final String COMMENT_PROPERTY = "comment";
- public CommentAction() {
+ private final IssueUpdater issueUpdater;
+
+ public CommentAction(IssueUpdater issueUpdater) {
super(COMMENT_ACTION_KEY);
+ this.issueUpdater = issueUpdater;
}
@Override
@Override
public boolean execute(Map<String, Object> properties, Context context) {
- context.issueUpdater().addComment((DefaultIssue) context.issue(), comment(properties), context.issueChangeContext());
+ issueUpdater.addComment((DefaultIssue) context.issue(), comment(properties), context.issueChangeContext());
return true;
}
import org.sonar.server.user.UserSession;
import javax.annotation.CheckForNull;
-
import java.util.Date;
import java.util.List;
for (String actionName : issueBulkChangeQuery.actions()) {
try {
Action action = getAction(actionName);
- ActionContext actionContext = new ActionContext(issue, issueUpdater, issueChangeContext);
+ ActionContext actionContext = new ActionContext(issue, issueChangeContext);
if (action.supports(issue) && action.execute(issueBulkChangeQuery.properties(actionName), actionContext)) {
issueStorage.save((DefaultIssue) issue);
issueNotifications.sendChanges((DefaultIssue) issue, issueChangeContext, issueQueryResult);
static class ActionContext implements Action.Context {
private final Issue issue;
- private final IssueUpdater updater;
private final IssueChangeContext changeContext;
- ActionContext(Issue issue, IssueUpdater updater, IssueChangeContext changeContext) {
- this.updater = updater;
+ ActionContext(Issue issue, IssueChangeContext changeContext) {
this.issue = issue;
this.changeContext = changeContext;
}
return issue;
}
- @Override
- public IssueUpdater issueUpdater() {
- return updater;
- }
-
@Override
public IssueChangeContext issueChangeContext() {
return changeContext;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.condition.IsUnResolved;
import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.IssueUpdater;
import org.sonar.server.user.UserSession;
import java.util.List;
public static final String PLAN_ACTION_KEY = "plan";
private final ActionPlanService actionPlanService;
+ private final IssueUpdater issueUpdater;
- public PlanAction(ActionPlanService actionPlanService) {
+ public PlanAction(ActionPlanService actionPlanService, IssueUpdater issueUpdater) {
super(PLAN_ACTION_KEY);
this.actionPlanService = actionPlanService;
+ this.issueUpdater = issueUpdater;
super.setConditions(new IsUnResolved());
}
@Override
public boolean execute(Map<String, Object> properties, Context context) {
- return context.issueUpdater().plan((DefaultIssue) context.issue(), planKey(properties), context.issueChangeContext());
+ return issueUpdater.plan((DefaultIssue) context.issue(), planKey(properties), context.issueChangeContext());
}
private String planKey(Map<String, Object> properties) {
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.condition.IsUnResolved;
import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.IssueUpdater;
import org.sonar.server.user.UserSession;
import java.util.List;
public static final String SET_SEVERITY_ACTION_KEY = "set_severity";
- public SetSeverityAction() {
+ private final IssueUpdater issueUpdater;
+
+ public SetSeverityAction(IssueUpdater issueUpdater) {
super(SET_SEVERITY_ACTION_KEY);
+ this.issueUpdater = issueUpdater;
super.setConditions(new IsUnResolved());
}
@Override
public boolean execute(Map<String, Object> properties, Context context) {
- return context.issueUpdater().setSeverity((DefaultIssue) context.issue(), severity(properties), context.issueChangeContext());
+ return issueUpdater.setSeverity((DefaultIssue) context.issue(), severity(properties), context.issueChangeContext());
}
private String severity(Map<String, Object> properties) {
@criteria_params = criteria_params_to_save
@criteria_params['pageSize'] = -1
issue_filter_result = Internal.issues.execute(@criteria_params)
- @issue_query = issue_filter_result.query
- @issues_result = issue_filter_result.result
+ issue_query = issue_filter_result.query
+ issues_result = issue_filter_result.result
+
+ @issues = issues_result.issues.map {|issue| issue.key()}
+ @project = issue_query.componentRoots.to_a.first if issue_query.componentRoots and issue_query.componentRoots.size == 1
- @issue_keys = @issues_result.issues.map {|issue| issue.key()}.join(',') unless @issues_result.issues.empty?
render :partial => 'issues/bulk_change_form'
end
+<%
+ project = params[:project] || @project
+ issues = params[:issues].split(',') if params[:issues]
+ issues = @issues unless issues
+%>
<form id="bulk-change-form" method="post" action="<%= ApplicationController.root_context -%>/issues/bulk_change">
- <input type="hidden" name="issues" value="<%= @issue_keys -%>">
- <input type="hidden" name="criteria_params" value="<%= @criteria_params.to_query -%>">
+ <input type="hidden" name="issues" value="<%= params[:issues] || @issues.join(',') -%>">
+ <input type="hidden" name="criteria_params" value="<%= params[:criteria_params] || @criteria_params.to_query -%>">
+ <input type="hidden" name="project" value="<%= project -%>">
<fieldset>
<div class="modal-head">
- <h2><%= message('issue_filter.bulk_change.form.title', {:params => @issues_result.issues.size.to_s}) -%></h2>
+ <h2><%= message('issue_filter.bulk_change.form.title', {:params => issues.size.to_s}) -%></h2>
</div>
<div class="modal-body">
<%= render :partial => 'display_errors' %>
</label>
<%= user_select_tag('assign.assignee', :html_id => 'assignee', :open => false) -%>
</div>
- <% if @issue_query.componentRoots and @issue_query.componentRoots.size == 1 %>
- <%
- componentRoot = @issue_query.componentRoots.to_a.first
- plans = Internal.issues.findOpenActionPlans(componentRoot)
+ <%
+ if project && !project.blank?
+ plans = Internal.issues.findOpenActionPlans(project)
first_plan = plans[0]
plan_options = ""
unless plans.empty?
private AssignAction action;
private final UserFinder userFinder = mock(UserFinder.class);
+ private IssueUpdater issueUpdater = mock(IssueUpdater.class);
@Before
public void before(){
- action = new AssignAction(userFinder);
+ action = new AssignAction(userFinder, issueUpdater);
}
@Test
Map<String, Object> properties = newHashMap();
properties.put("assignee", assignee);
DefaultIssue issue = mock(DefaultIssue.class);
- IssueUpdater issueUpdater = mock(IssueUpdater.class);
Action.Context context = mock(Action.Context.class);
- when(context.issueUpdater()).thenReturn(issueUpdater);
when(context.issue()).thenReturn(issue);
action.execute(properties, context);
}
}
+ @Test
+ public void should_fail_if_assignee_is_empty(){
+ String assignee = "";
+ Map<String, Object> properties = newHashMap();
+ properties.put("assignee", assignee);
+
+ List<Issue> issues = newArrayList((Issue) new DefaultIssue().setKey("ABC"));
+ when(userFinder.findByLogin(assignee)).thenReturn(null);
+ try {
+ action.verify(properties, issues, mock(UserSession.class));
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Unknown user: ");
+ }
+ }
+
@Test
public void should_support_only_unresolved_issues(){
assertThat(action.supports(new DefaultIssue().setResolution(null))).isTrue();
private CommentAction action;
+ private IssueUpdater issueUpdater = mock(IssueUpdater.class);
+
@Before
public void before(){
- action = new CommentAction();
+ action = new CommentAction(issueUpdater);
}
@Test
Map<String, Object> properties = newHashMap();
properties.put("comment", comment);
DefaultIssue issue = mock(DefaultIssue.class);
- IssueUpdater issueUpdater = mock(IssueUpdater.class);
Action.Context context = mock(Action.Context.class);
- when(context.issueUpdater()).thenReturn(issueUpdater);
when(context.issue()).thenReturn(issue);
action.execute(properties, context);
private PlanAction action;
private ActionPlanService actionPlanService = mock(ActionPlanService.class);
+ private IssueUpdater issueUpdater = mock(IssueUpdater.class);
@Before
public void before(){
- action = new PlanAction(actionPlanService);
+ action = new PlanAction(actionPlanService, issueUpdater);
}
@Test
Map<String, Object> properties = newHashMap();
properties.put("plan", planKey);
DefaultIssue issue = mock(DefaultIssue.class);
- IssueUpdater issueUpdater = mock(IssueUpdater.class);
Action.Context context = mock(Action.Context.class);
- when(context.issueUpdater()).thenReturn(issueUpdater);
when(context.issue()).thenReturn(issue);
action.execute(properties, context);
}
}
+ @Test
+ public void should_fail_if_action_plan_is_empty(){
+ String planKey = "";
+ Map<String, Object> properties = newHashMap();
+ properties.put("plan", planKey);
+
+ List<Issue> issues = newArrayList((Issue) new DefaultIssue().setKey("ABC").setProjectKey("struts"));
+ when(actionPlanService.findByKey(eq(planKey), any(UserSession.class))).thenReturn(null);
+ try {
+ action.verify(properties, issues, mock(UserSession.class));
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Unknown action plan: ");
+ }
+ }
+
@Test
public void should_verify_issues_are_on_the_same_project(){
String planKey = "ABCD";
private SetSeverityAction action;
+ private IssueUpdater issueUpdater = mock(IssueUpdater.class);
+
@Before
public void before(){
- action = new SetSeverityAction();
+ action = new SetSeverityAction(issueUpdater);
}
@Test
Map<String, Object> properties = newHashMap();
properties.put("severity", severity);
DefaultIssue issue = mock(DefaultIssue.class);
- IssueUpdater issueUpdater = mock(IssueUpdater.class);
Action.Context context = mock(Action.Context.class);
- when(context.issueUpdater()).thenReturn(issueUpdater);
when(context.issue()).thenReturn(issue);
action.execute(properties, context);