Skip to content

Commit

Permalink
SONAR-8899 Replace User by UserDto in Function
Browse files Browse the repository at this point in the history
  • Loading branch information
julienlancelot committed Mar 21, 2017
1 parent 528fd26 commit f766f22
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 114 deletions.
Expand Up @@ -19,62 +19,58 @@
*/ */
package org.sonar.server.issue; package org.sonar.server.issue;


import com.google.common.base.Strings;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import org.sonar.api.issue.condition.IsUnResolved; import org.sonar.api.issue.condition.IsUnResolved;
import org.sonar.api.server.ServerSide; import org.sonar.api.server.ServerSide;
import org.sonar.api.user.User;
import org.sonar.api.user.UserFinder;
import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.DefaultIssue;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.user.UserDto;
import org.sonar.server.user.UserSession; import org.sonar.server.user.UserSession;


import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static org.sonar.server.ws.WsUtils.checkFound;

@ServerSide @ServerSide
public class AssignAction extends Action { public class AssignAction extends Action {


public static final String ASSIGN_KEY = "assign"; public static final String ASSIGN_KEY = "assign";
public static final String ASSIGNEE_PARAMETER = "assignee"; public static final String ASSIGNEE_PARAMETER = "assignee";
public static final String VERIFIED_ASSIGNEE = "verifiedAssignee"; public static final String VERIFIED_ASSIGNEE = "verifiedAssignee";


private final UserFinder userFinder; private final DbClient dbClient;
private final IssueFieldsSetter issueUpdater; private final IssueFieldsSetter issueUpdater;


public AssignAction(UserFinder userFinder, IssueFieldsSetter issueUpdater) { public AssignAction(DbClient dbClient, IssueFieldsSetter issueUpdater) {
super(ASSIGN_KEY); super(ASSIGN_KEY);
this.userFinder = userFinder; this.dbClient = dbClient;
this.issueUpdater = issueUpdater; this.issueUpdater = issueUpdater;
super.setConditions(new IsUnResolved()); super.setConditions(new IsUnResolved());
} }


@Override @Override
public boolean verify(Map<String, Object> properties, Collection<DefaultIssue> issues, UserSession userSession) { public boolean verify(Map<String, Object> properties, Collection<DefaultIssue> issues, UserSession userSession) {
String assignee = assigneeValue(properties); String assignee = getAssigneeValue(properties);
if (!Strings.isNullOrEmpty(assignee)) { properties.put(VERIFIED_ASSIGNEE, isNullOrEmpty(assignee) ? null : getUser(assignee));
User user = selectUser(assignee);
if (user == null) {
throw new IllegalArgumentException("Unknown user: " + assignee);
}
properties.put(VERIFIED_ASSIGNEE, user);
} else {
properties.put(VERIFIED_ASSIGNEE, null);
}
return true; return true;
} }


@Override @Override
public boolean execute(Map<String, Object> properties, Context context) { public boolean execute(Map<String, Object> properties, Context context) {
if (!properties.containsKey(VERIFIED_ASSIGNEE)) { checkArgument(properties.containsKey(VERIFIED_ASSIGNEE), "Assignee is missing from the execution parameters");
throw new IllegalArgumentException("Assignee is missing from the execution parameters"); UserDto assignee = (UserDto) properties.get(VERIFIED_ASSIGNEE);
}
User assignee = (User) properties.get(VERIFIED_ASSIGNEE);
return issueUpdater.assign(context.issue(), assignee, context.issueChangeContext()); return issueUpdater.assign(context.issue(), assignee, context.issueChangeContext());
} }


private String assigneeValue(Map<String, Object> properties) { private static String getAssigneeValue(Map<String, Object> properties) {
return (String) properties.get(ASSIGNEE_PARAMETER); return (String) properties.get(ASSIGNEE_PARAMETER);
} }


private User selectUser(String assigneeKey) { private UserDto getUser(String assigneeKey) {
return userFinder.findByLogin(assigneeKey); try (DbSession dbSession = dbClient.openSession(false)) {
return checkFound(dbClient.userDao().selectByLogin(dbSession, assigneeKey), "Unknown user: %s", assigneeKey);
}
} }
} }
Expand Up @@ -33,12 +33,12 @@
import org.sonar.api.rules.RuleType; import org.sonar.api.rules.RuleType;
import org.sonar.api.server.ServerSide; import org.sonar.api.server.ServerSide;
import org.sonar.api.server.rule.RuleTagFormat; import org.sonar.api.server.rule.RuleTagFormat;
import org.sonar.api.user.User;
import org.sonar.api.utils.Duration; import org.sonar.api.utils.Duration;
import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.DefaultIssueComment; import org.sonar.core.issue.DefaultIssueComment;
import org.sonar.core.issue.IssueChangeContext; import org.sonar.core.issue.IssueChangeContext;
import org.sonar.core.util.stream.Collectors; import org.sonar.core.util.stream.Collectors;
import org.sonar.db.user.UserDto;


import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Strings.isNullOrEmpty; import static com.google.common.base.Strings.isNullOrEmpty;
Expand Down Expand Up @@ -109,13 +109,13 @@ public boolean setManualSeverity(DefaultIssue issue, String severity, IssueChang
return false; return false;
} }


public boolean assign(DefaultIssue issue, @Nullable User user, IssueChangeContext context) { public boolean assign(DefaultIssue issue, @Nullable UserDto user, IssueChangeContext context) {
String sanitizedAssignee = null; String sanitizedAssignee = null;
if (user != null) { if (user != null) {
sanitizedAssignee = StringUtils.defaultIfBlank(user.login(), null); sanitizedAssignee = StringUtils.defaultIfBlank(user.getLogin(), null);
} }
if (!Objects.equals(sanitizedAssignee, issue.assignee())) { if (!Objects.equals(sanitizedAssignee, issue.assignee())) {
String newAssigneeName = user != null ? user.name() : null; String newAssigneeName = user != null ? user.getName() : null;
issue.setFieldChange(context, ASSIGNEE, UNUSED, newAssigneeName); issue.setFieldChange(context, ASSIGNEE, UNUSED, newAssigneeName);
issue.setAssignee(sanitizedAssignee); issue.setAssignee(sanitizedAssignee);
issue.setUpdateDate(context.date()); issue.setUpdateDate(context.date());
Expand Down
Expand Up @@ -27,12 +27,11 @@
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.server.ServerSide; import org.sonar.api.server.ServerSide;
import org.sonar.api.user.User;
import org.sonar.api.user.UserFinder;
import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.IssueChangeContext; import org.sonar.core.issue.IssueChangeContext;
import org.sonar.db.DbClient; import org.sonar.db.DbClient;
import org.sonar.db.DbSession; import org.sonar.db.DbSession;
import org.sonar.db.user.UserDto;
import org.sonar.server.issue.index.IssueIndex; import org.sonar.server.issue.index.IssueIndex;
import org.sonar.server.user.UserSession; import org.sonar.server.user.UserSession;


Expand All @@ -48,17 +47,14 @@ public class IssueService {
private final IssueFinder issueFinder; private final IssueFinder issueFinder;
private final IssueFieldsSetter issueFieldsSetter; private final IssueFieldsSetter issueFieldsSetter;
private final IssueUpdater issueUpdater; private final IssueUpdater issueUpdater;
private final UserFinder userFinder;
private final UserSession userSession; private final UserSession userSession;


public IssueService(DbClient dbClient, IssueIndex issueIndex, IssueFinder issueFinder, IssueFieldsSetter issueFieldsSetter, IssueUpdater issueUpdater, public IssueService(DbClient dbClient, IssueIndex issueIndex, IssueFinder issueFinder, IssueFieldsSetter issueFieldsSetter, IssueUpdater issueUpdater, UserSession userSession) {
UserFinder userFinder, UserSession userSession) {
this.dbClient = dbClient; this.dbClient = dbClient;
this.issueIndex = issueIndex; this.issueIndex = issueIndex;
this.issueFinder = issueFinder; this.issueFinder = issueFinder;
this.issueFieldsSetter = issueFieldsSetter; this.issueFieldsSetter = issueFieldsSetter;
this.issueUpdater = issueUpdater; this.issueUpdater = issueUpdater;
this.userFinder = userFinder;
this.userSession = userSession; this.userSession = userSession;
} }


Expand All @@ -68,10 +64,10 @@ public void assign(String issueKey, @Nullable String assignee) {
DbSession session = dbClient.openSession(false); DbSession session = dbClient.openSession(false);
try { try {
DefaultIssue issue = issueFinder.getByKey(session, issueKey).toDefaultIssue(); DefaultIssue issue = issueFinder.getByKey(session, issueKey).toDefaultIssue();
User user = null; UserDto user = null;
if (!Strings.isNullOrEmpty(assignee)) { if (!Strings.isNullOrEmpty(assignee)) {
user = userFinder.findByLogin(assignee); user = dbClient.userDao().selectByLogin(session, assignee);
checkRequest(user != null, "Unknown user: %s", assignee); checkRequest(user != null && user.isActive(), "Unknown user: %s", assignee);
} }
IssueChangeContext context = IssueChangeContext.createUser(new Date(), userSession.getLogin()); IssueChangeContext context = IssueChangeContext.createUser(new Date(), userSession.getLogin());
if (issueFieldsSetter.assign(issue, user, context)) { if (issueFieldsSetter.assign(issue, user, context)) {
Expand Down
Expand Up @@ -21,13 +21,13 @@


import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.sonar.api.issue.Issue; import org.sonar.api.issue.Issue;
import org.sonar.api.user.User; import org.sonar.db.user.UserDto;


interface Function { interface Function {
interface Context { interface Context {
Issue issue(); Issue issue();


Context setAssignee(@Nullable User user); Context setAssignee(@Nullable UserDto user);


Context setResolution(@Nullable String s); Context setResolution(@Nullable String s);


Expand Down
Expand Up @@ -23,9 +23,9 @@
import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.issue.Issue; import org.sonar.api.issue.Issue;
import org.sonar.api.server.ServerSide; import org.sonar.api.server.ServerSide;
import org.sonar.api.user.User;
import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.IssueChangeContext; import org.sonar.core.issue.IssueChangeContext;
import org.sonar.db.user.UserDto;
import org.sonar.server.issue.IssueFieldsSetter; import org.sonar.server.issue.IssueFieldsSetter;


@ServerSide @ServerSide
Expand Down Expand Up @@ -64,7 +64,7 @@ public Issue issue() {
} }


@Override @Override
public Function.Context setAssignee(@Nullable User user) { public Function.Context setAssignee(@Nullable UserDto user) {
updater.assign(issue, user, changeContext); updater.assign(issue, user, changeContext);
return this; return this;
} }
Expand Down
Expand Up @@ -19,108 +19,92 @@
*/ */
package org.sonar.server.issue; package org.sonar.server.issue;


import java.util.List; import com.google.common.collect.ImmutableMap;
import java.util.Date;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import org.sonar.api.issue.Issue; import org.sonar.api.issue.Issue;
import org.sonar.api.user.User;
import org.sonar.api.user.UserFinder;
import org.sonar.core.issue.DefaultIssue; import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.IssueChangeContext; import org.sonar.core.issue.IssueChangeContext;
import org.sonar.core.user.DefaultUser; import org.sonar.db.DbTester;
import org.sonar.server.user.ThreadLocalUserSession; import org.sonar.db.user.UserDto;

import org.sonar.server.exceptions.NotFoundException;
import static com.google.common.collect.Lists.newArrayList; import org.sonar.server.issue.ws.BulkChangeAction;
import static com.google.common.collect.Maps.newHashMap; import org.sonar.server.tester.UserSessionRule;

import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.any; import static org.sonar.db.user.UserTesting.newUserDto;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;


public class AssignActionTest { public class AssignActionTest {


private AssignAction action; @Rule

public ExpectedException expectedException = ExpectedException.none();
private final UserFinder userFinder = mock(UserFinder.class);
private IssueFieldsSetter issueUpdater = mock(IssueFieldsSetter.class);


@Rule @Rule
public ExpectedException throwable = ExpectedException.none(); public UserSessionRule userSession = UserSessionRule.standalone();


@Before @Rule
public void before() { public DbTester dbTester = DbTester.create();
action = new AssignAction(userFinder, issueUpdater);
}


@Test private IssueFieldsSetter issueUpdater = new IssueFieldsSetter();
public void should_execute() {
User assignee = new DefaultUser();


Map<String, Object> properties = newHashMap(); private IssueChangeContext issueChangeContext = IssueChangeContext.createUser(new Date(), "emmerik");
properties.put(AssignAction.VERIFIED_ASSIGNEE, assignee);
DefaultIssue issue = mock(DefaultIssue.class);


Action.Context context = mock(Action.Context.class); private DefaultIssue issue = new DefaultIssue().setKey("ABC");
when(context.issue()).thenReturn(issue); private Action.Context context = new BulkChangeAction.ActionContext(issue, issueChangeContext);


action.execute(properties, context); private AssignAction action = new AssignAction(dbTester.getDbClient(), issueUpdater);
verify(issueUpdater).assign(eq(issue), eq(assignee), any(IssueChangeContext.class));
}


@Test @Test
public void should_fail_if_assignee_is_not_verified() { public void assign_issue() {
throwable.expect(IllegalArgumentException.class); UserDto assignee = newUserDto();
throwable.expectMessage("Assignee is missing from the execution parameters");


Map<String, Object> properties = newHashMap(); action.execute(ImmutableMap.of("verifiedAssignee", assignee), context);


Action.Context context = mock(Action.Context.class); assertThat(issue.assignee()).isEqualTo(assignee.getLogin());
}

@Test
public void fail_if_assignee_is_not_verified() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Assignee is missing from the execution parameters");


action.execute(properties, context); action.execute(emptyMap(), context);
} }


@Test @Test
public void should_verify_assignee_exists() { public void verify_that_assignee_exists() {
String assignee = "arthur"; String assignee = "arthur";
Map<String, Object> properties = newHashMap(); Map<String, Object> properties = new HashMap<>(ImmutableMap.of("assignee", assignee));
properties.put("assignee", assignee); UserDto user = dbTester.users().insertUser(assignee);


User user = new DefaultUser().setLogin(assignee); boolean verify = action.verify(properties, singletonList(issue), userSession);


List<DefaultIssue> issues = newArrayList(new DefaultIssue().setKey("ABC")); assertThat(verify).isTrue();
when(userFinder.findByLogin(assignee)).thenReturn(user); UserDto verifiedUser = (UserDto) properties.get(AssignAction.VERIFIED_ASSIGNEE);
assertThat(action.verify(properties, issues, mock(ThreadLocalUserSession.class))).isTrue(); assertThat(verifiedUser.getLogin()).isEqualTo(user.getLogin());
assertThat(properties.get(AssignAction.VERIFIED_ASSIGNEE)).isEqualTo(user);
} }


@Test @Test
public void should_fail_if_assignee_does_not_exists() { public void fail_if_assignee_does_not_exists() {
throwable.expect(IllegalArgumentException.class); expectedException.expect(NotFoundException.class);
throwable.expectMessage("Unknown user: arthur"); expectedException.expectMessage("Unknown user: arthur");


String assignee = "arthur"; action.verify(ImmutableMap.of("assignee", "arthur"), singletonList(issue), userSession);
Map<String, Object> properties = newHashMap();
properties.put("assignee", assignee);

List<DefaultIssue> issues = newArrayList(new DefaultIssue().setKey("ABC"));
when(userFinder.findByLogin(assignee)).thenReturn(null);
action.verify(properties, issues, mock(ThreadLocalUserSession.class));
} }


@Test @Test
public void should_unassign_if_assignee_is_empty() { public void unassign_issue_if_assignee_is_empty() {
String assignee = ""; Map<String, Object> properties = new HashMap<>(ImmutableMap.of("assignee", ""));
Map<String, Object> properties = newHashMap();
properties.put("assignee", assignee); boolean verify = action.verify(properties, singletonList(issue), userSession);


List<DefaultIssue> issues = newArrayList(new DefaultIssue().setKey("ABC")); assertThat(verify).isTrue();
action.verify(properties, issues, mock(ThreadLocalUserSession.class));
assertThat(action.verify(properties, issues, mock(ThreadLocalUserSession.class))).isTrue();
assertThat(properties.containsKey(AssignAction.VERIFIED_ASSIGNEE)).isTrue(); assertThat(properties.containsKey(AssignAction.VERIFIED_ASSIGNEE)).isTrue();
assertThat(properties.get(AssignAction.VERIFIED_ASSIGNEE)).isNull(); assertThat(properties.get(AssignAction.VERIFIED_ASSIGNEE)).isNull();
} }
Expand Down

0 comments on commit f766f22

Please sign in to comment.