*/
package org.sonar.server.issue;
+import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.collect.HashMultiset;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Multiset;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.issue.ActionPlan;
import org.sonar.core.issue.IssueNotifications;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.core.issue.db.IssueDao;
+import org.sonar.core.issue.db.IssueDto;
import org.sonar.core.issue.db.IssueStorage;
import org.sonar.core.issue.workflow.IssueWorkflow;
import org.sonar.core.issue.workflow.Transition;
import java.util.Date;
import java.util.List;
+import static com.google.common.collect.Lists.newArrayList;
+
public class DefaultIssueService implements IssueService {
private final DbClient dbClient;
public DefaultIssue getIssueByKey(DbSession session, String key) {
// Load from index to check permission
- indexClient.get(IssueIndex.class).getByKey(key);
- return dbClient.issueDao().getByKey(session, key).toDefaultIssue();
+ Issue authorizedIssueIndex = indexClient.get(IssueIndex.class).getByKey(key);
+ return dbClient.issueDao().getByKey(session, authorizedIssueIndex.key()).toDefaultIssue();
}
public DefaultIssue getIssueByKey(String key) {
}
public org.sonar.server.search.Result<Issue> search(IssueQuery query, QueryContext options) {
- IssueIndex issueIndex = indexClient.get(IssueIndex.class);
- return issueIndex.search(query, options);
+ return indexClient.get(IssueIndex.class).search(query, options);
+ }
+
+ /**
+ * Used by the bulk change
+ * TODO move it to the IssueBulkChangeService when OldIssueService will be removed
+ */
+ @Override
+ public List<Issue> search(List<String> issueKeys) {
+ // Load from index to check permission
+ List<Issue> authorizedIndexIssues = search(IssueQuery.builder().issueKeys(issueKeys).build(), new QueryContext().setMaxLimit()).getHits();
+ // return ;
+ List<String> authorizedIssueKeys = newArrayList(Iterables.transform(authorizedIndexIssues, new Function<Issue, String>() {
+ @Override
+ public String apply(@Nullable Issue input) {
+ return input != null ? input.key() : null;
+ }
+ }));
+
+ DbSession session = dbClient.openSession(false);
+ try {
+ List<IssueDto> issueDtos = dbClient.issueDao().getByKeys(session, authorizedIssueKeys);
+ return newArrayList(Iterables.transform(issueDtos, new Function<IssueDto, Issue>() {
+ @Override
+ public Issue apply(@Nullable IssueDto input) {
+ return input != null ? input.toDefaultIssue() : null;
+ }
+ }));
+ } finally {
+ session.close();
+ }
}
private void verifyLoggedIn() {
package org.sonar.server.issue;
-import org.sonar.core.preview.PreviewCache;
-
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.IssueQuery;
-import org.sonar.api.issue.IssueQueryResult;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.issue.internal.IssueChangeContext;
-import org.sonar.api.web.UserRole;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rules.Rule;
+import org.sonar.core.component.ComponentDto;
import org.sonar.core.issue.IssueNotifications;
import org.sonar.core.issue.db.IssueStorage;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.preview.PreviewCache;
+import org.sonar.server.db.DbClient;
import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.rule.DefaultRuleFinder;
import org.sonar.server.user.UserSession;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import javax.annotation.CheckForNull;
+
+import java.util.*;
import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Maps.newHashMap;
+import static com.google.common.collect.Sets.newHashSet;
public class IssueBulkChangeService {
private static final Logger LOG = LoggerFactory.getLogger(IssueBulkChangeService.class);
- private final DefaultIssueFinder issueFinder;
+ private final DbClient dbClient;
+ private final IssueService issueService;
private final IssueStorage issueStorage;
+ private final DefaultRuleFinder ruleFinder;
private final IssueNotifications issueNotifications;
private final PreviewCache dryRunCache;
private final List<Action> actions;
- public IssueBulkChangeService(DefaultIssueFinder issueFinder, IssueStorage issueStorage, IssueNotifications issueNotifications, List<Action> actions, PreviewCache dryRunCache) {
- this.issueFinder = issueFinder;
+ public IssueBulkChangeService(DbClient dbClient, IssueService issueService, IssueStorage issueStorage, DefaultRuleFinder ruleFinder,
+ IssueNotifications issueNotifications, List<Action> actions, PreviewCache dryRunCache) {
+ this.dbClient = dbClient;
+ this.issueService = issueService;
this.issueStorage = issueStorage;
+ this.ruleFinder = ruleFinder;
this.issueNotifications = issueNotifications;
this.actions = actions;
this.dryRunCache = dryRunCache;
userSession.checkLoggedIn();
IssueBulkChangeResult result = new IssueBulkChangeResult();
- IssueQueryResult issueQueryResult = issueFinder.find(IssueQuery.builder().issueKeys(issueBulkChangeQuery.issues()).pageSize(-1).requiredRole(UserRole.USER).build());
- List<Issue> issues = issueQueryResult.issues();
- List<Action> bulkActions = getActionsToApply(issueBulkChangeQuery, issues, userSession);
+ List<Issue> issues = issueService.search(issueBulkChangeQuery.issues());
+ Referentials referentials = new Referentials(issues);
+
+ List<Action> bulkActions = getActionsToApply(issueBulkChangeQuery, issues, userSession);
IssueChangeContext issueChangeContext = IssueChangeContext.createUser(new Date(), userSession.login());
Set<String> concernedProjects = new HashSet<String>();
for (Issue issue : issues) {
}
issueStorage.save((DefaultIssue) issue);
if (issueBulkChangeQuery.sendNotifications()) {
- issueNotifications.sendChanges((DefaultIssue) issue, issueChangeContext, issueQueryResult);
+ String projectKey = issue.projectKey();
+ if (projectKey != null) {
+ issueNotifications.sendChanges((DefaultIssue) issue, issueChangeContext,
+ referentials.rule(issue.ruleKey()),
+ referentials.project(projectKey),
+ referentials.component(issue.componentKey()));
+ }
}
- concernedProjects.add(((DefaultIssue) issue).projectKey());
+ concernedProjects.add(issue.projectKey());
}
}
// Purge dryRun cache
return changeContext;
}
}
+
+ private class Referentials {
+
+ private final Map<RuleKey, Rule> rules = newHashMap();
+ private final Map<String, ComponentDto> components = newHashMap();
+ private final Map<String, ComponentDto> projects = newHashMap();
+
+ public Referentials(List<Issue> issues) {
+ Set<RuleKey> ruleKeys = newHashSet();
+ Set<String> componentKeys = newHashSet();
+ Set<String> projectKeys = newHashSet();
+
+ for (Issue issue : issues) {
+ ruleKeys.add(issue.ruleKey());
+ componentKeys.add(issue.componentKey());
+ String projectKey = issue.projectKey();
+ if (projectKey != null) {
+ projectKeys.add(projectKey);
+ }
+ }
+
+ DbSession session = dbClient.openSession(false);
+ try {
+ for (Rule rule : ruleFinder.findByKeys(ruleKeys)) {
+ rules.put(rule.ruleKey(), rule);
+ }
+
+ for (ComponentDto file : dbClient.componentDao().getByKeys(session, componentKeys)) {
+ components.put(file.getKey(), file);
+ }
+
+ for (ComponentDto project : dbClient.componentDao().getByKeys(session, projectKeys)) {
+ projects.put(project.getKey(), project);
+ }
+ } finally {
+ session.close();
+ }
+ }
+
+ public Rule rule(RuleKey ruleKey) {
+ return rules.get(ruleKey);
+ }
+
+ @CheckForNull
+ public ComponentDto component(String key) {
+ return components.get(key);
+ }
+
+ public ComponentDto project(String key) {
+ return projects.get(key);
+ }
+ }
}
DefaultIssue getIssueByKey(String key);
+ List<Issue> search(List<String> issues);
+
}
public DefaultIssue getIssueByKey(String key) {
return (DefaultIssue) loadIssue(key).first();
}
+
+ @Override
+ public List<Issue> search(List<String> issues) {
+ return finder.find(IssueQuery.builder().issueKeys(issues).pageSize(-1).requiredRole(UserRole.USER).build()).issues();
+ }
}
}
public Result<Issue> search(IssueQuery query, QueryContext options) {
-
SearchRequestBuilder esSearch = getClient()
.prepareSearch(this.getIndexName())
.setTypes(this.getIndexType())
.setIndices(this.getIndexName());
+ // Integrate Pagination
+ esSearch.setFrom(options.getOffset());
+ esSearch.setSize(options.getLimit());
+
if (options.isScroll()) {
esSearch.setSearchType(SearchType.SCAN);
esSearch.setScroll(TimeValue.timeValueMinutes(3));
return rules;
}
+ @CheckForNull
+ public Collection<org.sonar.api.rules.Rule> findByKeys(Collection<RuleKey> ruleKeys) {
+ List<org.sonar.api.rules.Rule> rules = newArrayList();
+ if (ruleKeys.isEmpty()) {
+ return rules;
+ }
+ for (Rule rule : index.getByKeys(ruleKeys)) {
+ rules.add(toRule(rule));
+ }
+ return rules;
+ }
+
@CheckForNull
public org.sonar.api.rules.Rule findByKey(RuleKey key) {
Rule rule = index.getNullableByKey(key);
import java.util.List;
import java.util.UUID;
+import static com.google.common.collect.Lists.newArrayList;
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;
assertThat(result.count("UNKNOWN")).isEqualTo(0);
}
+ @Test
+ public void search_issues() {
+ IssueDto issue = newIssue();
+ tester.get(IssueDao.class).insert(session, issue);
+ session.commit();
+
+ List<Issue> result = service.search(newArrayList(issue.getKey()));
+ assertThat(result).hasSize(1);
+ }
+
private IssueDto newIssue() {
return new IssueDto()
.setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.server.issue;
+
+import com.google.common.base.Joiner;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.issue.DefaultTransitions;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Scopes;
+import org.sonar.api.security.DefaultGroups;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.issue.db.IssueDto;
+import org.sonar.core.permission.PermissionFacade;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.rule.RuleDto;
+import org.sonar.core.user.UserDto;
+import org.sonar.server.component.SnapshotTesting;
+import org.sonar.server.component.db.ComponentDao;
+import org.sonar.server.component.db.SnapshotDao;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.issue.db.IssueDao;
+import org.sonar.server.rule.RuleTesting;
+import org.sonar.server.rule.db.RuleDao;
+import org.sonar.server.search.IndexClient;
+import org.sonar.server.tester.ServerTester;
+import org.sonar.server.user.MockUserSession;
+import org.sonar.server.user.UserSession;
+
+import java.util.Date;
+import java.util.List;
+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;
+
+public class IssueBulkChangeServiceMediumTest {
+
+ @ClassRule
+ public static ServerTester tester = new ServerTester()
+ .setProperty("sonar.issues.use_es_backend", "true");
+
+ DbClient db;
+ IndexClient indexClient;
+ DbSession session;
+ IssueBulkChangeService service;
+
+ RuleDto rule;
+ ComponentDto project;
+ ComponentDto file;
+
+ UserSession userSession;
+
+ @Before
+ public void setUp() throws Exception {
+ tester.clearDbAndIndexes();
+ db = tester.get(DbClient.class);
+ indexClient = tester.get(IndexClient.class);
+ session = db.openSession(false);
+ service = tester.get(IssueBulkChangeService.class);
+
+ rule = RuleTesting.newXooX1();
+ tester.get(RuleDao.class).insert(session, rule);
+
+ project = new ComponentDto()
+ .setKey("MyProject")
+ .setLongName("My Project")
+ .setQualifier(Qualifiers.PROJECT)
+ .setScope(Scopes.PROJECT);
+ tester.get(ComponentDao.class).insert(session, project);
+ tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(project));
+
+ file = new ComponentDto()
+ .setProjectId(project.getId())
+ .setSubProjectId(project.getId())
+ .setKey("MyComponent")
+ .setLongName("My Component");
+ tester.get(ComponentDao.class).insert(session, file);
+ tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(file));
+
+ // project can be seen by anyone
+ tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), DefaultGroups.ANYONE, UserRole.USER, session);
+ db.issueAuthorizationDao().synchronizeAfter(session, new Date(0));
+
+ userSession = MockUserSession.set()
+ .setLogin("john")
+ .addProjectPermissions(UserRole.USER, project.key());
+
+ session.commit();
+ }
+
+ @After
+ public void after() {
+ session.close();
+ }
+
+ @Test
+ public void bulk_change() throws Exception {
+ UserDto user = new UserDto().setLogin("fred").setName("Fred");
+ db.userDao().insert(session, user);
+
+ IssueDto issue1 = IssueTesting.newDto(rule, file, project).setAssignee("fabrice");
+ IssueDto issue2 = IssueTesting.newDto(rule, file, project).setAssignee("simon");
+ tester.get(IssueDao.class).insert(session, issue1, issue2);
+ session.commit();
+
+ Map<String, Object> properties = newHashMap();
+ properties.put("issues", issue1.getKey() + "," + issue2.getKey());
+ properties.put("actions", "assign");
+ properties.put("assign.assignee", user.getLogin());
+
+ IssueBulkChangeQuery issueBulkChangeQuery = new IssueBulkChangeQuery(properties, true);
+ IssueBulkChangeResult result = service.execute(issueBulkChangeQuery, userSession);
+ assertThat(result.issuesChanged()).hasSize(2);
+ assertThat(result.issuesNotChanged()).isEmpty();
+ }
+
+ @Test
+ public void bulk_change_on_500_issues() throws Exception {
+ List<String> issueKeys = newArrayList();
+ for (int i=0; i<500; i++) {
+ IssueDto issue = IssueTesting.newDto(rule, file, project).setStatus(Issue.STATUS_OPEN);
+ tester.get(IssueDao.class).insert(session, issue);
+ issueKeys.add(issue.getKey());
+ }
+ session.commit();
+
+ Map<String, Object> properties = newHashMap();
+ properties.put("issues", Joiner.on(",").join(issueKeys));
+ properties.put("actions", "do_transition");
+ properties.put("do_transition.transition", DefaultTransitions.CONFIRM);
+
+ IssueBulkChangeQuery issueBulkChangeQuery = new IssueBulkChangeQuery(properties, false);
+ IssueBulkChangeResult result = service.execute(issueBulkChangeQuery, userSession);
+ assertThat(result.issuesChanged()).hasSize(500);
+ assertThat(result.issuesNotChanged()).isEmpty();
+ }
+
+ @Test
+ public void fail_if_bulk_change_on_more_than_500_issues() throws Exception {
+ List<String> issueKeys = newArrayList();
+ for (int i=0; i<510; i++) {
+ issueKeys.add("issue-" + i);
+ }
+
+ Map<String, Object> properties = newHashMap();
+ properties.put("issues", Joiner.on(",").join(issueKeys));
+ properties.put("actions", "do_transition");
+ properties.put("do_transition.transition", DefaultTransitions.CONFIRM);
+
+ try {
+ IssueBulkChangeQuery issueBulkChangeQuery = new IssueBulkChangeQuery(properties, true);
+ service.execute(issueBulkChangeQuery, userSession);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Number of issue keys must be less than 500 (got 510)");
+ }
+ }
+}
package org.sonar.server.issue;
-import org.sonar.core.preview.PreviewCache;
-
import org.junit.Before;
import org.junit.Test;
-import org.mockito.ArgumentCaptor;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.IssueQuery;
-import org.sonar.api.issue.IssueQueryResult;
import org.sonar.api.issue.condition.Condition;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.issue.internal.IssueChangeContext;
-import org.sonar.api.web.UserRole;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Scopes;
+import org.sonar.api.rules.Rule;
+import org.sonar.core.component.ComponentDto;
import org.sonar.core.issue.IssueNotifications;
import org.sonar.core.issue.db.IssueStorage;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.preview.PreviewCache;
+import org.sonar.server.component.db.ComponentDao;
+import org.sonar.server.db.DbClient;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.UnauthorizedException;
+import org.sonar.server.rule.DefaultRuleFinder;
import org.sonar.server.user.MockUserSession;
import org.sonar.server.user.UserSession;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
+import static com.google.common.collect.Sets.newHashSet;
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyListOf;
import static org.mockito.Matchers.anyMap;
import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
public class IssueBulkChangeServiceTest {
- private DefaultIssueFinder finder = mock(DefaultIssueFinder.class);
- private IssueStorage issueStorage = mock(IssueStorage.class);
- private IssueNotifications issueNotifications = mock(IssueNotifications.class);
+ DbClient dbClient = mock(DbClient.class);
+ DbSession dbSession = mock(DbSession.class);
+
+ IssueService issueService = mock(IssueService.class);
+ IssueStorage issueStorage = mock(IssueStorage.class);
+ DefaultRuleFinder ruleFinder = mock(DefaultRuleFinder.class);
+ ComponentDao componentDao = mock(ComponentDao.class);
+ IssueNotifications issueNotifications = mock(IssueNotifications.class);
+
+ IssueBulkChangeService service;
- private IssueQueryResult issueQueryResult = mock(IssueQueryResult.class);
- private UserSession userSession = MockUserSession.create().setLogin("john").setUserId(10);
- private DefaultIssue issue = new DefaultIssue().setKey("ABCD");
+ UserSession userSession = MockUserSession.create().setLogin("john").setUserId(10);
- private IssueBulkChangeService service;
+ DefaultIssue issue;
+ Rule rule;
+ ComponentDto project;
+ ComponentDto file;
- private List<Action> actions;
+ List<Action> actions;
@Before
public void before() {
- when(finder.find(any(IssueQuery.class))).thenReturn(issueQueryResult);
- when(issueQueryResult.issues()).thenReturn(newArrayList((Issue) issue));
+ when(dbClient.openSession(false)).thenReturn(dbSession);
+ when(dbClient.componentDao()).thenReturn(componentDao);
+
+ rule = Rule.create("repo", "key");
+ when(ruleFinder.findByKeys(newHashSet(rule.ruleKey()))).thenReturn(newArrayList(rule));
+
+ project = new ComponentDto()
+ .setId(1L)
+ .setKey("MyProject")
+ .setLongName("My Project")
+ .setQualifier(Qualifiers.PROJECT)
+ .setScope(Scopes.PROJECT);
+ when(componentDao.getByKeys(dbSession, newHashSet(project.key()))).thenReturn(newArrayList(project));
+
+ file = new ComponentDto()
+ .setId(2L)
+ .setProjectId(project.getId())
+ .setSubProjectId(project.getId())
+ .setKey("MyComponent")
+ .setLongName("My Component");
+ when(componentDao.getByKeys(dbSession, newHashSet(file.key()))).thenReturn(newArrayList(file));
+
+ issue = new DefaultIssue()
+ .setKey("ABCD")
+ .setRuleKey(rule.ruleKey())
+ .setProjectKey(project.key())
+ .setComponentKey(file.key());
+ when(issueService.search(anyListOf(String.class))).thenReturn(newArrayList((Issue) issue));
actions = newArrayList();
-
- service = new IssueBulkChangeService(finder, issueStorage, issueNotifications, actions, mock(PreviewCache.class));
+ service = new IssueBulkChangeService(dbClient, issueService, issueStorage, ruleFinder, issueNotifications, actions, mock(PreviewCache.class));
}
@Test
verify(issueStorage).save(eq(issue));
verifyNoMoreInteractions(issueStorage);
- verify(issueNotifications).sendChanges(eq(issue), any(IssueChangeContext.class), eq(issueQueryResult));
+ verify(issueNotifications).sendChanges(eq(issue), any(IssueChangeContext.class), eq(rule), eq(project), eq(file));
verifyNoMoreInteractions(issueNotifications);
}
verify(issueStorage).save(eq(issue));
verifyNoMoreInteractions(issueStorage);
- verify(issueNotifications, never()).sendChanges(eq(issue), any(IssueChangeContext.class), eq(issueQueryResult));
- verifyNoMoreInteractions(issueNotifications);
+ verifyZeroInteractions(issueNotifications);
}
@Test
@Test
public void should_execute_bulk_change_with_comment_only_on_changed_issues() {
- when(issueQueryResult.issues()).thenReturn(newArrayList((Issue) new DefaultIssue().setKey("ABCD"), new DefaultIssue().setKey("EFGH")));
+ when(issueService.search(anyListOf(String.class))).thenReturn(newArrayList((Issue) new DefaultIssue().setKey("ABCD"), new DefaultIssue().setKey("EFGH")));
Map<String, Object> properties = newHashMap();
properties.put("issues", "ABCD,EFGH");
verify(issueStorage, times(1)).save(eq(issue));
verifyNoMoreInteractions(issueStorage);
- verify(issueNotifications, times(1)).sendChanges(eq(issue), any(IssueChangeContext.class), eq(issueQueryResult));
+ verify(issueNotifications).sendChanges(eq(issue), any(IssueChangeContext.class), eq(rule), eq(project), eq(file));
verifyNoMoreInteractions(issueNotifications);
}
- @Test
- public void should_load_issues_from_issue_keys_with_maximum_page_size() {
- Map<String, Object> properties = newHashMap();
- properties.put("issues", "ABCD,DEFG");
- properties.put("actions", "assign");
- properties.put("assign.assignee", "fred");
- actions.add(new MockAction("assign"));
-
- IssueBulkChangeQuery issueBulkChangeQuery = new IssueBulkChangeQuery(properties, true);
- service.execute(issueBulkChangeQuery, userSession);
-
- ArgumentCaptor<IssueQuery> captor = ArgumentCaptor.forClass(IssueQuery.class);
- verify(finder).find(captor.capture());
- IssueQuery query = captor.getValue();
- assertThat(query.issueKeys()).containsOnly("ABCD", "DEFG");
- assertThat(query.pageSize()).isEqualTo(IssueQuery.MAX_PAGE_SIZE);
- assertThat(query.requiredRole()).isEqualTo(UserRole.USER);
- }
-
@Test
public void should_not_execute_bulk_if_issue_does_not_support_action() {
Map<String, Object> properties = newHashMap();
*/
package org.sonar.server.issue;
-
import org.sonar.api.issue.Issue;
import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.core.component.ComponentDto;
import org.sonar.core.issue.db.IssueDto;
+import org.sonar.core.rule.RuleDto;
+
+import java.util.UUID;
import static org.fest.assertions.Assertions.assertThat;
public class IssueTesting {
+ /**
+ * Full IssueDto used to feed database with fake data. Tests must not rely on the
+ * field contents declared here. They should override the fields they need to test,
+ * for example:
+ * <pre>
+ * issueDao.insert(dbSession, IssueTesting.newDto(rule, file, project).setStatus(Issue.STATUS_RESOLVED).setResolution(Issue.RESOLUTION_FALSE_POSITIVE));
+ * </pre>
+ */
+ public static IssueDto newDto(RuleDto rule, ComponentDto file, ComponentDto project) {
+ return new IssueDto()
+ .setKee(UUID.randomUUID().toString())
+ .setRule(rule)
+ .setComponent(file)
+ .setRootComponent(project)
+ .setStatus(Issue.STATUS_OPEN)
+ .setResolution(null)
+ .setSeverity(Severity.MAJOR)
+ .setDebt(10L)
+ .setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
+ .setIssueUpdateDate(DateUtils.parseDate("2014-12-04"));
+ }
+
public static void assertIsEquivalent(IssueDto dto, Issue issue) {
assertThat(issue).isNotNull();
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 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.server.issue;
-
-import com.google.common.collect.Multiset;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.api.issue.ActionPlan;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.IssueQuery;
-import org.sonar.api.issue.IssueQueryResult;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleFinder;
-import org.sonar.api.user.User;
-import org.sonar.api.user.UserFinder;
-import org.sonar.api.web.UserRole;
-import org.sonar.core.issue.DefaultActionPlan;
-import org.sonar.core.issue.IssueNotifications;
-import org.sonar.core.issue.IssueUpdater;
-import org.sonar.core.issue.db.IssueDao;
-import org.sonar.core.issue.db.IssueStorage;
-import org.sonar.core.issue.workflow.IssueWorkflow;
-import org.sonar.core.issue.workflow.Transition;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.preview.PreviewCache;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
-import org.sonar.core.resource.ResourceQuery;
-import org.sonar.core.rule.RuleDto;
-import org.sonar.core.user.AuthorizationDao;
-import org.sonar.core.user.DefaultUser;
-import org.sonar.server.issue.actionplan.ActionPlanService;
-import org.sonar.server.user.MockUserSession;
-import org.sonar.server.user.UserSession;
-
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.fest.assertions.Assertions.assertThat;
-import static org.fest.assertions.Fail.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.*;
-
-@RunWith(MockitoJUnitRunner.class)
-public class OldDefaultIssueServiceTest {
-
- @Mock
- DefaultIssueFinder finder;
-
- @Mock
- IssueWorkflow workflow;
-
- @Mock
- IssueUpdater issueUpdater;
-
- @Mock
- IssueStorage issueStorage;
-
- @Mock
- IssueNotifications issueNotifications;
-
- @Mock
- ActionPlanService actionPlanService;
-
- @Mock
- RuleFinder ruleFinder;
-
- @Mock
- ResourceDao resourceDao;
-
- @Mock
- IssueDao issueDao;
-
- @Mock
- AuthorizationDao authorizationDao;
-
- @Mock
- UserFinder userFinder;
-
- UserSession userSession;
-
- @Mock
- IssueQueryResult issueQueryResult;
-
- @Mock
- ResourceDto resource;
-
- @Mock
- ResourceDto project;
-
- Transition transition = Transition.create("reopen", Issue.STATUS_RESOLVED, Issue.STATUS_REOPENED);
-
- DefaultIssue issue = new DefaultIssue().setKey("ABCD");
-
- OldIssueService issueService;
-
- @Before
- public void before() {
- userSession = MockUserSession.set()
- .setLogin("arthur")
- .setUserId(10)
- .setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN)
- .addProjectPermissions(UserRole.USER, project.getKey())
- .addProjectPermissions(UserRole.ISSUE_ADMIN, project.getKey());
-
- when(authorizationDao.isAuthorizedComponentKey(anyString(), eq(10), anyString())).thenReturn(true);
- when(finder.find(any(IssueQuery.class))).thenReturn(issueQueryResult);
- when(issueQueryResult.issues()).thenReturn(newArrayList((Issue) issue));
- when(issueQueryResult.first()).thenReturn(issue);
-
- when(resource.getKey()).thenReturn("org.sonar.Sample");
- when(project.getKey()).thenReturn("Sample");
-
- issueService = new OldIssueService(finder, workflow, issueStorage, issueUpdater, issueNotifications, actionPlanService, ruleFinder, resourceDao, issueDao,
- authorizationDao, userFinder, mock(PreviewCache.class));
- }
-
- @Test
- public void load_issue() {
- IssueQueryResult result = issueService.loadIssue("ABCD");
- assertThat(result).isEqualTo(issueQueryResult);
- }
-
- @Test
- public void fail_to_load_issue() {
- when(issueQueryResult.issues()).thenReturn(Collections.<Issue>emptyList());
- when(finder.find(any(IssueQuery.class))).thenReturn(issueQueryResult);
-
- try {
- issueService.loadIssue("ABCD");
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Issue not found: ABCD");
- }
- }
-
- @Test
- public void list_status() {
- issueService.listStatus();
- verify(workflow).statusKeys();
- }
-
- @Test
- public void list_transitions() {
- List<Transition> transitions = newArrayList(transition);
- when(workflow.outTransitions(issue)).thenReturn(transitions);
-
- List<Transition> result = issueService.listTransitions("ABCD");
- assertThat(result).hasSize(1);
- assertThat(result.get(0)).isEqualTo(transition);
- }
-
- @Test
- public void return_no_transition() {
- when(issueQueryResult.first()).thenReturn(null);
- when(issueQueryResult.issues()).thenReturn(newArrayList((Issue) new DefaultIssue()));
-
- assertThat(issueService.listTransitions("ABCD")).isEmpty();
- verifyZeroInteractions(workflow);
- }
-
- @Test
- public void do_transition() {
- when(workflow.doTransition(eq(issue), eq(transition.key()), any(IssueChangeContext.class))).thenReturn(true);
-
- Issue result = issueService.doTransition("ABCD", transition.key());
- assertThat(result).isNotNull();
-
- ArgumentCaptor<IssueChangeContext> measureCaptor = ArgumentCaptor.forClass(IssueChangeContext.class);
- verify(workflow).doTransition(eq(issue), eq(transition.key()), measureCaptor.capture());
- verify(issueStorage).save(issue);
-
- IssueChangeContext issueChangeContext = measureCaptor.getValue();
- assertThat(issueChangeContext.login()).isEqualTo("arthur");
- assertThat(issueChangeContext.date()).isNotNull();
-
- verify(issueNotifications).sendChanges(eq(issue), eq(issueChangeContext), eq(issueQueryResult));
- }
-
- @Test
- public void not_do_transition() {
- when(workflow.doTransition(eq(issue), eq(transition.key()), any(IssueChangeContext.class))).thenReturn(false);
-
- Issue result = issueService.doTransition("ABCD", transition.key());
- assertThat(result).isNotNull();
- verify(workflow).doTransition(eq(issue), eq(transition.key()), any(IssueChangeContext.class));
- verifyZeroInteractions(issueStorage);
- verifyZeroInteractions(issueNotifications);
- }
-
- @Test
- public void fail_do_transition_if_not_logged() {
- MockUserSession.set();
- try {
- issueService.doTransition("ABCD", transition.key());
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("User is not logged in");
- }
- verifyZeroInteractions(authorizationDao);
- }
-
- @Test
- public void assign() {
- String assignee = "perceval";
- User user = new DefaultUser();
-
- when(userFinder.findByLogin(assignee)).thenReturn(user);
- when(issueUpdater.assign(eq(issue), eq(user), any(IssueChangeContext.class))).thenReturn(true);
-
- Issue result = issueService.assign("ABCD", assignee);
- assertThat(result).isNotNull();
-
- ArgumentCaptor<IssueChangeContext> measureCaptor = ArgumentCaptor.forClass(IssueChangeContext.class);
- verify(issueUpdater).assign(eq(issue), eq(user), measureCaptor.capture());
- verify(issueStorage).save(issue);
-
- IssueChangeContext issueChangeContext = measureCaptor.getValue();
- assertThat(issueChangeContext.login()).isEqualTo("arthur");
- assertThat(issueChangeContext.date()).isNotNull();
-
- verify(issueNotifications).sendChanges(eq(issue), eq(issueChangeContext), eq(issueQueryResult));
- }
-
- @Test
- public void unassign() {
- when(issueUpdater.assign(eq(issue), eq((User) null), any(IssueChangeContext.class))).thenReturn(true);
-
- Issue result = issueService.assign("ABCD", null);
- assertThat(result).isNotNull();
-
- ArgumentCaptor<IssueChangeContext> measureCaptor = ArgumentCaptor.forClass(IssueChangeContext.class);
- verify(issueUpdater).assign(eq(issue), eq((User) null), measureCaptor.capture());
- verify(issueStorage).save(issue);
-
- IssueChangeContext issueChangeContext = measureCaptor.getValue();
- assertThat(issueChangeContext.login()).isEqualTo("arthur");
- assertThat(issueChangeContext.date()).isNotNull();
-
- verify(issueNotifications).sendChanges(eq(issue), eq(issueChangeContext), eq(issueQueryResult));
- verify(userFinder, never()).findByLogin(anyString());
- }
-
- @Test
- public void not_assign() {
- String assignee = "perceval";
- User user = new DefaultUser();
-
- when(userFinder.findByLogin(assignee)).thenReturn(user);
- when(issueUpdater.assign(eq(issue), eq(user), any(IssueChangeContext.class))).thenReturn(false);
-
- Issue result = issueService.assign("ABCD", assignee);
- assertThat(result).isNotNull();
-
- verify(issueUpdater).assign(eq(issue), eq(user), any(IssueChangeContext.class));
- verifyZeroInteractions(issueStorage);
- verifyZeroInteractions(issueNotifications);
- }
-
- @Test
- public void fail_assign_if_assignee_not_found() {
- String assignee = "perceval";
-
- when(userFinder.findByLogin(assignee)).thenReturn(null);
-
- try {
- issueService.assign("ABCD", assignee);
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Unknown user: perceval");
- }
-
- verifyZeroInteractions(issueUpdater);
- verifyZeroInteractions(issueStorage);
- verifyZeroInteractions(issueNotifications);
- }
-
- @Test
- public void plan() {
- String actionPlanKey = "EFGH";
-
- ActionPlan actionPlan = new DefaultActionPlan();
-
- when(actionPlanService.findByKey(actionPlanKey, userSession)).thenReturn(actionPlan);
- when(issueUpdater.plan(eq(issue), eq(actionPlan), any(IssueChangeContext.class))).thenReturn(true);
-
- Issue result = issueService.plan("ABCD", actionPlanKey);
- assertThat(result).isNotNull();
-
- ArgumentCaptor<IssueChangeContext> measureCaptor = ArgumentCaptor.forClass(IssueChangeContext.class);
- verify(issueUpdater).plan(eq(issue), eq(actionPlan), measureCaptor.capture());
- verify(issueStorage).save(issue);
-
- IssueChangeContext issueChangeContext = measureCaptor.getValue();
- assertThat(issueChangeContext.login()).isEqualTo("arthur");
- assertThat(issueChangeContext.date()).isNotNull();
-
- verify(issueNotifications).sendChanges(eq(issue), eq(issueChangeContext), eq(issueQueryResult));
- }
-
- @Test
- public void unplan() {
- when(issueUpdater.plan(eq(issue), eq((ActionPlan) null), any(IssueChangeContext.class))).thenReturn(true);
-
- Issue result = issueService.plan("ABCD", null);
- assertThat(result).isNotNull();
-
- ArgumentCaptor<IssueChangeContext> measureCaptor = ArgumentCaptor.forClass(IssueChangeContext.class);
- verify(issueUpdater).plan(eq(issue), eq((ActionPlan) null), measureCaptor.capture());
- verify(issueStorage).save(issue);
-
- IssueChangeContext issueChangeContext = measureCaptor.getValue();
- assertThat(issueChangeContext.login()).isEqualTo("arthur");
- assertThat(issueChangeContext.date()).isNotNull();
-
- verify(issueNotifications).sendChanges(eq(issue), eq(issueChangeContext), eq(issueQueryResult));
- verify(actionPlanService, never()).findByKey(anyString(), any(UserSession.class));
- }
-
- @Test
- public void not_plan() {
- String actionPlanKey = "EFGH";
-
- ActionPlan actionPlan = new DefaultActionPlan();
-
- when(actionPlanService.findByKey(actionPlanKey, userSession)).thenReturn(actionPlan);
- when(issueUpdater.plan(eq(issue), eq(actionPlan), any(IssueChangeContext.class))).thenReturn(false);
-
- Issue result = issueService.plan("ABCD", actionPlanKey);
- assertThat(result).isNotNull();
- verify(issueUpdater).plan(eq(issue), eq(actionPlan), any(IssueChangeContext.class));
- verifyZeroInteractions(issueStorage);
- verifyZeroInteractions(issueNotifications);
- }
-
- @Test
- public void fail_plan_if_action_plan_not_found() {
- String actionPlanKey = "EFGH";
-
- when(actionPlanService.findByKey(actionPlanKey, userSession)).thenReturn(null);
- try {
- issueService.plan("ABCD", actionPlanKey);
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Unknown action plan: EFGH");
- }
-
- verifyZeroInteractions(issueUpdater);
- verifyZeroInteractions(issueStorage);
- verifyZeroInteractions(issueNotifications);
- }
-
- @Test
- public void set_severity() {
- String severity = "MINOR";
- when(issueUpdater.setManualSeverity(eq(issue), eq(severity), any(IssueChangeContext.class))).thenReturn(true);
-
- Issue result = issueService.setSeverity("ABCD", severity);
- assertThat(result).isNotNull();
-
- ArgumentCaptor<IssueChangeContext> measureCaptor = ArgumentCaptor.forClass(IssueChangeContext.class);
- verify(issueUpdater).setManualSeverity(eq(issue), eq(severity), measureCaptor.capture());
- verify(issueStorage).save(issue);
-
- IssueChangeContext issueChangeContext = measureCaptor.getValue();
- assertThat(issueChangeContext.login()).isEqualTo("arthur");
- assertThat(issueChangeContext.date()).isNotNull();
-
- verify(issueNotifications).sendChanges(eq(issue), eq(issueChangeContext), eq(issueQueryResult));
- }
-
- @Test
- public void not_set_severity() {
- String severity = "MINOR";
- when(issueUpdater.setManualSeverity(eq(issue), eq(severity), any(IssueChangeContext.class))).thenReturn(false);
-
- Issue result = issueService.setSeverity("ABCD", severity);
- assertThat(result).isNotNull();
- verify(issueUpdater).setManualSeverity(eq(issue), eq(severity), any(IssueChangeContext.class));
- verifyZeroInteractions(issueStorage);
- verifyZeroInteractions(issueNotifications);
- }
-
- @Test
- public void create_manual_issue() {
- RuleKey ruleKey = RuleKey.of("manual", "manualRuleKey");
- when(ruleFinder.findByKey(ruleKey)).thenReturn(Rule.create("manual", "manualRuleKey"));
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(resource);
- when(resourceDao.getRootProjectByComponentKey(anyString())).thenReturn(project);
-
- Issue result = issueService.createManualIssue("org.sonar.Sample", RuleKey.of("manual", "manualRuleKey"), null, "Fix it", null, null);
- assertThat(result).isNotNull();
- assertThat(result.message()).isEqualTo("Fix it");
- assertThat(result.creationDate()).isNotNull();
- assertThat(result.updateDate()).isNotNull();
-
- verify(issueStorage).save(any(DefaultIssue.class));
- verify(authorizationDao).isAuthorizedComponentKey(anyString(), anyInt(), eq(UserRole.USER));
- }
-
- @Test
- public void create_manual_issue_use_rule_name_if_no_message() {
- RuleKey ruleKey = RuleKey.of("manual", "manualRuleKey");
- when(ruleFinder.findByKey(ruleKey)).thenReturn(Rule.create("manual", "manualRuleKey").setName("Manual Rule"));
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(resource);
- when(resourceDao.getRootProjectByComponentKey(anyString())).thenReturn(project);
-
- Issue result = issueService.createManualIssue("org.sonar.Sample", RuleKey.of("manual", "manualRuleKey"), null, "", null, null);
- assertThat(result).isNotNull();
- assertThat(result.message()).isEqualTo("Manual Rule");
- assertThat(result.creationDate()).isNotNull();
- assertThat(result.updateDate()).isNotNull();
-
- verify(issueStorage).save(any(DefaultIssue.class));
- verify(authorizationDao).isAuthorizedComponentKey(anyString(), anyInt(), eq(UserRole.USER));
- }
-
- @Test
- public void fail_create_manual_issue_if_not_having_required_role() {
- RuleKey ruleKey = RuleKey.of("manual", "manualRuleKey");
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(resource);
- when(resourceDao.getRootProjectByComponentKey(anyString())).thenReturn(project);
- when(ruleFinder.findByKey(ruleKey)).thenReturn(Rule.create("manual", "manualRuleKey"));
- when(authorizationDao.isAuthorizedComponentKey(anyString(), eq(10), anyString())).thenReturn(false);
-
- try {
- issueService.createManualIssue("org.sonar.Sample", ruleKey, null, null, null, null);
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("User does not have the required role");
- }
- }
-
- @Test
- public void fail_create_manual_issue_if_not_manual_rule() {
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(resource);
- when(resourceDao.getRootProjectByComponentKey(anyString())).thenReturn(project);
-
- RuleKey ruleKey = RuleKey.of("squid", "s100");
- try {
- issueService.createManualIssue("org.sonar.Sample", ruleKey, null, null, null, null);
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Issues can be created only on rules marked as 'manual': squid:s100");
- }
- verifyZeroInteractions(issueStorage);
- }
-
- @Test
- public void fail_create_manual_issue_if_rule_not_found() {
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(resource);
- when(resourceDao.getRootProjectByComponentKey(anyString())).thenReturn(project);
-
- RuleKey ruleKey = RuleKey.of("manual", "manualRuleKey");
- when(ruleFinder.findByKey(ruleKey)).thenReturn(null);
- try {
- issueService.createManualIssue("org.sonar.Sample", RuleKey.of("manual", "manualRuleKey"), null, null, null, null);
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Unknown rule: manual:manualRuleKey");
- }
- verifyZeroInteractions(issueStorage);
- }
-
- @Test
- public void fail_create_manual_issue_if_component_not_found() {
- RuleKey ruleKey = RuleKey.of("manual", "manualRuleKey");
- when(ruleFinder.findByKey(ruleKey)).thenReturn(Rule.create("manual", "manualRuleKey"));
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(null);
- try {
- issueService.createManualIssue("org.sonar.Sample", RuleKey.of("manual", "manualRuleKey"), null, null, null, null);
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Unknown component: org.sonar.Sample");
- }
- verifyZeroInteractions(issueStorage);
- }
-
- @Test
- public void find_rules_by_component() throws Exception {
- DbSession session = mock(DbSession.class);
- String componentKey = "org.sonar.Sample";
-
- Date date = new Date();
- when(issueDao.findRulesByComponent(componentKey, date, session)).thenReturn(newArrayList(
- RuleDto.createFor(RuleKey.of("repo", "rule")).setName("Rule name"),
- RuleDto.createFor(RuleKey.of("repo", "rule")).setName("Rule name")
- ));
-
- RulesAggregation result = issueService.findRulesByComponent(componentKey, date, session);
- assertThat(result.rules()).hasSize(1);
- }
-
- @Test
- public void find_rules_by_severity() throws Exception {
- DbSession session = mock(DbSession.class);
- String componentKey = "org.sonar.Sample";
-
- Date date = new Date();
- when(issueDao.findSeveritiesByComponent(componentKey, date, session)).thenReturn(newArrayList("MAJOR", "MAJOR", "INFO"));
-
- Multiset<String> result = issueService.findSeveritiesByComponent(componentKey, date, session);
- assertThat(result.count("MAJOR")).isEqualTo(2);
- assertThat(result.count("INFO")).isEqualTo(1);
- assertThat(result.count("UNKNOWN")).isEqualTo(0);
- }
-}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.server.issue;
+
+import com.google.common.collect.Multiset;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.sonar.api.issue.ActionPlan;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.IssueQuery;
+import org.sonar.api.issue.IssueQueryResult;
+import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RuleFinder;
+import org.sonar.api.user.User;
+import org.sonar.api.user.UserFinder;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.issue.DefaultActionPlan;
+import org.sonar.core.issue.IssueNotifications;
+import org.sonar.core.issue.IssueUpdater;
+import org.sonar.core.issue.db.IssueDao;
+import org.sonar.core.issue.db.IssueStorage;
+import org.sonar.core.issue.workflow.IssueWorkflow;
+import org.sonar.core.issue.workflow.Transition;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.preview.PreviewCache;
+import org.sonar.core.resource.ResourceDao;
+import org.sonar.core.resource.ResourceDto;
+import org.sonar.core.resource.ResourceQuery;
+import org.sonar.core.rule.RuleDto;
+import org.sonar.core.user.AuthorizationDao;
+import org.sonar.core.user.DefaultUser;
+import org.sonar.server.issue.actionplan.ActionPlanService;
+import org.sonar.server.user.MockUserSession;
+import org.sonar.server.user.UserSession;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.*;
+
+@RunWith(MockitoJUnitRunner.class)
+public class OldIssueServiceTest {
+
+ @Mock
+ DefaultIssueFinder finder;
+
+ @Mock
+ IssueWorkflow workflow;
+
+ @Mock
+ IssueUpdater issueUpdater;
+
+ @Mock
+ IssueStorage issueStorage;
+
+ @Mock
+ IssueNotifications issueNotifications;
+
+ @Mock
+ ActionPlanService actionPlanService;
+
+ @Mock
+ RuleFinder ruleFinder;
+
+ @Mock
+ ResourceDao resourceDao;
+
+ @Mock
+ IssueDao issueDao;
+
+ @Mock
+ AuthorizationDao authorizationDao;
+
+ @Mock
+ UserFinder userFinder;
+
+ UserSession userSession;
+
+ @Mock
+ IssueQueryResult issueQueryResult;
+
+ @Mock
+ ResourceDto resource;
+
+ @Mock
+ ResourceDto project;
+
+ Transition transition = Transition.create("reopen", Issue.STATUS_RESOLVED, Issue.STATUS_REOPENED);
+
+ DefaultIssue issue = new DefaultIssue().setKey("ABCD");
+
+ OldIssueService issueService;
+
+ @Before
+ public void before() {
+ userSession = MockUserSession.set()
+ .setLogin("arthur")
+ .setUserId(10)
+ .setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN)
+ .addProjectPermissions(UserRole.USER, project.getKey())
+ .addProjectPermissions(UserRole.ISSUE_ADMIN, project.getKey());
+
+ when(authorizationDao.isAuthorizedComponentKey(anyString(), eq(10), anyString())).thenReturn(true);
+ when(finder.find(any(IssueQuery.class))).thenReturn(issueQueryResult);
+ when(issueQueryResult.issues()).thenReturn(newArrayList((Issue) issue));
+ when(issueQueryResult.first()).thenReturn(issue);
+
+ when(resource.getKey()).thenReturn("org.sonar.Sample");
+ when(project.getKey()).thenReturn("Sample");
+
+ issueService = new OldIssueService(finder, workflow, issueStorage, issueUpdater, issueNotifications, actionPlanService, ruleFinder, resourceDao, issueDao,
+ authorizationDao, userFinder, mock(PreviewCache.class));
+ }
+
+ @Test
+ public void load_issue() {
+ IssueQueryResult result = issueService.loadIssue("ABCD");
+ assertThat(result).isEqualTo(issueQueryResult);
+ }
+
+ @Test
+ public void fail_to_load_issue() {
+ when(issueQueryResult.issues()).thenReturn(Collections.<Issue>emptyList());
+ when(finder.find(any(IssueQuery.class))).thenReturn(issueQueryResult);
+
+ try {
+ issueService.loadIssue("ABCD");
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Issue not found: ABCD");
+ }
+ }
+
+ @Test
+ public void list_status() {
+ issueService.listStatus();
+ verify(workflow).statusKeys();
+ }
+
+ @Test
+ public void list_transitions() {
+ List<Transition> transitions = newArrayList(transition);
+ when(workflow.outTransitions(issue)).thenReturn(transitions);
+
+ List<Transition> result = issueService.listTransitions("ABCD");
+ assertThat(result).hasSize(1);
+ assertThat(result.get(0)).isEqualTo(transition);
+ }
+
+ @Test
+ public void return_no_transition() {
+ when(issueQueryResult.first()).thenReturn(null);
+ when(issueQueryResult.issues()).thenReturn(newArrayList((Issue) new DefaultIssue()));
+
+ assertThat(issueService.listTransitions("ABCD")).isEmpty();
+ verifyZeroInteractions(workflow);
+ }
+
+ @Test
+ public void do_transition() {
+ when(workflow.doTransition(eq(issue), eq(transition.key()), any(IssueChangeContext.class))).thenReturn(true);
+
+ Issue result = issueService.doTransition("ABCD", transition.key());
+ assertThat(result).isNotNull();
+
+ ArgumentCaptor<IssueChangeContext> measureCaptor = ArgumentCaptor.forClass(IssueChangeContext.class);
+ verify(workflow).doTransition(eq(issue), eq(transition.key()), measureCaptor.capture());
+ verify(issueStorage).save(issue);
+
+ IssueChangeContext issueChangeContext = measureCaptor.getValue();
+ assertThat(issueChangeContext.login()).isEqualTo("arthur");
+ assertThat(issueChangeContext.date()).isNotNull();
+
+ verify(issueNotifications).sendChanges(eq(issue), eq(issueChangeContext), eq(issueQueryResult));
+ }
+
+ @Test
+ public void not_do_transition() {
+ when(workflow.doTransition(eq(issue), eq(transition.key()), any(IssueChangeContext.class))).thenReturn(false);
+
+ Issue result = issueService.doTransition("ABCD", transition.key());
+ assertThat(result).isNotNull();
+ verify(workflow).doTransition(eq(issue), eq(transition.key()), any(IssueChangeContext.class));
+ verifyZeroInteractions(issueStorage);
+ verifyZeroInteractions(issueNotifications);
+ }
+
+ @Test
+ public void fail_do_transition_if_not_logged() {
+ MockUserSession.set();
+ try {
+ issueService.doTransition("ABCD", transition.key());
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("User is not logged in");
+ }
+ verifyZeroInteractions(authorizationDao);
+ }
+
+ @Test
+ public void assign() {
+ String assignee = "perceval";
+ User user = new DefaultUser();
+
+ when(userFinder.findByLogin(assignee)).thenReturn(user);
+ when(issueUpdater.assign(eq(issue), eq(user), any(IssueChangeContext.class))).thenReturn(true);
+
+ Issue result = issueService.assign("ABCD", assignee);
+ assertThat(result).isNotNull();
+
+ ArgumentCaptor<IssueChangeContext> measureCaptor = ArgumentCaptor.forClass(IssueChangeContext.class);
+ verify(issueUpdater).assign(eq(issue), eq(user), measureCaptor.capture());
+ verify(issueStorage).save(issue);
+
+ IssueChangeContext issueChangeContext = measureCaptor.getValue();
+ assertThat(issueChangeContext.login()).isEqualTo("arthur");
+ assertThat(issueChangeContext.date()).isNotNull();
+
+ verify(issueNotifications).sendChanges(eq(issue), eq(issueChangeContext), eq(issueQueryResult));
+ }
+
+ @Test
+ public void unassign() {
+ when(issueUpdater.assign(eq(issue), eq((User) null), any(IssueChangeContext.class))).thenReturn(true);
+
+ Issue result = issueService.assign("ABCD", null);
+ assertThat(result).isNotNull();
+
+ ArgumentCaptor<IssueChangeContext> measureCaptor = ArgumentCaptor.forClass(IssueChangeContext.class);
+ verify(issueUpdater).assign(eq(issue), eq((User) null), measureCaptor.capture());
+ verify(issueStorage).save(issue);
+
+ IssueChangeContext issueChangeContext = measureCaptor.getValue();
+ assertThat(issueChangeContext.login()).isEqualTo("arthur");
+ assertThat(issueChangeContext.date()).isNotNull();
+
+ verify(issueNotifications).sendChanges(eq(issue), eq(issueChangeContext), eq(issueQueryResult));
+ verify(userFinder, never()).findByLogin(anyString());
+ }
+
+ @Test
+ public void not_assign() {
+ String assignee = "perceval";
+ User user = new DefaultUser();
+
+ when(userFinder.findByLogin(assignee)).thenReturn(user);
+ when(issueUpdater.assign(eq(issue), eq(user), any(IssueChangeContext.class))).thenReturn(false);
+
+ Issue result = issueService.assign("ABCD", assignee);
+ assertThat(result).isNotNull();
+
+ verify(issueUpdater).assign(eq(issue), eq(user), any(IssueChangeContext.class));
+ verifyZeroInteractions(issueStorage);
+ verifyZeroInteractions(issueNotifications);
+ }
+
+ @Test
+ public void fail_assign_if_assignee_not_found() {
+ String assignee = "perceval";
+
+ when(userFinder.findByLogin(assignee)).thenReturn(null);
+
+ try {
+ issueService.assign("ABCD", assignee);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Unknown user: perceval");
+ }
+
+ verifyZeroInteractions(issueUpdater);
+ verifyZeroInteractions(issueStorage);
+ verifyZeroInteractions(issueNotifications);
+ }
+
+ @Test
+ public void plan() {
+ String actionPlanKey = "EFGH";
+
+ ActionPlan actionPlan = new DefaultActionPlan();
+
+ when(actionPlanService.findByKey(actionPlanKey, userSession)).thenReturn(actionPlan);
+ when(issueUpdater.plan(eq(issue), eq(actionPlan), any(IssueChangeContext.class))).thenReturn(true);
+
+ Issue result = issueService.plan("ABCD", actionPlanKey);
+ assertThat(result).isNotNull();
+
+ ArgumentCaptor<IssueChangeContext> measureCaptor = ArgumentCaptor.forClass(IssueChangeContext.class);
+ verify(issueUpdater).plan(eq(issue), eq(actionPlan), measureCaptor.capture());
+ verify(issueStorage).save(issue);
+
+ IssueChangeContext issueChangeContext = measureCaptor.getValue();
+ assertThat(issueChangeContext.login()).isEqualTo("arthur");
+ assertThat(issueChangeContext.date()).isNotNull();
+
+ verify(issueNotifications).sendChanges(eq(issue), eq(issueChangeContext), eq(issueQueryResult));
+ }
+
+ @Test
+ public void unplan() {
+ when(issueUpdater.plan(eq(issue), eq((ActionPlan) null), any(IssueChangeContext.class))).thenReturn(true);
+
+ Issue result = issueService.plan("ABCD", null);
+ assertThat(result).isNotNull();
+
+ ArgumentCaptor<IssueChangeContext> measureCaptor = ArgumentCaptor.forClass(IssueChangeContext.class);
+ verify(issueUpdater).plan(eq(issue), eq((ActionPlan) null), measureCaptor.capture());
+ verify(issueStorage).save(issue);
+
+ IssueChangeContext issueChangeContext = measureCaptor.getValue();
+ assertThat(issueChangeContext.login()).isEqualTo("arthur");
+ assertThat(issueChangeContext.date()).isNotNull();
+
+ verify(issueNotifications).sendChanges(eq(issue), eq(issueChangeContext), eq(issueQueryResult));
+ verify(actionPlanService, never()).findByKey(anyString(), any(UserSession.class));
+ }
+
+ @Test
+ public void not_plan() {
+ String actionPlanKey = "EFGH";
+
+ ActionPlan actionPlan = new DefaultActionPlan();
+
+ when(actionPlanService.findByKey(actionPlanKey, userSession)).thenReturn(actionPlan);
+ when(issueUpdater.plan(eq(issue), eq(actionPlan), any(IssueChangeContext.class))).thenReturn(false);
+
+ Issue result = issueService.plan("ABCD", actionPlanKey);
+ assertThat(result).isNotNull();
+ verify(issueUpdater).plan(eq(issue), eq(actionPlan), any(IssueChangeContext.class));
+ verifyZeroInteractions(issueStorage);
+ verifyZeroInteractions(issueNotifications);
+ }
+
+ @Test
+ public void fail_plan_if_action_plan_not_found() {
+ String actionPlanKey = "EFGH";
+
+ when(actionPlanService.findByKey(actionPlanKey, userSession)).thenReturn(null);
+ try {
+ issueService.plan("ABCD", actionPlanKey);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Unknown action plan: EFGH");
+ }
+
+ verifyZeroInteractions(issueUpdater);
+ verifyZeroInteractions(issueStorage);
+ verifyZeroInteractions(issueNotifications);
+ }
+
+ @Test
+ public void set_severity() {
+ String severity = "MINOR";
+ when(issueUpdater.setManualSeverity(eq(issue), eq(severity), any(IssueChangeContext.class))).thenReturn(true);
+
+ Issue result = issueService.setSeverity("ABCD", severity);
+ assertThat(result).isNotNull();
+
+ ArgumentCaptor<IssueChangeContext> measureCaptor = ArgumentCaptor.forClass(IssueChangeContext.class);
+ verify(issueUpdater).setManualSeverity(eq(issue), eq(severity), measureCaptor.capture());
+ verify(issueStorage).save(issue);
+
+ IssueChangeContext issueChangeContext = measureCaptor.getValue();
+ assertThat(issueChangeContext.login()).isEqualTo("arthur");
+ assertThat(issueChangeContext.date()).isNotNull();
+
+ verify(issueNotifications).sendChanges(eq(issue), eq(issueChangeContext), eq(issueQueryResult));
+ }
+
+ @Test
+ public void not_set_severity() {
+ String severity = "MINOR";
+ when(issueUpdater.setManualSeverity(eq(issue), eq(severity), any(IssueChangeContext.class))).thenReturn(false);
+
+ Issue result = issueService.setSeverity("ABCD", severity);
+ assertThat(result).isNotNull();
+ verify(issueUpdater).setManualSeverity(eq(issue), eq(severity), any(IssueChangeContext.class));
+ verifyZeroInteractions(issueStorage);
+ verifyZeroInteractions(issueNotifications);
+ }
+
+ @Test
+ public void create_manual_issue() {
+ RuleKey ruleKey = RuleKey.of("manual", "manualRuleKey");
+ when(ruleFinder.findByKey(ruleKey)).thenReturn(Rule.create("manual", "manualRuleKey"));
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(resource);
+ when(resourceDao.getRootProjectByComponentKey(anyString())).thenReturn(project);
+
+ Issue result = issueService.createManualIssue("org.sonar.Sample", RuleKey.of("manual", "manualRuleKey"), null, "Fix it", null, null);
+ assertThat(result).isNotNull();
+ assertThat(result.message()).isEqualTo("Fix it");
+ assertThat(result.creationDate()).isNotNull();
+ assertThat(result.updateDate()).isNotNull();
+
+ verify(issueStorage).save(any(DefaultIssue.class));
+ verify(authorizationDao).isAuthorizedComponentKey(anyString(), anyInt(), eq(UserRole.USER));
+ }
+
+ @Test
+ public void create_manual_issue_use_rule_name_if_no_message() {
+ RuleKey ruleKey = RuleKey.of("manual", "manualRuleKey");
+ when(ruleFinder.findByKey(ruleKey)).thenReturn(Rule.create("manual", "manualRuleKey").setName("Manual Rule"));
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(resource);
+ when(resourceDao.getRootProjectByComponentKey(anyString())).thenReturn(project);
+
+ Issue result = issueService.createManualIssue("org.sonar.Sample", RuleKey.of("manual", "manualRuleKey"), null, "", null, null);
+ assertThat(result).isNotNull();
+ assertThat(result.message()).isEqualTo("Manual Rule");
+ assertThat(result.creationDate()).isNotNull();
+ assertThat(result.updateDate()).isNotNull();
+
+ verify(issueStorage).save(any(DefaultIssue.class));
+ verify(authorizationDao).isAuthorizedComponentKey(anyString(), anyInt(), eq(UserRole.USER));
+ }
+
+ @Test
+ public void fail_create_manual_issue_if_not_having_required_role() {
+ RuleKey ruleKey = RuleKey.of("manual", "manualRuleKey");
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(resource);
+ when(resourceDao.getRootProjectByComponentKey(anyString())).thenReturn(project);
+ when(ruleFinder.findByKey(ruleKey)).thenReturn(Rule.create("manual", "manualRuleKey"));
+ when(authorizationDao.isAuthorizedComponentKey(anyString(), eq(10), anyString())).thenReturn(false);
+
+ try {
+ issueService.createManualIssue("org.sonar.Sample", ruleKey, null, null, null, null);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("User does not have the required role");
+ }
+ }
+
+ @Test
+ public void fail_create_manual_issue_if_not_manual_rule() {
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(resource);
+ when(resourceDao.getRootProjectByComponentKey(anyString())).thenReturn(project);
+
+ RuleKey ruleKey = RuleKey.of("squid", "s100");
+ try {
+ issueService.createManualIssue("org.sonar.Sample", ruleKey, null, null, null, null);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Issues can be created only on rules marked as 'manual': squid:s100");
+ }
+ verifyZeroInteractions(issueStorage);
+ }
+
+ @Test
+ public void fail_create_manual_issue_if_rule_not_found() {
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(resource);
+ when(resourceDao.getRootProjectByComponentKey(anyString())).thenReturn(project);
+
+ RuleKey ruleKey = RuleKey.of("manual", "manualRuleKey");
+ when(ruleFinder.findByKey(ruleKey)).thenReturn(null);
+ try {
+ issueService.createManualIssue("org.sonar.Sample", RuleKey.of("manual", "manualRuleKey"), null, null, null, null);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Unknown rule: manual:manualRuleKey");
+ }
+ verifyZeroInteractions(issueStorage);
+ }
+
+ @Test
+ public void fail_create_manual_issue_if_component_not_found() {
+ RuleKey ruleKey = RuleKey.of("manual", "manualRuleKey");
+ when(ruleFinder.findByKey(ruleKey)).thenReturn(Rule.create("manual", "manualRuleKey"));
+ when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(null);
+ try {
+ issueService.createManualIssue("org.sonar.Sample", RuleKey.of("manual", "manualRuleKey"), null, null, null, null);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Unknown component: org.sonar.Sample");
+ }
+ verifyZeroInteractions(issueStorage);
+ }
+
+ @Test
+ public void find_rules_by_component() throws Exception {
+ DbSession session = mock(DbSession.class);
+ String componentKey = "org.sonar.Sample";
+
+ Date date = new Date();
+ when(issueDao.findRulesByComponent(componentKey, date, session)).thenReturn(newArrayList(
+ RuleDto.createFor(RuleKey.of("repo", "rule")).setName("Rule name"),
+ RuleDto.createFor(RuleKey.of("repo", "rule")).setName("Rule name")
+ ));
+
+ RulesAggregation result = issueService.findRulesByComponent(componentKey, date, session);
+ assertThat(result.rules()).hasSize(1);
+ }
+
+ @Test
+ public void find_rules_by_severity() throws Exception {
+ DbSession session = mock(DbSession.class);
+ String componentKey = "org.sonar.Sample";
+
+ Date date = new Date();
+ when(issueDao.findSeveritiesByComponent(componentKey, date, session)).thenReturn(newArrayList("MAJOR", "MAJOR", "INFO"));
+
+ Multiset<String> result = issueService.findSeveritiesByComponent(componentKey, date, session);
+ assertThat(result.count("MAJOR")).isEqualTo(2);
+ assertThat(result.count("INFO")).isEqualTo(1);
+ assertThat(result.count("UNKNOWN")).isEqualTo(0);
+ }
+
+ @Test
+ public void search_issues() {
+ assertThat(issueService.search(newArrayList("ABCD"))).hasSize(1);
+ }
+}
import org.sonar.server.component.db.ComponentDao;
import org.sonar.server.db.DbClient;
import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.issue.db.IssueDao;
import org.sonar.server.rule.RuleTesting;
import org.sonar.server.rule.db.RuleDao;
import org.sonar.server.search.QueryContext;
import org.sonar.server.user.MockUserSession;
import java.util.Date;
+import java.util.List;
import java.util.UUID;
+import static com.google.common.collect.Lists.newArrayList;
import static org.fest.assertions.Assertions.assertThat;
public class IssueIndexMediumTest {
assertThat(result.getHits()).hasSize(2);
}
+ @Test
+ public void search_with_paging() throws Exception {
+ for (int i=0; i<12; i++) {
+ IssueDto issue = createIssue();
+ tester.get(IssueDao.class).insert(session, issue);
+ }
+ session.commit();
+
+ IssueQuery.Builder query = IssueQuery.builder();
+ // There are 12 issues in total, with 10 issues per page, the page 2 should only contain 2 elements
+ Result<Issue> result = index.search(query.build(), new QueryContext().setPage(2, 10));
+ assertThat(result.getHits()).hasSize(2);
+ assertThat(result.getTotal()).isEqualTo(12);
+ }
+
+ @Test
+ public void search_with_limit() throws Exception {
+ for (int i=0; i<20; i++) {
+ IssueDto issue = createIssue();
+ tester.get(IssueDao.class).insert(session, issue);
+ }
+ session.commit();
+
+ IssueQuery.Builder query = IssueQuery.builder();
+ Result<Issue> result = index.search(query.build(), new QueryContext().setLimit(20));
+ assertThat(result.getHits()).hasSize(20);
+ }
+
+ @Test
+ public void search_with_max_limit() throws Exception {
+ List<String> issueKeys = newArrayList();
+ for (int i=0; i<500; i++) {
+ IssueDto issue = createIssue();
+ tester.get(IssueDao.class).insert(session, issue);
+ issueKeys.add(issue.getKey());
+ }
+ session.commit();
+
+ IssueQuery.Builder query = IssueQuery.builder();
+ Result<Issue> result = index.search(query.build(), new QueryContext().setMaxLimit());
+ assertThat(result.getHits()).hasSize(500);
+ }
+
@Test
public void authorized_issues_on_groups() throws Exception {
ComponentDto project1 = new ComponentDto()
import org.fest.assertions.Assertions;
import org.junit.*;
+import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleQuery;
assertThat(finder.findByIds(newArrayList(2))).hasSize(1);
}
+ @Test
+ public void find_keys_including_removed_rule() {
+ assertThat(finder.findByKeys(newArrayList(RuleKey.of("checkstyle", "DisabledCheck")))).hasSize(1);
+
+ // find rule with id 2 is REMOVED
+ assertThat(finder.findByKeys(newArrayList(RuleKey.of("checkstyle", "com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck")))).hasSize(1);
+
+ assertThat(finder.findByKeys(Collections.<RuleKey>emptyList())).isEmpty();
+ }
+
@Test
public void find_id_return_null_on_removed_rule() {
// find rule with id 2 is REMOVED