if (action == null) {
throw new BadRequestException("The action : '"+ actionName + "' is unknown");
}
- action.verify(issueBulkChangeQuery.properties(actionName), issues, userSession);
- bulkActions.add(action);
+ if (action.verify(issueBulkChangeQuery.properties(actionName), issues, userSession)) {
+ bulkActions.add(action);
+ }
}
IssueChangeContext issueChangeContext = IssueChangeContext.createUser(new Date(), userSession.login());
package org.sonar.server.issue;
+import com.google.common.base.Predicate;
import com.google.common.base.Strings;
+import com.google.common.collect.Iterables;
import org.sonar.api.ServerComponent;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.core.issue.workflow.IssueWorkflow;
+import org.sonar.core.issue.workflow.Transition;
import org.sonar.server.user.UserSession;
import java.util.List;
@Override
public boolean execute(Map<String, Object> properties, Context context) {
- return workflow.doTransition((DefaultIssue) context.issue(), transition(properties), context.issueChangeContext());
+ DefaultIssue issue = (DefaultIssue) context.issue();
+ String transition = transition(properties);
+ if (canExecuteTransition(issue, transition)){
+ return workflow.doTransition((DefaultIssue) context.issue(), transition(properties), context.issueChangeContext());
+ }
+ return false;
+ }
+
+ private boolean canExecuteTransition(Issue issue, final String transition){
+ return Iterables.find(workflow.outTransitions(issue), new Predicate<Transition>() {
+ @Override
+ public boolean apply(Transition input) {
+ return input.key().equals(transition);
+ }
+ }, null) != null;
}
private String transition(Map<String, Object> properties) {
actions.add(action);
when(action.key()).thenReturn("assign");
when(action.supports(any(Issue.class))).thenReturn(true);
+ when(action.verify(anyMap(), anyListOf(Issue.class), any(UserSession.class))).thenReturn(true);
doThrow(new RuntimeException("Error")).when(action).execute(anyMap(), any(IssueBulkChangeService.ActionContext.class));
IssueBulkChangeQuery issueBulkChangeQuery = new IssueBulkChangeQuery(properties);
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.issue.internal.IssueChangeContext;
import org.sonar.core.issue.workflow.IssueWorkflow;
+import org.sonar.core.issue.workflow.Transition;
import org.sonar.server.user.MockUserSession;
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.fest.assertions.Fail.fail;
Action.Context context = mock(Action.Context.class);
when(context.issue()).thenReturn(issue);
+ when(workflow.outTransitions(context.issue())).thenReturn(newArrayList(Transition.create(transition, "REOPEN", "CONFIRMED")));
+
action.execute(properties, context);
verify(workflow).doTransition(eq(issue), eq(transition), any(IssueChangeContext.class));
}
+ @Test
+ public void should_not_execute_if_transition_is_not_available() {
+ String transition = "reopen";
+ Map<String, Object> properties = newHashMap();
+ properties.put("transition", transition);
+ DefaultIssue issue = mock(DefaultIssue.class);
+
+ Action.Context context = mock(Action.Context.class);
+ when(context.issue()).thenReturn(issue);
+
+ // Do not contain reopen, transition is not possible
+ when(workflow.outTransitions(context.issue())).thenReturn(newArrayList(Transition.create("resolve", "OPEN", "RESOLVED")));
+
+ assertThat(action.execute(properties, context)).isFalse();
+ verify(workflow, never()).doTransition(eq(issue), eq(transition), any(IssueChangeContext.class));
+ }
+
@Test
public void should_verify_fail_if_parameter_not_found() {
String transition = "reopen";