import it.issue.IssueTrackingTest;
import it.issue.IssueWorkflowTest;
import it.issue.ManualIssueRelocationTest;
-import it.issue.ManualIssueTest;
import it.issue.NewIssuesMeasureTest;
import it.qualityModel.MaintainabilityMeasureTest;
import it.qualityModel.MaintainabilityRatingMeasureTest;
IssueTrackingTest.class,
IssueWorkflowTest.class,
ManualIssueRelocationTest.class,
- ManualIssueTest.class,
NewIssuesMeasureTest.class,
// rule
ManualRulesTest.class,
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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 it.issue;
-
-import com.google.common.collect.ImmutableMap;
-import java.util.List;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.sonar.wsclient.issue.Issue;
-import org.sonar.wsclient.issue.IssueComment;
-import org.sonar.wsclient.issue.IssueQuery;
-import org.sonar.wsclient.issue.Issues;
-import org.sonar.wsclient.issue.NewIssue;
-import util.QaOnly;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-import static util.ItUtils.runProjectAnalysis;
-import static util.ItUtils.verifyHttpException;
-
-/**
- * SONAR-4304
- */
-@Category(QaOnly.class)
-public class ManualIssueTest extends AbstractIssueTest {
-
- private final static String COMPONENT_KEY = "sample:src/main/xoo/sample/Sample.xoo";
-
- @Before
- public void before() {
- ORCHESTRATOR.resetData();
- analyzeProject();
- createManualRule();
- }
-
- @Test
- public void create_manual_issue_through_ws() throws Exception {
- // Create the manual issue
- Issue newIssue = adminIssueClient().create(NewIssue.create().component(COMPONENT_KEY)
- .rule("manual:invalidclassname")
- .line(3)
- .severity("CRITICAL")
- .message("The name 'Sample' is too generic"));
- assertThat(newIssue.key()).isNotNull();
- assertThat(newIssue.creationDate()).isNotNull();
- assertThat(newIssue.updateDate()).isNotNull();
- assertThat(newIssue.ruleKey()).isEqualTo("manual:invalidclassname");
- assertThat(newIssue.line()).isEqualTo(3);
- assertThat(newIssue.severity()).isEqualTo(("CRITICAL"));
- assertThat(newIssue.message()).isEqualTo(("The name 'Sample' is too generic"));
- assertThat(newIssue.status()).isEqualTo("OPEN");
- assertThat(newIssue.resolution()).isNull();
- assertThat(newIssue.reporter()).isEqualTo("admin");
-
- Issues issues = search(IssueQuery.create().issues(newIssue.key()));
- assertThat(issues.list().get(0).reporter()).isEqualTo("admin");
-
- // get the detail of the reporter
- assertThat(issues.user("admin").name()).isEqualTo("Administrator");
- }
-
- @Test
- public void scan_should_keep_manual_issues_open() throws Exception {
- // Create the manual issue
- Issue newIssue = adminIssueClient().create(NewIssue.create().component(COMPONENT_KEY)
- .rule("manual:invalidclassname")
- .line(3)
- .severity("CRITICAL")
- .message("The name 'Sample' is too generic"));
- assertThat(newIssue.key()).isNotNull();
- assertThat(newIssue.creationDate()).isNotNull();
- assertThat(newIssue.updateDate()).isNotNull();
-
- // the metric 'issues' is not up-to-date yet
- assertThat(searchIssuesByComponent(COMPONENT_KEY)).hasSize(1);
-
- // re-inspect the project : the issue still exists
- analyzeProject();
-
- Issue issue = searchIssueByKey(newIssue.key());
- assertThat(issue.ruleKey()).isEqualTo("manual:invalidclassname");
- assertThat(issue.line()).isEqualTo(3);
- assertThat(issue.severity()).isEqualTo(("CRITICAL"));
- assertThat(issue.message()).isEqualTo(("The name 'Sample' is too generic"));
- assertThat(issue.status()).isEqualTo("OPEN");
- assertThat(issue.resolution()).isNull();
- assertThat(issue.reporter()).isEqualTo("admin");
- assertThat(issue.creationDate()).isEqualTo(newIssue.creationDate());
- assertThat(issue.updateDate()).isEqualTo(newIssue.updateDate());
- }
-
- @Test
- public void scan_should_close_issues_on_deleted_manual_rules() throws Exception {
- // Create another manual rule
- ORCHESTRATOR.getServer().adminWsClient().post("/api/rules/create", ImmutableMap.<String, Object>of(
- "manual_key", "ruletoberemoved",
- "name", "RuleToBeRemoved",
- "markdown_description", "Rule to be removed"
- ));
-
- // Create the manual issue
- Issue newIssue = adminIssueClient().create(NewIssue.create().component(COMPONENT_KEY)
- .rule("manual:ruletoberemoved")
- .line(3)
- .severity("CRITICAL")
- .message("The name 'Sample' is too generic"));
- assertThat(newIssue.status()).isEqualTo("OPEN");
-
- // Delete the manual rule (will be in fact disabled in the db, not removed)
- ORCHESTRATOR.getServer().adminWsClient().post("/api/rules/delete", ImmutableMap.<String, Object>of("key", "manual:ruletoberemoved"));
-
- analyzeProject();
- Issue closedIssue = searchIssueByKey(newIssue.key());
- assertThat(closedIssue.status()).isEqualTo("CLOSED");
- assertThat(closedIssue.resolution()).isEqualTo("REMOVED");
- assertThat(closedIssue.creationDate()).isEqualTo(newIssue.creationDate());
- assertThat(closedIssue.updateDate().before(newIssue.updateDate())).isFalse();
- assertThat(closedIssue.closeDate().before(closedIssue.creationDate())).isFalse();
- }
-
- @Test
- public void scan_should_close_manual_resolved_issues() throws Exception {
- // Create the manual issue
- Issue newIssue = adminIssueClient().create(NewIssue.create().component(COMPONENT_KEY)
- .rule("manual:invalidclassname")
- .line(3)
- .severity("CRITICAL")
- .message("The name 'Sample' is too generic"));
- assertThat(newIssue.status()).isEqualTo("OPEN");
-
- // mark issue as resolved
- adminIssueClient().doTransition(newIssue.key(), "resolve");
-
- analyzeProject();
- Issue closedIssue = searchIssueByKey(newIssue.key());
- assertThat(closedIssue.status()).isEqualTo("CLOSED");
- assertThat(closedIssue.resolution()).isEqualTo("FIXED");
- assertThat(closedIssue.creationDate()).isEqualTo(newIssue.creationDate());
- assertThat(closedIssue.updateDate().before(newIssue.updateDate())).isFalse();
- assertThat(closedIssue.closeDate().before(closedIssue.creationDate())).isFalse();
- }
-
- @Test
- public void add_comment_to_manual_issue() throws Exception {
- // Create the manual issue
- Issue manualIssue = adminIssueClient().create(NewIssue.create().component(COMPONENT_KEY)
- .rule("manual:invalidclassname")
- .line(3)
- .severity("CRITICAL")
- .message("The name 'Sample' is too generic"));
-
- // Add a comment on the manual issue
- IssueComment comment = adminIssueClient().addComment(manualIssue.key(), "this is my *comment*");
-
- // Reload manual issue
- Issue reloaded = searchIssueWithComments(manualIssue.key());
-
- assertThat(reloaded.comments()).hasSize(1);
- assertThat(reloaded.comments().get(0).key()).isEqualTo(comment.key());
- }
-
- @Test
- public void resolve_manual_issue() throws Exception {
- // Create the manual issue
- Issue manualIssue = adminIssueClient().create(NewIssue.create().component(COMPONENT_KEY)
- .rule("manual:invalidclassname")
- .line(3)
- .severity("CRITICAL")
- .message("The name 'Sample' is too generic"));
-
- // Resolve the manual issue
- adminIssueClient().doTransition(manualIssue.key(), "resolve");
-
- // Check the manual issue is well resolved
- Issue reloaded = searchIssueByKey(manualIssue.key());
- assertThat(reloaded.status()).isEqualTo("RESOLVED");
- assertThat(reloaded.resolution()).isEqualTo("FIXED");
- assertThat(reloaded.creationDate()).isEqualTo(manualIssue.creationDate());
- assertThat(reloaded.updateDate().before(manualIssue.updateDate())).isFalse();
-
- analyzeProject();
-
- // Reload after analyse -> manual issue should be closed
- reloaded = searchIssueByKey(manualIssue.key());
- assertThat(reloaded.status()).isEqualTo("CLOSED");
- assertThat(reloaded.resolution()).isEqualTo("FIXED");
- assertThat(reloaded.creationDate()).isEqualTo(manualIssue.creationDate());
- assertThat(reloaded.updateDate().before(manualIssue.updateDate())).isFalse();
- assertThat(reloaded.closeDate()).isNotNull();
- assertThat(reloaded.closeDate().before(reloaded.creationDate())).isFalse();
- }
-
- @Test
- public void resolve_and_reopen_manual_issue() throws Exception {
- // Create the manual issue
- Issue issue = adminIssueClient().create(NewIssue.create().component(COMPONENT_KEY)
- .rule("manual:invalidclassname")
- .line(3)
- .severity("CRITICAL")
- .message("The name 'Sample' is too generic"));
-
- // Resolve the manual issue
- adminIssueClient().doTransition(issue.key(), "resolve");
-
- // Check the manual issue is well resolved
- assertThat(searchIssueByKey(issue.key()).status()).isEqualTo("RESOLVED");
-
- analyzeProject();
- // Reload after analyse -> manual issue is closed
- assertThat(searchIssueByKey(issue.key()).status()).isEqualTo("CLOSED");
-
- // Reopen the manual issue
- adminIssueClient().doTransition(issue.key(), "reopen");
-
- analyzeProject();
- // Reload after analyse -> manual issue is reopened
- Issue reloaded = searchIssueByKey(issue.key());
- assertThat(reloaded.status()).isEqualTo("REOPENED");
- assertThat(reloaded.resolution()).isNull();
- assertThat(reloaded.creationDate()).isEqualTo(issue.creationDate());
- assertThat(reloaded.updateDate().before(issue.updateDate())).isFalse();
- }
-
- @Test
- public void fail_if_unknown_rule() throws Exception {
- try {
- adminIssueClient().create(NewIssue.create().component(COMPONENT_KEY)
- // this rule does not exist
- .rule("manual:unknown-rule")
- .line(3)
- .severity("CRITICAL")
- .message("The name 'Sample' is too generic"));
- fail();
- } catch (Exception e) {
- verifyHttpException(e, 400);
- }
- }
-
- @Test
- public void fail_if_missing_rule() throws Exception {
- try {
- adminIssueClient().create(NewIssue.create().component(COMPONENT_KEY)
- .line(3)
- .severity("CRITICAL")
- .message("The name 'Sample' is too generic"));
- fail();
- } catch (Exception e) {
- verifyHttpException(e, 400);
- }
- }
-
- @Test
- public void fail_if_not_a_manual_rule() throws Exception {
- try {
- adminIssueClient().create(NewIssue.create().component(COMPONENT_KEY)
- // Not a manual rule
- .rule("xoo:OneIssuePerLine")
- .line(3)
- .severity("CRITICAL")
- .message("The name 'Sample' is too generic"));
- fail();
- } catch (Exception e) {
- verifyHttpException(e, 400);
- }
- }
-
- @Test
- public void fail_if_rule_is_disabled() throws Exception {
- // Create and delete a manual rule
- ORCHESTRATOR.getServer().adminWsClient().post("/api/rules/create", ImmutableMap.<String, Object>of(
- "manual_key", "anotherinvalidclassname",
- "name", "AnotherInvalidClassName",
- "markdown_description", "Another invalid class name"
- ));
- ORCHESTRATOR.getServer().adminWsClient().post("/api/rules/delete", ImmutableMap.<String, Object>of(
- "key", "manual:anotherinvalidclassname"
- ));
-
- try {
- adminIssueClient().create(NewIssue.create().component(COMPONENT_KEY)
- // This rule is disabled
- .rule("manual:anotherinvalidclassname")
- .line(3)
- .severity("CRITICAL")
- .message("The name 'Sample' is too generic"));
- fail();
- } catch (Exception e) {
- verifyHttpException(e, 400);
- }
- }
-
- @Test
- public void fail_if_component_does_not_exist() throws Exception {
- try {
- adminIssueClient().create(NewIssue.create().component("unknown component")
- .rule("manual:invalidclassname")
- .line(3)
- .severity("CRITICAL")
- .message("The name 'Sample' is too generic"));
- fail();
- } catch (Exception e) {
- verifyHttpException(e, 400);
- }
- }
-
- @Test
- public void fail_if_not_logged_in() throws Exception {
- try {
- issueClient().create(NewIssue.create().component("unknown component")
- .rule("manual:invalidclassname")
- .line(3)
- .severity("CRITICAL")
- .message("The name 'Sample' is too generic"));
- fail();
- } catch (Exception e) {
- verifyHttpException(e, 401);
- }
- }
-
- private static void analyzeProject() {
- // no active rules
- runProjectAnalysis(ORCHESTRATOR, "shared/xoo-sample");
- }
-
- private static void createManualRule() {
- ORCHESTRATOR.getServer().adminWsClient().post("/api/rules/create", ImmutableMap.<String, Object>of(
- "manual_key", "invalidclassname",
- "name", "InvalidClassName",
- "markdown_description", "Invalid class name"
- ));
- }
-
- private static List<Issue> searchIssuesByComponent(String componentKey) {
- return search(IssueQuery.create().components(componentKey)).list();
- }
-
- private static Issue searchIssueWithComments(String issueKey) {
- return searchIssue(issueKey, true);
- }
-}
private static void appendPermissions(JsonWriter json, ComponentDto component, UserSession userSession) {
boolean hasBrowsePermission = userSession.hasComponentPermission(UserRole.USER, component.key());
json.prop("canMarkAsFavourite", userSession.isLoggedIn() && hasBrowsePermission);
- json.prop("canCreateManualIssue", userSession.isLoggedIn() && hasBrowsePermission);
}
private void appendMeasures(JsonWriter json, Map<String, MeasureDto> measuresByMetricKey) {
*/
package org.sonar.server.issue;
-import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Strings;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
-import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.issue.Issue;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
-import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.server.ServerSide;
import org.sonar.api.user.UserFinder;
import org.sonar.api.web.UserRole;
import org.sonar.core.issue.DefaultIssue;
-import org.sonar.core.issue.DefaultIssueBuilder;
import org.sonar.core.issue.IssueChangeContext;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.issue.IssueDto;
-import org.sonar.db.protobuf.DbFileSources;
import org.sonar.db.rule.RuleDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.issue.index.IssueIndex;
import org.sonar.server.issue.workflow.IssueWorkflow;
import org.sonar.server.issue.workflow.Transition;
import org.sonar.server.notification.NotificationManager;
-import org.sonar.server.source.SourceService;
import org.sonar.server.user.UserSession;
-import org.sonar.server.user.index.UserDoc;
-import org.sonar.server.user.index.UserIndex;
@ServerSide
@ComputeEngineSide
private final IssueStorage issueStorage;
private final NotificationManager notificationService;
private final UserFinder userFinder;
- private final UserIndex userIndex;
- private final SourceService sourceService;
private final UserSession userSession;
public IssueService(DbClient dbClient, IssueIndex issueIndex,
IssueUpdater issueUpdater,
NotificationManager notificationService,
UserFinder userFinder,
- UserIndex userIndex, SourceService sourceService, UserSession userSession) {
+ UserSession userSession) {
this.dbClient = dbClient;
this.issueIndex = issueIndex;
this.workflow = workflow;
this.issueUpdater = issueUpdater;
this.notificationService = notificationService;
this.userFinder = userFinder;
- this.userIndex = userIndex;
- this.sourceService = sourceService;
this.userSession = userSession;
}
}
}
- public Issue createManualIssue(String componentKey, RuleKey ruleKey, @Nullable Integer line, @Nullable String message, @Nullable String severity) {
- userSession.checkLoggedIn();
-
- DbSession dbSession = dbClient.openSession(false);
- try {
- Optional<ComponentDto> componentOptional = dbClient.componentDao().selectByKey(dbSession, componentKey);
- if (!componentOptional.isPresent()) {
- throw new BadRequestException(String.format("Component with key '%s' not found", componentKey));
- }
- ComponentDto component = componentOptional.get();
- ComponentDto project = dbClient.componentDao().selectOrFailByUuid(dbSession, component.projectUuid());
-
- userSession.checkComponentPermission(UserRole.USER, project.getKey());
- if (!ruleKey.isManual()) {
- throw new IllegalArgumentException("Issues can be created only on rules marked as 'manual': " + ruleKey);
- }
- Optional<RuleDto> rule = getRuleByKey(dbSession, ruleKey);
- if (!rule.isPresent()) {
- throw new IllegalArgumentException("Unknown rule: " + ruleKey);
- }
-
- DefaultIssue issue = new DefaultIssueBuilder()
- .componentKey(component.getKey())
- .type(RuleType.valueOf(rule.get().getType()))
- .projectKey(project.getKey())
- .line(line)
- .message(!Strings.isNullOrEmpty(message) ? message : rule.get().getName())
- .severity(Objects.firstNonNull(severity, Severity.MAJOR))
- .ruleKey(ruleKey)
- .reporter(userSession.getLogin())
- .assignee(findSourceLineUser(dbSession, component.uuid(), line))
- .build();
-
- Date now = new Date();
- issue.setCreationDate(now);
- issue.setUpdateDate(now);
- issueStorage.save(issue);
- return issue;
- } finally {
- dbSession.close();
- }
- }
-
public Issue getByKey(String key) {
return issueIndex.getByKey(key);
}
return issueIndex.countTags(query, pageSize);
}
- @CheckForNull
- private String findSourceLineUser(DbSession dbSession, String fileUuid, @Nullable Integer line) {
- if (line != null) {
- Optional<DbFileSources.Line> sourceLine = sourceService.getLine(dbSession, fileUuid, line);
- if (sourceLine.isPresent() && sourceLine.get().hasScmAuthor()) {
- UserDoc userDoc = userIndex.getNullableByScmAccount(sourceLine.get().getScmAuthor());
- if (userDoc != null) {
- return userDoc.login();
- }
- }
- }
- return null;
- }
}
*/
package org.sonar.server.issue.ws;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
-import org.sonar.server.issue.IssueService;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
public static final String ACTION = "create";
- private final IssueService issueService;
- private final OperationResponseWriter responseWriter;
-
- public CreateAction(IssueService issueService, OperationResponseWriter responseWriter) {
- this.issueService = issueService;
- this.responseWriter = responseWriter;
- }
-
@Override
public void define(WebService.NewController controller) {
WebService.NewAction action = controller.createAction(ACTION)
- .setDescription("Create a manual issue. Requires authentication and Browse permission on project")
+ .setDescription("Deprecated web service to do create a manual issue. Manual issue feature has been removed in 5.5. This web service has no effect.")
.setSince("3.6")
+ .setDeprecatedSince("5.5")
.setHandler(this)
.setPost(true);
@Override
public void handle(Request request, Response response) throws Exception {
- // required parameters
- String componentKey = request.mandatoryParam("component");
- RuleKey ruleKey = RuleKey.parse(request.mandatoryParam("rule"));
-
- Issue issue = issueService.createManualIssue(componentKey, ruleKey,
- request.paramAsInt("line"),
- request.param("message"),
- request.param("severity"));
-
- responseWriter.write(issue.key(), request, response);
+ response.noContent();
}
}
return getLines(dbSession, fileUuid, from, toInclusive, lineToHtml());
}
- /**
- * Returns a single line from a source file. {@code Optional.absent()} is returned if the
- * file or the line do not exist.
- * @param line starts from 1
- */
- public Optional<DbFileSources.Line> getLine(DbSession dbSession, String fileUuid, int line) {
- verifyLine(line);
- FileSourceDto dto = dbClient.fileSourceDao().selectSourceByFileUuid(dbSession, fileUuid);
- if (dto == null) {
- return Optional.absent();
- }
- DbFileSources.Data data = dto.getSourceData();
- return FluentIterable.from(data.getLinesList())
- .filter(new IsGreaterOrEqualThanLine(line))
- .first();
- }
-
private <E> Optional<Iterable<E>> getLines(DbSession dbSession, String fileUuid, int from, int toInclusive, Function<DbFileSources.Line, E> function) {
verifyLine(from);
Preconditions.checkArgument(toInclusive >= from, String.format("Line number must greater than or equal to %d, got %d", from, toInclusive));
return null;
}
- /**
- * Returns the user associated with the given SCM account. If multiple users have the same
- * SCM account, then result is null.
- */
- @CheckForNull
- public UserDoc getNullableByScmAccount(String scmAccount) {
- List<UserDoc> users = getAtMostThreeActiveUsersForScmAccount(scmAccount);
- if (users.size() == 1) {
- return users.get(0);
- }
- return null;
- }
-
public UserDoc getByLogin(String login) {
UserDoc userDoc = getNullableByLogin(login);
if (userDoc == null) {
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
import org.sonar.api.issue.DefaultTransitions;
import org.sonar.api.issue.Issue;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
import org.sonar.api.security.DefaultGroups;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.issue.IssueDao;
import org.sonar.db.issue.IssueDto;
-import org.sonar.db.protobuf.DbFileSources;
import org.sonar.db.rule.RuleDao;
import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleTesting;
-import org.sonar.db.source.FileSourceDao;
-import org.sonar.db.source.FileSourceDto;
-import org.sonar.db.user.GroupDao;
-import org.sonar.db.user.GroupDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.exceptions.BadRequestException;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.issue.index.IssueDoc;
import org.sonar.server.issue.index.IssueIndex;
import org.sonar.server.issue.index.IssueIndexer;
import org.sonar.server.issue.workflow.Transition;
import org.sonar.server.rule.index.RuleIndexer;
import org.sonar.server.tester.ServerTester;
import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.user.NewUser;
-import org.sonar.server.user.UserUpdater;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
assertThat(IssueIndex.getByKey(issue.getKey()).type()).isEqualTo(RuleType.BUG);
}
- @Test
- public void create_manual_issue() {
- ComponentDto project = newProject();
- ComponentDto file = newFile(project);
- userSessionRule.login("john").addProjectPermissions(UserRole.USER, project.key());
-
- RuleDto manualRule = RuleTesting.newManualRule("manualRuleKey");
- tester.get(RuleDao.class).insert(session, manualRule);
- session.commit();
-
- Issue result = service.createManualIssue(file.key(), manualRule.getKey(), null, "Fix it", Severity.MINOR);
-
- IssueDoc manualIssue = IssueIndex.getByKey(result.key());
- assertThat(manualIssue.componentUuid()).isEqualTo(file.uuid());
- assertThat(manualIssue.projectUuid()).isEqualTo(project.uuid());
- assertThat(manualIssue.ruleKey()).isEqualTo(manualRule.getKey());
- assertThat(manualIssue.message()).isEqualTo("Fix it");
- assertThat(manualIssue.line()).isNull();
- assertThat(manualIssue.severity()).isEqualTo(Severity.MINOR);
- }
-
- @Test
- public void create_manual_issue_on_line() {
- ComponentDto project = newProject();
- ComponentDto file = newFile(project);
- newSourceLine(file, 1, "arthur");
- createDefaultGroup();
- newUser("arthur");
- userSessionRule.login("john").addProjectPermissions(UserRole.USER, project.key());
-
- RuleDto manualRule = RuleTesting.newManualRule("manualRuleKey");
- tester.get(RuleDao.class).insert(session, manualRule);
- session.commit();
-
- Issue result = service.createManualIssue(file.key(), manualRule.getKey(), 1, "Fix it", Severity.MINOR);
-
- IssueDoc manualIssue = IssueIndex.getByKey(result.key());
- assertThat(manualIssue.componentUuid()).isEqualTo(file.uuid());
- assertThat(manualIssue.projectUuid()).isEqualTo(project.uuid());
- assertThat(manualIssue.ruleKey()).isEqualTo(manualRule.getKey());
- assertThat(manualIssue.message()).isEqualTo("Fix it");
- assertThat(manualIssue.line()).isEqualTo(1);
- assertThat(manualIssue.severity()).isEqualTo(Severity.MINOR);
- assertThat(manualIssue.gap()).isNull();
- assertThat(manualIssue.assignee()).isEqualTo("arthur");
- }
-
- @Test
- public void create_manual_issue_with_major_severity_when_no_severity() {
- ComponentDto project = newProject();
- ComponentDto file = newFile(project);
- userSessionRule.login("john").addProjectPermissions(UserRole.USER, project.key());
-
- RuleDto manualRule = RuleTesting.newManualRule("manualRuleKey");
- tester.get(RuleDao.class).insert(session, manualRule);
- session.commit();
-
- Issue result = service.createManualIssue(file.key(), manualRule.getKey(), null, "Fix it", null);
-
- Issue manualIssue = IssueIndex.getByKey(result.key());
- assertThat(manualIssue.severity()).isEqualTo(Severity.MAJOR);
- }
-
- @Test
- public void create_manual_issue_with_rule_name_when_no_message() {
- ComponentDto project = newProject();
- ComponentDto file = newFile(project);
- userSessionRule.login("john").addProjectPermissions(UserRole.USER, project.key());
-
- RuleDto manualRule = RuleTesting.newManualRule("manualRuleKey").setName("Manual rule name");
- tester.get(RuleDao.class).insert(session, manualRule);
- session.commit();
-
- Issue result = service.createManualIssue(file.key(), manualRule.getKey(), null, null, null);
-
- Issue manualIssue = IssueIndex.getByKey(result.key());
- assertThat(manualIssue.message()).isEqualTo("Manual rule name");
- }
-
- @Test
- public void create_manual_issue_without_assignee_when_scm_author_do_not_match_user() {
- ComponentDto project = newProject();
- ComponentDto file = newFile(project);
- // Unknown SCM account
- newSourceLine(file, 1, "unknown");
- createDefaultGroup();
- newUser("arthur");
- userSessionRule.login("john").addProjectPermissions(UserRole.USER, project.key());
-
- RuleDto manualRule = RuleTesting.newManualRule("manualRuleKey");
- tester.get(RuleDao.class).insert(session, manualRule);
- session.commit();
-
- Issue result = service.createManualIssue(file.key(), manualRule.getKey(), 1, "Fix it", Severity.MINOR);
-
- IssueDoc manualIssue = IssueIndex.getByKey(result.key());
- assertThat(manualIssue.assignee()).isNull();
- }
-
- @Test
- public void create_manual_issue_without_assignee_when_no_scm_author_on_line() {
- ComponentDto project = newProject();
- ComponentDto file = newFile(project);
- // No author on line 1
- newSourceLine(file, 1, "");
- userSessionRule.login("john").addProjectPermissions(UserRole.USER, project.key());
-
- RuleDto manualRule = RuleTesting.newManualRule("manualRuleKey");
- tester.get(RuleDao.class).insert(session, manualRule);
- session.commit();
-
- Issue result = service.createManualIssue(file.key(), manualRule.getKey(), 1, "Fix it", Severity.MINOR);
-
- IssueDoc manualIssue = IssueIndex.getByKey(result.key());
- assertThat(manualIssue.assignee()).isNull();
- }
-
- @Test
- public void fail_create_manual_issue_on_not_manual_rule() {
- RuleDto rule = newRule();
- ComponentDto project = newProject();
- ComponentDto file = newFile(project);
- userSessionRule.login("john").addProjectPermissions(UserRole.USER, project.key());
-
- try {
- service.createManualIssue(file.key(), rule.getKey(), null, "Fix it", null);
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Issues can be created only on rules marked as 'manual': xoo:x1");
- }
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void fail_create_manual_issue_if_rule_does_not_exist() {
- ComponentDto project = newProject();
- ComponentDto file = newFile(project);
- userSessionRule.login("john").addProjectPermissions(UserRole.USER, project.key());
-
- service.createManualIssue(file.key(), RuleKey.of("rule", "unknown"), 10, "Fix it", null);
- }
-
- @Test(expected = ForbiddenException.class)
- public void fail_create_manual_issue_if_not_having_required_role() {
- RuleDto rule = newRule();
- ComponentDto project = newProject();
- ComponentDto file = newFile(project);
-
- // User has not the 'user' role on the project
- userSessionRule.login("john").addProjectPermissions(UserRole.CODEVIEWER, project.key());
-
- RuleDto manualRule = RuleTesting.newManualRule("manualRuleKey");
- tester.get(RuleDao.class).insert(session, manualRule);
- session.commit();
-
- service.createManualIssue(file.key(), rule.getKey(), 10, "Fix it", null);
- }
-
- @Test(expected = BadRequestException.class)
- public void fail_to_create_manual_issue_on_unknown_component() {
- ComponentDto project = newProject();
- userSessionRule.login("john").addProjectPermissions(UserRole.USER, project.key());
-
- RuleDto manualRule = RuleTesting.newManualRule("manualRuleKey");
- tester.get(RuleDao.class).insert(session, manualRule);
- session.commit();
-
- service.createManualIssue("UNKNOWN", manualRule.getKey(), null, "Fix it", Severity.MINOR);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void fail_create_manual_issue_on_removed_rule() {
- RuleDto rule = newRule(RuleTesting.newXooX1().setStatus(RuleStatus.REMOVED));
- ComponentDto project = newProject();
- ComponentDto file = newFile(project);
- userSessionRule.login("john").addProjectPermissions(UserRole.USER, project.key());
-
- service.createManualIssue(file.key(), rule.getKey(), 10, "Fix it", null);
- }
-
@Test
public void list_tags() {
RuleDto rule = newRule();
return issue;
}
- private void newSourceLine(ComponentDto file, int line, String scmAuthor) {
- DbFileSources.Data.Builder dataBuilder = DbFileSources.Data.newBuilder();
- dataBuilder.addLinesBuilder()
- .setLine(line)
- .setScmAuthor(scmAuthor)
- .build();
- FileSourceDto dto = new FileSourceDto();
- dto.setProjectUuid(file.projectUuid());
- dto.setFileUuid(file.uuid());
- dto.setCreatedAt(System.currentTimeMillis());
- dto.setSourceData(dataBuilder.build());
- dto.setDataType(FileSourceDto.Type.SOURCE);
- tester.get(FileSourceDao.class).insert(dto);
- }
-
- private void newUser(String login) {
- tester.get(UserUpdater.class).create(NewUser.create().setLogin(login).setName(login).setPassword("test"));
- }
-
- private void createDefaultGroup() {
- tester.get(Settings.class).setProperty(CoreProperties.CORE_DEFAULT_GROUP, "sonar-users");
- tester.get(GroupDao.class).insert(session, new GroupDto().setName("sonar-users").setDescription("Sonar Users"));
- session.commit();
- }
}
package org.sonar.server.issue.ws;
import org.junit.Test;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.Response;
-import org.sonar.core.issue.DefaultIssue;
-import org.sonar.server.issue.IssueService;
import org.sonar.server.ws.WsAction;
import org.sonar.server.ws.WsActionTester;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
public class CreateActionTest {
- IssueService issueService = mock(IssueService.class);
- OperationResponseWriter responseWriter = mock(OperationResponseWriter.class);
- WsAction underTest = new CreateAction(issueService, responseWriter);
+ WsAction underTest = new CreateAction();
WsActionTester tester = new WsActionTester(underTest);
@Test
- public void create_manual_issue_with_default_values() throws Exception {
- RuleKey ruleKey = RuleKey.of(RuleKey.MANUAL_REPOSITORY_KEY, "S1");
- when(issueService.createManualIssue("FILE_KEY", ruleKey, null, null, null))
- .thenReturn(new DefaultIssue().setKey("ISSUE_KEY"));
-
+ public void does_nothing() throws Exception {
tester.newRequest()
.setParam("component", "FILE_KEY")
- .setParam("rule", ruleKey.toString())
+ .setParam("rule", "ruleKey")
.execute();
-
- verify(issueService).createManualIssue("FILE_KEY", ruleKey, null, null, null);
- verify(responseWriter).write(eq("ISSUE_KEY"), any(Request.class), any(Response.class));
}
- @Test
- public void create_manual_issue() throws Exception {
- RuleKey ruleKey = RuleKey.of(RuleKey.MANUAL_REPOSITORY_KEY, "S1");
- when(issueService.createManualIssue("FILE_KEY", ruleKey, 13, "the msg", "BLOCKER"))
- .thenReturn(new DefaultIssue().setKey("ISSUE_KEY"));
-
- tester.newRequest()
- .setParam("component", "FILE_KEY")
- .setParam("rule", ruleKey.toString())
- .setParam("severity", "BLOCKER")
- .setParam("line", "13")
- .setParam("message", "the msg")
- .execute();
-
- verify(issueService).createManualIssue("FILE_KEY", ruleKey, 13, "the msg", "BLOCKER");
- verify(responseWriter).write(eq("ISSUE_KEY"), any(Request.class), any(Response.class));
- }
}
assertThat(lines.isPresent()).isFalse();
}
- @Test
- public void getLine() throws Exception {
- Optional<DbFileSources.Line> line = underTest.getLine(dbTester.getSession(), FILE_UUID, 4);
- assertThat(line.isPresent()).isTrue();
- assertThat(line.get().getLine()).isEqualTo(4);
- assertThat(line.get().getSource()).isEqualTo("SOURCE_4");
- }
-
- @Test
- public void getLine_absent_line() throws Exception {
- Optional<DbFileSources.Line> line = underTest.getLine(dbTester.getSession(), FILE_UUID, 500);
- assertThat(line.isPresent()).isFalse();
- }
-
- @Test
- public void getLine_absent_file() throws Exception {
- Optional<DbFileSources.Line> line = underTest.getLine(dbTester.getSession(), "FILE_DOES_NOT_EXIST", 10);
- assertThat(line.isPresent()).isFalse();
- }
}
}
}
- @Test
- public void get_nullable_by_scm_account() throws Exception {
- esTester.putDocuments(UserIndexDefinition.INDEX, UserIndexDefinition.TYPE_USER, this.getClass(), "user1.json", "user2.json");
-
- assertThat(index.getNullableByScmAccount("user_1").login()).isEqualTo("user1");
- assertThat(index.getNullableByScmAccount("user1@mail.com").login()).isEqualTo("user1");
- assertThat(index.getNullableByScmAccount("user1").login()).isEqualTo("user1");
-
- assertThat(index.getNullableByScmAccount("")).isNull();
- assertThat(index.getNullableByScmAccount("unknown")).isNull();
- }
-
- @Test
- public void get_nullable_by_scm_account_return_null_when_two_users_have_same_email() throws Exception {
- esTester.putDocuments(UserIndexDefinition.INDEX, UserIndexDefinition.TYPE_USER, this.getClass(), "user1.json", "user3-with-same-email-as-user1.json");
-
- assertThat(index.getNullableByScmAccount("user1@mail.com")).isNull();
- }
-
@Test
public void getAtMostThreeActiveUsersForScmAccount() throws Exception {
esTester.putDocuments(UserIndexDefinition.INDEX, UserIndexDefinition.TYPE_USER, this.getClass(), "user1.json", "user3-with-same-email-as-user1.json", "inactive-user.json");
"projectName": "SonarQube",
"fav": true,
"canMarkAsFavourite": true,
- "canCreateManualIssue": true,
"measures": {}
}
"projectName": "SonarQube",
"fav": false,
"canMarkAsFavourite": false,
- "canCreateManualIssue": false,
"measures": {"coverage": "85.2%"}
}
"projectName": "SonarQube",
"fav": false,
"canMarkAsFavourite": false,
- "canCreateManualIssue": false,
"measures": {
"lines": "200",
"coverage": "95.4%",
"projectName": "SonarQube",
"fav": false,
"canMarkAsFavourite": false,
- "canCreateManualIssue": false,
"measures": {"coverage": "90.1%"}
}
"projectName": "SonarQube",
"fav": false,
"canMarkAsFavourite": false,
- "canCreateManualIssue": false,
"measures": {"coverage": "95.4%"}
}
optional string debt = 14;
optional string assignee = 15;
- optional string reporter = 16;
+
+ // Unused since 5.5, manual issues feature has been removed
+ optional string unusedReporter = 16;
// SCM login of the committer who introduced the issue
optional string author = 17;