aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/batch/UploadReportAction.java15
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueDoc.java10
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java11
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueNormalizer.java11
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java24
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/search/ws/SearchRequestHandler.java15
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/batch/UploadReportActionMediumTest.java5
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java1
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java47
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java (renamed from server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssuesWsMediumTest.java)132
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssuesWsMediumTest/empty_result.json7
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssuesWsMediumTest/single_result.json57
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/default_page_size_is_100.json13
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/empty_result.json16
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/paging.json13
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/single_result.json63
-rw-r--r--sonar-core/src/main/java/org/sonar/core/issue/db/IssueDto.java17
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml1
-rw-r--r--sonar-core/src/test/java/org/sonar/core/issue/db/IssueDtoTest.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssue.java16
21 files changed, 298 insertions, 180 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/UploadReportAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/UploadReportAction.java
index 547accceb03..f8c670f0733 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/batch/UploadReportAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/batch/UploadReportAction.java
@@ -41,7 +41,6 @@ public class UploadReportAction implements RequestHandler {
public static final String UPLOAD_REPORT_ACTION = "upload_report";
static final String PARAM_PROJECT = "project";
- static final String PARAM_FIRST_ANALYSIS = "firstAnalysis";
private final DbClient dbClient;
private final IndexClient index;
@@ -68,12 +67,6 @@ public class UploadReportAction implements RequestHandler {
.setRequired(true)
.setDescription("Project key")
.setExampleValue("org.codehaus.sonar:sonar");
-
- action
- .createParam(PARAM_FIRST_ANALYSIS)
- .setDescription("Is it the first analysis of this project ?")
- .setDefaultValue(false)
- .setBooleanPossibleValues();
}
@Override
@@ -88,11 +81,9 @@ public class UploadReportAction implements RequestHandler {
AuthorizedComponentDto project = dbClient.componentDao().getAuthorizedComponentByKey(projectKey, session);
// Synchronize project permission indexes
- boolean isFirstAnalysis = request.mandatoryParamAsBoolean(PARAM_FIRST_ANALYSIS);
- if (isFirstAnalysis) {
- permissionService.synchronizePermissions(session, project.key());
- session.commit();
- }
+ // TODO only update permission if no permission for a project
+ permissionService.synchronizePermissions(session, project.key());
+ session.commit();
// Index project's issues
dbClient.issueDao().synchronizeAfter(session,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueDoc.java b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueDoc.java
index c0552d9c752..f025ccbd874 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueDoc.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueDoc.java
@@ -27,6 +27,7 @@ import org.sonar.server.search.BaseDoc;
import org.sonar.server.search.IndexUtils;
import javax.annotation.CheckForNull;
+
import java.util.Collections;
import java.util.Date;
import java.util.List;
@@ -50,9 +51,12 @@ public class IssueDoc extends BaseDoc implements Issue {
@Override
public RuleKey ruleKey() {
- return RuleKey.of(
- (String) getField(IssueNormalizer.IssueField.REPOSITORY.field()),
- (String) getField(IssueNormalizer.IssueField.RULE.field()));
+ return RuleKey.parse((String) getField(IssueNormalizer.IssueField.RULE_KEY.field()));
+ }
+
+ @Override
+ public String language() {
+ return getField(IssueNormalizer.IssueField.LANGUAGE.field());
}
@Override
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
index f5b67dfca6d..7825074a811 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
@@ -35,6 +35,8 @@ import org.sonar.api.web.UserRole;
import org.sonar.core.issue.db.IssueDto;
import org.sonar.server.search.*;
+import javax.annotation.Nullable;
+
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
@@ -172,16 +174,15 @@ public class IssueIndex extends BaseIndex<Issue, IssueDto, String> {
}
// Field Filters
+ matchFilter(esFilter, IssueNormalizer.IssueField.KEY, query.issueKeys());
matchFilter(esFilter, IssueNormalizer.IssueField.ACTION_PLAN, query.actionPlans());
matchFilter(esFilter, IssueNormalizer.IssueField.ASSIGNEE, query.assignees());
matchFilter(esFilter, IssueNormalizer.IssueField.PROJECT, query.componentRoots());
matchFilter(esFilter, IssueNormalizer.IssueField.COMPONENT, query.components());
- matchFilter(esFilter, IssueNormalizer.IssueField.KEY, query.issueKeys());
- // TODO need to either materialize the language or join with rule
- // query.languages(esFilter, IssueNormalizer.IssueField.L, query.issueKeys());
+ matchFilter(esFilter, IssueNormalizer.IssueField.LANGUAGE, query.languages());
matchFilter(esFilter, IssueNormalizer.IssueField.RESOLUTION, query.resolutions());
matchFilter(esFilter, IssueNormalizer.IssueField.REPORTER, query.reporters());
- matchFilter(esFilter, IssueNormalizer.IssueField.RULE, query.rules());
+ matchFilter(esFilter, IssueNormalizer.IssueField.RULE_KEY, query.rules());
matchFilter(esFilter, IssueNormalizer.IssueField.SEVERITY, query.severities());
matchFilter(esFilter, IssueNormalizer.IssueField.STATUS, query.statuses());
@@ -227,7 +228,7 @@ public class IssueIndex extends BaseIndex<Issue, IssueDto, String> {
return new Result<Issue>(this, response);
}
- private void matchFilter(BoolFilterBuilder filter, IndexField field, Collection<?> values) {
+ private void matchFilter(BoolFilterBuilder filter, IndexField field, @Nullable Collection<?> values) {
if (values != null && !values.isEmpty()) {
filter.must(FilterBuilders.termsFilter(field.field(), values));
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueNormalizer.java b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueNormalizer.java
index 4fc6977e070..ba91903c0e9 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueNormalizer.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueNormalizer.java
@@ -60,9 +60,8 @@ public class IssueNormalizer extends BaseNormalizer<IssueDto, String> {
public static final IndexField REPORTER = add(IndexField.Type.STRING, "reporter");
public static final IndexField STATUS = add(IndexField.Type.STRING, "status");
public static final IndexField SEVERITY = add(IndexField.Type.STRING, "severity");
-
- public static final IndexField RULE = addSearchable(IndexField.Type.STRING, "rule");
- public static final IndexField REPOSITORY = addSearchable(IndexField.Type.STRING, "repository");
+ public static final IndexField LANGUAGE = add(IndexField.Type.STRING, "language");
+ public static final IndexField RULE_KEY = addSearchable(IndexField.Type.STRING, "ruleKey");
public static final Set<IndexField> ALL_FIELDS = getAllFields();
@@ -115,10 +114,8 @@ public class IssueNormalizer extends BaseNormalizer<IssueDto, String> {
update.put(IssueField.STATUS.field(), dto.getStatus());
update.put(IssueField.SEVERITY.field(), dto.getSeverity());
update.put(IssueField.DEBT.field(), dto.getDebt());
-
- // issueDoc.ruleKey();
- update.put(IssueField.RULE.field(), dto.getRule());
- update.put(IssueField.REPOSITORY.field(), dto.getRuleRepo());
+ update.put(IssueField.LANGUAGE.field(), dto.getLanguage());
+ update.put(IssueField.RULE_KEY.field(), dto.getRuleKey().toString());
// TODO Not yet normalized
// IssueDoc issueDoc = new IssueDoc(null);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java
index 30fd11a0cc2..56c07d46e87 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java
@@ -167,19 +167,12 @@ public class SearchAction extends SearchRequestHandler<IssueQuery, Issue> {
action.createParam(IssueFilterParameters.CREATED_BEFORE)
.setDescription("To retrieve issues created before the given date (exclusive). Format: date or datetime ISO formats")
.setExampleValue("2013-05-01 (or 2013-05-01T13:00:00+0100)");
- action.createParam(IssueFilterParameters.PAGE_SIZE)
- .setDescription("Maximum number of results per page. " +
- "Default value: 100 (except when the 'components' parameter is set, value is set to \"-1\" in this case). " +
- "If set to \"-1\", the max possible value is used")
- .setExampleValue("50");
- action.createParam(IssueFilterParameters.PAGE_INDEX)
- .setDescription("Index of the selected page")
- .setDefaultValue("1")
- .setExampleValue("2");
- action.createParam(IssueFilterParameters.SORT)
+ action.createParam(SearchRequestHandler.PARAM_SORT)
.setDescription("Sort field")
+ .setDeprecatedKey(IssueFilterParameters.SORT)
.setPossibleValues(IssueQuery.SORTS);
- action.createParam(IssueFilterParameters.ASC)
+ action.createParam(SearchRequestHandler.PARAM_ASCENDING)
+ .setDeprecatedKey(IssueFilterParameters.ASC)
.setDescription("Ascending sort")
.setBooleanPossibleValues();
action.createParam("format")
@@ -207,19 +200,18 @@ public class SearchAction extends SearchRequestHandler<IssueQuery, Issue> {
.hideRules(request.paramAsBoolean(IssueFilterParameters.HIDE_RULES))
.createdAt(request.paramAsDateTime(IssueFilterParameters.CREATED_AT))
.createdAfter(request.paramAsDateTime(IssueFilterParameters.CREATED_AFTER))
- .createdBefore(request.paramAsDateTime(IssueFilterParameters.CREATED_BEFORE))
- .pageSize(request.paramAsInt(IssueFilterParameters.PAGE_SIZE))
- .pageIndex(request.paramAsInt(IssueFilterParameters.PAGE_INDEX));
- String sort = request.param(IssueFilterParameters.SORT);
+ .createdBefore(request.paramAsDateTime(IssueFilterParameters.CREATED_BEFORE));
+ String sort = request.param(SearchRequestHandler.PARAM_SORT);
if (!Strings.isNullOrEmpty(sort)) {
builder.sort(sort);
- builder.asc(request.paramAsBoolean(IssueFilterParameters.ASC));
+ builder.asc(request.paramAsBoolean(SearchRequestHandler.PARAM_ASCENDING));
}
return builder.build();
}
@Override
protected Result<Issue> doSearch(IssueQuery query, QueryContext context) {
+ // Set limit to context ?
return ((DefaultIssueService)service).search(query, context);
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/search/ws/SearchRequestHandler.java b/server/sonar-server/src/main/java/org/sonar/server/search/ws/SearchRequestHandler.java
index 0379aedf1b1..4ccc0d56aca 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/search/ws/SearchRequestHandler.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/search/ws/SearchRequestHandler.java
@@ -29,6 +29,7 @@ import org.sonar.server.search.QueryContext;
import org.sonar.server.search.Result;
import javax.annotation.CheckForNull;
+
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -44,8 +45,6 @@ public abstract class SearchRequestHandler<QUERY, DOMAIN> implements RequestHand
public static final String PARAM_FACETS = "facets";
- private int pageSize;
- private int page;
private List<String> fields;
private final String actionName;
@@ -79,15 +78,17 @@ public abstract class SearchRequestHandler<QUERY, DOMAIN> implements RequestHand
action
.createParam(PARAM_PAGE)
+ .setDeprecatedKey("pageIndex")
.setDescription("1-based page number")
.setExampleValue("42")
.setDefaultValue("1");
action
.createParam(PARAM_PAGE_SIZE)
+ .setDeprecatedKey("pageSize")
.setDescription("Page size. Must be greater than 0.")
.setExampleValue("20")
- .setDefaultValue(String.valueOf(QueryContext.DEFAULT_LIMIT));
+ .setDefaultValue("100");
action.createParam(PARAM_FACETS)
.setDescription("Compute predefined facets")
@@ -114,7 +115,7 @@ public abstract class SearchRequestHandler<QUERY, DOMAIN> implements RequestHand
Result<DOMAIN> result = doSearch(query, context);
JsonWriter json = response.newJsonWriter().beginObject();
- this.writeStatistics(json, result);
+ this.writeStatistics(json, result, context);
doResultResponse(request, context, result, json);
doContextResponse(request, context, result, json);
if (context.isFacet()) {
@@ -130,10 +131,10 @@ public abstract class SearchRequestHandler<QUERY, DOMAIN> implements RequestHand
request.mandatoryParamAsInt(PARAM_PAGE_SIZE));
}
- protected void writeStatistics(JsonWriter json, Result searchResult) {
+ protected void writeStatistics(JsonWriter json, Result searchResult, QueryContext context) {
json.prop("total", searchResult.getTotal());
- json.prop(PARAM_PAGE, page);
- json.prop(PARAM_PAGE_SIZE, pageSize);
+ json.prop(PARAM_PAGE, context.getPage());
+ json.prop(PARAM_PAGE_SIZE, context.getLimit());
}
protected void writeFacets(Result<?> results, JsonWriter json) {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/UploadReportActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/UploadReportActionMediumTest.java
index 2f2fb36c024..73d2a074597 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/batch/UploadReportActionMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/batch/UploadReportActionMediumTest.java
@@ -86,11 +86,11 @@ public class UploadReportActionMediumTest {
public void define() throws Exception {
WebService.Action restoreProfiles = controller.action(UploadReportAction.UPLOAD_REPORT_ACTION);
assertThat(restoreProfiles).isNotNull();
- assertThat(restoreProfiles.params()).hasSize(2);
+ assertThat(restoreProfiles.params()).hasSize(1);
}
@Test
- public void add_project_issue_permission_index_on_first_analysis() throws Exception {
+ public void add_project_issue_permission_index() throws Exception {
ComponentDto project = new ComponentDto()
.setId(1L)
.setKey("MyProject")
@@ -107,7 +107,6 @@ public class UploadReportActionMediumTest {
MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
WsTester.TestRequest request = wsTester.newGetRequest(BatchWs.API_ENDPOINT, UploadReportAction.UPLOAD_REPORT_ACTION);
request.setParam(UploadReportAction.PARAM_PROJECT, project.key());
- request.setParam(UploadReportAction.PARAM_FIRST_ANALYSIS, "true");
request.execute();
// Check that issue authorization index has been created
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java
index 5034e196290..962af1149af 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java
@@ -66,6 +66,7 @@ public class IssueDaoTest extends AbstractDaoTestCase {
assertThat(issue.getComponentId()).isEqualTo(401);
assertThat(issue.getRootComponentId()).isEqualTo(399);
assertThat(issue.getRuleId()).isEqualTo(500);
+ assertThat(issue.getLanguage()).isEqualTo("java");
assertThat(issue.getSeverity()).isEqualTo("BLOCKER");
assertThat(issue.isManualSeverity()).isFalse();
assertThat(issue.getMessage()).isNull();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java
index 8312ebf1c98..7e3261f7b62 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java
@@ -20,12 +20,10 @@
package org.sonar.server.issue.index;
import com.google.common.collect.ImmutableList;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
+import org.junit.*;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.IssueQuery;
+import org.sonar.api.rule.RuleKey;
import org.sonar.api.security.DefaultGroups;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.web.UserRole;
@@ -148,6 +146,26 @@ public class IssueIndexMediumTest {
}
@Test
+ public void filter_by_rule() throws Exception {
+ db.issueDao().insert(session, createIssue().setRule(rule));
+
+ tester.get(RuleDao.class).insert(session, RuleTesting.newDto(RuleKey.of("rule", "without issue")));
+ session.commit();
+
+ assertThat(index.search(IssueQuery.builder().rules(newArrayList(rule.getKey())).build(), new QueryContext()).getHits()).hasSize(1);
+ assertThat(index.search(IssueQuery.builder().rules(newArrayList(RuleKey.of("rule", "without issue"))).build(), new QueryContext()).getHits()).isEmpty();
+ }
+
+ @Test
+ public void filter_by_language() throws Exception {
+ db.issueDao().insert(session, createIssue().setRule(rule));
+ session.commit();
+
+ assertThat(index.search(IssueQuery.builder().languages(newArrayList(rule.getLanguage())).build(), new QueryContext()).getHits()).hasSize(1);
+ assertThat(index.search(IssueQuery.builder().languages(newArrayList("unknown")).build(), new QueryContext()).getHits()).isEmpty();
+ }
+
+ @Test
public void is_assigned_filter() throws Exception {
String assignee = "steph";
IssueDto issue1 = createIssue()
@@ -237,6 +255,27 @@ public class IssueIndexMediumTest {
}
@Test
+ @Ignore("TODO")
+ public void sort_by_assignee() throws Exception {
+ IssueDto issue1 = createIssue().setAssignee("steph");
+ IssueDto issue2 = createIssue().setAssignee("simon");
+ db.issueDao().insert(session, issue1, issue2);
+ session.commit();
+
+ IssueQuery.Builder query = IssueQuery.builder().sort(IssueQuery.SORT_BY_ASSIGNEE).asc(true);
+ Result<Issue> result = index.search(query.build(), new QueryContext());
+ assertThat(result.getHits()).hasSize(2);
+ assertThat(result.getHits().get(0).assignee()).isEqualTo("simon");
+ assertThat(result.getHits().get(1).assignee()).isEqualTo("steph");
+
+ query = IssueQuery.builder().sort(IssueQuery.SORT_BY_ASSIGNEE).asc(false);
+ result = index.search(query.build(), new QueryContext());
+ assertThat(result.getHits()).hasSize(2);
+ assertThat(result.getHits().get(0).assignee()).isEqualTo("steph");
+ assertThat(result.getHits().get(1).assignee()).isEqualTo("simon");
+ }
+
+ @Test
public void authorized_issues_on_groups() throws Exception {
ComponentDto project1 = new ComponentDto()
.setId(10L)
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssuesWsMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java
index fb8d9428188..5183b725c80 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/IssuesWsMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java
@@ -17,6 +17,7 @@
* 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.ws;
import org.junit.After;
@@ -24,17 +25,18 @@ import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.sonar.api.security.DefaultGroups;
-import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.web.UserRole;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.issue.db.IssueDto;
-import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.permission.PermissionFacade;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.rule.RuleDto;
import org.sonar.server.component.SnapshotTesting;
import org.sonar.server.db.DbClient;
+import org.sonar.server.issue.IssueTesting;
+import org.sonar.server.issue.db.IssueDao;
+import org.sonar.server.issue.filter.IssueFilterParameters;
import org.sonar.server.rule.RuleTesting;
import org.sonar.server.rule.db.RuleDao;
import org.sonar.server.tester.ServerTester;
@@ -45,7 +47,7 @@ import java.util.Date;
import static org.fest.assertions.Assertions.assertThat;
-public class IssuesWsMediumTest {
+public class SearchActionMediumTest {
@ClassRule
public static ServerTester tester = new ServerTester()
@@ -56,6 +58,10 @@ public class IssuesWsMediumTest {
DbSession session;
WsTester wsTester;
+ RuleDto rule;
+ ComponentDto project;
+ ComponentDto file;
+
@Before
public void setUp() throws Exception {
tester.clearDbAndIndexes();
@@ -63,7 +69,31 @@ public class IssuesWsMediumTest {
ws = tester.get(IssuesWs.class);
wsTester = tester.get(WsTester.class);
session = db.openSession(false);
- MockUserSession.set().setLogin("gandalf").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
+
+ rule = RuleTesting.newXooX1();
+ tester.get(RuleDao.class).insert(session, rule);
+
+ project = new ComponentDto()
+ .setId(1L)
+ .setKey("MyProject")
+ .setProjectId(1L);
+ db.componentDao().insert(session, project);
+ db.snapshotDao().insert(session, SnapshotTesting.createForComponent(project));
+
+ // project can be seen by anyone
+ tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), DefaultGroups.ANYONE, UserRole.USER, session);
+ db.issueAuthorizationDao().synchronizeAfter(session, new Date(0));
+
+ file = new ComponentDto()
+ .setProjectId(1L)
+ .setKey("MyComponent")
+ .setId(2L);
+ db.componentDao().insert(session, file);
+ db.snapshotDao().insert(session, SnapshotTesting.createForComponent(file));
+
+ session.commit();
+
+ MockUserSession.set().setLogin("gandalf");
}
@After
@@ -72,30 +102,7 @@ public class IssuesWsMediumTest {
}
@Test
- public void define() throws Exception {
- WebService.Controller controller = wsTester.controller(IssuesWs.API_ENDPOINT);
-
- assertThat(controller).isNotNull();
- assertThat(controller.actions()).hasSize(14);
- assertThat(controller.action(IssuesWs.ADD_COMMENT_ACTION)).isNotNull();
- assertThat(controller.action(IssuesWs.ASSIGN_ACTION)).isNotNull();
- assertThat(controller.action(IssuesWs.BULK_CHANGE_ACTION)).isNotNull();
- assertThat(controller.action(IssuesWs.CHANGELOG_ACTION)).isNotNull();
- assertThat(controller.action(IssuesWs.CREATE_ACTION)).isNotNull();
- assertThat(controller.action(IssuesWs.DELETE_COMMENT_ACTION)).isNotNull();
- assertThat(controller.action(IssuesWs.DO_ACTION_ACTION)).isNotNull();
- assertThat(controller.action(IssuesWs.DO_TRANSITION_ACTION)).isNotNull();
- assertThat(controller.action(IssuesWs.EDIT_COMMENT_ACTION)).isNotNull();
- assertThat(controller.action(IssuesWs.PLAN_ACTION)).isNotNull();
- assertThat(controller.action(IssuesWs.SET_SEVERITY_ACTION)).isNotNull();
- assertThat(controller.action(IssuesWs.TRANSITIONS_ACTION)).isNotNull();
-
- assertThat(controller.action(SearchAction.SEARCH_ACTION)).isNotNull();
- }
-
- @Test
public void empty_search() throws Exception {
-
WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION);
WsTester.Result result = request.execute();
@@ -105,48 +112,65 @@ public class IssuesWsMediumTest {
@Test
public void find_single_result() throws Exception {
-
- RuleDto rule = RuleTesting.newXooX1();
- tester.get(RuleDao.class).insert(session, rule);
-
- ComponentDto project = new ComponentDto()
- .setId(1L)
- .setKey("MyProject")
- .setProjectId(1L);
- db.componentDao().insert(session, project);
- db.snapshotDao().insert(session, SnapshotTesting.createForComponent(project));
-
- // project can be seen by anyone
- tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), DefaultGroups.ANYONE, UserRole.USER, session);
- db.issueAuthorizationDao().synchronizeAfter(session, new Date(0));
-
- ComponentDto resource = new ComponentDto()
- .setProjectId(1L)
- .setKey("MyComponent")
- .setId(2L);
- db.componentDao().insert(session, resource);
- db.snapshotDao().insert(session, SnapshotTesting.createForComponent(resource));
-
- IssueDto issue = new IssueDto()
+ IssueDto issue = IssueTesting.newDto(rule, file, project)
.setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
.setIssueUpdateDate(DateUtils.parseDate("2014-12-04"))
.setRule(rule)
.setDebt(10L)
.setRootComponent(project)
- .setComponent(resource)
+ .setComponent(file)
.setStatus("OPEN").setResolution("OPEN")
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
.setSeverity("MAJOR");
db.issueDao().insert(session, issue);
-
session.commit();
WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION);
request.setParam(SearchAction.PARAM_FACETS, "true");
- WsTester.Result result = request.execute();
- assertThat(result).isNotNull();
+ WsTester.Result result = request.execute();
// TODO Date assertion is complex du to System2
result.assertJson(this.getClass(), "single_result.json", false);
}
+
+ @Test
+ public void paging() throws Exception {
+ for (int i=0; i<12; i++) {
+ IssueDto issue = IssueTesting.newDto(rule, file, project);
+ tester.get(IssueDao.class).insert(session, issue);
+ }
+ session.commit();
+
+ WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION);
+ request.setParam(SearchAction.PARAM_PAGE, "2");
+ request.setParam(SearchAction.PARAM_PAGE_SIZE, "9");
+
+ WsTester.Result result = request.execute();
+ result.assertJson(this.getClass(), "paging.json", false);
+ }
+
+ @Test
+ public void paging_with_deprecated_params() throws Exception {
+ for (int i=0; i<12; i++) {
+ IssueDto issue = IssueTesting.newDto(rule, file, project);
+ tester.get(IssueDao.class).insert(session, issue);
+ }
+ session.commit();
+
+ WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION);
+ request.setParam(IssueFilterParameters.PAGE_INDEX, "2");
+ request.setParam(IssueFilterParameters.PAGE_SIZE, "9");
+
+ WsTester.Result result = request.execute();
+ result.assertJson(this.getClass(), "paging.json", false);
+ }
+
+ @Test
+ public void default_page_size_is_100() throws Exception {
+ WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION);
+
+ WsTester.Result result = request.execute();
+ result.assertJson(this.getClass(), "default_page_size_is_100.json", false);
+ }
+
}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssuesWsMediumTest/empty_result.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssuesWsMediumTest/empty_result.json
deleted file mode 100644
index 60269eb00c9..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssuesWsMediumTest/empty_result.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{"maxResultsReached": false, "paging": {
- "pageIndex": 1,
- "pageSize": 10,
- "total": 0,
- "fTotal": "0",
- "pages": 0
-}, "issues": [], "components": [], "projects": []}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssuesWsMediumTest/single_result.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssuesWsMediumTest/single_result.json
deleted file mode 100644
index 4fa5dc29b8a..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/IssuesWsMediumTest/single_result.json
+++ /dev/null
@@ -1,57 +0,0 @@
-{"maxResultsReached": false, "paging": {
- "pageIndex": 1,
- "pageSize": 10,
- "total": 1,
- "fTotal": "1",
- "pages": 1
-}, "issues": [
- {
- "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
- "component": "MyComponent",
- "project": "MyProject",
- "rule": "xoo:x1",
- "status": "OPEN",
- "resolution": "OPEN",
- "severity": "MAJOR",
- "debt": "10min",
- "fUpdateAge": "less than a minute"
- }
-], "components": [
- {
- "key": "MyComponent",
- "id": 2
- }
-], "projects": [
- {
- "key": "MyProject",
- "id": 1
- }
-], "facets": [
- {
- "property": "status",
- "values": [
- {
- "val": "OPEN",
- "count": 1
- }
- ]
- },
- {
- "property": "severity",
- "values": [
- {
- "val": "MAJOR",
- "count": 1
- }
- ]
- },
- {
- "property": "resolution",
- "values": [
- {
- "val": "OPEN",
- "count": 1
- }
- ]
- }
-]}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/default_page_size_is_100.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/default_page_size_is_100.json
new file mode 100644
index 00000000000..0fc07a00b50
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/default_page_size_is_100.json
@@ -0,0 +1,13 @@
+{
+ "total": 0,
+ "p": 1,
+ "ps": 100,
+ "maxResultsReached": false,
+ "paging": {
+ "pageIndex": 1,
+ "pageSize": 100,
+ "total": 0,
+ "fTotal": "0",
+ "pages": 0
+ }
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/empty_result.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/empty_result.json
new file mode 100644
index 00000000000..4d91f3e640f
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/empty_result.json
@@ -0,0 +1,16 @@
+{
+ "total": 0,
+ "p": 1,
+ "ps": 100,
+ "maxResultsReached": false,
+ "paging": {
+ "pageIndex": 1,
+ "pageSize": 100,
+ "total": 0,
+ "fTotal": "0",
+ "pages": 0
+ },
+ "issues": [],
+ "components": [],
+ "projects": []
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/paging.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/paging.json
new file mode 100644
index 00000000000..ec4dd63a356
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/paging.json
@@ -0,0 +1,13 @@
+{
+ "total": 12,
+ "p": 2,
+ "ps": 9,
+ "maxResultsReached": false,
+ "paging": {
+ "pageIndex": 2,
+ "pageSize": 9,
+ "total": 12,
+ "fTotal": "12",
+ "pages": 2
+ }
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/single_result.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/single_result.json
new file mode 100644
index 00000000000..28202fd070f
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/single_result.json
@@ -0,0 +1,63 @@
+{
+ "maxResultsReached": false,
+ "paging": {
+ "pageIndex": 1,
+ "pageSize": 100,
+ "total": 1,
+ "fTotal": "1",
+ "pages": 1
+ },
+ "issues": [
+ {
+ "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
+ "component": "MyComponent",
+ "project": "MyProject",
+ "rule": "xoo:x1",
+ "status": "OPEN",
+ "resolution": "OPEN",
+ "severity": "MAJOR",
+ "debt": "10min",
+ "fUpdateAge": "less than a minute"
+ }
+ ],
+ "components": [
+ {
+ "key": "MyComponent",
+ "id": 2
+ }
+ ],
+ "projects": [
+ {
+ "key": "MyProject",
+ "id": 1
+ }
+ ],
+ "facets": [
+ {
+ "property": "status",
+ "values": [
+ {
+ "val": "OPEN",
+ "count": 1
+ }
+ ]
+ },
+ {
+ "property": "severity",
+ "values": [
+ {
+ "val": "MAJOR",
+ "count": 1
+ }
+ ]
+ },
+ {
+ "property": "resolution",
+ "values": [
+ {
+ "val": "OPEN",
+ "count": 1
+ }
+ ]
+ }
+ ]}
diff --git a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDto.java b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDto.java
index fa67f6872a9..15092940d68 100644
--- a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDto.java
+++ b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDto.java
@@ -78,6 +78,7 @@ public final class IssueDto extends Dto<String> implements Serializable {
// joins
private String ruleKey;
private String ruleRepo;
+ private String language;
private String componentKey;
private String rootComponentKey;
@@ -153,6 +154,7 @@ public final class IssueDto extends Dto<String> implements Serializable {
this.ruleId = rule.getId();
this.ruleKey = rule.getRuleKey();
this.ruleRepo = rule.getRepositoryKey();
+ this.language = rule.getLanguage();
return this;
}
@@ -353,6 +355,10 @@ public final class IssueDto extends Dto<String> implements Serializable {
return RuleKey.of(ruleRepo, ruleKey);
}
+ public String getLanguage(){
+ return language;
+ }
+
public String getComponentKey() {
return componentKey;
}
@@ -385,6 +391,16 @@ public final class IssueDto extends Dto<String> implements Serializable {
/**
* Should only be used to persist in E/S
*
+ * Please use {@link #setRule(org.sonar.core.rule.RuleDto)} instead
+ */
+ public IssueDto setLanguage(String language) {
+ this.language = language;
+ return this;
+ }
+
+ /**
+ * Should only be used to persist in E/S
+ *
* Please use {@link #setComponent(org.sonar.core.component.ComponentDto)} instead
*/
public IssueDto setComponentKey(String componentKey) {
@@ -485,6 +501,7 @@ public final class IssueDto extends Dto<String> implements Serializable {
issue.setProjectKey(rootComponentKey);
issue.setManualSeverity(manualSeverity);
issue.setRuleKey(getRuleKey());
+ issue.setLanguage(language);
issue.setActionPlanKey(actionPlanKey);
issue.setAuthorLogin(authorLogin);
issue.setNew(false);
diff --git a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml
index 76fb97eaadf..cd9e5cfa79d 100644
--- a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml
+++ b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml
@@ -31,6 +31,7 @@
i.updated_at as updatedAt,
r.plugin_rule_key as ruleKey,
r.plugin_name as ruleRepo,
+ r.language as language,
p.kee as componentKey,
root.kee as rootComponentKey
</sql>
diff --git a/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDtoTest.java b/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDtoTest.java
index ddda3b57f71..791c7125556 100644
--- a/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDtoTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDtoTest.java
@@ -59,6 +59,7 @@ public class IssueDtoTest {
.setKee("100")
.setRuleId(1)
.setRuleKey("squid", "AvoidCycle")
+ .setLanguage("xoo")
.setComponentKey("org.sonar.sample:Sample")
.setRootComponentKey("org.sonar.sample")
.setComponentId(1l)
@@ -82,6 +83,7 @@ public class IssueDtoTest {
DefaultIssue issue = dto.toDefaultIssue();
assertThat(issue.key()).isEqualTo("100");
assertThat(issue.ruleKey().toString()).isEqualTo("squid:AvoidCycle");
+ assertThat(issue.language()).isEqualTo("xoo");
assertThat(issue.componentKey()).isEqualTo("org.sonar.sample:Sample");
assertThat(issue.componentId()).isEqualTo(1L);
assertThat(issue.projectKey()).isEqualTo("org.sonar.sample");
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java
index b3907d233de..44c8b456fd3 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java
@@ -83,6 +83,8 @@ public interface Issue extends Serializable {
RuleKey ruleKey();
+ String language();
+
/**
* See constants in {@link org.sonar.api.rule.Severity}.
*/
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssue.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssue.java
index 51a5abfd174..a6c528dc2a6 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssue.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssue.java
@@ -39,11 +39,7 @@ import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import java.io.Serializable;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import static com.google.common.collect.Lists.newArrayList;
@@ -59,6 +55,7 @@ public class DefaultIssue implements Issue {
private Long componentId;
private String projectKey;
private RuleKey ruleKey;
+ private String language;
private String severity;
private boolean manualSeverity = false;
private String message;
@@ -159,6 +156,15 @@ public class DefaultIssue implements Issue {
return this;
}
+ public String language() {
+ return language;
+ }
+
+ public DefaultIssue setLanguage(String l) {
+ this.language = l;
+ return this;
+ }
+
public String severity() {
return severity;
}