aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pom.xml5
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssueChanges.java5
-rw-r--r--sonar-batch/src/test/resources/org/sonar/batch/issue/IssuePersisterTest/should_insert_new_issue-result.xml2
-rw-r--r--sonar-batch/src/test/resources/org/sonar/batch/issue/IssuePersisterTest/should_update_existing_issue-result.xml2
-rw-r--r--sonar-batch/src/test/resources/org/sonar/batch/issue/IssuePersisterTest/should_update_existing_issue.xml2
-rw-r--r--sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java3
-rw-r--r--sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueFinder.java74
-rw-r--r--sonar-core/src/main/java/org/sonar/core/issue/IssueDto.java47
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/issue/IssueMapper.xml43
-rw-r--r--sonar-core/src/test/java/org/sonar/core/issue/DefaultIssueFinderTest.java45
-rw-r--r--sonar-core/src/test/java/org/sonar/core/issue/IssueDaoTest.java123
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/select.xml167
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/shared.xml244
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_all.xml77
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_component_root.xml (renamed from sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/select-with-component-children.xml)39
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_date_creation.xml27
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_id.xml47
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_key.xml27
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_query.xml27
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_rules.xml77
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_open_issues.xml (renamed from sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/select-open-issues.xml)28
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueChanges.java4
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueFinder.java16
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/api/issues_controller.rb44
24 files changed, 624 insertions, 551 deletions
diff --git a/pom.xml b/pom.xml
index fc58197a2aa..8205ae043d5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1050,6 +1050,11 @@
<artifactId>akiban-persistit</artifactId>
<version>3.2.7</version>
</dependency>
+ <dependency>
+ <groupId>com.github.kevinsawicki</groupId>
+ <artifactId>http-request</artifactId>
+ <version>4.1</version>
+ </dependency>
</dependencies>
</dependencyManagement>
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssueChanges.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssueChanges.java
index 59a4142105a..702e87c14f2 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssueChanges.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssueChanges.java
@@ -62,7 +62,7 @@ public class ScanIssueChanges implements IssueChanges {
if (change.isAssigneeChanged()) {
issue.setAssigneeLogin(change.assignee());
}
- if (change.resolution()!=null) {
+ if (change.resolution() != null) {
issue.setResolution(change.resolution());
}
if (change.isLineChanged()) {
@@ -74,8 +74,7 @@ public class ScanIssueChanges implements IssueChanges {
}
private DefaultIssue reload(Issue issue) {
- DefaultIssue reloaded = (DefaultIssue) issue;
- reloaded = (DefaultIssue) cache.componentIssue(reloaded.componentKey(), reloaded.key());
+ DefaultIssue reloaded = (DefaultIssue) cache.componentIssue(issue.componentKey(), issue.key());
if (reloaded == null) {
throw new IllegalStateException("Bad API usage. Unregistered issues can't be changed.");
}
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/issue/IssuePersisterTest/should_insert_new_issue-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/issue/IssuePersisterTest/should_insert_new_issue-result.xml
index 1efaeb4b5fa..f1e9d3a94f9 100644
--- a/sonar-batch/src/test/resources/org/sonar/batch/issue/IssuePersisterTest/should_insert_new_issue-result.xml
+++ b/sonar-batch/src/test/resources/org/sonar/batch/issue/IssuePersisterTest/should_insert_new_issue-result.xml
@@ -2,5 +2,5 @@
<snapshots id="100" project_id="200" islast="[true]"/>
<issues id="1" uuid="ABCD" resource_id="200" rule_id="300" severity="BLOCKER" manual_severity="[false]" manual_issue="[false]" title="[null]" message="[null]"
line="[null]" cost="[null]" status="OPEN" resolution="[null]" checksum="[null]" user_login="[null]" assignee_login="[null]" person_id="[null]"
- data="[null]" created_at="2013-05-18" updated_at="2013-05-23" closed_at="[null]" />
+ data="" created_at="2013-05-18" updated_at="2013-05-23" closed_at="[null]" />
</dataset> \ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/issue/IssuePersisterTest/should_update_existing_issue-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/issue/IssuePersisterTest/should_update_existing_issue-result.xml
index e3899a743f0..bab422fd0a2 100644
--- a/sonar-batch/src/test/resources/org/sonar/batch/issue/IssuePersisterTest/should_update_existing_issue-result.xml
+++ b/sonar-batch/src/test/resources/org/sonar/batch/issue/IssuePersisterTest/should_update_existing_issue-result.xml
@@ -2,5 +2,5 @@
<snapshots id="100" project_id="200" islast="[true]"/>
<issues id="1" uuid="ABCD" resource_id="200" rule_id="300" severity="BLOCKER" manual_severity="[false]" manual_issue="[false]" title="[null]" message="[null]"
line="[null]" cost="[null]" status="CLOSED" resolution="[null]" checksum="[null]" user_login="[null]" assignee_login="[null]" person_id="[null]"
- data="[null]" created_at="2013-05-18" updated_at="2013-05-23" closed_at="[null]" />
+ data="" created_at="2013-05-18" updated_at="2013-05-23" closed_at="[null]" />
</dataset> \ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/issue/IssuePersisterTest/should_update_existing_issue.xml b/sonar-batch/src/test/resources/org/sonar/batch/issue/IssuePersisterTest/should_update_existing_issue.xml
index 48ec8d68fbe..f4a989b8e24 100644
--- a/sonar-batch/src/test/resources/org/sonar/batch/issue/IssuePersisterTest/should_update_existing_issue.xml
+++ b/sonar-batch/src/test/resources/org/sonar/batch/issue/IssuePersisterTest/should_update_existing_issue.xml
@@ -2,5 +2,5 @@
<snapshots id="100" project_id="200" islast="[true]"/>
<issues id="1" uuid="ABCD" resource_id="200" rule_id="300" severity="INFO" manual_severity="[false]" manual_issue="[false]" title="[null]" message="[null]"
line="[null]" cost="[null]" status="OPEN" resolution="[null]" checksum="[null]" user_login="[null]" assignee_login="[null]" person_id="[null]"
- data="[null]" created_at="2012-01-01" updated_at="2012-01-01" closed_at="[null]" />
+ data="" created_at="2012-01-01" updated_at="2012-01-01" closed_at="[null]" />
</dataset> \ No newline at end of file
diff --git a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java
index cd1bb9f78a0..8d7ee81454f 100644
--- a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java
+++ b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java
@@ -31,6 +31,7 @@ import org.sonar.api.rule.Severity;
import javax.annotation.Nullable;
import java.io.Serializable;
+import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.Set;
@@ -254,7 +255,7 @@ public class DefaultIssue implements Issue, Serializable {
}
public Map<String, String> attributes() {
- return attributes == null ? null : ImmutableMap.copyOf(attributes);
+ return attributes == null ? Collections.<String,String>emptyMap() : ImmutableMap.copyOf(attributes);
}
public DefaultIssue setAttributes(Map<String, String> attributes) {
diff --git a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueFinder.java b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueFinder.java
index 1904092edb5..c2091b65bcc 100644
--- a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueFinder.java
+++ b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueFinder.java
@@ -20,10 +20,7 @@
package org.sonar.core.issue;
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
+import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
@@ -32,17 +29,12 @@ import org.sonar.api.issue.Issue;
import org.sonar.api.issue.IssueFinder;
import org.sonar.api.issue.IssueQuery;
import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleFinder;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
import org.sonar.core.user.AuthorizationDao;
import javax.annotation.Nullable;
import java.util.List;
-import java.util.Map;
import java.util.Set;
/**
@@ -59,59 +51,32 @@ public class DefaultIssueFinder implements IssueFinder {
private final MyBatis myBatis;
private final IssueDao issueDao;
- private final ResourceDao resourceDao;
private final AuthorizationDao authorizationDao;
- private final RuleFinder ruleFinder;
- public DefaultIssueFinder(MyBatis myBatis, IssueDao issueDao, ResourceDao resourceDao,
- AuthorizationDao authorizationDao, RuleFinder ruleFinder) {
+
+ public DefaultIssueFinder(MyBatis myBatis, IssueDao issueDao, AuthorizationDao authorizationDao) {
this.myBatis = myBatis;
this.issueDao = issueDao;
- this.resourceDao = resourceDao;
this.authorizationDao = authorizationDao;
- this.ruleFinder = ruleFinder;
}
public Results find(IssueQuery query, @Nullable Integer currentUserId) {
LOG.debug("IssueQuery : {}", query);
SqlSession sqlSession = myBatis.openSession();
try {
- List<IssueDto> issueDtos = issueDao.select(query, sqlSession);
+ List<IssueDto> dtos = issueDao.select(query, sqlSession);
Set<Integer> componentIds = Sets.newLinkedHashSet();
- Set<Integer> ruleIds = Sets.newLinkedHashSet();
- for (IssueDto issueDto : issueDtos) {
+ for (IssueDto issueDto : dtos) {
componentIds.add(issueDto.getResourceId());
- ruleIds.add(issueDto.getRuleId());
}
-
- componentIds = authorizationDao.keepAuthorizedComponentIds(componentIds, currentUserId, ROLE, sqlSession);
-
- final Map<Integer, Rule> rules = Maps.newHashMap();
- for (Integer ruleId : ruleIds) {
- Rule rule = ruleFinder.findById(ruleId);
- if (rule != null) {
- rules.put(rule.getId(), rule);
+ Set<Integer> authorizedComponentIds = authorizationDao.keepAuthorizedComponentIds(componentIds, currentUserId, ROLE, sqlSession);
+ List<Issue> issues = Lists.newArrayList();
+ for (IssueDto dto : dtos) {
+ if (authorizedComponentIds.contains(dto.getResourceId())) {
+ issues.add(toIssue(dto));
}
}
- final Map<Integer, ResourceDto> resources = Maps.newHashMap();
- for (Integer componentId : componentIds) {
- // TODO replace N+1 SQL requests by a single one
- ResourceDto resource = resourceDao.getResource(componentId);
- if (resource != null) {
- resources.put(resource.getId().intValue(), resource);
- }
- }
-
- List<Issue> issues = ImmutableList.copyOf(Iterables.transform(issueDtos, new Function<IssueDto, Issue>() {
- @Override
- public Issue apply(IssueDto dto) {
- Rule rule = rules.get(dto.getRuleId());
- ResourceDto resource = resources.get(dto.getResourceId());
- return toIssue(dto, rule, resource);
- }
- }));
-
return new DefaultResults(issues);
} finally {
MyBatis.closeQuietly(sqlSession);
@@ -120,16 +85,10 @@ public class DefaultIssueFinder implements IssueFinder {
public Issue findByKey(String key) {
IssueDto dto = issueDao.selectByKey(key);
- Issue issue = null;
- if (dto != null) {
- Rule rule = ruleFinder.findById(dto.getRuleId());
- ResourceDto resource = resourceDao.getResource(dto.getResourceId());
- issue = toIssue(dto, rule, resource);
- }
- return issue;
+ return dto != null ? toIssue(dto) : null;
}
- private Issue toIssue(IssueDto dto, Rule rule, ResourceDto resource) {
+ private Issue toIssue(IssueDto dto) {
DefaultIssue issue = new DefaultIssue();
issue.setKey(dto.getUuid());
issue.setStatus(dto.getStatus());
@@ -147,13 +106,8 @@ public class DefaultIssueFinder implements IssueFinder {
issue.setAttributes(KeyValueFormat.parse(dto.getData()));
issue.setManual(dto.isManualIssue());
issue.setManualSeverity(dto.isManualSeverity());
-
- if (resource != null) {
- issue.setComponentKey(resource.getKey());
- }
- if (rule != null) {
- issue.setRuleKey(RuleKey.of(rule.getRepositoryKey(), rule.getKey()));
- }
+ issue.setComponentKey(dto.getComponentKey());
+ issue.setRuleKey(RuleKey.of(dto.getRuleRepo(), dto.getRule()));
return issue;
}
diff --git a/sonar-core/src/main/java/org/sonar/core/issue/IssueDto.java b/sonar-core/src/main/java/org/sonar/core/issue/IssueDto.java
index 53db3d967dc..3a5416666ea 100644
--- a/sonar-core/src/main/java/org/sonar/core/issue/IssueDto.java
+++ b/sonar-core/src/main/java/org/sonar/core/issue/IssueDto.java
@@ -25,7 +25,6 @@ import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import javax.annotation.Nullable;
-
import java.util.Date;
/**
@@ -53,11 +52,15 @@ public final class IssueDto {
private String assigneeLogin;
private Long personId;
private String data;
-
private Date createdAt;
private Date updatedAt;
private Date closedAt;
+ // joins
+ private String rule;
+ private String ruleRepo;
+ private String componentKey;
+
public Long getId() {
return id;
}
@@ -217,7 +220,7 @@ public final class IssueDto {
public IssueDto setData(@Nullable String s) {
Preconditions.checkArgument(s == null || s.length() <= 1000,
- "Issue data must not exceed 1000 characters: " + s);
+ "Issue data must not exceed 1000 characters: " + s);
this.data = s;
return this;
}
@@ -250,7 +253,43 @@ public final class IssueDto {
}
public static String abbreviateMessage(String message) {
- return message!= null ? StringUtils.abbreviate(StringUtils.trim(message), MESSAGE_MAX_SIZE) : null;
+ return message != null ? StringUtils.abbreviate(StringUtils.trim(message), MESSAGE_MAX_SIZE) : null;
+ }
+
+ public String getRule() {
+ return rule;
+ }
+
+ public String getRuleRepo() {
+ return ruleRepo;
+ }
+
+ public String getComponentKey() {
+ return componentKey;
+ }
+
+ /**
+ * Only for unit tests
+ */
+ public IssueDto setRule_unit_test_only(String rule) {
+ this.rule = rule;
+ return this;
+ }
+
+ /**
+ * Only for unit tests
+ */
+ public IssueDto setRuleRepo_unit_test_only(String ruleRepo) {
+ this.ruleRepo = ruleRepo;
+ return this;
+ }
+
+ /**
+ * Only for unit tests
+ */
+ public IssueDto setComponentKey_unit_test_only(String componentKey) {
+ this.componentKey = componentKey;
+ return this;
}
@Override
diff --git a/sonar-core/src/main/resources/org/sonar/core/issue/IssueMapper.xml b/sonar-core/src/main/resources/org/sonar/core/issue/IssueMapper.xml
index b731c4bf3f2..15b286f201d 100644
--- a/sonar-core/src/main/resources/org/sonar/core/issue/IssueMapper.xml
+++ b/sonar-core/src/main/resources/org/sonar/core/issue/IssueMapper.xml
@@ -25,7 +25,10 @@
i.data as data,
i.created_at as createdAt,
i.updated_at as updatedAt,
- i.closed_at as closedAt
+ i.closed_at as closedAt,
+ r.plugin_rule_key as rule,
+ r.plugin_name as ruleRepo,
+ p.kee as componentKey
</sql>
<insert id="insert" parameterType="Issue" useGeneratedKeys="true" keyProperty="id">
@@ -73,24 +76,25 @@
<select id="selectById" parameterType="long" resultType="Issue">
select
<include refid="issueColumns"/>
- from issues i
- where i.id=#{id}
+ from issues i, rules r, projects p
+ where i.id=#{id} and i.rule_id=r.id and p.id=i.resource_id
</select>
<select id="selectByKey" parameterType="String" resultType="Issue">
select
<include refid="issueColumns"/>
- from issues i
- where i.uuid=#{uuid}
+ from issues i, rules r, projects p
+ where i.uuid=#{uuid} and i.rule_id=r.id and p.id=i.resource_id
</select>
<select id="selectOpenIssues" parameterType="String" resultType="Issue">
select distinct
<include refid="issueColumns"/>
- from issues i, projects p
+ from issues i, rules r, projects p
where i.status &lt;&gt; 'CLOSED'
- and p.root_id=#{componentId} or (p.root_id is null and p.id=#{componentId})
- and i.resource_id=p.id
+ and (p.root_id=#{componentId} or (p.root_id is null and p.id=#{componentId}))
+ and i.resource_id=p.id
+ and r.id=i.rule_id
</select>
<select id="select" parameterType="map" resultType="Issue">
@@ -100,32 +104,30 @@
</select>
<sql id="selectQueryConditions">
- from issues i
+ from issues i, projects p, rules r
<if test="componentRoots != null and componentRoots.size() > 0">
- , projects p, snapshots root, snapshots s
+ , projects rootprojects, snapshots rootsnapshots, snapshots s
</if>
<if test="components != null and components.size() > 0">
, projects project_component
</if>
- <if test="rules != null and rules.size() > 0">
- , rules r
- </if>
<where>
+ p.id=i.resource_id and i.rule_id=r.id
<if test="componentRoots != null and componentRoots.size() > 0">
- and p.enabled=${_true}
- and p.kee in
+ and rootprojects.enabled=${_true}
+ and rootprojects.kee in
<foreach item="componentRoot" index="index" collection="componentRoots" open="(" separator="," close=")">
#{componentRoot}
</foreach>
- and root.project_id=p.id
- and root.islast=${_true}
- and (s.id=root.id or (s.root_snapshot_id=root.id and
+ and rootsnapshots.project_id=rootprojects.id
+ and rootsnapshots.islast=${_true}
+ and (s.id=rootsnapshots.id or (s.root_snapshot_id=rootsnapshots.id and
<choose>
<when test="_databaseId == 'mssql'">
- s.path LIKE root.path + CAST(root.id AS varchar(15)) + '.%'
+ s.path LIKE rootsnapshots.path + CAST(rootsnapshots.id AS varchar(15)) + '.%'
</when>
<otherwise>
- s.path LIKE root.path || root.id || '.%'
+ s.path LIKE rootsnapshots.path || rootsnapshots.id || '.%'
</otherwise>
</choose>
))
@@ -170,7 +172,6 @@
</foreach>
</if>
<if test="rules != null and rules.size() > 0">
- and i.rule_id = r.id
and (<foreach item="rule" index="index" collection="rules" open="(" separator=" or " close=")">r.plugin_name=#{rule.repository} and r.plugin_rule_key=#{rule.rule}</foreach>)
</if>
<if test="createdAfter">
diff --git a/sonar-core/src/test/java/org/sonar/core/issue/DefaultIssueFinderTest.java b/sonar-core/src/test/java/org/sonar/core/issue/DefaultIssueFinderTest.java
index 92ab7e30021..54b52850807 100644
--- a/sonar-core/src/test/java/org/sonar/core/issue/DefaultIssueFinderTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/issue/DefaultIssueFinderTest.java
@@ -27,22 +27,14 @@ import org.mockito.stubbing.Answer;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.IssueFinder;
import org.sonar.api.issue.IssueQuery;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleFinder;
import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
import org.sonar.core.user.AuthorizationDao;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anySet;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -51,18 +43,14 @@ public class DefaultIssueFinderTest {
MyBatis mybatis;
DefaultIssueFinder finder;
IssueDao issueDao;
- ResourceDao resourceDao;
- RuleFinder ruleFinder;
AuthorizationDao authorizationDao;
@Before
public void before() {
mybatis = mock(MyBatis.class);
issueDao = mock(IssueDao.class);
- resourceDao = mock(ResourceDao.class);
- ruleFinder = mock(RuleFinder.class);
authorizationDao = mock(AuthorizationDao.class);
- finder = new DefaultIssueFinder(mybatis, issueDao, resourceDao, authorizationDao, ruleFinder);
+ finder = new DefaultIssueFinder(mybatis, issueDao, authorizationDao);
}
@Test
@@ -70,33 +58,36 @@ public class DefaultIssueFinderTest {
grantAccessRights();
IssueQuery issueQuery = mock(IssueQuery.class);
- IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setResourceId(123);
- IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setResourceId(123);
+ IssueDto issue1 = new IssueDto().setId(1L).setRuleId(50).setResourceId(123)
+ .setComponentKey_unit_test_only("Action.java")
+ .setRuleRepo_unit_test_only("squid")
+ .setRule_unit_test_only("AvoidCycle");
+ IssueDto issue2 = new IssueDto().setId(2L).setRuleId(50).setResourceId(123)
+ .setComponentKey_unit_test_only("Action.java")
+ .setRuleRepo_unit_test_only("squid")
+ .setRule_unit_test_only("AvoidCycle");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
when(issueDao.select(eq(issueQuery), any(SqlSession.class))).thenReturn(dtoList);
- Rule rule = Rule.create("repo", "key");
- rule.setId(50);
- when(ruleFinder.findById(anyInt())).thenReturn(rule);
- when(resourceDao.getResource(anyInt())).thenReturn(new ResourceDto().setKey("componentKey").setId(123L));
IssueFinder.Results results = finder.find(issueQuery, null);
assertThat(results.issues()).hasSize(2);
Issue issue = results.issues().iterator().next();
- assertThat(issue.componentKey()).isEqualTo("componentKey");
- assertThat(issue.ruleKey().toString()).isEqualTo("repo:key");
+ assertThat(issue.componentKey()).isEqualTo("Action.java");
+ assertThat(issue.ruleKey().toString()).isEqualTo("squid:AvoidCycle");
}
@Test
public void should_find_by_key() {
- IssueDto issueDto = new IssueDto().setId(1L).setRuleId(1).setResourceId(1);
+ IssueDto issueDto = new IssueDto().setId(1L).setRuleId(1).setResourceId(1)
+ .setComponentKey_unit_test_only("Action.java")
+ .setRuleRepo_unit_test_only("squid")
+ .setRule_unit_test_only("AvoidCycle");
when(issueDao.selectByKey("ABCDE")).thenReturn(issueDto);
- when(ruleFinder.findById(anyInt())).thenReturn(Rule.create("squid", "NullDeref"));
- when(resourceDao.getResource(anyInt())).thenReturn(new ResourceDto().setKey("org/struts/Action.java"));
Issue issue = finder.findByKey("ABCDE");
assertThat(issue).isNotNull();
- assertThat(issue.componentKey()).isEqualTo("org/struts/Action.java");
- assertThat(issue.ruleKey().toString()).isEqualTo("squid:NullDeref");
+ assertThat(issue.componentKey()).isEqualTo("Action.java");
+ assertThat(issue.ruleKey().toString()).isEqualTo("squid:AvoidCycle");
}
private void grantAccessRights() {
diff --git a/sonar-core/src/test/java/org/sonar/core/issue/IssueDaoTest.java b/sonar-core/src/test/java/org/sonar/core/issue/IssueDaoTest.java
index 03b296ac13e..59f909a68d9 100644
--- a/sonar-core/src/test/java/org/sonar/core/issue/IssueDaoTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/issue/IssueDaoTest.java
@@ -73,7 +73,7 @@ public class IssueDaoTest extends AbstractDaoTestCase {
@Test
public void update() {
- setupData("update");
+ setupData("shared", "update");
Collection<IssueDto> issues = newArrayList(dao.selectById(100L));
IssueDto issue = issues.iterator().next();
issue.setLine(1000);
@@ -94,12 +94,11 @@ public class IssueDaoTest extends AbstractDaoTestCase {
}
@Test
- public void should_find_issue_by_id() {
- setupData("shared");
-
+ public void should_select_by_id() {
+ setupData("shared", "should_select_by_id");
IssueDto issue = dao.selectById(100L);
assertThat(issue.getId()).isEqualTo(100L);
- assertThat(issue.getUuid()).isEqualTo("100");
+ assertThat(issue.getUuid()).isEqualTo("ABCDE");
assertThat(issue.getResourceId()).isEqualTo(400);
assertThat(issue.getRuleId()).isEqualTo(500);
assertThat(issue.getSeverity()).isEqualTo("BLOCKER");
@@ -108,102 +107,94 @@ public class IssueDaoTest extends AbstractDaoTestCase {
assertThat(issue.getTitle()).isNull();
assertThat(issue.getMessage()).isNull();
assertThat(issue.getLine()).isEqualTo(200);
- assertThat(issue.getCost()).isNull();
+ assertThat(issue.getCost()).isEqualTo(4.2);
assertThat(issue.getStatus()).isEqualTo("OPEN");
- assertThat(issue.getResolution()).isNull();
- assertThat(issue.getChecksum()).isNull();
- assertThat(issue.getAssigneeLogin()).isEqualTo("user");
+ assertThat(issue.getResolution()).isEqualTo("FIXED");
+ assertThat(issue.getChecksum()).isEqualTo("XXX");
assertThat(issue.getPersonId()).isNull();
- assertThat(issue.getUserLogin()).isNull();
- assertThat(issue.getData()).isNull();
- assertThat(issue.getCreatedAt()).isNull();
- assertThat(issue.getUpdatedAt()).isNull();
- assertThat(issue.getClosedAt()).isNull();
+ assertThat(issue.getUserLogin()).isEqualTo("arthur");
+ assertThat(issue.getAssigneeLogin()).isEqualTo("perceval");
+ assertThat(issue.getData()).isEqualTo("JIRA=FOO-1234");
+ assertThat(issue.getCreatedAt()).isNotNull();
+ assertThat(issue.getUpdatedAt()).isNotNull();
+ assertThat(issue.getClosedAt()).isNotNull();
}
@Test
- public void should_find_issue_by_key() {
- setupData("shared");
+ public void should_select_by_key() {
+ setupData("shared", "should_select_by_key");
- IssueDto issue = dao.selectByKey("100");
- assertThat(issue).isNotNull();
+ IssueDto issue = dao.selectByKey("ABCDE");
+ assertThat(issue.getUuid()).isEqualTo("ABCDE");
+ assertThat(issue.getId()).isEqualTo(100);
}
@Test
- public void should_select_by_parameter() {
- setupData("select");
-
- IssueQuery issueQuery = IssueQuery.builder().keys(newArrayList("100")).build();
- assertThat(dao.select(issueQuery)).hasSize(1);
-
- issueQuery = IssueQuery.builder().components(newArrayList("key")).build();
- assertThat(dao.select(issueQuery)).hasSize(2);
-
- issueQuery = IssueQuery.builder().resolutions(newArrayList("FALSE-POSITIVE")).build();
- assertThat(dao.select(issueQuery)).hasSize(1);
-
- issueQuery = IssueQuery.builder().statuses(newArrayList("OPEN")).build();
- assertThat(dao.select(issueQuery)).hasSize(2);
-
- issueQuery = IssueQuery.builder().severities(newArrayList("BLOCKER")).build();
- assertThat(dao.select(issueQuery)).hasSize(4);
-
- issueQuery = IssueQuery.builder().userLogins(newArrayList("user")).build();
- assertThat(dao.select(issueQuery)).hasSize(1);
-
- issueQuery = IssueQuery.builder().assigneeLogins(newArrayList("user")).build();
- assertThat(dao.select(issueQuery)).hasSize(5);
-
- issueQuery = IssueQuery.builder().userLogins(newArrayList("user")).statuses(newArrayList("OPEN")).build();
- assertThat(dao.select(issueQuery)).hasSize(1);
+ public void should_select_by_query() {
+ setupData("shared", "should_select_by_query");
+
+ IssueQuery query = IssueQuery.builder()
+ .keys(newArrayList("ABCDE"))
+ .userLogins(newArrayList("arthur", "otherguy"))
+ .assigneeLogins(newArrayList("perceval", "otherguy"))
+ .components(newArrayList("Action.java"))
+ .resolutions(newArrayList("FIXED"))
+ .severities(newArrayList("BLOCKER"))
+ .rules(newArrayList(RuleKey.of("squid", "AvoidCycle")))
+ .build();
+ assertThat(dao.select(query)).hasSize(1);
+ assertThat(dao.select(query).get(0).getId()).isEqualTo(100);
}
@Test
- public void should_find_issue_by_rules() {
- setupData("select");
+ public void should_select_by_rules() {
+ setupData("shared", "should_select_by_rules");
+
+ IssueQuery query = IssueQuery.builder().rules(newArrayList(RuleKey.of("squid", "AvoidCycle"))).build();
+ assertThat(dao.select(query)).hasSize(2);
- IssueQuery issueQuery = IssueQuery.builder().rules(newArrayList(RuleKey.of("squid", "AvoidCycle"))).build();
- assertThat(dao.select(issueQuery)).hasSize(4);
+ query = IssueQuery.builder().rules(newArrayList(RuleKey.of("squid", "AvoidCycle"), RuleKey.of("squid", "NullRef"))).build();
+ assertThat(dao.select(query)).hasSize(3);
- issueQuery = IssueQuery.builder().rules(newArrayList(RuleKey.of("squid", "Other"))).build();
- assertThat(dao.select(issueQuery)).isEmpty();
+ query = IssueQuery.builder().rules(newArrayList(RuleKey.of("squid", "Other"))).build();
+ assertThat(dao.select(query)).isEmpty();
}
@Test
- public void should_find_issue_by_date_creation() {
- setupData("select");
+ public void should_select_by_date_creation() {
+ setupData("shared", "should_select_by_date_creation");
- IssueQuery issueQuery = IssueQuery.builder().createdAfter(DateUtils.parseDate("2013-04-15")).build();
- assertThat(dao.select(issueQuery)).hasSize(1);
+ IssueQuery query = IssueQuery.builder().createdAfter(DateUtils.parseDate("2013-04-15")).build();
+ assertThat(dao.select(query)).hasSize(1);
- issueQuery = IssueQuery.builder().createdBefore(DateUtils.parseDate("2013-04-17")).build();
- assertThat(dao.select(issueQuery)).hasSize(2);
+ query = IssueQuery.builder().createdBefore(DateUtils.parseDate("2013-04-17")).build();
+ assertThat(dao.select(query)).hasSize(1);
}
@Test
- public void should_return_issues_from_component_root() {
- setupData("select-with-component-children");
+ public void should_select_by_component_root() {
+ setupData("shared", "should_select_by_component_root");
- IssueQuery issueQuery = IssueQuery.builder().componentRoots(newArrayList("key")).build();
- List<IssueDto> issues = newArrayList(dao.select(issueQuery));
+ IssueQuery query = IssueQuery.builder().componentRoots(newArrayList("struts")).build();
+ List<IssueDto> issues = newArrayList(dao.select(query));
assertThat(issues).hasSize(2);
assertThat(issues.get(0).getId()).isEqualTo(100);
assertThat(issues.get(1).getId()).isEqualTo(101);
}
@Test
- public void should_select_without_parameter_return_all_issues() {
- setupData("select");
+ public void should_select_all() {
+ setupData("shared", "should_select_all");
- IssueQuery issueQuery = IssueQuery.builder().build();
- assertThat(dao.select(issueQuery)).hasSize(5);
+ IssueQuery query = IssueQuery.builder().build();
+ assertThat(dao.select(query)).hasSize(3);
}
@Test
public void should_select_open_issues() {
- setupData("select-open-issues");
+ setupData("shared", "should_select_open_issues");
- assertThat(dao.selectOpenIssues(400)).hasSize(2);
+ assertThat(dao.selectOpenIssues(399)).hasSize(2);
}
}
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/select.xml b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/select.xml
deleted file mode 100644
index 31fb7d91297..00000000000
--- a/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/select.xml
+++ /dev/null
@@ -1,167 +0,0 @@
-<!--
- ~ Sonar, open source software quality management tool.
- ~ Copyright (C) 2008-2012 SonarSource
- ~ mailto:contact AT sonarsource DOT com
- ~
- ~ Sonar 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.
- ~
- ~ Sonar 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 Sonar; if not, write to the Free Software
- ~ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- -->
-
-<dataset>
-
- <!-- First resource -->
- <issues
- id="100"
- uuid="100"
- resource_id="400"
- rule_id="500"
- severity="BLOCKER"
- manual_severity="[false]"
- manual_issue="[false]"
- title="[null]"
- message="[null]"
- line="200"
- cost="[null]"
- status="OPEN"
- resolution="[null]"
- checksum="[null]"
- user_login="user"
- assignee_login="user"
- person_id="[null]"
- data="[null]"
- created_at="2013-04-16"
- updated_at="[null]"
- closed_at="[null]"
- />
-
- <issues
- id="101"
- uuid="101"
- resource_id="400"
- rule_id="505"
- severity="MAJOR"
- manual_severity="[false]"
- manual_issue="[false]"
- title="[null]"
- message="[null]"
- line="120"
- cost="[null]"
- status="CLOSED"
- resolution="FIXED"
- checksum="[null]"
- user_login="[null]"
- assignee_login="user"
- person_id="[null]"
- data="[null]"
- created_at="2013-04-10"
- updated_at="[null]"
- closed_at="[null]"
- />
-
-
- <!-- Second resource -->
- <issues
- id="102"
- uuid="102"
- resource_id="500"
- rule_id="500"
- severity="BLOCKER"
- manual_severity="[false]"
- manual_issue="[false]"
- title="[null]"
- message="[null]"
- line="200"
- cost="[null]"
- status="OPEN"
- resolution="FIXED"
- checksum="[null]"
- user_login="[null]"
- assignee_login="user"
- person_id="[null]"
- data="[null]"
- created_at="[null]"
- updated_at="[null]"
- closed_at="[null]"
- />
-
- <issues
- id="103"
- uuid="103"
- resource_id="500"
- rule_id="500"
- severity="BLOCKER"
- manual_severity="[false]"
- manual_issue="[false]"
- title="[null]"
- message="[null]"
- line="200"
- cost="[null]"
- status="REOPENED"
- resolution="FIXED"
- checksum="[null]"
- user_login="[null]"
- assignee_login="user"
- person_id="[null]"
- data="[null]"
- created_at="[null]"
- updated_at="[null]"
- closed_at="[null]"
- />
-
- <issues
- id="104"
- uuid="104"
- resource_id="500"
- rule_id="500"
- severity="BLOCKER"
- manual_severity="[false]"
- manual_issue="[false]"
- title="[null]"
- message="[null]"
- line="200"
- cost="[null]"
- status="[null]"
- resolution="FALSE-POSITIVE"
- checksum="[null]"
- user_login="[null]"
- assignee_login="user"
- person_id="[null]"
- data="[null]"
- created_at="[null]"
- updated_at="[null]"
- closed_at="[null]"
- />
-
- <projects
- id="400"
- kee="key"
- enabled="[true]"
- />
-
- <snapshots
- id="100"
- project_id="400"
- root_snapshot_id="[null]"
- path=""
- islast="[true]"
- />
-
-
- <rules
- id="500"
- plugin_name="squid"
- plugin_rule_key="AvoidCycle"
- />
-
-</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/shared.xml b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/shared.xml
index 5b0a7f24ea0..7112b2b4980 100644
--- a/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/shared.xml
+++ b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/shared.xml
@@ -20,127 +20,137 @@
<dataset>
- <!-- First resource -->
- <issues
- id="100"
- uuid="100"
- resource_id="400"
- rule_id="500"
- severity="BLOCKER"
- manual_severity="[false]"
- manual_issue="[false]"
- title="[null]"
- message="[null]"
- line="200"
- cost="[null]"
- status="OPEN"
- resolution="[null]"
- checksum="[null]"
- user_login="[null]"
- assignee_login="user"
- person_id="[null]"
- data="[null]"
- created_at="[null]"
- updated_at="[null]"
- closed_at="[null]"
- />
+ <projects id="399" kee="struts" root_id="[null]" />
+ <projects id="400" kee="Action.java" root_id="399" />
+ <projects id="401" kee="Filter.java" root_id="399"/>
+ <snapshots id="100" project_id="399" root_snapshot_id="[null]" path="" islast="[true]" />
+ <snapshots id="101" project_id="400" root_snapshot_id="100" path="100." islast="[true]" />
+ <snapshots id="102" project_id="401" root_snapshot_id="100" path="100." islast="[true]" />
- <issues
- id="101"
- uuid="101"
- resource_id="400"
- rule_id="505"
- severity="MAJOR"
- manual_severity="[false]"
- manual_issue="[false]"
- title="[null]"
- message="[null]"
- line="120"
- cost="[null]"
- status="CLOSED"
- resolution="FIXED"
- checksum="[null]"
- user_login="[null]"
- assignee_login="user"
- person_id="[null]"
- data="[null]"
- created_at="[null]"
- updated_at="[null]"
- closed_at="[null]"
- />
+ <rules id="500" plugin_rule_key="AvoidCycle" plugin_name="squid" />
+ <rules id="501" plugin_rule_key="NullRef" plugin_name="squid" />
+ <!--&lt;!&ndash; First resource &ndash;&gt;-->
+ <!--<issues-->
+ <!--id="100"-->
+ <!--uuid="100"-->
+ <!--resource_id="400"-->
+ <!--rule_id="500"-->
+ <!--severity="BLOCKER"-->
+ <!--manual_severity="[false]"-->
+ <!--manual_issue="[false]"-->
+ <!--title="[null]"-->
+ <!--message="[null]"-->
+ <!--line="200"-->
+ <!--cost="[null]"-->
+ <!--status="OPEN"-->
+ <!--resolution="[null]"-->
+ <!--checksum="[null]"-->
+ <!--user_login="[null]"-->
+ <!--assignee_login="user"-->
+ <!--person_id="[null]"-->
+ <!--data="[null]"-->
+ <!--created_at="[null]"-->
+ <!--updated_at="[null]"-->
+ <!--closed_at="[null]"-->
+ <!--/>-->
- <!-- Second resource -->
- <issues
- id="102"
- uuid="102"
- resource_id="401"
- rule_id="500"
- severity="BLOCKER"
- manual_severity="[false]"
- manual_issue="[false]"
- title="[null]"
- message="[null]"
- line="200"
- cost="[null]"
- status="OPEN"
- resolution="FIXED"
- checksum="[null]"
- user_login="[null]"
- assignee_login="user"
- person_id="[null]"
- data="[null]"
- created_at="[null]"
- updated_at="[null]"
- closed_at="[null]"
- />
+ <!--<issues-->
+ <!--id="101"-->
+ <!--uuid="101"-->
+ <!--resource_id="400"-->
+ <!--rule_id="501"-->
+ <!--severity="MAJOR"-->
+ <!--manual_severity="[false]"-->
+ <!--manual_issue="[false]"-->
+ <!--title="[null]"-->
+ <!--message="[null]"-->
+ <!--line="120"-->
+ <!--cost="[null]"-->
+ <!--status="CLOSED"-->
+ <!--resolution="FIXED"-->
+ <!--checksum="[null]"-->
+ <!--user_login="[null]"-->
+ <!--assignee_login="user"-->
+ <!--person_id="[null]"-->
+ <!--data="[null]"-->
+ <!--created_at="[null]"-->
+ <!--updated_at="[null]"-->
+ <!--closed_at="[null]"-->
+ <!--/>-->
- <issues
- id="103"
- uuid="103"
- resource_id="401"
- rule_id="500"
- severity="BLOCKER"
- manual_severity="[false]"
- manual_issue="[false]"
- title="[null]"
- message="[null]"
- line="200"
- cost="[null]"
- status="REOPENED"
- resolution="FIXED"
- checksum="[null]"
- user_login="[null]"
- assignee_login="user"
- person_id="[null]"
- data="[null]"
- created_at="[null]"
- updated_at="[null]"
- closed_at="[null]"
- />
- <issues
- id="104"
- uuid="104"
- resource_id="401"
- rule_id="500"
- severity="BLOCKER"
- manual_severity="[false]"
- manual_issue="[false]"
- title="[null]"
- message="[null]"
- line="200"
- cost="[null]"
- status="[null]"
- resolution="FALSE-POSITIVE"
- checksum="[null]"
- user_login="[null]"
- assignee_login="user"
- person_id="[null]"
- data="[null]"
- created_at="[null]"
- updated_at="[null]"
- closed_at="[null]"
- />
+ <!--&lt;!&ndash; Second resource &ndash;&gt;-->
+ <!--<issues-->
+ <!--id="102"-->
+ <!--uuid="102"-->
+ <!--resource_id="401"-->
+ <!--rule_id="500"-->
+ <!--severity="BLOCKER"-->
+ <!--manual_severity="[false]"-->
+ <!--manual_issue="[false]"-->
+ <!--title="[null]"-->
+ <!--message="[null]"-->
+ <!--line="200"-->
+ <!--cost="[null]"-->
+ <!--status="OPEN"-->
+ <!--resolution="FIXED"-->
+ <!--checksum="[null]"-->
+ <!--user_login="[null]"-->
+ <!--assignee_login="user"-->
+ <!--person_id="[null]"-->
+ <!--data="[null]"-->
+ <!--created_at="[null]"-->
+ <!--updated_at="[null]"-->
+ <!--closed_at="[null]"-->
+ <!--/>-->
+
+ <!--<issues-->
+ <!--id="103"-->
+ <!--uuid="103"-->
+ <!--resource_id="401"-->
+ <!--rule_id="500"-->
+ <!--severity="BLOCKER"-->
+ <!--manual_severity="[false]"-->
+ <!--manual_issue="[false]"-->
+ <!--title="[null]"-->
+ <!--message="[null]"-->
+ <!--line="200"-->
+ <!--cost="[null]"-->
+ <!--status="REOPENED"-->
+ <!--resolution="FIXED"-->
+ <!--checksum="[null]"-->
+ <!--user_login="[null]"-->
+ <!--assignee_login="user"-->
+ <!--person_id="[null]"-->
+ <!--data="[null]"-->
+ <!--created_at="[null]"-->
+ <!--updated_at="[null]"-->
+ <!--closed_at="[null]"-->
+ <!--/>-->
+
+ <!--<issues-->
+ <!--id="104"-->
+ <!--uuid="104"-->
+ <!--resource_id="401"-->
+ <!--rule_id="500"-->
+ <!--severity="BLOCKER"-->
+ <!--manual_severity="[false]"-->
+ <!--manual_issue="[false]"-->
+ <!--title="[null]"-->
+ <!--message="[null]"-->
+ <!--line="200"-->
+ <!--cost="[null]"-->
+ <!--status="[null]"-->
+ <!--resolution="FALSE-POSITIVE"-->
+ <!--checksum="[null]"-->
+ <!--user_login="[null]"-->
+ <!--assignee_login="user"-->
+ <!--person_id="[null]"-->
+ <!--data="[null]"-->
+ <!--created_at="[null]"-->
+ <!--updated_at="[null]"-->
+ <!--closed_at="[null]"-->
+ <!--/>-->
</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_all.xml b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_all.xml
new file mode 100644
index 00000000000..39b6ef6681d
--- /dev/null
+++ b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_all.xml
@@ -0,0 +1,77 @@
+<dataset>
+
+ <!-- rule 500 -->
+ <issues
+ id="100"
+ uuid="ABCDE"
+ resource_id="400"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ manual_issue="[false]"
+ title="[null]"
+ message="[null]"
+ line="200"
+ cost="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ user_login="arthur"
+ assignee_login="perceval"
+ person_id="[null]"
+ data="JIRA=FOO-1234"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ closed_at="2013-04-16"
+ />
+
+ <issues
+ id="101"
+ uuid="ABCDE"
+ resource_id="400"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ manual_issue="[false]"
+ title="[null]"
+ message="[null]"
+ line="200"
+ cost="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ user_login="arthur"
+ assignee_login="perceval"
+ person_id="[null]"
+ data="JIRA=FOO-1234"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ closed_at="2013-04-16"
+ />
+
+
+ <!-- rule 501 -->
+ <issues
+ id="102"
+ uuid="ABCDE"
+ resource_id="400"
+ rule_id="501"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ manual_issue="[false]"
+ title="[null]"
+ message="[null]"
+ line="200"
+ cost="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ user_login="arthur"
+ assignee_login="perceval"
+ person_id="[null]"
+ data="JIRA=FOO-1234"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ closed_at="2013-04-16"
+ />
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/select-with-component-children.xml b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_component_root.xml
index 8a10dc8568e..a0d42686118 100644
--- a/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/select-with-component-children.xml
+++ b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_component_root.xml
@@ -48,7 +48,7 @@
id="101"
uuid="101"
resource_id="401"
- rule_id="505"
+ rule_id="501"
severity="MAJOR"
manual_severity="[false]"
manual_issue="[false]"
@@ -69,42 +69,5 @@
/>
- <projects
- id="400"
- kee="key"
- enabled="[true]"
- />
-
- <snapshots
- id="100"
- project_id="400"
- root_snapshot_id="[null]"
- path=""
- islast="[false]"
- />
-
- <snapshots
- id="101"
- project_id="400"
- root_snapshot_id="[null]"
- path=""
- islast="[true]"
- />
-
-
- <projects
- id="401"
- kee="child"
- enabled="[true]"
- />
-
- <snapshots
- id="102"
- project_id="401"
- root_snapshot_id="101"
- path="101."
- islast="[true]"
- />
-
</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_date_creation.xml b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_date_creation.xml
new file mode 100644
index 00000000000..4e3977640cf
--- /dev/null
+++ b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_date_creation.xml
@@ -0,0 +1,27 @@
+<dataset>
+
+ <issues
+ id="100"
+ uuid="ABCDE"
+ resource_id="400"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ manual_issue="[false]"
+ title="[null]"
+ message="[null]"
+ line="200"
+ cost="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ user_login="arthur"
+ assignee_login="perceval"
+ person_id="[null]"
+ data="JIRA=FOO-1234"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ closed_at="2013-04-16"
+ />
+
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_id.xml b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_id.xml
new file mode 100644
index 00000000000..2bd2c2ab619
--- /dev/null
+++ b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_id.xml
@@ -0,0 +1,47 @@
+<!--
+ ~ Sonar, open source software quality management tool.
+ ~ Copyright (C) 2008-2012 SonarSource
+ ~ mailto:contact AT sonarsource DOT com
+ ~
+ ~ Sonar 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.
+ ~
+ ~ Sonar 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 Sonar; if not, write to the Free Software
+ ~ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ -->
+
+<dataset>
+
+ <issues
+ id="100"
+ uuid="ABCDE"
+ resource_id="400"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ manual_issue="[false]"
+ title="[null]"
+ message="[null]"
+ line="200"
+ cost="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ user_login="arthur"
+ assignee_login="perceval"
+ person_id="[null]"
+ data="JIRA=FOO-1234"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ closed_at="2013-04-16"
+ />
+
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_key.xml b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_key.xml
new file mode 100644
index 00000000000..4e3977640cf
--- /dev/null
+++ b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_key.xml
@@ -0,0 +1,27 @@
+<dataset>
+
+ <issues
+ id="100"
+ uuid="ABCDE"
+ resource_id="400"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ manual_issue="[false]"
+ title="[null]"
+ message="[null]"
+ line="200"
+ cost="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ user_login="arthur"
+ assignee_login="perceval"
+ person_id="[null]"
+ data="JIRA=FOO-1234"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ closed_at="2013-04-16"
+ />
+
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_query.xml b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_query.xml
new file mode 100644
index 00000000000..4e3977640cf
--- /dev/null
+++ b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_query.xml
@@ -0,0 +1,27 @@
+<dataset>
+
+ <issues
+ id="100"
+ uuid="ABCDE"
+ resource_id="400"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ manual_issue="[false]"
+ title="[null]"
+ message="[null]"
+ line="200"
+ cost="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ user_login="arthur"
+ assignee_login="perceval"
+ person_id="[null]"
+ data="JIRA=FOO-1234"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ closed_at="2013-04-16"
+ />
+
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_rules.xml b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_rules.xml
new file mode 100644
index 00000000000..39b6ef6681d
--- /dev/null
+++ b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_by_rules.xml
@@ -0,0 +1,77 @@
+<dataset>
+
+ <!-- rule 500 -->
+ <issues
+ id="100"
+ uuid="ABCDE"
+ resource_id="400"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ manual_issue="[false]"
+ title="[null]"
+ message="[null]"
+ line="200"
+ cost="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ user_login="arthur"
+ assignee_login="perceval"
+ person_id="[null]"
+ data="JIRA=FOO-1234"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ closed_at="2013-04-16"
+ />
+
+ <issues
+ id="101"
+ uuid="ABCDE"
+ resource_id="400"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ manual_issue="[false]"
+ title="[null]"
+ message="[null]"
+ line="200"
+ cost="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ user_login="arthur"
+ assignee_login="perceval"
+ person_id="[null]"
+ data="JIRA=FOO-1234"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ closed_at="2013-04-16"
+ />
+
+
+ <!-- rule 501 -->
+ <issues
+ id="102"
+ uuid="ABCDE"
+ resource_id="400"
+ rule_id="501"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ manual_issue="[false]"
+ title="[null]"
+ message="[null]"
+ line="200"
+ cost="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ user_login="arthur"
+ assignee_login="perceval"
+ person_id="[null]"
+ data="JIRA=FOO-1234"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ closed_at="2013-04-16"
+ />
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/select-open-issues.xml b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_open_issues.xml
index eb4ad253c36..9f0f803543d 100644
--- a/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/select-open-issues.xml
+++ b/sonar-core/src/test/resources/org/sonar/core/issue/IssueDaoTest/should_select_open_issues.xml
@@ -48,7 +48,7 @@
id="101"
uuid="101"
resource_id="401"
- rule_id="505"
+ rule_id="501"
severity="MAJOR"
manual_severity="[false]"
manual_issue="[false]"
@@ -71,8 +71,8 @@
<issues
id="102"
uuid="102"
- resource_id="402"
- rule_id="505"
+ resource_id="401"
+ rule_id="501"
severity="MAJOR"
manual_severity="[false]"
manual_issue="[false]"
@@ -91,26 +91,4 @@
updated_at="[null]"
closed_at="[null]"
/>
-
- <projects
- id="400"
- kee="key"
- root_id="[null]"
- enabled="[true]"
- />
-
- <projects
- id="401"
- kee="key2"
- root_id="400"
- enabled="[true]"
- />
-
- <projects
- id="402"
- kee="key3"
- root_id="400"
- enabled="[true]"
- />
-
</dataset>
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueChanges.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueChanges.java
index 1185b34f0f6..260d377b449 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueChanges.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueChanges.java
@@ -24,6 +24,10 @@ import org.sonar.api.ServerComponent;
import javax.annotation.Nullable;
+/**
+ * Change existing issues
+ * @since 3.6
+ */
public interface IssueChanges extends BatchComponent, ServerComponent {
Issue apply(Issue issue, IssueChange change);
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueFinder.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueFinder.java
index 144f9d241e8..0377194db41 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueFinder.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueFinder.java
@@ -23,20 +23,26 @@ package org.sonar.api.issue;
import org.sonar.api.ServerComponent;
import javax.annotation.Nullable;
-
import java.util.List;
/**
+ * Search for issues. This component can be used only by server-side extensions. Batch extensions should
+ * use the perspective {@link Issuable}.
+ *
* @since 3.6
*/
public interface IssueFinder extends ServerComponent {
- Results find(IssueQuery issueQuery, @Nullable Integer currentUserId);
-
- Issue findByKey(String key);
-
interface Results {
List<Issue> issues();
}
+ Results find(IssueQuery query, @Nullable Integer currentUserId);
+
+ Issue findByKey(String key /* TODO @Nullable Integer currentUserId */);
+/*
+ Map<RuleKey, Rule> rules(Collection<Issue> issues);
+
+ Map<String, Component> components(Collection<Issue> issues);
+*/
}
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/issues_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/issues_controller.rb
index 0940bc021e3..ac9515d9efe 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/issues_controller.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/issues_controller.rb
@@ -22,18 +22,34 @@ class Api::IssuesController < Api::ApiController
# GET /api/issues/search?<parameters>
def search
- user = current_user ? current_user.id : nil
- results = Api.issues.find(params, user)
- render :json => jsonp(issues_to_json(results.issues))
+ user_id = current_user ? current_user.id : nil
+ results = Api.issues.find(params, user_id)
+ render :json => jsonp(results_to_json(results))
+ end
+
+ # POST /api/issues/change?key=<issue key>&<newSeverity=xxx>&<newResolution=xxx>...
+ def change
+ verify_post_request
+ access_denied unless logged_in?
+
+ # TODO
+ render :json => jsonp({})
+ end
+
+ # POST /api/issues/create?severity=xxx>&<resolution=xxx>&component=<component key>
+ def create
+ verify_post_request
+ access_denied unless logged_in?
+
+ # TODO
+ render :json => jsonp({})
end
private
- def issues_to_json(issues)
- json = []
- issues.each do |issue|
- json << issue_to_json(issue) if issue
- end
+ def results_to_json(results)
+ json = {}
+ json[:issues] = results.issues.map { |issue| issue_to_json(issue) }
json
end
@@ -41,21 +57,21 @@ class Api::IssuesController < Api::ApiController
json = {
:key => issue.key,
:component => issue.componentKey,
- :ruleRepository => issue.ruleKey.repository,
- :rule => issue.ruleKey.rule
+ :rule => issue.ruleKey.toString(),
+ :status => issue.status,
+ :resolution => issue.resolution
}
json[:severity] = issue.severity if issue.severity
json[:title] = issue.title if issue.title
- json[:message] = issue.message if issue.message
+ json[:desc] = issue.message if issue.message
json[:line] = issue.line if issue.line
json[:cost] = issue.cost if issue.cost
- json[:status] = issue.status if issue.status
- json[:resolution] = issue.resolution if issue.resolution
json[:userLogin] = issue.userLogin if issue.userLogin
- json[:assigneeLogin] = issue.assigneeLogin if issue.assigneeLogin
+ json[:assignee] = issue.assigneeLogin if issue.assigneeLogin
json[:createdAt] = format_java_datetime(issue.createdAt) if issue.createdAt
json[:updatedAt] = format_java_datetime(issue.updatedAt) if issue.updatedAt
json[:closedAt] = format_java_datetime(issue.closedAt) if issue.closedAt
+ json[:attr] = issue.attributes.to_hash unless issue.attributes.isEmpty()
json
end