Browse Source

SONAR-4301 Add sort on issue search page

tags/3.6
Julien Lancelot 11 years ago
parent
commit
c93e1fea3a
22 changed files with 589 additions and 73 deletions
  1. 7
    5
      sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java
  2. 36
    25
      sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml
  3. 65
    3
      sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java
  4. 10
    10
      sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_by_ids.xml
  5. 0
    0
      sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_returned_sorted_result_by_assignee.xml
  6. 77
    0
      sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_returned_sorted_result_by_close_date.xml
  7. 74
    0
      sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_returned_sorted_result_by_creation_date.xml
  8. 74
    0
      sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_returned_sorted_result_by_severity.xml
  9. 77
    0
      sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_returned_sorted_result_by_status.xml
  10. 74
    0
      sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_returned_sorted_result_by_update_date.xml
  11. 6
    5
      sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueQuery.java
  12. 2
    1
      sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java
  13. 3
    1
      sonar-server/src/main/java/org/sonar/server/issue/PublicRubyIssueService.java
  14. 0
    1
      sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb
  15. 0
    1
      sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb
  16. 32
    0
      sonar-server/src/main/webapp/WEB-INF/app/helpers/issues_helper.rb
  17. 3
    4
      sonar-server/src/main/webapp/WEB-INF/app/models/issue_filter.rb
  18. 26
    7
      sonar-server/src/main/webapp/WEB-INF/app/views/issues/_list.html.erb
  19. 4
    1
      sonar-server/src/main/webapp/WEB-INF/app/views/issues/_sidebar.html.erb
  20. 5
    0
      sonar-server/src/main/webapp/WEB-INF/app/views/issues/search.html.erb
  21. 10
    9
      sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java
  22. 4
    0
      sonar-server/src/test/java/org/sonar/server/issue/PublicRubyIssueServiceTest.java

+ 7
- 5
sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java View File

@@ -30,6 +30,7 @@ import org.sonar.api.issue.IssueQuery;
import org.sonar.core.persistence.MyBatis;

import javax.annotation.CheckForNull;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -97,21 +98,22 @@ public class IssueDao implements BatchComponent, ServerComponent {
return mapper.selectIssueAndComponentIds(query);
}

Collection<IssueDto> selectByIds(Collection<Long> ids) {
@VisibleForTesting
Collection<IssueDto> selectByIds(Collection<Long> ids, IssueQuery.Sort sort, boolean asc) {
SqlSession session = mybatis.openSession();
try {
return selectByIds(ids, session);
return selectByIds(ids, sort, asc, session);
} finally {
MyBatis.closeQuietly(session);
}
}

public Collection<IssueDto> selectByIds(Collection<Long> ids, SqlSession session) {
public Collection<IssueDto> selectByIds(Collection<Long> ids, IssueQuery.Sort sort, boolean asc, SqlSession session) {
if (ids.isEmpty()) {
return Collections.emptyList();
}
List<List<Long>> idsPartition = Lists.partition(newArrayList(ids), 1000);
Map<String, List<List<Long>>> params = ImmutableMap.of("ids", idsPartition);
Object idsPartition = Lists.partition(newArrayList(ids), 1000);
Map<String, Object> params = ImmutableMap.of("ids", idsPartition, "sort", sort, "asc", asc);
return session.selectList("org.sonar.core.issue.db.IssueMapper.selectByIds", params);
}
}

+ 36
- 25
sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml View File

@@ -32,6 +32,40 @@
p.kee as componentKey
</sql>

<sql id="sortFilter">
<if test="sort != null">
order by
<choose>
<when test="'SEVERITY'.equals(sort.name())">
i.severity
</when>
<when test="'STATUS'.equals(sort.name())">
i.status
</when>
<when test="'ASSIGNEE'.equals(sort.name())">
i.assignee
</when>
<when test="'CREATION_DATE'.equals(sort.name())">
i.issue_creation_date
</when>
<when test="'UPDATE_DATE'.equals(sort.name())">
i.issue_update_date
</when>
<when test="'CLOSE_DATE'.equals(sort.name())">
i.issue_close_date
</when>
</choose>
<choose>
<when test="true.equals(asc)">
asc
</when>
<otherwise>
desc
</otherwise>
</choose>
</if>
</sql>

<insert id="insert" parameterType="Issue" useGeneratedKeys="false" keyProperty="id">
INSERT INTO issues (kee, resource_id, rule_id, action_plan_key, severity, manual_severity,
message, line, effort_to_fix, status,
@@ -115,6 +149,7 @@
and i.rule_id=r.id
and p.id=i.resource_id
</where>
<include refid="sortFilter"/>
</select>

<select id="selectIssueAndComponentIds" parameterType="map" resultType="Issue">
@@ -244,31 +279,7 @@
<if test="sort == null">
order by i.id
</if>
<if test="sort != null">
order by
<choose>
<when test="'CREATION_DATE'.equals(sort.name())">
i.issue_creation_date
</when>
<when test="'UPDATE_DATE'.equals(sort.name())">
i.issue_update_date
</when>
<when test="'CLOSE_DATE'.equals(sort.name())">
i.issue_close_date
</when>
<when test="'ASSIGNEE'.equals(sort.name())">
i.assignee
</when>
</choose>
<choose>
<when test="true.equals(asc)">
asc
</when>
<otherwise>
desc
</otherwise>
</choose>
</if>
<include refid="sortFilter"/>
</sql>

</mapper>

+ 65
- 3
sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java View File

@@ -27,7 +27,6 @@ import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.DateUtils;
import org.sonar.core.persistence.AbstractDaoTestCase;

import java.util.Collection;
import java.util.List;

import static com.google.common.collect.Lists.newArrayList;
@@ -221,9 +220,33 @@ public class IssueDaoTest extends AbstractDaoTestCase {
assertThat(dao.select(query)).hasSize(3);
}

@Test
public void should_select_sort_by_severity() {
setupData("shared", "should_select_returned_sorted_result_by_severity");

IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.SEVERITY).asc(true).build();
List<IssueDto> results = newArrayList(dao.select(query));
assertThat(results).hasSize(3);
assertThat(results.get(0).getSeverity()).isEqualTo("BLOCKER");
assertThat(results.get(1).getSeverity()).isEqualTo("MAJOR");
assertThat(results.get(2).getSeverity()).isEqualTo("MINOR");
}

@Test
public void should_select_sort_by_status() {
setupData("shared", "should_select_returned_sorted_result_by_status");

IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.STATUS).asc(true).build();
List<IssueDto> results = newArrayList(dao.select(query));
assertThat(results).hasSize(3);
assertThat(results.get(0).getStatus()).isEqualTo("CLOSED");
assertThat(results.get(1).getStatus()).isEqualTo("OPEN");
assertThat(results.get(2).getStatus()).isEqualTo("REOPEN");
}

@Test
public void should_select_sort_by_assignee() {
setupData("shared", "should_select_returned_sorted_result");
setupData("shared", "should_select_returned_sorted_result_by_assignee");

IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.ASSIGNEE).asc(true).build();
List<IssueDto> results = newArrayList(dao.select(query));
@@ -233,6 +256,42 @@ public class IssueDaoTest extends AbstractDaoTestCase {
assertThat(results.get(2).getAssignee()).isEqualTo("perceval");
}

@Test
public void should_select_sort_by_creation_date() {
setupData("shared", "should_select_returned_sorted_result_by_creation_date");

IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.CREATION_DATE).asc(false).build();
List<IssueDto> results = newArrayList(dao.select(query));
assertThat(results).hasSize(3);
assertThat(results.get(0).getId()).isEqualTo(102);
assertThat(results.get(1).getId()).isEqualTo(100);
assertThat(results.get(2).getId()).isEqualTo(101);
}

@Test
public void should_select_sort_by_update_date() {
setupData("shared", "should_select_returned_sorted_result_by_update_date");

IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.UPDATE_DATE).asc(false).build();
List<IssueDto> results = newArrayList(dao.select(query));
assertThat(results).hasSize(3);
assertThat(results.get(0).getId()).isEqualTo(102);
assertThat(results.get(1).getId()).isEqualTo(100);
assertThat(results.get(2).getId()).isEqualTo(101);
}

@Test
public void should_select_sort_by_close_date() {
setupData("shared", "should_select_returned_sorted_result_by_close_date");

IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.CLOSE_DATE).asc(false).build();
List<IssueDto> results = newArrayList(dao.select(query));
assertThat(results).hasSize(3);
assertThat(results.get(0).getId()).isEqualTo(102);
assertThat(results.get(1).getId()).isEqualTo(100);
assertThat(results.get(2).getId()).isEqualTo(101);
}

@Test
public void should_select_issue_and_component_ids() {
setupData("shared", "should_select_issue_and_component_ids");
@@ -259,7 +318,10 @@ public class IssueDaoTest extends AbstractDaoTestCase {
public void should_select_by_ids() {
setupData("shared", "should_select_by_ids");

Collection<IssueDto> results = dao.selectByIds(newArrayList(100l, 101l, 102l));
List<IssueDto> results = newArrayList(dao.selectByIds(newArrayList(100l, 101l, 102l), IssueQuery.Sort.CREATION_DATE, false));
assertThat(results).hasSize(3);
assertThat(results.get(0).getId()).isEqualTo(102);
assertThat(results.get(1).getId()).isEqualTo(100);
assertThat(results.get(2).getId()).isEqualTo(101);
}
}

+ 10
- 10
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_by_ids.xml View File

@@ -18,11 +18,11 @@
assignee="perceval"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-16"
issue_update_date="2013-04-16"
issue_close_date="2013-04-16"
created_at="2013-04-16"
updated_at="2013-04-16"
issue_creation_date="2013-04-17"
issue_update_date="2013-04-17"
issue_close_date="2013-04-17"
created_at="2013-04-17"
updated_at="2013-04-17"
/>

<issues
@@ -68,10 +68,10 @@
assignee="perceval"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-16"
issue_update_date="2013-04-16"
issue_close_date="2013-04-16"
created_at="2013-04-16"
updated_at="2013-04-16"
issue_creation_date="2013-04-18"
issue_update_date="2013-04-18"
issue_close_date="2013-04-18"
created_at="2013-04-18"
updated_at="2013-04-18"
/>
</dataset>

sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_returned_sorted_result.xml → sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_returned_sorted_result_by_assignee.xml View File


+ 77
- 0
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_returned_sorted_result_by_close_date.xml View File

@@ -0,0 +1,77 @@
<dataset>

<!-- rule 500 -->
<issues
id="100"
kee="ABCDE-1"
resource_id="401"
rule_id="500"
severity="BLOCKER"
manual_severity="[false]"
message="[null]"
line="200"
effort_to_fix="4.2"
status="OPEN"
resolution="FIXED"
checksum="XXX"
reporter="arthur"
assignee="arthur"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-16"
issue_update_date="2013-04-17"
issue_close_date="2013-04-17"
created_at="2013-04-16"
updated_at="2013-04-17"
/>

<issues
id="101"
kee="ABCDE-2"
resource_id="401"
rule_id="500"
severity="BLOCKER"
manual_severity="[false]"
message="[null]"
line="200"
effort_to_fix="4.2"
status="OPEN"
resolution="FIXED"
checksum="XXX"
reporter="arthur"
assignee="perceval"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-16"
issue_update_date="2013-04-16"
issue_close_date="2013-04-16"
created_at="2013-04-16"
updated_at="2013-04-16"
/>


<!-- rule 501 -->
<issues
id="102"
kee="ABCDE-3"
resource_id="401"
rule_id="501"
severity="BLOCKER"
manual_severity="[false]"
message="[null]"
line="200"
effort_to_fix="4.2"
status="OPEN"
resolution="FIXED"
checksum="XXX"
reporter="arthur"
assignee="henry"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-16"
issue_update_date="2013-04-18"
issue_close_date="2013-04-18"
created_at="2013-04-16"
updated_at="2013-04-18"
/>
</dataset>

+ 74
- 0
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_returned_sorted_result_by_creation_date.xml View File

@@ -0,0 +1,74 @@
<dataset>

<issues
id="100"
kee="ABCDE-1"
resource_id="401"
rule_id="500"
severity="BLOCKER"
manual_severity="[false]"
message="[null]"
line="200"
effort_to_fix="4.2"
status="OPEN"
resolution="FIXED"
checksum="XXX"
reporter="arthur"
assignee="arthur"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-15"
issue_update_date="2013-04-16"
issue_close_date="2013-04-16"
created_at="2013-04-15"
updated_at="2013-04-16"
/>

<issues
id="101"
kee="ABCDE-2"
resource_id="401"
rule_id="500"
severity="BLOCKER"
manual_severity="[false]"
message="[null]"
line="200"
effort_to_fix="4.2"
status="OPEN"
resolution="FIXED"
checksum="XXX"
reporter="arthur"
assignee="perceval"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-14"
issue_update_date="2013-04-16"
issue_close_date="2013-04-16"
created_at="2013-04-14"
updated_at="2013-04-16"
/>

<issues
id="102"
kee="ABCDE-3"
resource_id="401"
rule_id="501"
severity="BLOCKER"
manual_severity="[false]"
message="[null]"
line="200"
effort_to_fix="4.2"
status="OPEN"
resolution="FIXED"
checksum="XXX"
reporter="arthur"
assignee="henry"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-16"
issue_update_date="2013-04-16"
issue_close_date="2013-04-16"
created_at="2013-04-16"
updated_at="2013-04-16"
/>
</dataset>

+ 74
- 0
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_returned_sorted_result_by_severity.xml View File

@@ -0,0 +1,74 @@
<dataset>

<issues
id="100"
kee="ABCDE-1"
resource_id="401"
rule_id="500"
severity="MINOR"
manual_severity="[false]"
message="[null]"
line="200"
effort_to_fix="4.2"
status="OPEN"
resolution="FIXED"
checksum="XXX"
reporter="arthur"
assignee="arthur"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-16"
issue_update_date="2013-04-16"
issue_close_date="2013-04-16"
created_at="2013-04-16"
updated_at="2013-04-16"
/>

<issues
id="101"
kee="ABCDE-2"
resource_id="401"
rule_id="500"
severity="BLOCKER"
manual_severity="[false]"
message="[null]"
line="200"
effort_to_fix="4.2"
status="OPEN"
resolution="FIXED"
checksum="XXX"
reporter="arthur"
assignee="perceval"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-16"
issue_update_date="2013-04-16"
issue_close_date="2013-04-16"
created_at="2013-04-16"
updated_at="2013-04-16"
/>

<issues
id="102"
kee="ABCDE-3"
resource_id="401"
rule_id="501"
severity="MAJOR"
manual_severity="[false]"
message="[null]"
line="200"
effort_to_fix="4.2"
status="OPEN"
resolution="FIXED"
checksum="XXX"
reporter="arthur"
assignee="henry"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-16"
issue_update_date="2013-04-16"
issue_close_date="2013-04-16"
created_at="2013-04-16"
updated_at="2013-04-16"
/>
</dataset>

+ 77
- 0
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_returned_sorted_result_by_status.xml View File

@@ -0,0 +1,77 @@
<dataset>

<!-- rule 500 -->
<issues
id="100"
kee="ABCDE-1"
resource_id="401"
rule_id="500"
severity="BLOCKER"
manual_severity="[false]"
message="[null]"
line="200"
effort_to_fix="4.2"
status="OPEN"
resolution="FIXED"
checksum="XXX"
reporter="arthur"
assignee="arthur"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-16"
issue_update_date="2013-04-16"
issue_close_date="2013-04-16"
created_at="2013-04-16"
updated_at="2013-04-16"
/>

<issues
id="101"
kee="ABCDE-2"
resource_id="401"
rule_id="500"
severity="BLOCKER"
manual_severity="[false]"
message="[null]"
line="200"
effort_to_fix="4.2"
status="CLOSED"
resolution="FIXED"
checksum="XXX"
reporter="arthur"
assignee="perceval"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-16"
issue_update_date="2013-04-16"
issue_close_date="2013-04-16"
created_at="2013-04-16"
updated_at="2013-04-16"
/>


<!-- rule 501 -->
<issues
id="102"
kee="ABCDE-3"
resource_id="401"
rule_id="501"
severity="BLOCKER"
manual_severity="[false]"
message="[null]"
line="200"
effort_to_fix="4.2"
status="REOPEN"
resolution="FIXED"
checksum="XXX"
reporter="arthur"
assignee="henry"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-16"
issue_update_date="2013-04-16"
issue_close_date="2013-04-16"
created_at="2013-04-16"
updated_at="2013-04-16"
/>
</dataset>

+ 74
- 0
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_returned_sorted_result_by_update_date.xml View File

@@ -0,0 +1,74 @@
<dataset>

<issues
id="100"
kee="ABCDE-1"
resource_id="401"
rule_id="500"
severity="BLOCKER"
manual_severity="[false]"
message="[null]"
line="200"
effort_to_fix="4.2"
status="OPEN"
resolution="FIXED"
checksum="XXX"
reporter="arthur"
assignee="arthur"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-16"
issue_update_date="2013-04-17"
issue_close_date="2013-04-17"
created_at="2013-04-16"
updated_at="2013-04-17"
/>

<issues
id="101"
kee="ABCDE-2"
resource_id="401"
rule_id="500"
severity="BLOCKER"
manual_severity="[false]"
message="[null]"
line="200"
effort_to_fix="4.2"
status="OPEN"
resolution="FIXED"
checksum="XXX"
reporter="arthur"
assignee="perceval"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-16"
issue_update_date="2013-04-16"
issue_close_date="2013-04-16"
created_at="2013-04-16"
updated_at="2013-04-16"
/>

<issues
id="102"
kee="ABCDE-3"
resource_id="401"
rule_id="501"
severity="BLOCKER"
manual_severity="[false]"
message="[null]"
line="200"
effort_to_fix="4.2"
status="OPEN"
resolution="FIXED"
checksum="XXX"
reporter="arthur"
assignee="henry"
author_login="[null]"
attributes="JIRA=FOO-1234"
issue_creation_date="2013-04-16"
issue_update_date="2013-04-18"
issue_close_date="2013-04-18"
created_at="2013-04-16"
updated_at="2013-04-18"
/>
</dataset>

+ 6
- 5
sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueQuery.java View File

@@ -25,6 +25,7 @@ import org.sonar.api.rule.RuleKey;

import javax.annotation.CheckForNull;
import javax.annotation.Nullable;

import java.util.Collection;
import java.util.Date;

@@ -39,7 +40,7 @@ public class IssueQuery {
public static final int MAX_ISSUE_KEYS = 500;

public static enum Sort {
CREATION_DATE, UPDATE_DATE, CLOSE_DATE, ASSIGNEE, SEVERITY
CREATION_DATE, UPDATE_DATE, CLOSE_DATE, ASSIGNEE, SEVERITY, STATUS
}

private final Collection<String> issueKeys;
@@ -58,7 +59,7 @@ public class IssueQuery {
private final Date createdAfter;
private final Date createdBefore;
private final Sort sort;
private final boolean asc;
private final Boolean asc;
private final String requiredRole;

// max results per page
@@ -154,7 +155,7 @@ public class IssueQuery {
return sort;
}

public boolean asc() {
public Boolean asc() {
return asc;
}

@@ -197,7 +198,7 @@ public class IssueQuery {
private Date createdAfter;
private Date createdBefore;
private Sort sort;
private boolean asc = false;
private Boolean asc = false;
private Integer pageSize;
private Integer pageIndex;
private String requiredRole;
@@ -297,7 +298,7 @@ public class IssueQuery {
return this;
}

public Builder asc(boolean asc) {
public Builder asc(Boolean asc) {
this.asc = asc;
return this;
}

+ 2
- 1
sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java View File

@@ -46,6 +46,7 @@ import org.sonar.core.user.AuthorizationDao;
import org.sonar.server.platform.UserSession;

import javax.annotation.CheckForNull;

import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -117,7 +118,7 @@ public class DefaultIssueFinder implements IssueFinder {
Set<Long> pagedIssueIds = pagedIssueIds(authorizedIssues, paging);

// 4. Load issues and their related data (rules, components, comments, action plans, ...)
Collection<IssueDto> pagedIssues = issueDao.selectByIds(pagedIssueIds, sqlSession);
Collection<IssueDto> pagedIssues = issueDao.selectByIds(pagedIssueIds, query.sort(), query.asc(), sqlSession);
Map<String, DefaultIssue> issuesByKey = newHashMap();
List<Issue> issues = newArrayList();
Set<Integer> ruleIds = Sets.newHashSet();

+ 3
- 1
sonar-server/src/main/java/org/sonar/server/issue/PublicRubyIssueService.java View File

@@ -32,6 +32,7 @@ import org.sonar.api.web.UserRole;
import org.sonar.server.util.RubyUtils;

import javax.annotation.Nullable;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@@ -84,7 +85,8 @@ public class PublicRubyIssueService implements RubyIssueService {
builder.pageIndex(RubyUtils.toInteger(props.get("pageIndex")));
String sort = (String) props.get("sort");
if (sort != null) {
builder.sort(IssueQuery.Sort.valueOf(sort));
builder.sort(IssueQuery.Sort.valueOf(sort.toUpperCase()));
builder.asc(RubyUtils.toBoolean(props.get("asc")));
}
return builder.build();
}

+ 0
- 1
sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb View File

@@ -32,7 +32,6 @@ class IssuesController < ApplicationController
@filter.criteria=criteria_params
@filter.execute

# TODO replace by project from issues result API
@project = Project.by_key(@filter.criteria('componentRoots')).root_project if @filter.criteria('componentRoots')
end


+ 0
- 1
sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb View File

@@ -912,5 +912,4 @@ module ApplicationHelper
html
end


end

+ 32
- 0
sonar-server/src/main/webapp/WEB-INF/app/helpers/issues_helper.rb View File

@@ -0,0 +1,32 @@
#
# Sonar, entreprise quality control tool.
# Copyright (C) 2008-2013 SonarSource
# mailto:contact AT sonarsource DOT com
#
# SonarQube is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 3 of the License, or (at your option) any later version.
#
# SonarQube is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
module IssuesHelper

def column_html(filter, column_label, column_tooltip, sort)
filter_sort = filter.criteria[:sort]
filter_asc = filter.criteria[:asc] == 'true' ? true : false
html = link_to_function(h(column_label), "refreshList('#{escape_javascript sort}',#{!filter_asc}, #{filter.criteria[:page]||1})", :title => h(column_tooltip))
if sort == filter_sort
html << (filter_asc ? image_tag("asc12.png") : image_tag("desc12.png"))
end
html
end

end

+ 3
- 4
sonar-server/src/main/webapp/WEB-INF/app/models/issue_filter.rb View File

@@ -20,9 +20,6 @@
require 'set'
class IssueFilter

CRITERIA_SEPARATOR = '|'
CRITERIA_KEY_VALUE_SEPARATOR = ','

attr_reader :paging, :issues, :issues_result

def criteria(key=nil)
@@ -75,7 +72,9 @@ class IssueFilter
@issues_result = nil
@paging = nil
@issues = nil
criteria['pageSize'] = 25
criteria['pageSize'] = 100
criteria['sort'] ||= 'CREATION_DATE'
criteria['asc'] ||= 'false'
self
end


+ 26
- 7
sonar-server/src/main/webapp/WEB-INF/app/views/issues/_list.html.erb View File

@@ -1,3 +1,22 @@
<% content_for :script do %>
<script>
var filterCriteria = <%= @filter.criteria.to_json -%>;

function refreshList(sort, asc, page) {
$j('#issue-filter-foot_pages').hide();
$j('#issue-filter-foot_loading').show();

filterCriteria['sort']=sort;
filterCriteria['asc']=asc;
filterCriteria['pageIndex']=page;
var url=baseUrl + '/issues/search?' + $j.param(filterCriteria);

window.location = url;
return false;
}
</script>
<% end %>

<%
if @filter.issues && !@filter.issues.empty?
colspan = 8
@@ -7,10 +26,10 @@
<thead>
<tr>
<th width="1%" nowrap>
<%= message('severity_abbreviated') -%>
<%= column_html(@filter, message('severity_abbreviated'), message('severity'), 'SEVERITY') %>
</th>
<th width="1%" nowrap>
<%= message('status_abbreviated') -%>
<%= column_html(@filter, message('status_abbreviated'), message('status'), 'STATUS') %>
</th>
<th>
<%= message('description') -%>
@@ -19,16 +38,16 @@
<%= message('component') -%>
</th>
<th>
<%= message('issue_filter.header.assignee') -%>
<%= column_html(@filter, message('issue_filter.header.assignee'), message('issue_filter.header.assignee'), 'ASSIGNEE') %>
</th>
<th>
<%= message('issue_filter.header.action_plan') -%>
</th>
<th>
<%= message('issue_filter.header.creation_date') -%>
<%= column_html(@filter, message('issue_filter.header.creation_date'), message('issue_filter.header.creation_date'), 'CREATION_DATE') %>
</th>
<th>
<%= message('issue_filter.header.update_date') -%>
<%= column_html(@filter, message('issue_filter.header.update_date'), message('issue_filter.header.update_date'), 'UPDATE_DATE') %>
</th>
</tr>
</thead>
@@ -44,7 +63,7 @@
<img src="<%= ApplicationController.root_context -%>/images/status/<%= issue.status -%>.png" title="<%= message(issue.status.downcase).capitalize -%>"/>
</td>
<td>
<%= link_to h(issue.message), :controller => 'issue', :action => 'view', :id => issue.key -%>
<%= link_to h(truncate(issue.message, :length => 100)), :controller => 'issue', :action => 'view', :id => issue.key -%>
</td>
<td>
<%= h @filter.issues_result.component(issue).name -%>
@@ -72,7 +91,7 @@
<% end %>
</tbody>

<%= paginate_java(@filter.paging, :colspan => colspan, :include_loading_icon => true) { |label, page_id|
<%= paginate_java(@filter.paging, :colspan => colspan, :id => 'issue-filter-foot', :include_loading_icon => true) { |label, page_id|
link_to(label, @filter.criteria.merge({:pageIndex => page_id}))
} -%>


+ 4
- 1
sonar-server/src/main/webapp/WEB-INF/app/views/issues/_sidebar.html.erb View File

@@ -1,10 +1,13 @@
<ul class="sidebar gray-sidebar">
<form method="GET" action="<%= ApplicationController.root_context -%>/issues/search" >

<input type="hidden" name="sort" value="<%= @filter.criteria('sort')-%>"/>
<input type="hidden" name="asc" value="<%= @filter.criteria('asc') -%>"/>

<li class="sidebar-title">
<%= message('issue_filter.new_search') -%>
</li>
<li id="criteria-project" class="marginbottom5">
<!-- TODO replace by project from issues result API-->
<% selected_project = @project if @filter.criteria('componentRoots') %>
<%= message 'issue_filter.criteria.project' -%>:
<%= resource_select_tag 'componentRoots', :resource_type_property => 'supportsGlobalDashboards', :width => '100%',

+ 5
- 0
sonar-server/src/main/webapp/WEB-INF/app/views/issues/search.html.erb View File

@@ -3,9 +3,14 @@
<%= render :partial => 'issues/sidebar' -%>
</div>


<div class="page-split-right">
<div id="content">
<div class="marginbottom10">
<% if @filter.issues_result && @filter.issues_result.securityExclusions() %>
<p class="notes"><%= message('results_not_display_due_to_security') -%></p>
<% end %>

<%= render :partial => 'list' -%>
</div>
</div>

+ 10
- 9
sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java View File

@@ -53,6 +53,7 @@ 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.Mockito.anyBoolean;
import static org.mockito.Mockito.*;

public class DefaultIssueFinderTest {
@@ -82,7 +83,7 @@ public class DefaultIssueFinderTest {
.setStatus("OPEN").setResolution("OPEN");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
when(issueDao.selectIssueAndComponentIds(eq(query), any(SqlSession.class))).thenReturn(dtoList);
when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList);

IssueQueryResult results = finder.find(query);
assertThat(results.issues()).hasSize(2);
@@ -107,11 +108,11 @@ public class DefaultIssueFinderTest {
List<IssueDto> dtoList = newArrayList(issue1, issue2);
when(issueDao.selectIssueAndComponentIds(eq(query), any(SqlSession.class))).thenReturn(dtoList);
when(authorizationDao.keepAuthorizedComponentIds(anySet(), anyInt(), anyString(), any(SqlSession.class))).thenReturn(newHashSet(123));
when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(newArrayList(issue1));
when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(newArrayList(issue1));

IssueQueryResult results = finder.find(query);

verify(issueDao).selectByIds(eq(newHashSet(1L)), any(SqlSession.class));
verify(issueDao).selectByIds(eq(newHashSet(1L)), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class));
assertThat(results.securityExclusions()).isTrue();
}

@@ -131,7 +132,7 @@ public class DefaultIssueFinderTest {
.setStatus("OPEN").setResolution("OPEN");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
when(issueDao.selectIssueAndComponentIds(eq(query), any(SqlSession.class))).thenReturn(dtoList);
when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList);

IssueQueryResult results = finder.find(query);
assertThat(results.paging().offset()).isEqualTo(0);
@@ -139,7 +140,7 @@ public class DefaultIssueFinderTest {
assertThat(results.paging().pages()).isEqualTo(2);

// Only one result is expected because the limit is 1
verify(issueDao).selectByIds(eq(newHashSet(1L)), any(SqlSession.class));
verify(issueDao).selectByIds(eq(newHashSet(1L)), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class));
}

@Test
@@ -174,7 +175,7 @@ public class DefaultIssueFinderTest {
.setStatus("OPEN").setResolution("OPEN");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
when(issueDao.selectIssueAndComponentIds(eq(query), any(SqlSession.class))).thenReturn(dtoList);
when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList);

IssueQueryResult results = finder.find(query);
assertThat(results.issues()).hasSize(2);
@@ -202,7 +203,7 @@ public class DefaultIssueFinderTest {
.setStatus("OPEN").setResolution("OPEN");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
when(issueDao.selectIssueAndComponentIds(eq(query), any(SqlSession.class))).thenReturn(dtoList);
when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList);

IssueQueryResult results = finder.find(query);
assertThat(results.issues()).hasSize(2);
@@ -230,7 +231,7 @@ public class DefaultIssueFinderTest {
.setStatus("OPEN").setResolution("OPEN");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
when(issueDao.selectIssueAndComponentIds(eq(query), any(SqlSession.class))).thenReturn(dtoList);
when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList);
when(actionPlanService.findByKeys(anyCollection())).thenReturn(newArrayList(actionPlan1, actionPlan2));

IssueQueryResult results = finder.find(query);
@@ -245,7 +246,7 @@ public class DefaultIssueFinderTest {
grantAccessRights();
IssueQuery query = IssueQuery.builder().build();
when(issueDao.selectIssueAndComponentIds(eq(query), any(SqlSession.class))).thenReturn(Collections.<IssueDto>emptyList());
when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(Collections.<IssueDto>emptyList());
when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(Collections.<IssueDto>emptyList());


IssueQueryResult results = finder.find(query);

+ 4
- 0
sonar-server/src/test/java/org/sonar/server/issue/PublicRubyIssueServiceTest.java View File

@@ -74,6 +74,8 @@ public class PublicRubyIssueServiceTest {
map.put("rules", "squid:AvoidCycle,findbugs:NullReference");
map.put("pageSize", 10l);
map.put("pageIndex", 50);
map.put("sort", "creation_date");
map.put("asc", true);

IssueQuery query = new PublicRubyIssueService(finder).toQuery(map);
assertThat(query.issueKeys()).containsOnly("ABCDE1234");
@@ -92,6 +94,8 @@ public class PublicRubyIssueServiceTest {
assertThat(query.createdBefore()).isEqualTo(DateUtils.parseDateTime("2013-04-17T09:08:24+0200"));
assertThat(query.pageSize()).isEqualTo(10);
assertThat(query.pageIndex()).isEqualTo(50);
assertThat(query.sort()).isEqualTo(IssueQuery.Sort.CREATION_DATE);
assertThat(query.asc()).isTrue();
}

@Test

Loading…
Cancel
Save