*/
package org.sonar.server.issue;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import org.sonar.api.ServerComponent;
+import org.sonar.api.component.Component;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.IssueQuery;
import org.sonar.api.issue.IssueQueryResult;
import org.sonar.api.issue.internal.IssueChangeContext;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
+import org.sonar.api.user.UserFinder;
import org.sonar.api.web.UserRole;
import org.sonar.core.issue.IssueNotifications;
import org.sonar.core.issue.IssueUpdater;
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.resource.ResourceDao;
+import org.sonar.core.resource.ResourceDto;
+import org.sonar.core.user.AuthorizationDao;
import org.sonar.server.user.UserSession;
import javax.annotation.Nullable;
private final IssueWorkflow workflow;
private final IssueUpdater issueUpdater;
private final IssueStorage issueStorage;
+ private final IssueNotifications issueNotifications;
private final ActionPlanService actionPlanService;
private final RuleFinder ruleFinder;
- private final IssueNotifications issueNotifications;
+ private final ResourceDao resourceDao;
+ private final AuthorizationDao authorizationDao;
+ private final UserFinder userFinder;
public IssueService(DefaultIssueFinder finder,
IssueWorkflow workflow,
IssueStorage issueStorage,
IssueUpdater issueUpdater,
+ IssueNotifications issueNotifications,
ActionPlanService actionPlanService,
RuleFinder ruleFinder,
- IssueNotifications issueNotifications) {
+ ResourceDao resourceDao,
+ AuthorizationDao authorizationDao,
+ UserFinder userFinder) {
this.finder = finder;
this.workflow = workflow;
this.issueStorage = issueStorage;
this.actionPlanService = actionPlanService;
this.ruleFinder = ruleFinder;
this.issueNotifications = issueNotifications;
+ this.resourceDao = resourceDao;
+ this.authorizationDao = authorizationDao;
+ this.userFinder = userFinder;
}
/**
}
public Issue doTransition(String issueKey, String transition, UserSession userSession) {
- verifyLoggedIn(userSession);
IssueQueryResult queryResult = loadIssue(issueKey);
DefaultIssue issue = (DefaultIssue) queryResult.first();
+ checkAuthorization(userSession, issue, UserRole.USER);
IssueChangeContext context = IssueChangeContext.createUser(new Date(), userSession.login());
if (workflow.doTransition(issue, transition, context)) {
issueStorage.save(issue);
}
public Issue assign(String issueKey, @Nullable String assignee, UserSession userSession) {
- verifyLoggedIn(userSession);
IssueQueryResult queryResult = loadIssue(issueKey);
DefaultIssue issue = (DefaultIssue) queryResult.first();
-
- if (issue != null) {
- // TODO check that assignee exists
- IssueChangeContext context = IssueChangeContext.createUser(new Date(), userSession.login());
- if (issueUpdater.assign(issue, assignee, context)) {
- issueStorage.save(issue);
- issueNotifications.sendChanges(issue, context, queryResult);
- }
+ checkAuthorization(userSession, issue, UserRole.USER);
+ if (assignee != null && userFinder.findByLogin(assignee) == null) {
+ throw new IllegalArgumentException("Unknown user: " + assignee);
+ }
+ IssueChangeContext context = IssueChangeContext.createUser(new Date(), userSession.login());
+ if (issueUpdater.assign(issue, assignee, context)) {
+ issueStorage.save(issue);
+ issueNotifications.sendChanges(issue, context, queryResult);
}
return issue;
}
public Issue plan(String issueKey, @Nullable String actionPlanKey, UserSession userSession) {
if (!Strings.isNullOrEmpty(actionPlanKey) && actionPlanService.findByKey(actionPlanKey, userSession) == null) {
- throw new IllegalStateException("Unknown action plan: " + actionPlanKey);
+ throw new IllegalArgumentException("Unknown action plan: " + actionPlanKey);
}
-
- verifyLoggedIn(userSession);
IssueQueryResult queryResult = loadIssue(issueKey);
DefaultIssue issue = (DefaultIssue) queryResult.first();
+ checkAuthorization(userSession, issue, UserRole.USER);
+
IssueChangeContext context = IssueChangeContext.createUser(new Date(), userSession.login());
if (issueUpdater.plan(issue, actionPlanKey, context)) {
issueStorage.save(issue);
}
public Issue setSeverity(String issueKey, String severity, UserSession userSession) {
- verifyLoggedIn(userSession);
IssueQueryResult queryResult = loadIssue(issueKey);
DefaultIssue issue = (DefaultIssue) queryResult.first();
+ checkAuthorization(userSession, issue, UserRole.USER);
+
IssueChangeContext context = IssueChangeContext.createUser(new Date(), userSession.login());
if (issueUpdater.setManualSeverity(issue, severity, context)) {
issueStorage.save(issue);
}
public DefaultIssue createManualIssue(DefaultIssue issue, UserSession userSession) {
- verifyLoggedIn(userSession);
+ checkAuthorization(userSession, issue, UserRole.USER);
if (!"manual".equals(issue.ruleKey().repository())) {
throw new IllegalArgumentException("Issues can be created only on rules marked as 'manual': " + issue.ruleKey());
}
if (rule == null) {
throw new IllegalArgumentException("Unknown rule: " + issue.ruleKey());
}
+ Component component = resourceDao.findByKey(issue.componentKey());
+ if (component == null) {
+ throw new IllegalArgumentException("Unknown component: " + issue.componentKey());
+ }
Date now = new Date();
issue.setCreationDate(now);
issue.setUpdateDate(now);
-
- // TODO check existence of component
- // TODO verify authorization
-
issueStorage.save(issue);
return issue;
}
-
public IssueQueryResult loadIssue(String issueKey) {
- IssueQuery query = IssueQuery.builder().issueKeys(Arrays.asList(issueKey)).requiredRole(UserRole.USER).build();
- IssueQueryResult result = finder.find(query);
- if (result.issues().size()!=1) {
- throw new IllegalStateException("Issue not found: " + issueKey);
+ IssueQueryResult result = finder.find(IssueQuery.builder().issueKeys(Arrays.asList(issueKey)).requiredRole(UserRole.USER).build());
+ if (result.issues().size() != 1) {
+ // TODO throw 404
+ throw new IllegalArgumentException("Issue not found: " + issueKey);
}
return result;
}
return workflow.statusKeys();
}
- private void verifyLoggedIn(UserSession userSession) {
+ @VisibleForTesting
+ void checkAuthorization(UserSession userSession, Issue issue, String requiredRole) {
if (!userSession.isLoggedIn()) {
// must be logged
throw new IllegalStateException("User is not logged in");
}
+ if (!authorizationDao.isAuthorizedComponentId(findProject(issue.componentKey()).getId(), userSession.userId(), requiredRole)) {
+ // TODO throw unauthorized
+ throw new IllegalStateException("User does not have the required role");
+ }
+ }
+
+ @VisibleForTesting
+ ResourceDto findProject(String componentKey) {
+ ResourceDto resourceDto = resourceDao.getRootProjectByComponentKey(componentKey);
+ if (resourceDto == null) {
+ // TODO throw 404
+ throw new IllegalArgumentException("Component '" + componentKey + "' does not exists.");
+ }
+ return resourceDto;
}
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.issue;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.sonar.api.component.Component;
+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.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.IssueStorage;
+import org.sonar.core.issue.workflow.IssueWorkflow;
+import org.sonar.core.issue.workflow.Transition;
+import org.sonar.core.resource.ResourceDao;
+import org.sonar.core.resource.ResourceDto;
+import org.sonar.core.user.AuthorizationDao;
+import org.sonar.core.user.DefaultUser;
+import org.sonar.server.user.UserSession;
+
+import java.util.Collections;
+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.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.*;
+
+public class IssueServiceTest {
+
+ private DefaultIssueFinder finder = mock(DefaultIssueFinder.class);
+ private IssueWorkflow workflow = mock(IssueWorkflow.class);
+ private IssueUpdater issueUpdater = mock(IssueUpdater.class);
+ private IssueStorage issueStorage = mock(IssueStorage.class);
+ private IssueNotifications issueNotifications = mock(IssueNotifications.class);
+ private ActionPlanService actionPlanService = mock(ActionPlanService.class);
+ private RuleFinder ruleFinder = mock(RuleFinder.class);
+ private ResourceDao resourceDao = mock(ResourceDao.class);
+ private AuthorizationDao authorizationDao = mock(AuthorizationDao.class);
+ private UserFinder userFinder = mock(UserFinder.class);
+ private UserSession userSession = mock(UserSession.class);
+ private Transition transition = Transition.create("reopen", Issue.STATUS_RESOLVED, Issue.STATUS_REOPENED);
+ private IssueQueryResult issueQueryResult = mock(IssueQueryResult.class);
+ private DefaultIssue issue = new DefaultIssue().setKey("ABCD");
+ private IssueService issueService;
+
+ @Before
+ public void before() {
+ when(userSession.isLoggedIn()).thenReturn(true);
+ when(userSession.userId()).thenReturn(10);
+ when(userSession.login()).thenReturn("arthur");
+
+ when(authorizationDao.isAuthorizedComponentId(anyLong(), 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);
+
+ issueService = new IssueService(finder, workflow, issueStorage, issueUpdater, issueNotifications, actionPlanService, ruleFinder, resourceDao, authorizationDao, userFinder);
+ }
+
+ @Test
+ public void should_load_issue() {
+ IssueQueryResult result = issueService.loadIssue("ABCD");
+ assertThat(result).isEqualTo(issueQueryResult);
+ }
+
+ @Test
+ public void should_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 should_list_status() {
+ issueService.listStatus();
+ verify(workflow).statusKeys();
+ }
+
+ @Test
+ public void should_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 should_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 should_do_transition() {
+ grantAccess();
+ when(workflow.doTransition(eq(issue), eq(transition.key()), any(IssueChangeContext.class))).thenReturn(true);
+
+ Issue result = issueService.doTransition("ABCD", transition.key(), userSession);
+ 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));
+ verify(authorizationDao).isAuthorizedComponentId(anyLong(), anyInt(), eq(UserRole.USER));
+ }
+
+ @Test
+ public void should_not_do_transition() {
+ grantAccess();
+ when(workflow.doTransition(eq(issue), eq(transition.key()), any(IssueChangeContext.class))).thenReturn(false);
+
+ Issue result = issueService.doTransition("ABCD", transition.key(), userSession);
+ assertThat(result).isNotNull();
+ verify(workflow).doTransition(eq(issue), eq(transition.key()), any(IssueChangeContext.class));
+ verifyZeroInteractions(issueStorage);
+ verifyZeroInteractions(issueNotifications);
+ }
+
+ @Test
+ public void should_assign() {
+ grantAccess();
+ String assignee = "perceval";
+
+ when(userFinder.findByLogin(assignee)).thenReturn(new DefaultUser());
+ when(issueUpdater.assign(eq(issue), eq(assignee), any(IssueChangeContext.class))).thenReturn(true);
+
+ Issue result = issueService.assign("ABCD", assignee, userSession);
+ assertThat(result).isNotNull();
+
+ ArgumentCaptor<IssueChangeContext> measureCaptor = ArgumentCaptor.forClass(IssueChangeContext.class);
+ verify(issueUpdater).assign(eq(issue), eq(assignee), 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(authorizationDao).isAuthorizedComponentId(anyLong(), anyInt(), eq(UserRole.USER));
+ }
+
+ @Test
+ public void should_not_assign() {
+ grantAccess();
+ String assignee = "perceval";
+
+ when(userFinder.findByLogin(assignee)).thenReturn(new DefaultUser());
+ when(issueUpdater.assign(eq(issue), eq(assignee), any(IssueChangeContext.class))).thenReturn(false);
+
+ Issue result = issueService.assign("ABCD", assignee, userSession);
+ assertThat(result).isNotNull();
+ verify(issueUpdater).assign(eq(issue), eq(assignee),any(IssueChangeContext.class));
+ verifyZeroInteractions(issueStorage);
+ verifyZeroInteractions(issueNotifications);
+ }
+
+ @Test
+ public void should_fail_assign_if_assignee_not_found() {
+ grantAccess();
+ String assignee = "perceval";
+
+ when(userFinder.findByLogin(assignee)).thenReturn(null);
+
+ try {
+ issueService.assign("ABCD", assignee, userSession);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Unknown user: perceval");
+ }
+
+ verifyZeroInteractions(issueUpdater);
+ verifyZeroInteractions(issueStorage);
+ verifyZeroInteractions(issueNotifications);
+ }
+
+ @Test
+ public void should_plan() {
+ grantAccess();
+ String actionPlanKey = "EFGH";
+
+ when(actionPlanService.findByKey(actionPlanKey, userSession)).thenReturn(new DefaultActionPlan());
+ when(issueUpdater.plan(eq(issue), eq(actionPlanKey), any(IssueChangeContext.class))).thenReturn(true);
+
+ Issue result = issueService.plan("ABCD", actionPlanKey, userSession);
+ assertThat(result).isNotNull();
+
+ ArgumentCaptor<IssueChangeContext> measureCaptor = ArgumentCaptor.forClass(IssueChangeContext.class);
+ verify(issueUpdater).plan(eq(issue), eq(actionPlanKey), 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(authorizationDao).isAuthorizedComponentId(anyLong(), anyInt(), eq(UserRole.USER));
+ }
+
+ @Test
+ public void should_not_plan() {
+ grantAccess();
+ String actionPlanKey = "EFGH";
+
+ when(actionPlanService.findByKey(actionPlanKey, userSession)).thenReturn(new DefaultActionPlan());
+ when(issueUpdater.plan(eq(issue), eq(actionPlanKey), any(IssueChangeContext.class))).thenReturn(false);
+
+ Issue result = issueService.plan("ABCD", actionPlanKey, userSession);
+ assertThat(result).isNotNull();
+ verify(issueUpdater).plan(eq(issue), eq(actionPlanKey), any(IssueChangeContext.class));
+ verifyZeroInteractions(issueStorage);
+ verifyZeroInteractions(issueNotifications);
+ }
+
+ @Test
+ public void should_fail_plan_if_action_plan_not_found() {
+ grantAccess();
+ String actionPlanKey = "EFGH";
+
+ when(actionPlanService.findByKey(actionPlanKey, userSession)).thenReturn(null);
+ try {
+ issueService.plan("ABCD", actionPlanKey, userSession);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Unknown action plan: EFGH");
+ }
+
+ verifyZeroInteractions(issueUpdater);
+ verifyZeroInteractions(issueStorage);
+ verifyZeroInteractions(issueNotifications);
+ }
+
+ @Test
+ public void should_set_severity() {
+ grantAccess();
+ String severity = "MINOR";
+ when(issueUpdater.setManualSeverity(eq(issue), eq(severity), any(IssueChangeContext.class))).thenReturn(true);
+
+ Issue result = issueService.setSeverity("ABCD", severity, userSession);
+ 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));
+ verify(authorizationDao).isAuthorizedComponentId(anyLong(), anyInt(), eq(UserRole.USER));
+ }
+
+ @Test
+ public void should_not_set_severity() {
+ grantAccess();
+ String severity = "MINOR";
+ when(issueUpdater.setManualSeverity(eq(issue), eq(severity), any(IssueChangeContext.class))).thenReturn(false);
+
+ Issue result = issueService.setSeverity("ABCD", severity, userSession);
+ assertThat(result).isNotNull();
+ verify(issueUpdater).setManualSeverity(eq(issue), eq(severity), any(IssueChangeContext.class));
+ verifyZeroInteractions(issueStorage);
+ verifyZeroInteractions(issueNotifications);
+ }
+
+ @Test
+ public void should_create_manual_issue() {
+ grantAccess();
+ RuleKey ruleKey = RuleKey.of("manual", "manualRuleKey");
+ DefaultIssue manualIssue = new DefaultIssue().setKey("GHIJ").setRuleKey(RuleKey.of("manual", "manualRuleKey")).setComponentKey("org.sonar.Sample");
+ when(ruleFinder.findByKey(ruleKey)).thenReturn(Rule.create("manual", "manualRuleKey"));
+ when(resourceDao.findByKey("org.sonar.Sample")).thenReturn(mock(Component.class));
+
+ Issue result = issueService.createManualIssue(manualIssue, userSession);
+ assertThat(result).isNotNull();
+ assertThat(result.creationDate()).isNotNull();
+ assertThat(result.updateDate()).isNotNull();
+
+ verify(issueStorage).save(manualIssue);
+ verify(authorizationDao).isAuthorizedComponentId(anyLong(), anyInt(), eq(UserRole.USER));
+ }
+
+ @Test
+ public void should_fail_create_manual_issue_if_not_manual_rule() {
+ grantAccess();
+ RuleKey ruleKey = RuleKey.of("squid", "s100");
+ DefaultIssue manualIssue = new DefaultIssue().setKey("GHIJ").setRuleKey(ruleKey).setComponentKey("org.sonar.Sample");
+ try {
+ issueService.createManualIssue(manualIssue, userSession);
+ 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 should_fail_create_manual_issue_if_rule_not_found() {
+ grantAccess();
+ RuleKey ruleKey = RuleKey.of("manual", "manualRuleKey");
+ DefaultIssue manualIssue = new DefaultIssue().setKey("GHIJ").setRuleKey(RuleKey.of("manual", "manualRuleKey")).setComponentKey("org.sonar.Sample");
+ when(ruleFinder.findByKey(ruleKey)).thenReturn(null);
+ try {
+ issueService.createManualIssue(manualIssue, userSession);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Unknown rule: manual:manualRuleKey");
+ }
+
+ verifyZeroInteractions(issueStorage);
+ }
+
+ @Test
+ public void should_fail_create_manual_issue_if_component_not_found() {
+ grantAccess();
+ RuleKey ruleKey = RuleKey.of("manual", "manualRuleKey");
+ DefaultIssue manualIssue = new DefaultIssue().setKey("GHIJ").setRuleKey(RuleKey.of("manual", "manualRuleKey")).setComponentKey("org.sonar.Sample");
+ when(ruleFinder.findByKey(ruleKey)).thenReturn(Rule.create("manual", "manualRuleKey"));
+ when(resourceDao.findByKey("org.sonar.Sample")).thenReturn(null);
+ try {
+ issueService.createManualIssue(manualIssue, userSession);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Unknown component: org.sonar.Sample");
+ }
+
+ verifyZeroInteractions(issueStorage);
+ }
+
+ @Test
+ public void should_fail_if_not_logged() {
+ when(userSession.isLoggedIn()).thenReturn(false);
+ try {
+ issueService.checkAuthorization(userSession, issue, UserRole.USER);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("User is not logged in");
+ }
+ verifyZeroInteractions(authorizationDao);
+ }
+
+ @Test
+ public void should_fail_if_not_having_required_role() {
+ grantAccess();
+ when(userSession.isLoggedIn()).thenReturn(true);
+ when(authorizationDao.isAuthorizedComponentId(anyLong(), anyInt(), anyString())).thenReturn(false);
+ try {
+ issueService.checkAuthorization(userSession, issue, UserRole.USER);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("User does not have the required role");
+ }
+ }
+
+ @Test
+ public void should_find_project() {
+ ResourceDto project = new ResourceDto().setKey("org.sonar.Sample").setId(1l);
+ when(resourceDao.getRootProjectByComponentKey(anyString())).thenReturn(project);
+ assertThat(issueService.findProject("org.sonar.Sample")).isEqualTo(project);
+ }
+
+ @Test
+ public void should_fail_to_find_project() {
+ when(resourceDao.getRootProjectByComponentKey(anyString())).thenReturn(null);
+ try {
+ issueService.findProject("org.sonar.Sample");
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Component 'org.sonar.Sample' does not exists.");
+ }
+ }
+
+ private void grantAccess(){
+ when(resourceDao.getRootProjectByComponentKey(anyString())).thenReturn(new ResourceDto().setKey("org.sonar.Sample").setId(1l));
+ }
+
+}