]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7472 Drop ability to create manual issues from WS
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 24 Mar 2016 10:33:44 +0000 (11:33 +0100)
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Tue, 29 Mar 2016 17:10:52 +0000 (19:10 +0200)
17 files changed:
it/it-tests/src/test/java/it/Category2Suite.java
it/it-tests/src/test/java/it/issue/ManualIssueTest.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/component/ws/AppAction.java
server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java
server/sonar-server/src/main/java/org/sonar/server/issue/ws/CreateAction.java
server/sonar-server/src/main/java/org/sonar/server/source/SourceService.java
server/sonar-server/src/main/java/org/sonar/server/user/index/UserIndex.java
server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/ws/CreateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java
server/sonar-server/src/test/java/org/sonar/server/user/index/UserIndexTest.java
server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app.json
server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app_with_it_measure.json
server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app_with_measures.json
server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app_with_overall_measure.json
server/sonar-server/src/test/resources/org/sonar/server/component/ws/AppActionTest/app_with_ut_measure.json
sonar-ws/src/main/protobuf/ws-issues.proto

index bb7f7dead2c48856f0772c9ba6887b136ecd5f46..23087b451c80f49c10ea309e4bb3ff3f3b414cc3 100644 (file)
@@ -33,7 +33,6 @@ import it.issue.IssueSearchTest;
 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;
@@ -73,7 +72,6 @@ import static util.ItUtils.xooPlugin;
   IssueTrackingTest.class,
   IssueWorkflowTest.class,
   ManualIssueRelocationTest.class,
-  ManualIssueTest.class,
   NewIssuesMeasureTest.class,
   // rule
   ManualRulesTest.class,
diff --git a/it/it-tests/src/test/java/it/issue/ManualIssueTest.java b/it/it-tests/src/test/java/it/issue/ManualIssueTest.java
deleted file mode 100644 (file)
index 2539737..0000000
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * 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);
-  }
-}
index 09e9169ca3d89dce251e1c40b0b77d8f6cc6af5a..7158081180539f6dd6f705632db2ecfd6052695d 100644 (file)
@@ -150,7 +150,6 @@ public class AppAction implements RequestHandler {
   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) {
index 190af4ebc680be19b9d53f67e15695b254c97881..e8f36a9e0166af64ddf9ef0ea64b5c8233e8433b 100644 (file)
@@ -19,7 +19,6 @@
  */
 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;
@@ -28,13 +27,11 @@ import java.util.Collections;
 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;
@@ -42,13 +39,11 @@ import org.sonar.api.user.User;
 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;
@@ -56,10 +51,7 @@ import org.sonar.server.issue.notification.IssueChangeNotification;
 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
@@ -73,8 +65,6 @@ public class IssueService {
   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,
@@ -83,7 +73,7 @@ public class IssueService {
     IssueUpdater issueUpdater,
     NotificationManager notificationService,
     UserFinder userFinder,
-    UserIndex userIndex, SourceService sourceService, UserSession userSession) {
+    UserSession userSession) {
     this.dbClient = dbClient;
     this.issueIndex = issueIndex;
     this.workflow = workflow;
@@ -91,8 +81,6 @@ public class IssueService {
     this.issueUpdater = issueUpdater;
     this.notificationService = notificationService;
     this.userFinder = userFinder;
-    this.userIndex = userIndex;
-    this.sourceService = sourceService;
     this.userSession = userSession;
   }
 
@@ -218,49 +206,6 @@ public class IssueService {
     }
   }
 
-  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);
   }
@@ -335,17 +280,4 @@ public class IssueService {
     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;
-  }
 }
index fb3bf745ddc565b63987aa490bdeabfeadad7ce4..a54b2628fd608a80c0fb7dafaa11fd14b7302bea 100644 (file)
  */
 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;
 
@@ -33,19 +30,12 @@ public class CreateAction implements IssuesWsAction {
 
   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);
 
@@ -72,15 +62,6 @@ public class CreateAction implements IssuesWsAction {
 
   @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();
   }
 }
index 0d9034461a45e5610e1dc824a4bf7efcdf474bd6..57689404bc4198409dc7b38f3844f8988b6a2c23 100644 (file)
@@ -62,23 +62,6 @@ public class SourceService {
     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));
index ab5d886f254310e6d899b8839326e5695315a7c7..fafc0648833a78550662eacc159c1125810fc90d 100644 (file)
@@ -85,19 +85,6 @@ public class UserIndex {
     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) {
index d8009ea2ac8ee25d3a51ee237859510055663bc8..5a6d8846cda802f556420bc66f5b1c0aa3489896 100644 (file)
@@ -28,12 +28,8 @@ import org.junit.Before;
 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;
@@ -46,18 +42,11 @@ import org.sonar.db.component.ComponentDto;
 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;
@@ -66,8 +55,6 @@ import org.sonar.server.permission.PermissionUpdater;
 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;
@@ -241,185 +228,6 @@ public class IssueServiceMediumTest {
     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();
@@ -549,28 +357,4 @@ public class IssueServiceMediumTest {
     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();
-  }
 }
index ca317cfa73bfb3224f20daa5a873ceadb991faf4..cfccf1c9e5412b7c21655111dabd3e495369596e 100644 (file)
 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));
-  }
 }
index b05daf018fc023e44a1a5de7412fd4eba1bab63c..05c735089273dda798feaf21887ae243ed9ee192 100644 (file)
@@ -119,23 +119,4 @@ public class SourceServiceTest {
     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();
-  }
 }
index b0e58b69a891530ce67727ece2da4eb542c5a4b9..cc5bce8e65c7c2e712ed997e5bca09f9018180ca 100644 (file)
@@ -94,25 +94,6 @@ public class UserIndexTest {
     }
   }
 
-  @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");
index 201fc70537f699cb81fff8073bae337411e65598..43319c9e2a3ebdb21e19d0653b674d9102840b07 100644 (file)
@@ -11,6 +11,5 @@
   "projectName": "SonarQube",
   "fav": true,
   "canMarkAsFavourite": true,
-  "canCreateManualIssue": true,
   "measures": {}
 }
index 0b233ce08e20f3c80e970d9ad0a5ea297e60bd38..56210aad5400ad8b0967d131a5b611e85350d439 100644 (file)
@@ -11,6 +11,5 @@
   "projectName": "SonarQube",
   "fav": false,
   "canMarkAsFavourite": false,
-  "canCreateManualIssue": false,
   "measures": {"coverage": "85.2%"}
 }
index 606f6594f53d4fb62f2a44f58b5c53df4c7f098d..66d5394790a73c852142e2b375285baddb1cc04f 100644 (file)
@@ -11,7 +11,6 @@
   "projectName": "SonarQube",
   "fav": false,
   "canMarkAsFavourite": false,
-  "canCreateManualIssue": false,
   "measures": {
     "lines": "200",
     "coverage": "95.4%",
index 7cc5aedb715a2359ccbbe6edf342aca76d65b73d..ec96dd5d243e5f971a290cd7b2922c1c4e62cd9d 100644 (file)
@@ -11,6 +11,5 @@
   "projectName": "SonarQube",
   "fav": false,
   "canMarkAsFavourite": false,
-  "canCreateManualIssue": false,
   "measures": {"coverage": "90.1%"}
 }
index c6ef590ad5d3b36993f5a735731a0d5f8aafe3e4..ff6d928222640b174cdce9cb7518f85aa1016589 100644 (file)
@@ -11,6 +11,5 @@
   "projectName": "SonarQube",
   "fav": false,
   "canMarkAsFavourite": false,
-  "canCreateManualIssue": false,
   "measures": {"coverage": "95.4%"}
 }
index a253c424402fff7b367e415201c789e726db1621..c5c76bcad78ea524e9047196e48a1cd5c2d475aa 100644 (file)
@@ -79,7 +79,9 @@ message Issue {
   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;