+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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 java.util.Collections;
-import java.util.List;
-import org.sonar.db.issue.IssueDto;
-import org.sonar.server.user.UserSession;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static java.util.Objects.requireNonNull;
-import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
-import static org.sonar.server.issue.AssignAction.ASSIGN_KEY;
-import static org.sonar.server.issue.CommentAction.COMMENT_KEY;
-import static org.sonar.server.issue.SetSeverityAction.SET_SEVERITY_KEY;
-import static org.sonar.server.issue.SetTypeAction.SET_TYPE_KEY;
-
-public class ActionFinder {
-
- private final UserSession userSession;
-
- public ActionFinder(UserSession userSession) {
- this.userSession = userSession;
- }
-
- public List<String> listAvailableActions(IssueDto issue) {
- List<String> availableActions = newArrayList();
- String login = userSession.getLogin();
- if (login == null) {
- return Collections.emptyList();
- }
- availableActions.add(COMMENT_KEY);
- if (issue.getResolution() != null) {
- return availableActions;
- }
- availableActions.add(ASSIGN_KEY);
- availableActions.add("set_tags");
- if (!login.equals(issue.getAssignee())) {
- // This action will be removed by
- availableActions.add("assign_to_me");
- }
- if (userSession.hasComponentUuidPermission(ISSUE_ADMIN, requireNonNull(issue.getProjectUuid()))) {
- availableActions.add(SET_TYPE_KEY);
- availableActions.add(SET_SEVERITY_KEY);
- }
- return availableActions;
- }
-
-}
package org.sonar.server.issue.ws;
import org.sonar.core.platform.Module;
-import org.sonar.server.issue.ActionFinder;
import org.sonar.server.issue.IssueFieldsSetter;
import org.sonar.server.issue.IssueFinder;
import org.sonar.server.issue.IssueQueryFactory;
@Override
protected void configureModule() {
add(
- ActionFinder.class,
IssueUpdater.class,
IssueFinder.class,
TransitionService.class,
import com.google.common.collect.MultimapBuilder;
import com.google.common.collect.SetMultimap;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.es.Facets;
-import org.sonar.server.issue.ActionFinder;
import org.sonar.server.issue.TransitionService;
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.client.issue.IssuesWsParameters;
import static com.google.common.collect.Sets.difference;
import static java.util.Collections.emptyList;
import static java.util.stream.Stream.concat;
+import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
import static org.sonar.core.util.stream.MoreCollectors.toList;
+import static org.sonar.server.issue.AssignAction.ASSIGN_KEY;
+import static org.sonar.server.issue.CommentAction.COMMENT_KEY;
+import static org.sonar.server.issue.SetSeverityAction.SET_SEVERITY_KEY;
+import static org.sonar.server.issue.SetTypeAction.SET_TYPE_KEY;
import static org.sonar.server.issue.ws.SearchAdditionalField.ACTIONS;
import static org.sonar.server.issue.ws.SearchAdditionalField.COMMENTS;
import static org.sonar.server.issue.ws.SearchAdditionalField.RULES;
private final UserSession userSession;
private final DbClient dbClient;
- private final ActionFinder actionService;
private final TransitionService transitionService;
- public SearchResponseLoader(UserSession userSession, DbClient dbClient, ActionFinder actionService, TransitionService transitionService) {
+ public SearchResponseLoader(UserSession userSession, DbClient dbClient, TransitionService transitionService) {
this.userSession = userSession;
this.dbClient = dbClient;
- this.actionService = actionService;
this.transitionService = transitionService;
}
private void loadActionsAndTransitions(Collector collector, SearchResponseData result) {
if (collector.contains(ACTIONS) || collector.contains(TRANSITIONS)) {
+ Map<String, ComponentDto> componentsByProjectUuid =
+ result.getComponents()
+ .stream()
+ .filter(ComponentDto::isRootProject)
+ .collect(MoreCollectors.uniqueIndex(ComponentDto::projectUuid));
for (IssueDto dto : result.getIssues()) {
// so that IssueDto can be used.
if (collector.contains(ACTIONS)) {
- result.addActions(dto.getKey(), actionService.listAvailableActions(dto));
+ ComponentDto project = componentsByProjectUuid.get(dto.getProjectUuid());
+ result.addActions(dto.getKey(), listAvailableActions(dto, project));
}
if (collector.contains(TRANSITIONS)) {
// TODO workflow and action engines must not depend on org.sonar.api.issue.Issue but on a generic interface
}
}
+ private List<String> listAvailableActions(IssueDto issue, ComponentDto project) {
+ List<String> availableActions = newArrayList();
+ String login = userSession.getLogin();
+ if (login == null) {
+ return Collections.emptyList();
+ }
+ availableActions.add(COMMENT_KEY);
+ if (issue.getResolution() != null) {
+ return availableActions;
+ }
+ availableActions.add(ASSIGN_KEY);
+ availableActions.add("set_tags");
+ if (userSession.hasComponentPermission(ISSUE_ADMIN, project)) {
+ availableActions.add(SET_TYPE_KEY);
+ availableActions.add(SET_SEVERITY_KEY);
+ }
+ return availableActions;
+ }
+
private static void completeTotalEffortFromFacet(@Nullable Facets facets, SearchResponseData result) {
if (facets != null) {
Map<String, Long> effortFacet = facets.get(IssuesWsParameters.FACET_MODE_EFFORT);
"assign",
"set_tags",
"set_type",
- "assign_to_me",
"set_severity"
],
"comments": [
"assign",
"set_tags",
"set_type",
- "assign_to_me",
"set_severity"
],
"comments": [
"assign",
"set_tags",
"set_type",
- "assign_to_me",
"set_severity"
],
"comments": [
"assign",
"set_tags",
"set_type",
- "assign_to_me",
"set_severity"
],
"comments": [
"assign",
"set_tags",
"set_type",
- "assign_to_me",
"set_severity"
],
"comments": [
"assign",
"set_tags",
"set_type",
- "assign_to_me",
"set_severity"
],
"comments": [
"assign",
"set_tags",
"set_type",
- "assign_to_me",
"set_severity"
],
"comments": [
"assign",
"set_tags",
"set_type",
- "assign_to_me",
"set_severity"
],
"comments": [
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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 org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTesting;
-import org.sonar.db.issue.IssueDto;
-import org.sonar.db.organization.OrganizationTesting;
-import org.sonar.server.tester.UserSessionRule;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.api.issue.Issue.RESOLUTION_FIXED;
-import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
-import static org.sonar.db.component.ComponentTesting.newFileDto;
-import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
-import static org.sonar.db.issue.IssueTesting.newDto;
-import static org.sonar.db.rule.RuleTesting.newXooX1;
-
-public class ActionFinderTest {
-
- static final String PROJECT_KEY = "PROJECT_KEY";
- static final String PROJECT_UUID = "PROJECT_UUID";
-
- static final String ISSUE_KEY = "ISSUE_KEY";
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- @Rule
- public UserSessionRule userSession = UserSessionRule.standalone().logIn("arthur");
-
- private ComponentDto project = newPrivateProjectDto(OrganizationTesting.newOrganizationDto(), PROJECT_UUID).setDbKey(PROJECT_KEY);
- private IssueDto issue = newDto(newXooX1().setId(10), newFileDto(project, null), project).setKee(ISSUE_KEY);
-
- private ActionFinder underTest = new ActionFinder(userSession);
-
- @Test
- public void return_provided_actions_without_set_severity_and_set_tpye_when_not_issue_admin() {
- assertThat(underTest.listAvailableActions(issue)).containsOnly("comment", "assign", "set_tags", "assign_to_me");
- }
-
- @Test
- public void return_provided_actions_with_set_severity_and_set_type_when_issue_admin() {
- userSession.addProjectPermission(ISSUE_ADMIN, ComponentTesting.newPrivateProjectDto(OrganizationTesting.newOrganizationDto(), PROJECT_UUID));
- assertThat(underTest.listAvailableActions(issue)).containsOnly("comment", "assign", "set_tags", "set_type", "assign_to_me", "set_severity");
- }
-
- @Test
- public void return_no_actions_when_not_logged() {
- userSession.anonymous();
- assertThat(underTest.listAvailableActions(issue)).isEmpty();
- }
-
- @Test
- public void doest_not_return_assign_to_me_action_when_issue_already_assigned_to_user() {
-
- userSession.logIn("julien");
- IssueDto issue = newDto(newXooX1().setId(10), newFileDto(project, null), project).setKee(ISSUE_KEY).setAssignee("julien");
- assertThat(underTest.listAvailableActions(issue)).doesNotContain("assign_to_me");
- }
-
- @Test
- public void return_only_comment_action_when_issue_has_a_resolution() {
- IssueDto issue = newDto(newXooX1().setId(10), newFileDto(project, null), project).setKee(ISSUE_KEY).setResolution(RESOLUTION_FIXED);
- assertThat(underTest.listAvailableActions(issue)).containsOnly("comment");
- }
-
-}
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new IssueWsModule().configure(container);
- assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 31);
+ assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 30);
}
}
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.server.es.EsTester;
-import org.sonar.server.issue.ActionFinder;
import org.sonar.server.issue.IssueFieldsSetter;
import org.sonar.server.issue.IssueQueryFactory;
import org.sonar.server.issue.TransitionService;
private IssueQueryFactory issueQueryFactory = new IssueQueryFactory(dbClient, Clock.systemUTC(), userSession);
private IssueFieldsSetter issueFieldsSetter = new IssueFieldsSetter();
private IssueWorkflow issueWorkflow = new IssueWorkflow(new FunctionExecutor(issueFieldsSetter), issueFieldsSetter);
- private SearchResponseLoader searchResponseLoader = new SearchResponseLoader(userSession, dbClient, new ActionFinder(userSession),
- new TransitionService(userSession, issueWorkflow));
+ private SearchResponseLoader searchResponseLoader = new SearchResponseLoader(userSession, dbClient, new TransitionService(userSession, issueWorkflow));
private Languages languages = new Languages();
private SearchResponseFormat searchResponseFormat = new SearchResponseFormat(new Durations(), new WsResponseCommonFormat(languages), languages, new AvatarResolverImpl());
private PermissionIndexerTester permissionIndexer = new PermissionIndexerTester(es, issueIndexer);
import org.sonar.server.es.EsTester;
import org.sonar.server.es.SearchOptions;
import org.sonar.server.es.StartupIndexer;
-import org.sonar.server.issue.ActionFinder;
import org.sonar.server.issue.IssueFieldsSetter;
import org.sonar.server.issue.IssueQuery;
import org.sonar.server.issue.IssueQueryFactory;
private IssueQueryFactory issueQueryFactory = new IssueQueryFactory(dbClient, Clock.systemUTC(), userSessionRule);
private IssueFieldsSetter issueFieldsSetter = new IssueFieldsSetter();
private IssueWorkflow issueWorkflow = new IssueWorkflow(new FunctionExecutor(issueFieldsSetter), issueFieldsSetter);
- private SearchResponseLoader searchResponseLoader = new SearchResponseLoader(userSessionRule, dbClient, new ActionFinder(userSessionRule),
- new TransitionService(userSessionRule, issueWorkflow));
+ private SearchResponseLoader searchResponseLoader = new SearchResponseLoader(userSessionRule, dbClient, new TransitionService(userSessionRule, issueWorkflow));
private Languages languages = new Languages();
private SearchResponseFormat searchResponseFormat = new SearchResponseFormat(new Durations(), new WsResponseCommonFormat(languages), languages, new AvatarResolverImpl());
private WsActionTester ws = new WsActionTester(new SearchAction(userSessionRule, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat));
"actions": [
"comment",
"assign",
- "set_tags",
- "assign_to_me"
+ "set_tags"
],
"transitions": [
"confirm",
"comment",
"assign",
"set_tags",
- "assign_to_me",
"set_type",
"set_severity"
],