it.issue.IssueSearchTest.java Source code

Java tutorial

Introduction

Here is the source code for it.issue.IssueSearchTest.java

Source

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

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.time.DateUtils;
import org.assertj.core.api.Fail;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.sonar.wsclient.base.HttpException;
import org.sonar.wsclient.base.Paging;
import org.sonar.wsclient.component.Component;
import org.sonar.wsclient.issue.Issue;
import org.sonar.wsclient.issue.IssueQuery;
import org.sonar.wsclient.issue.Issues;
import org.sonarqube.ws.Common;
import org.sonarqube.ws.client.issue.SearchWsRequest;
import util.ItUtils;

import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.sonarqube.ws.Issues.SearchWsResponse;
import static util.ItUtils.newAdminWsClient;
import static util.ItUtils.runProjectAnalysis;
import static util.ItUtils.setServerProperty;
import static util.ItUtils.toDate;
import static util.ItUtils.verifyHttpException;

public class IssueSearchTest extends AbstractIssueTest {

    private static final String PROJECT_KEY = "com.sonarsource.it.samples:multi-modules-sample";
    private static final String PROJECT_KEY2 = "com.sonarsource.it.samples:multi-modules-sample2";

    private static int DEFAULT_PAGINATED_RESULTS = 100;
    private static int TOTAL_NB_ISSUES = 272;

    @BeforeClass
    public static void prepareData() {
        ORCHESTRATOR.resetData();

        ItUtils.restoreProfile(ORCHESTRATOR, IssueSearchTest.class.getResource("/issue/with-many-rules.xml"));

        // Launch 2 analysis to have more than 100 issues in total
        ORCHESTRATOR.getServer().provisionProject(PROJECT_KEY, PROJECT_KEY);
        ORCHESTRATOR.getServer().associateProjectToQualityProfile(PROJECT_KEY, "xoo", "with-many-rules");
        runProjectAnalysis(ORCHESTRATOR, "shared/xoo-multi-modules-sample");

        ORCHESTRATOR.getServer().provisionProject(PROJECT_KEY2, PROJECT_KEY2);
        ORCHESTRATOR.getServer().associateProjectToQualityProfile(PROJECT_KEY2, "xoo", "with-many-rules");
        runProjectAnalysis(ORCHESTRATOR, "shared/xoo-multi-modules-sample", "sonar.projectKey", PROJECT_KEY2);

        // Assign a issue to test search by assignee
        adminIssueClient().assign(searchRandomIssue().key(), "admin");

        // Resolve a issue to test search by status and by resolution
        adminIssueClient().doTransition(searchRandomIssue().key(), "resolve");
    }

    @Before
    public void resetProperties() throws Exception {
        setServerProperty(ORCHESTRATOR, "sonar.forceAuthentication", "false");
    }

    @Test
    public void search_all_issues() {
        assertThat(search(IssueQuery.create()).list()).hasSize(DEFAULT_PAGINATED_RESULTS);
    }

    @Test
    public void search_issues_by_component_roots() {
        assertThat(search(IssueQuery.create().componentRoots("com.sonarsource.it.samples:multi-modules-sample"))
                .list()).hasSize(DEFAULT_PAGINATED_RESULTS);
        assertThat(search(
                IssueQuery.create().componentRoots("com.sonarsource.it.samples:multi-modules-sample:module_a"))
                        .list()).hasSize(82);
        assertThat(search(IssueQuery.create()
                .componentRoots("com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1")).list())
                        .hasSize(36);

        assertThat(search(IssueQuery.create().componentRoots("unknown")).list()).isEmpty();
    }

    @Test
    public void search_issues_by_components() {
        assertThat(search(IssueQuery.create().components(
                "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo"))
                        .list()).hasSize(34);
        assertThat(search(IssueQuery.create().components("unknown")).list()).isEmpty();
    }

    @Test
    public void search_issues_by_severities() {
        assertThat(search(IssueQuery.create().severities("BLOCKER")).list()).hasSize(8);
        assertThat(search(IssueQuery.create().severities("CRITICAL")).list()).hasSize(8);
        assertThat(search(IssueQuery.create().severities("MAJOR")).list()).hasSize(DEFAULT_PAGINATED_RESULTS);
        assertThat(search(IssueQuery.create().severities("MINOR")).list()).hasSize(DEFAULT_PAGINATED_RESULTS);
        assertThat(search(IssueQuery.create().severities("INFO")).list()).hasSize(4);
    }

    @Test
    public void search_issues_by_statuses() {
        assertThat(search(IssueQuery.create().statuses("OPEN")).list()).hasSize(DEFAULT_PAGINATED_RESULTS);
        assertThat(search(IssueQuery.create().statuses("RESOLVED")).list()).hasSize(1);
        assertThat(search(IssueQuery.create().statuses("CLOSED")).list()).isEmpty();
    }

    @Test
    public void search_issues_by_resolutions() {
        assertThat(search(IssueQuery.create().resolutions("FIXED")).list()).hasSize(1);
        assertThat(search(IssueQuery.create().resolutions("FALSE-POSITIVE")).list()).isEmpty();
        assertThat(search(IssueQuery.create().resolved(true)).list()).hasSize(1);
        assertThat(search(IssueQuery.create().resolved(false)).paging().total()).isEqualTo(TOTAL_NB_ISSUES - 1);
    }

    @Test
    public void search_issues_by_assignees() {
        assertThat(search(IssueQuery.create().assignees("admin")).list()).hasSize(1);
        assertThat(search(IssueQuery.create().assignees("unknown")).list()).isEmpty();
        assertThat(search(IssueQuery.create().assigned(true)).list()).hasSize(1);
        assertThat(search(IssueQuery.create().assigned(false)).paging().total()).isEqualTo(TOTAL_NB_ISSUES - 1);
    }

    @Test
    public void search_issues_by_rules() {
        assertThat(search(IssueQuery.create().rules("xoo:OneIssuePerLine")).list())
                .hasSize(DEFAULT_PAGINATED_RESULTS);
        assertThat(search(IssueQuery.create().rules("xoo:OneIssuePerFile")).list()).hasSize(8);

        try {
            assertThat(search(IssueQuery.create().rules("unknown")).list()).isEmpty();
            fail();
        } catch (Exception e) {
            verifyHttpException(e, 400);
        }
    }

    /**
     * SONAR-2981
     */
    @Test
    public void search_issues_by_dates() {
        // issues have been created today
        Date today = toDate(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
        Date past = toDate("2013-01-01");
        Date future = toDate("2020-12-31");

        // createdAfter in the future => bad request
        try {
            search(IssueQuery.create().createdAfter(future)).list();
            Fail.fail("Expecting 400 from issues search WS");
        } catch (HttpException exception) {
            assertThat(exception.getMessage()).contains("Start bound cannot be in the future");
        }

        // after date
        assertThat(search(IssueQuery.create().createdAfter(today)).list().size()).isGreaterThan(0);
        assertThat(search(IssueQuery.create().createdAfter(past)).list().size()).isGreaterThan(0);

        // before
        assertThat(search(IssueQuery.create().createdBefore(future)).list().size()).isGreaterThan(0);
        assertThat(search(IssueQuery.create().createdBefore(past)).list()).isEmpty();

        // before and after
        assertThat(search(IssueQuery.create().createdBefore(future).createdAfter(past)).list().size())
                .isGreaterThan(0);

        // createdAfter > createdBefore => bad request
        try {
            search(IssueQuery.create().createdBefore(past).createdAfter(today)).list();
            Fail.fail("Expecting 400 from issues search WS");
        } catch (HttpException exception) {
            assertThat(exception.getMessage()).contains("Start bound cannot be larger or equal to end bound");
        }

    }

    /**
     * SONAR-5132
     */
    @Test
    public void search_issues_by_languages() {
        assertThat(search(IssueQuery.create().languages("xoo")).list()).hasSize(DEFAULT_PAGINATED_RESULTS);
        assertThat(search(IssueQuery.create().languages("foo")).list()).isEmpty();
    }

    @Test
    public void paginate_results() {
        Issues issues = search(IssueQuery.create().pageSize(20).pageIndex(2));

        assertThat(issues.list()).hasSize(20);
        Paging paging = issues.paging();
        assertThat(paging.pageIndex()).isEqualTo(2);
        assertThat(paging.pageSize()).isEqualTo(20);
        assertThat(paging.total()).isEqualTo(TOTAL_NB_ISSUES);

        // SONAR-3257
        // return max page size results when using negative page size value
        assertThat(search(IssueQuery.create().pageSize(0)).list()).hasSize(TOTAL_NB_ISSUES);
        assertThat(search(IssueQuery.create().pageSize(-1)).list()).hasSize(TOTAL_NB_ISSUES);
    }

    @Test
    public void sort_results() {
        List<Issue> issues = search(IssueQuery.create().sort("SEVERITY").asc(false)).list();
        assertThat(issues.get(0).severity()).isEqualTo("BLOCKER");
        assertThat(issues.get(8).severity()).isEqualTo("CRITICAL");
        assertThat(issues.get(17).severity()).isEqualTo("MAJOR");
    }

    /**
     * SONAR-4563
     */
    @Test
    public void search_by_exact_creation_date() {
        final Issue issue = search(IssueQuery.create()).list().get(0);
        assertThat(issue.creationDate()).isNotNull();

        // search the issue key with the same date
        assertThat(search(IssueQuery.create().issues().issues(issue.key()).createdAt(issue.creationDate())).list())
                .hasSize(1);

        // search issue key with 1 second more and less should return nothing
        assertThat(search(IssueQuery.create().issues().issues(issue.key())
                .createdAt(DateUtils.addSeconds(issue.creationDate(), 1))).size()).isEqualTo(0);
        assertThat(search(IssueQuery.create().issues().issues(issue.key())
                .createdAt(DateUtils.addSeconds(issue.creationDate(), -1))).size()).isEqualTo(0);

        // search with future and past dates that do not match any issues
        assertThat(search(IssueQuery.create().createdAt(toDate("2020-01-01"))).size()).isEqualTo(0);
        assertThat(search(IssueQuery.create().createdAt(toDate("2010-01-01"))).size()).isEqualTo(0);
    }

    @Test
    public void components_contain_sub_project_id_and_project_id_informations() {
        String fileKey = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo";

        Issues issues = issueClient().find(IssueQuery.create().components(fileKey));
        assertThat(issues.list()).isNotEmpty();

        Collection<Component> components = issues.components();

        Component project = findComponent(components, "com.sonarsource.it.samples:multi-modules-sample");
        assertThat(project.subProjectId()).isNull();
        assertThat(project.projectId()).isNull();

        Component subModuleA1 = findComponent(components,
                "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1");
        assertThat(subModuleA1.subProjectId()).isEqualTo(project.id());
        assertThat(subModuleA1.projectId()).isEqualTo(project.id());

        Component file = findComponent(components, fileKey);
        assertThat(file.subProjectId()).isNotNull();
        assertThat(file.projectId()).isNotNull();

        Issue issue = issues.list().get(0);
        assertThat(issues.component(issue)).isNotNull();
        assertThat(issues.component(issue).subProjectId()).isEqualTo(subModuleA1.id());
        assertThat(issues.component(issue).projectId()).isEqualTo(project.id());
    }

    @Test
    public void return_issue_type() throws Exception {
        List<org.sonarqube.ws.Issues.Issue> issues = searchByRuleKey("xoo:OneBugIssuePerLine");
        assertThat(issues).isNotEmpty();
        org.sonarqube.ws.Issues.Issue issue = issues.get(0);
        assertThat(issue.getType()).isEqualTo(Common.RuleType.BUG);

        issues = searchByRuleKey("xoo:OneVulnerabilityIssuePerModule");
        assertThat(issues).isNotEmpty();
        issue = issues.get(0);
        assertThat(issue.getType()).isEqualTo(Common.RuleType.VULNERABILITY);

        issues = searchByRuleKey("xoo:OneIssuePerLine");
        assertThat(issues).isNotEmpty();
        issue = issues.get(0);
        assertThat(issue.getType()).isEqualTo(Common.RuleType.CODE_SMELL);
    }

    @Test
    public void search_issues_by_types() throws IOException {
        assertThat(searchIssues(new SearchWsRequest().setTypes(singletonList("CODE_SMELL"))).getPaging().getTotal())
                .isEqualTo(142);
        assertThat(searchIssues(new SearchWsRequest().setTypes(singletonList("BUG"))).getPaging().getTotal())
                .isEqualTo(122);
        assertThat(
                searchIssues(new SearchWsRequest().setTypes(singletonList("VULNERABILITY"))).getPaging().getTotal())
                        .isEqualTo(8);
    }

    private List<org.sonarqube.ws.Issues.Issue> searchByRuleKey(String... ruleKey) throws IOException {
        return searchIssues(new SearchWsRequest().setRules(asList(ruleKey))).getIssuesList();
    }

    private SearchWsResponse searchIssues(SearchWsRequest request) throws IOException {
        return newAdminWsClient(ORCHESTRATOR).issues().search(request);
    }

    private static Component findComponent(Collection<Component> components, String key) {
        return components.stream().filter(input -> key.equals(input.key())).findFirst()
                .orElseThrow(() -> new IllegalStateException("Component key not found: " + key));
    }

}