interface Function {
interface Context {
Issue issue();
+ Context setAssignee(@Nullable String s);
Context setResolution(@Nullable String s);
Context setCloseDate(boolean b);
}
import org.sonar.core.issue.IssueChangeContext;
import org.sonar.core.issue.IssueUpdater;
+import javax.annotation.Nullable;
+
public class FunctionExecutor implements BatchComponent, ServerComponent {
private final IssueUpdater updater;
}
@Override
- public Function.Context setResolution(String s) {
+ public Function.Context setAssignee(@Nullable String s) {
+ updater.assign(issue, s, changeContext);
+ return this;
+ }
+
+ @Override
+ public Function.Context setResolution(@Nullable String s) {
updater.setResolution(issue, s, changeContext);
return this;
}
.from(Issue.STATUS_CLOSED).to(Issue.STATUS_REOPENED)
.functions(new SetResolution(null), new SetCloseDate(false))
.build())
+
+ // resolve as false-positive
.transition(Transition.builder(DefaultTransitions.FALSE_POSITIVE)
.from(Issue.STATUS_OPEN).to(Issue.STATUS_RESOLVED)
.conditions(new IsManual(false))
- .functions(new SetResolution(Issue.RESOLUTION_FALSE_POSITIVE))
+ .functions(new SetResolution(Issue.RESOLUTION_FALSE_POSITIVE), SetAssignee.UNASSIGN)
.build())
.transition(Transition.builder(DefaultTransitions.FALSE_POSITIVE)
.from(Issue.STATUS_REOPENED).to(Issue.STATUS_RESOLVED)
.conditions(new IsManual(false))
- .functions(new SetResolution(Issue.RESOLUTION_FALSE_POSITIVE))
+ .functions(new SetResolution(Issue.RESOLUTION_FALSE_POSITIVE), SetAssignee.UNASSIGN)
.build())
.transition(Transition.builder(DefaultTransitions.FALSE_POSITIVE)
.from(Issue.STATUS_CONFIRMED).to(Issue.STATUS_RESOLVED)
.conditions(new IsManual(false))
- .functions(new SetResolution(Issue.RESOLUTION_FALSE_POSITIVE))
+ .functions(new SetResolution(Issue.RESOLUTION_FALSE_POSITIVE), SetAssignee.UNASSIGN)
.build())
// automatic transitions
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.core.issue.workflow;
+
+import javax.annotation.Nullable;
+
+public class SetAssignee implements Function {
+ public static final SetAssignee UNASSIGN = new SetAssignee(null);
+
+ private final String assignee;
+
+ public SetAssignee(@Nullable String assignee) {
+ this.assignee = assignee;
+ }
+
+ @Override
+ public void execute(Context context) {
+ context.setAssignee(assignee);
+ }
+}
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import org.junit.Test;
+import org.sonar.api.issue.DefaultTransitions;
import org.sonar.api.issue.Issue;
+import org.sonar.api.rule.RuleKey;
import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.DefaultIssueBuilder;
import org.sonar.core.issue.IssueChangeContext;
import org.sonar.core.issue.IssueUpdater;
} catch (IllegalStateException e) {
assertThat(e).hasMessage("Unknown status: xxx [issue=ABCDE]");
}
+ }
+
+ @Test
+ public void should_flag_as_false_positive() throws Exception {
+ DefaultIssue issue = new DefaultIssue()
+ .setKey("ABCDE")
+ .setStatus(Issue.STATUS_OPEN)
+ .setRuleKey(RuleKey.of("squid", "AvoidCycle"))
+ .setAssignee("morgan")
+ .setReporter("simon");
+
+ workflow.start();
+ workflow.doTransition(issue, DefaultTransitions.FALSE_POSITIVE, IssueChangeContext.createScan(new Date()));
+
+ assertThat(issue.resolution()).isEqualTo(Issue.RESOLUTION_FALSE_POSITIVE);
+ assertThat(issue.status()).isEqualTo(Issue.STATUS_RESOLVED);
+ // should remove assignee
+ assertThat(issue.assignee()).isNull();
}
private Collection<String> keys(List<Transition> transitions) {
--- /dev/null
+package org.sonar.core.issue.workflow;
+
+import org.junit.Test;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+public class SetAssigneeTest {
+ @Test
+ public void assign() throws Exception {
+ SetAssignee function = new SetAssignee("eric");
+ Function.Context context = mock(Function.Context.class);
+ function.execute(context);
+ verify(context, times(1)).setAssignee("eric");
+ }
+
+ @Test
+ public void unassign() throws Exception {
+ Function.Context context = mock(Function.Context.class);
+ SetAssignee.UNASSIGN.execute(context);
+ verify(context, times(1)).setAssignee(null);
+ }
+}