From 9e07f99785a2f3b33118b6fdcc27b9b889e079d2 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Thu, 10 Aug 2017 19:04:38 +0200 Subject: [PATCH] Fix bad merge of SearchActionComponentsTest Tests on application has been removed when merging SearchActionComponentsMediumTest to SearchActionComponentsTest --- .../issue/ws/SearchActionComponentsTest.java | 341 +++++++-- .../issue/ws/SearchActionMediumTest.java | 698 ------------------ .../server/issue/ws/SearchActionTest.java | 670 ++++++++++++++++- ...apply_paging_with_multiple_components.json | 0 .../apply_paging_with_one_component.json | 0 ...st_escape_login_of_authenticated_user.json | 0 .../assigned_to_me_facet_sticky.json | 0 .../components_contains_sub_projects.json | 0 .../default_page_size_is_100.json | 0 .../deprecated_paging.json | 0 .../display_deprecated_debt_fields.json | 0 .../display_facets.json | 0 .../display_facets_effort.json | 0 .../display_zero_facets.json | 0 .../empty_result.json | 0 .../filter_by_assigned_to_me.json | 0 .../hide_rules.json | 0 .../ignore_paging_with_one_component.json | 0 .../issue_on_removed_file.json | 0 .../issue_with_comment_hidden.json | 0 .../issue_with_comments.json | 0 .../load_additional_fields.json | 0 ...al_fields_with_issue_admin_permission.json | 0 .../no_issue.json | 0 .../paging.json | 0 .../paging_with_page_size_to_minus_one.json | 0 ...s_all_fields_except_additional_fields.json | 0 .../sort_by_updated_at.json | 0 28 files changed, 923 insertions(+), 786 deletions(-) delete mode 100644 server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/apply_paging_with_multiple_components.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/apply_paging_with_one_component.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/assignedToMe_facet_must_escape_login_of_authenticated_user.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/assigned_to_me_facet_sticky.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/components_contains_sub_projects.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/default_page_size_is_100.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/deprecated_paging.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/display_deprecated_debt_fields.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/display_facets.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/display_facets_effort.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/display_zero_facets.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/empty_result.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/filter_by_assigned_to_me.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/hide_rules.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/ignore_paging_with_one_component.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/issue_on_removed_file.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/issue_with_comment_hidden.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/issue_with_comments.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/load_additional_fields.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/load_additional_fields_with_issue_admin_permission.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/no_issue.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/paging.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/paging_with_page_size_to_minus_one.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/response_contains_all_fields_except_additional_fields.json (100%) rename server/sonar-server/src/test/resources/org/sonar/server/issue/ws/{SearchActionMediumTest => SearchActionTest}/sort_by_updated_at.json (100%) diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java index 29fac927c51..fcea82be27a 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java @@ -20,6 +20,7 @@ package org.sonar.server.issue.ws; import java.io.IOException; +import java.util.Date; import java.util.List; import org.junit.After; import org.junit.Before; @@ -59,56 +60,63 @@ import org.sonar.server.issue.workflow.FunctionExecutor; import org.sonar.server.issue.workflow.IssueWorkflow; import org.sonar.server.permission.index.AuthorizationTypeSupport; import org.sonar.server.permission.index.PermissionIndexer; +import org.sonar.server.permission.index.PermissionIndexerTester; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.view.index.ViewDoc; import org.sonar.server.view.index.ViewIndexDefinition; import org.sonar.server.view.index.ViewIndexer; import org.sonar.server.ws.WsActionTester; import org.sonar.server.ws.WsResponseCommonFormat; -import org.sonarqube.ws.Issues; +import org.sonarqube.ws.Issues.Issue; import org.sonarqube.ws.Issues.SearchWsResponse; import org.sonarqube.ws.client.issue.IssuesWsParameters; import static com.google.common.collect.Lists.newArrayList; import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.api.utils.DateUtils.addDays; import static org.sonar.api.utils.DateUtils.parseDateTime; import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01; import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newModuleDto; +import static org.sonar.db.component.ComponentTesting.newProjectCopy; import static org.sonar.db.component.SnapshotTesting.newAnalysis; +import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMPONENT_KEYS; +import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PROJECT_KEYS; +import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SINCE_LEAK_PERIOD; public class SearchActionComponentsTest { @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); + public UserSessionRule userSession = UserSessionRule.standalone(); @Rule - public DbTester dbTester = DbTester.create(); + public DbTester db = DbTester.create(); @Rule - public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings().asConfig()), new ViewIndexDefinition(new MapSettings().asConfig())); - - private DbClient db = dbTester.getDbClient(); - private DbSession session = dbTester.getSession(); - private IssueIndex issueIndex = new IssueIndex(esTester.client(), System2.INSTANCE, userSessionRule, new AuthorizationTypeSupport(userSessionRule)); - private IssueIndexer issueIndexer = new IssueIndexer(esTester.client(), db, new IssueIteratorFactory(db)); - private ViewIndexer viewIndexer = new ViewIndexer(db, esTester.client()); - private IssueQueryFactory issueQueryFactory = new IssueQueryFactory(db, System2.INSTANCE, userSessionRule); + public EsTester es = new EsTester(new IssueIndexDefinition(new MapSettings().asConfig()), new ViewIndexDefinition(new MapSettings().asConfig())); + + private DbClient dbClient = db.getDbClient(); + private DbSession session = db.getSession(); + private IssueIndex issueIndex = new IssueIndex(es.client(), System2.INSTANCE, userSession, new AuthorizationTypeSupport(userSession)); + private IssueIndexer issueIndexer = new IssueIndexer(es.client(), dbClient, new IssueIteratorFactory(dbClient)); + private ViewIndexer viewIndexer = new ViewIndexer(dbClient, es.client()); + private IssueQueryFactory issueQueryFactory = new IssueQueryFactory(dbClient, System2.INSTANCE, userSession); private IssueFieldsSetter issueFieldsSetter = new IssueFieldsSetter(); private IssueWorkflow issueWorkflow = new IssueWorkflow(new FunctionExecutor(issueFieldsSetter), issueFieldsSetter); - private SearchResponseLoader searchResponseLoader = new SearchResponseLoader(userSessionRule, db, new ActionFinder(userSessionRule), new TransitionService(userSessionRule, issueWorkflow)); + private SearchResponseLoader searchResponseLoader = new SearchResponseLoader(userSession, dbClient, new ActionFinder(userSession), new TransitionService(userSession, issueWorkflow)); private Languages languages = new Languages(); private SearchResponseFormat searchResponseFormat = new SearchResponseFormat(new Durations(), new WsResponseCommonFormat(languages), languages, new AvatarResolverImpl()); - private WsActionTester wsTester = new WsActionTester(new SearchAction(userSessionRule, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat)); + private WsActionTester ws = new WsActionTester(new SearchAction(userSession, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat)); private OrganizationDto defaultOrganization; private OrganizationDto otherOrganization1; private OrganizationDto otherOrganization2; - private StartupIndexer permissionIndexer = new PermissionIndexer(db, esTester.client(), issueIndexer); + private PermissionIndexerTester permissionIndexerTester = new PermissionIndexerTester(es, issueIndexer); + private StartupIndexer permissionIndexer = new PermissionIndexer(dbClient, es.client(), issueIndexer); @Before public void setUp() { - session = db.openSession(false); - OrganizationDao organizationDao = db.organizationDao(); - this.defaultOrganization = dbTester.getDefaultOrganization(); + session = dbClient.openSession(false); + OrganizationDao organizationDao = dbClient.organizationDao(); + this.defaultOrganization = db.getDefaultOrganization(); this.otherOrganization1 = OrganizationTesting.newOrganizationDto().setKey("my-org-1"); this.otherOrganization2 = OrganizationTesting.newOrganizationDto().setKey("my-org-2"); organizationDao.insert(session, this.otherOrganization1, false); @@ -132,7 +140,7 @@ public class SearchActionComponentsTest { .setSeverity("MAJOR") .setIssueCreationDate(DateUtils.parseDateTime("2014-09-04T00:00:00+0100")) .setIssueUpdateDate(DateUtils.parseDateTime("2017-12-04T00:00:00+0100")); - db.issueDao().insert(session, issue); + dbClient.issueDao().insert(session, issue); ComponentDto project2 = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "P2").setDbKey("PK2")); ComponentDto file2 = insertComponent(newFileDto(project2, null, "F2").setDbKey("FK2")); @@ -142,12 +150,12 @@ public class SearchActionComponentsTest { .setSeverity("MAJOR") .setIssueCreationDate(DateUtils.parseDateTime("2014-09-04T00:00:00+0100")) .setIssueUpdateDate(DateUtils.parseDateTime("2017-12-04T00:00:00+0100")); - db.issueDao().insert(session, issue2); + dbClient.issueDao().insert(session, issue2); session.commit(); indexIssues(); indexPermissions(); - wsTester.newRequest() + ws.newRequest() .execute() .assertJson(this.getClass(), "issues_on_different_projects.json"); } @@ -160,15 +168,15 @@ public class SearchActionComponentsTest { RuleDto newRule = newRule(); IssueDto issueInModule = IssueTesting.newDto(newRule, file, project).setKee("ISSUE_IN_MODULE"); IssueDto issueInRootModule = IssueTesting.newDto(newRule, project, project).setKee("ISSUE_IN_ROOT_MODULE"); - db.issueDao().insert(session, issueInModule, issueInRootModule); + dbClient.issueDao().insert(session, issueInModule, issueInRootModule); session.commit(); indexIssues(); indexPermissions(); - SearchWsResponse searchResponse = wsTester.newRequest().executeProtobuf(SearchWsResponse.class); + SearchWsResponse searchResponse = ws.newRequest().executeProtobuf(SearchWsResponse.class); assertThat(searchResponse.getIssuesCount()).isEqualTo(2); - for (Issues.Issue issue : searchResponse.getIssuesList()) { + for (Issue issue : searchResponse.getIssuesList()) { assertThat(issue.getProject()).isEqualTo("PK1"); if (issue.getKey().equals("ISSUE_IN_MODULE")) { assertThat(issue.getSubProject()).isEqualTo("MK1"); @@ -183,27 +191,27 @@ public class SearchActionComponentsTest { ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "P1").setDbKey("PK1")); ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1")); IssueDto issue = IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); - db.issueDao().insert(session, issue); + dbClient.issueDao().insert(session, issue); session.commit(); indexIssues(); indexPermissions(); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_PROJECT_UUIDS, project.uuid()) .execute() .assertJson(this.getClass(), "search_by_project_uuid.json"); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_PROJECT_UUIDS, "unknown") .execute() .assertJson(this.getClass(), "no_issue.json"); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, project.uuid()) .execute() .assertJson(this.getClass(), "search_by_project_uuid.json"); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, "unknown") .execute() .assertJson(this.getClass(), "no_issue.json"); @@ -213,7 +221,7 @@ public class SearchActionComponentsTest { public void search_since_leak_period_on_project() throws Exception { ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "P1").setDbKey("PK1")); ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1")); - db.snapshotDao().insert(session, + dbClient.snapshotDao().insert(session, newAnalysis(project) .setPeriodDate(parseDateTime("2015-09-03T00:00:00+0100").getTime())); RuleDto rule = newRule(); @@ -225,14 +233,14 @@ public class SearchActionComponentsTest { .setKee(UUID_EXAMPLE_02) .setIssueCreationDate(parseDateTime("2014-09-04T00:00:00+0100")) .setIssueUpdateDate(parseDateTime("2015-10-04T00:00:00+0100")); - db.issueDao().insert(session, issueAfterLeak, issueBeforeLeak); + dbClient.issueDao().insert(session, issueAfterLeak, issueBeforeLeak); session.commit(); indexIssues(); indexPermissions(); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, project.uuid()) - .setParam(IssuesWsParameters.PARAM_SINCE_LEAK_PERIOD, "true") + .setParam(PARAM_SINCE_LEAK_PERIOD, "true") .execute() .assertJson(this.getClass(), "search_since_leak_period.json"); } @@ -242,7 +250,7 @@ public class SearchActionComponentsTest { ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1")); ComponentDto module = insertComponent(newModuleDto(project)); ComponentDto file = insertComponent(newFileDto(module, null, "F1").setDbKey("FK1")); - db.snapshotDao().insert(session, + dbClient.snapshotDao().insert(session, newAnalysis(project).setPeriodDate(parseDateTime("2015-09-03T00:00:00+0100").getTime())); RuleDto rule = newRule(); IssueDto issueAfterLeak = IssueTesting.newDto(rule, file, project) @@ -253,15 +261,15 @@ public class SearchActionComponentsTest { .setKee(UUID_EXAMPLE_02) .setIssueCreationDate(parseDateTime("2014-09-04T00:00:00+0100")) .setIssueUpdateDate(parseDateTime("2015-10-04T00:00:00+0100")); - db.issueDao().insert(session, issueAfterLeak, issueBeforeLeak); + dbClient.issueDao().insert(session, issueAfterLeak, issueBeforeLeak); session.commit(); indexIssues(); indexPermissions(); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, project.uuid()) .setParam(IssuesWsParameters.PARAM_FILE_UUIDS, file.uuid()) - .setParam(IssuesWsParameters.PARAM_SINCE_LEAK_PERIOD, "true") + .setParam(PARAM_SINCE_LEAK_PERIOD, "true") .execute() .assertJson(this.getClass(), "search_since_leak_period.json"); } @@ -278,12 +286,12 @@ public class SearchActionComponentsTest { IssueDto issue1 = IssueTesting.newDto(rule, file1, project1).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); IssueDto issue2 = IssueTesting.newDto(rule, file2, project2).setKee("2bd4eac2-b650-4037-80bc-7b1182fd47d4"); IssueDto issue3 = IssueTesting.newDto(rule, file3, project3).setKee("7b1182fd-b650-4037-80bc-82fd47d4eac2"); - db.issueDao().insert(session, issue1, issue2, issue3); + dbClient.issueDao().insert(session, issue1, issue2, issue3); session.commit(); indexIssues(); indexPermissions(); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_PROJECT_UUIDS, project1.uuid()) .setParam(WebService.Param.FACETS, "projectUuids") .execute() @@ -295,27 +303,27 @@ public class SearchActionComponentsTest { ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1")); ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1")); IssueDto issue = IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); - db.issueDao().insert(session, issue); + dbClient.issueDao().insert(session, issue); session.commit(); indexIssues(); indexPermissions(); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_FILE_UUIDS, file.uuid()) .execute() .assertJson(this.getClass(), "search_by_file_uuid.json"); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_FILE_UUIDS, "unknown") .execute() .assertJson(this.getClass(), "no_issue.json"); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, file.uuid()) .execute() .assertJson(this.getClass(), "search_by_file_uuid.json"); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, "unknown") .execute() .assertJson(this.getClass(), "no_issue.json"); @@ -329,17 +337,17 @@ public class SearchActionComponentsTest { RuleDto rule = newRule(); IssueDto issueOnFile = IssueTesting.newDto(rule, file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); IssueDto issueOnTest = IssueTesting.newDto(rule, unitTest, project).setKee("2bd4eac2-b650-4037-80bc-7b1182fd47d4"); - db.issueDao().insert(session, issueOnFile, issueOnTest); + dbClient.issueDao().insert(session, issueOnFile, issueOnTest); session.commit(); indexIssues(); indexPermissions(); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENTS, file.getDbKey()) .execute() .assertJson(this.getClass(), "search_by_file_key.json"); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENTS, unitTest.getDbKey()) .execute() .assertJson(this.getClass(), "search_by_test_key.json"); @@ -354,12 +362,12 @@ public class SearchActionComponentsTest { RuleDto newRule = newRule(); IssueDto issue1 = IssueTesting.newDto(newRule, file1, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); IssueDto issue2 = IssueTesting.newDto(newRule, file2, project).setKee("2bd4eac2-b650-4037-80bc-7b1182fd47d4"); - db.issueDao().insert(session, issue1, issue2); + dbClient.issueDao().insert(session, issue1, issue2); session.commit(); indexIssues(); indexPermissions(); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, project.uuid()) .setParam(IssuesWsParameters.PARAM_FILE_UUIDS, file1.uuid() + "," + file3.uuid()) .setParam(WebService.Param.FACETS, "fileUuids") @@ -373,27 +381,27 @@ public class SearchActionComponentsTest { ComponentDto directory = insertComponent(ComponentTesting.newDirectory(project, "D1", "src/main/java/dir")); ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1").setPath(directory.path() + "/MyComponent.java")); IssueDto issue = IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); - db.issueDao().insert(session, issue); + dbClient.issueDao().insert(session, issue); session.commit(); indexIssues(); indexPermissions(); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, directory.uuid()) .execute() .assertJson(this.getClass(), "search_by_file_uuid.json"); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, "unknown") .execute() .assertJson(this.getClass(), "no_issue.json"); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java/dir") .execute() .assertJson(this.getClass(), "search_by_file_uuid.json"); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java") .execute() .assertJson(this.getClass(), "no_issue.json"); @@ -410,39 +418,39 @@ public class SearchActionComponentsTest { insertComponent(newFileDto(module2, directory2, "F2").setDbKey("FK2").setPath(directory2.path() + "/MyComponent.java")); RuleDto rule = newRule(); IssueDto issue1 = IssueTesting.newDto(rule, file1, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); - db.issueDao().insert(session, issue1); + dbClient.issueDao().insert(session, issue1); session.commit(); indexIssues(); indexPermissions(); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, directory1.uuid()) .execute() .assertJson(this.getClass(), "search_by_directory_uuid.json"); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, directory2.uuid()) .execute() .assertJson(this.getClass(), "no_issue.json"); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_MODULE_UUIDS, module1.uuid()) .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java/dir") .execute() .assertJson(this.getClass(), "search_by_directory_uuid.json"); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_MODULE_UUIDS, module2.uuid()) .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java/dir") .execute() .assertJson(this.getClass(), "no_issue.json"); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java/dir") .execute() .assertJson(this.getClass(), "search_by_directory_uuid.json"); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java") .execute() .assertJson(this.getClass(), "no_issue.json"); @@ -460,12 +468,12 @@ public class SearchActionComponentsTest { RuleDto newRule = newRule(); IssueDto issue1 = IssueTesting.newDto(newRule, file1, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); IssueDto issue2 = IssueTesting.newDto(newRule, file2, project).setKee("2bd4eac2-b650-4037-80bc-7b1182fd47d4"); - db.issueDao().insert(session, issue1, issue2); + dbClient.issueDao().insert(session, issue1, issue2); session.commit(); indexIssues(); indexPermissions(); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, module.uuid()) .setParam(IssuesWsParameters.PARAM_MODULE_UUIDS, subModule1.uuid() + "," + subModule3.uuid()) .setParam(WebService.Param.FACETS, "moduleUuids") @@ -479,13 +487,13 @@ public class SearchActionComponentsTest { ComponentDto directory = insertComponent(ComponentTesting.newDirectory(project, "D1", "src/main/java/dir")); ComponentDto file = insertComponent(newFileDto(project, directory, "F1").setDbKey("FK1").setPath(directory.path() + "/MyComponent.java")); IssueDto issue = IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); - db.issueDao().insert(session, issue); + dbClient.issueDao().insert(session, issue); session.commit(); indexIssues(); indexPermissions(); - userSessionRule.logIn("john"); - wsTester.newRequest() + userSession.logIn("john"); + ws.newRequest() .setParam("resolved", "false") .setParam(WebService.Param.FACETS, "directories") .execute() @@ -502,10 +510,10 @@ public class SearchActionComponentsTest { insertIssue(IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")); - userSessionRule.logIn("john") + userSession.logIn("john") .registerComponents(project, file, view); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, view.uuid()) .execute() .assertJson(this.getClass(), "search_by_view_uuid.json"); @@ -523,9 +531,9 @@ public class SearchActionComponentsTest { indexView(subView.uuid(), newArrayList(project.uuid())); indexPermissions(); - userSessionRule.logIn("john") + userSession.logIn("john") .registerComponents(project, file, view, subView); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, subView.uuid()) .execute() .assertJson(this.getClass(), "search_by_view_uuid.json"); @@ -543,10 +551,10 @@ public class SearchActionComponentsTest { indexView(subView.uuid(), newArrayList(project.uuid())); // User has wrong permission on the view, no issue will be returned - userSessionRule.logIn("john") + userSession.logIn("john") .registerComponents(project, file, view, subView); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, subView.uuid()) .execute() .assertJson(this.getClass(), "no_issue.json"); @@ -561,21 +569,195 @@ public class SearchActionComponentsTest { IssueDto issue2 = IssueTesting.newDto(newRule, file, project).setAuthorLogin("luke@skywalker.name").setKee("82fd47d4-b650-4037-80bc-7b1182fd47d4"); indexPermissions(); - db.issueDao().insert(session, issue1, issue2); + dbClient.issueDao().insert(session, issue1, issue2); session.commit(); indexIssues(); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_AUTHORS, "leia") .setParam(WebService.Param.FACETS, "authors") .execute() .assertJson(this.getClass(), "search_by_authors.json"); - wsTester.newRequest() + ws.newRequest() .setParam(IssuesWsParameters.PARAM_AUTHORS, "unknown") .execute() .assertJson(this.getClass(), "no_issue.json"); + } + @Test + public void search_by_application_key() throws Exception { + ComponentDto project1 = db.components().insertPublicProject(); + ComponentDto project2 = db.components().insertPublicProject(); + ComponentDto application = db.components().insertApplication(db.getDefaultOrganization()); + db.components().insertComponents(newProjectCopy("PC1", project1, application)); + db.components().insertComponents(newProjectCopy("PC2", project2, application)); + IssueDto issue1 = db.issues().insertIssue(i -> i.setProject(project1)); + IssueDto issue2 = db.issues().insertIssue(i -> i.setProject(project2)); + userSession.registerComponents(application, project1, project2); + permissionIndexerTester.allowOnlyAnyone(project1); + permissionIndexerTester.allowOnlyAnyone(project2); + indexIssuesAndViews(); + + SearchWsResponse result = ws.newRequest() + .setParam(PARAM_COMPONENT_KEYS, application.getDbKey()) + .executeProtobuf(SearchWsResponse.class); + + assertThat(result.getIssuesList()).extracting(Issue::getKey) + .containsExactlyInAnyOrder(issue1.getKey(), issue2.getKey()); + } + @Test + public void ignore_application_without_browse_permission() { + ComponentDto project = db.components().insertPublicProject(); + ComponentDto application = db.components().insertApplication(db.getDefaultOrganization()); + db.components().insertComponents(newProjectCopy("PC1", project, application)); + db.issues().insertIssue(i -> i.setProject(project)); + userSession.registerComponents(project); + permissionIndexerTester.allowOnlyAnyone(project); + indexIssuesAndViews(); + + SearchWsResponse result = ws.newRequest() + .setParam(PARAM_COMPONENT_KEYS, application.getDbKey()) + .executeProtobuf(SearchWsResponse.class); + + assertThat(result.getIssuesList()).isEmpty(); + } + + @Test + public void search_application_without_projects() { + ComponentDto project = db.components().insertPublicProject(); + ComponentDto application = db.components().insertApplication(db.getDefaultOrganization()); + db.issues().insertIssue(i -> i.setProject(project)); + userSession.registerComponents(application, project); + permissionIndexerTester.allowOnlyAnyone(project); + indexIssuesAndViews(); + + SearchWsResponse result = ws.newRequest() + .setParam(PARAM_COMPONENT_KEYS, application.getDbKey()) + .executeProtobuf(SearchWsResponse.class); + + assertThat(result.getIssuesList()).isEmpty(); + } + + @Test + public void search_by_application_and_by_leak() throws Exception { + Date now = new Date(); + ComponentDto application = db.components().insertApplication(db.getDefaultOrganization()); + // Project 1 + ComponentDto project1 = db.components().insertPublicProject(); + db.components().insertSnapshot(project1, s -> s.setPeriodDate(addDays(now, -14).getTime())); + db.components().insertComponents(newProjectCopy("PC1", project1, application)); + IssueDto project1Issue1 = db.issues().insertIssue(i -> i.setProject(project1).setIssueCreationDate(addDays(now, -10))); + IssueDto project1Issue2 = db.issues().insertIssue(i -> i.setProject(project1).setIssueCreationDate(addDays(now, -20))); + // Project 2 + ComponentDto project2 = db.components().insertPublicProject(); + db.components().insertSnapshot(project2, s -> s.setPeriodDate(addDays(now, -25).getTime())); + db.components().insertComponents(newProjectCopy("PC2", project2, application)); + IssueDto project2Issue1 = db.issues().insertIssue(i -> i.setProject(project2).setIssueCreationDate(addDays(now, -15))); + IssueDto project2Issue2 = db.issues().insertIssue(i -> i.setProject(project2).setIssueCreationDate(addDays(now, -30))); + // Permissions and index + userSession.registerComponents(application, project1, project2); + permissionIndexerTester.allowOnlyAnyone(project1); + permissionIndexerTester.allowOnlyAnyone(project2); + indexIssuesAndViews(); + + SearchWsResponse result = ws.newRequest() + .setParam(PARAM_COMPONENT_KEYS, application.getDbKey()) + .setParam(PARAM_SINCE_LEAK_PERIOD, "true") + .executeProtobuf(SearchWsResponse.class); + + assertThat(result.getIssuesList()).extracting(Issue::getKey) + .containsExactlyInAnyOrder(project1Issue1.getKey(), project2Issue1.getKey()) + .doesNotContain(project1Issue2.getKey(), project2Issue2.getKey()); + } + + @Test + public void search_by_application_and_project() throws Exception { + ComponentDto project1 = db.components().insertPublicProject(); + ComponentDto project2 = db.components().insertPublicProject(); + ComponentDto application = db.components().insertApplication(db.getDefaultOrganization()); + db.components().insertComponents(newProjectCopy("PC1", project1, application)); + db.components().insertComponents(newProjectCopy("PC2", project2, application)); + IssueDto issue1 = db.issues().insertIssue(i -> i.setProject(project1)); + IssueDto issue2 = db.issues().insertIssue(i -> i.setProject(project2)); + userSession.registerComponents(application, project1, project2); + permissionIndexerTester.allowOnlyAnyone(project1); + permissionIndexerTester.allowOnlyAnyone(project2); + indexIssuesAndViews(); + + SearchWsResponse result = ws.newRequest() + .setParam(PARAM_COMPONENT_KEYS, application.getDbKey()) + .setParam(PARAM_PROJECT_KEYS, project1.getDbKey()) + .executeProtobuf(SearchWsResponse.class); + + assertThat(result.getIssuesList()).extracting(Issue::getKey) + .containsExactlyInAnyOrder(issue1.getKey()) + .doesNotContain(issue2.getKey()); + } + + @Test + public void search_by_application_and_project_and_leak() throws Exception { + Date now = new Date(); + ComponentDto application = db.components().insertApplication(db.getDefaultOrganization()); + // Project 1 + ComponentDto project1 = db.components().insertPublicProject(); + db.components().insertSnapshot(project1, s -> s.setPeriodDate(addDays(now, -14).getTime())); + db.components().insertComponents(newProjectCopy("PC1", project1, application)); + IssueDto project1Issue1 = db.issues().insertIssue(i -> i.setProject(project1).setIssueCreationDate(addDays(now, -10))); + IssueDto project1Issue2 = db.issues().insertIssue(i -> i.setProject(project1).setIssueCreationDate(addDays(now, -20))); + // Project 2 + ComponentDto project2 = db.components().insertPublicProject(); + db.components().insertSnapshot(project2, s -> s.setPeriodDate(addDays(now, -25).getTime())); + db.components().insertComponents(newProjectCopy("PC2", project2, application)); + IssueDto project2Issue1 = db.issues().insertIssue(i -> i.setProject(project2).setIssueCreationDate(addDays(now, -15))); + IssueDto project2Issue2 = db.issues().insertIssue(i -> i.setProject(project2).setIssueCreationDate(addDays(now, -30))); + // Permissions and index + userSession.registerComponents(application, project1, project2); + permissionIndexerTester.allowOnlyAnyone(project1); + permissionIndexerTester.allowOnlyAnyone(project2); + indexIssuesAndViews(); + + SearchWsResponse result = ws.newRequest() + .setParam(PARAM_COMPONENT_KEYS, application.getDbKey()) + .setParam(PARAM_PROJECT_KEYS, project1.getDbKey()) + .setParam(PARAM_SINCE_LEAK_PERIOD, "true") + .executeProtobuf(SearchWsResponse.class); + + assertThat(result.getIssuesList()).extracting(Issue::getKey) + .containsExactlyInAnyOrder(project1Issue1.getKey()) + .doesNotContain(project1Issue2.getKey(), project2Issue1.getKey(), project2Issue2.getKey()); + } + + @Test + public void search_by_application_and_by_leak_when_one_project_has_no_leak() throws Exception { + Date now = new Date(); + ComponentDto application = db.components().insertApplication(db.getDefaultOrganization()); + // Project 1 + ComponentDto project1 = db.components().insertPublicProject(); + db.components().insertSnapshot(project1, s -> s.setPeriodDate(addDays(now, -14).getTime())); + db.components().insertComponents(newProjectCopy("PC1", project1, application)); + IssueDto project1Issue1 = db.issues().insertIssue(i -> i.setProject(project1).setIssueCreationDate(addDays(now, -10))); + IssueDto project1Issue2 = db.issues().insertIssue(i -> i.setProject(project1).setIssueCreationDate(addDays(now, -20))); + // Project 2, without leak => no issue form it should be returned + ComponentDto project2 = db.components().insertPublicProject(); + db.components().insertSnapshot(project2, s -> s.setPeriodDate(null)); + db.components().insertComponents(newProjectCopy("PC2", project2, application)); + IssueDto project2Issue1 = db.issues().insertIssue(i -> i.setProject(project2).setIssueCreationDate(addDays(now, -15))); + IssueDto project2Issue2 = db.issues().insertIssue(i -> i.setProject(project2).setIssueCreationDate(addDays(now, -30))); + // Permissions and index + userSession.registerComponents(application, project1, project2); + permissionIndexerTester.allowOnlyAnyone(project1); + permissionIndexerTester.allowOnlyAnyone(project2); + indexIssuesAndViews(); + + SearchWsResponse result = ws.newRequest() + .setParam(PARAM_COMPONENT_KEYS, application.getDbKey()) + .setParam(PARAM_SINCE_LEAK_PERIOD, "true") + .executeProtobuf(SearchWsResponse.class); + + assertThat(result.getIssuesList()).extracting(Issue::getKey) + .containsExactlyInAnyOrder(project1Issue1.getKey()) + .doesNotContain(project1Issue2.getKey(), project2Issue1.getKey(), project2Issue2.getKey()); } private RuleDto newRule() { @@ -583,7 +765,7 @@ public class SearchActionComponentsTest { .setName("Rule name") .setDescription("Rule desc") .setStatus(RuleStatus.READY); - dbTester.rules().insert(rule.getDefinition()); + db.rules().insert(rule.getDefinition()); session.commit(); return rule; } @@ -593,14 +775,14 @@ public class SearchActionComponentsTest { } private IssueDto insertIssue(IssueDto issue) { - db.issueDao().insert(session, issue); + dbClient.issueDao().insert(session, issue); session.commit(); indexIssues(); return issue; } private ComponentDto insertComponent(ComponentDto component) { - db.componentDao().insert(session, component); + dbClient.componentDao().insert(session, component); session.commit(); return component; } @@ -612,4 +794,9 @@ public class SearchActionComponentsTest { private void indexView(String viewUuid, List projects) { viewIndexer.index(new ViewDoc().setUuid(viewUuid).setProjects(projects)); } + + private void indexIssuesAndViews() { + issueIndexer.indexOnStartup(null); + viewIndexer.indexOnStartup(null); + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java deleted file mode 100644 index 9e8da6622b1..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java +++ /dev/null @@ -1,698 +0,0 @@ -/* - * 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 org.sonar.server.issue.ws; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.config.internal.MapSettings; -import org.sonar.api.issue.Issue; -import org.sonar.api.resources.Languages; -import org.sonar.api.rule.RuleStatus; -import org.sonar.api.server.ws.WebService; -import org.sonar.api.utils.DateUtils; -import org.sonar.api.utils.Durations; -import org.sonar.api.utils.System2; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentTesting; -import org.sonar.db.issue.IssueChangeDto; -import org.sonar.db.issue.IssueDto; -import org.sonar.db.issue.IssueTesting; -import org.sonar.db.organization.OrganizationDao; -import org.sonar.db.organization.OrganizationDto; -import org.sonar.db.organization.OrganizationTesting; -import org.sonar.db.permission.GroupPermissionDto; -import org.sonar.db.rule.RuleDto; -import org.sonar.db.rule.RuleTesting; -import org.sonar.db.user.UserDto; -import org.sonar.server.es.EsTester; -import org.sonar.server.es.SearchOptions; -import org.sonar.server.es.StartupIndexer; -import org.sonar.server.issue.ActionFinder; -import org.sonar.server.issue.IssueFieldsSetter; -import org.sonar.server.issue.IssueQuery; -import org.sonar.server.issue.IssueQueryFactory; -import org.sonar.server.issue.TransitionService; -import org.sonar.server.issue.index.IssueIndex; -import org.sonar.server.issue.index.IssueIndexDefinition; -import org.sonar.server.issue.index.IssueIndexer; -import org.sonar.server.issue.index.IssueIteratorFactory; -import org.sonar.server.issue.workflow.FunctionExecutor; -import org.sonar.server.issue.workflow.IssueWorkflow; -import org.sonar.server.permission.index.AuthorizationTypeSupport; -import org.sonar.server.permission.index.PermissionIndexer; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.TestResponse; -import org.sonar.server.ws.WsActionTester; -import org.sonar.server.ws.WsResponseCommonFormat; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonarqube.ws.client.issue.IssuesWsParameters.DEPRECATED_FACET_MODE_DEBT; -import static org.sonarqube.ws.client.issue.IssuesWsParameters.FACET_MODE_EFFORT; -import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ADDITIONAL_FIELDS; -import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMPONENTS; -import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_AFTER; -import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_HIDE_COMMENTS; -import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PAGE_INDEX; -import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PAGE_SIZE; - -public class SearchActionMediumTest { - - @Rule - public UserSessionRule userSessionRule = UserSessionRule.standalone(); - @Rule - public DbTester dbTester = DbTester.create(); - @Rule - public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings().asConfig())); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - private DbClient db = dbTester.getDbClient(); - private DbSession session = dbTester.getSession(); - private IssueIndex issueIndex = new IssueIndex(esTester.client(), System2.INSTANCE, userSessionRule, new AuthorizationTypeSupport(userSessionRule)); - private IssueIndexer issueIndexer = new IssueIndexer(esTester.client(), db, new IssueIteratorFactory(db)); - private IssueQueryFactory issueQueryFactory = new IssueQueryFactory(db, System2.INSTANCE, userSessionRule); - private IssueFieldsSetter issueFieldsSetter = new IssueFieldsSetter(); - private IssueWorkflow issueWorkflow = new IssueWorkflow(new FunctionExecutor(issueFieldsSetter), issueFieldsSetter); - private SearchResponseLoader searchResponseLoader = new SearchResponseLoader(userSessionRule, db, new ActionFinder(userSessionRule), new TransitionService(userSessionRule, issueWorkflow)); - private Languages languages = new Languages(); - private SearchResponseFormat searchResponseFormat = new SearchResponseFormat(new Durations(), new WsResponseCommonFormat(languages), languages, new AvatarResolverImpl()); - private WsActionTester wsTester = new WsActionTester(new SearchAction(userSessionRule, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat)); - private OrganizationDto defaultOrganization; - private OrganizationDto otherOrganization1; - private OrganizationDto otherOrganization2; - private StartupIndexer permissionIndexer = new PermissionIndexer(db, esTester.client(), issueIndexer); - - @Before - public void setUp() { - OrganizationDao organizationDao = db.organizationDao(); - this.defaultOrganization = dbTester.getDefaultOrganization(); - this.otherOrganization1 = OrganizationTesting.newOrganizationDto().setKey("my-org-1"); - this.otherOrganization2 = OrganizationTesting.newOrganizationDto().setKey("my-org-2"); - organizationDao.insert(session, this.otherOrganization1, false); - organizationDao.insert(session, this.otherOrganization2, false); - session.commit(); - issueWorkflow.start(); - } - - @Test - public void empty_search() throws Exception { - TestResponse result = wsTester.newRequest() - .execute(); - - assertThat(result).isNotNull(); - result.assertJson(this.getClass(), "empty_result.json"); - } - - @Test - public void response_contains_all_fields_except_additional_fields() throws Exception { - db.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com")); - db.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); - - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); - IssueDto issue = IssueTesting.newDto(newRule(), file, project) - .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") - .setEffort(10L) - .setMessage("the message") - .setStatus(Issue.STATUS_RESOLVED) - .setResolution(Issue.RESOLUTION_FIXED) - .setSeverity("MAJOR") - .setAuthorLogin("John") - .setAssignee("simon") - .setTags(asList("bug", "owasp")) - .setIssueCreationDate(DateUtils.parseDateTime("2014-09-04T00:00:00+0100")) - .setIssueUpdateDate(DateUtils.parseDateTime("2017-12-04T00:00:00+0100")); - db.issueDao().insert(session, issue); - session.commit(); - issueIndexer.indexOnStartup(issueIndexer.getIndexTypes()); - - wsTester.newRequest().execute() - .assertJson(this.getClass(), "response_contains_all_fields_except_additional_fields.json"); - } - - @Test - public void issue_with_comments() throws Exception { - db.userDao().insert(session, new UserDto().setLogin("john").setName("John")); - db.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); - - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); - IssueDto issue = IssueTesting.newDto(newRule(), file, project) - .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); - db.issueDao().insert(session, issue); - - db.issueChangeDao().insert(session, - new IssueChangeDto().setIssueKey(issue.getKey()) - .setKey("COMMENT-ABCD") - .setChangeData("*My comment*") - .setChangeType(IssueChangeDto.TYPE_COMMENT) - .setUserLogin("john") - .setCreatedAt(DateUtils.parseDateTime("2014-09-09T12:00:00+0000").getTime())); - db.issueChangeDao().insert(session, - new IssueChangeDto().setIssueKey(issue.getKey()) - .setKey("COMMENT-ABCE") - .setChangeData("Another comment") - .setChangeType(IssueChangeDto.TYPE_COMMENT) - .setUserLogin("fabrice") - .setCreatedAt(DateUtils.parseDateTime("2014-09-10T12:00:00+0000").getTime())); - session.commit(); - indexIssues(); - - userSessionRule.logIn("john"); - wsTester.newRequest() - .setParam("additionalFields", "comments,users") - .execute() - .assertJson(this.getClass(), "issue_with_comments.json"); - } - - @Test - public void issue_with_comment_hidden() throws Exception { - db.userDao().insert(session, new UserDto().setLogin("john").setName("John").setEmail("john@email.com")); - db.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); - - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); - IssueDto issue = IssueTesting.newDto(newRule(), file, project) - .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); - db.issueDao().insert(session, issue); - - db.issueChangeDao().insert(session, - new IssueChangeDto().setIssueKey(issue.getKey()) - .setKey("COMMENT-ABCD") - .setChangeData("*My comment*") - .setChangeType(IssueChangeDto.TYPE_COMMENT) - .setUserLogin("john") - .setCreatedAt(DateUtils.parseDateTime("2014-09-09T12:00:00+0000").getTime())); - db.issueChangeDao().insert(session, - new IssueChangeDto().setIssueKey(issue.getKey()) - .setKey("COMMENT-ABCE") - .setChangeData("Another comment") - .setChangeType(IssueChangeDto.TYPE_COMMENT) - .setUserLogin("fabrice") - .setCreatedAt(DateUtils.parseDateTime("2014-09-10T19:10:03+0000").getTime())); - session.commit(); - indexIssues(); - - userSessionRule.logIn("john"); - TestResponse result = wsTester.newRequest().setParam(PARAM_HIDE_COMMENTS, "true").execute(); - result.assertJson(this.getClass(), "issue_with_comment_hidden.json"); - assertThat(result.getInput()).doesNotContain("fabrice"); - } - - @Test - public void load_additional_fields() throws Exception { - db.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com")); - db.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY").setLanguage("java")); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY").setLanguage("js")); - - IssueDto issue = IssueTesting.newDto(newRule(), file, project) - .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") - .setAuthorLogin("John") - .setAssignee("simon"); - db.issueDao().insert(session, issue); - session.commit(); - indexIssues(); - - userSessionRule.logIn("john"); - wsTester.newRequest() - .setParam("additionalFields", "_all").execute() - .assertJson(this.getClass(), "load_additional_fields.json"); - } - - @Test - public void load_additional_fields_with_issue_admin_permission() throws Exception { - db.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com")); - db.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY").setLanguage("java")); - grantPermissionToAnyone(project, ISSUE_ADMIN); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY").setLanguage("js")); - - IssueDto issue = IssueTesting.newDto(newRule(), file, project) - .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") - .setAuthorLogin("John") - .setAssignee("simon"); - db.issueDao().insert(session, issue); - session.commit(); - indexIssues(); - - userSessionRule.logIn("john") - .addProjectPermission(ISSUE_ADMIN, project); // granted by Anyone - wsTester.newRequest() - .setParam("additionalFields", "_all").execute() - .assertJson(this.getClass(), "load_additional_fields_with_issue_admin_permission.json"); - } - - @Test - public void issue_on_removed_file() throws Exception { - RuleDto rule = newRule(); - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); - indexPermissions(); - ComponentDto removedFile = insertComponent(ComponentTesting.newFileDto(project, null).setUuid("REMOVED_FILE_ID") - .setDbKey("REMOVED_FILE_KEY") - .setEnabled(false)); - - IssueDto issue = IssueTesting.newDto(rule, removedFile, project) - .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") - .setComponent(removedFile) - .setStatus("OPEN").setResolution("OPEN") - .setSeverity("MAJOR") - .setIssueCreationDate(DateUtils.parseDateTime("2014-09-04T00:00:00+0100")) - .setIssueUpdateDate(DateUtils.parseDateTime("2017-12-04T00:00:00+0100")); - db.issueDao().insert(session, issue); - session.commit(); - indexIssues(); - - wsTester.newRequest() - .execute() - .assertJson(this.getClass(), "issue_on_removed_file.json"); - } - - @Test - public void apply_paging_with_one_component() throws Exception { - RuleDto rule = newRule(); - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); - for (int i = 0; i < SearchOptions.MAX_LIMIT + 1; i++) { - IssueDto issue = IssueTesting.newDto(rule, file, project); - db.issueDao().insert(session, issue); - } - session.commit(); - indexIssues(); - - wsTester.newRequest().setParam(PARAM_COMPONENTS, file.getDbKey()).execute() - .assertJson(this.getClass(), "apply_paging_with_one_component.json"); - } - - @Test - public void components_contains_sub_projects() throws Exception { - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("ProjectHavingModule")); - indexPermissions(); - ComponentDto module = insertComponent(ComponentTesting.newModuleDto(project).setDbKey("ModuleHavingFile")); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(module, null, "BCDE").setDbKey("FileLinkedToModule")); - IssueDto issue = IssueTesting.newDto(newRule(), file, project); - db.issueDao().insert(session, issue); - session.commit(); - indexIssues(); - - wsTester.newRequest().setParam(PARAM_ADDITIONAL_FIELDS, "_all").execute() - .assertJson(this.getClass(), "components_contains_sub_projects.json"); - } - - @Test - public void display_facets() throws Exception { - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); - IssueDto issue = IssueTesting.newDto(newRule(), file, project) - .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) - .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) - .setEffort(10L) - .setStatus("OPEN") - .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") - .setSeverity("MAJOR"); - db.issueDao().insert(session, issue); - session.commit(); - indexIssues(); - - userSessionRule.logIn("john"); - wsTester.newRequest() - .setParam("resolved", "false") - .setParam(WebService.Param.FACETS, "statuses,severities,resolutions,projectUuids,rules,fileUuids,assignees,languages,actionPlans,types") - .execute() - .assertJson(this.getClass(), "display_facets.json"); - } - - @Test - public void display_facets_in_effort_mode() throws Exception { - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); - IssueDto issue = IssueTesting.newDto(newRule(), file, project) - .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) - .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) - .setEffort(10L) - .setStatus("OPEN") - .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") - .setSeverity("MAJOR"); - db.issueDao().insert(session, issue); - session.commit(); - indexIssues(); - - userSessionRule.logIn("john"); - wsTester.newRequest() - .setParam("resolved", "false") - .setParam(WebService.Param.FACETS, "statuses,severities,resolutions,projectUuids,rules,fileUuids,assignees,languages,actionPlans") - .setParam("facetMode", FACET_MODE_EFFORT) - .execute() - .assertJson(this.getClass(), "display_facets_effort.json"); - } - - @Test - public void display_zero_valued_facets_for_selected_items() throws Exception { - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); - IssueDto issue = IssueTesting.newDto(newRule(), file, project) - .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) - .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) - .setEffort(10L) - .setStatus("OPEN") - .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") - .setSeverity("MAJOR"); - db.issueDao().insert(session, issue); - session.commit(); - indexIssues(); - - userSessionRule.logIn("john"); - wsTester.newRequest() - .setParam("resolved", "false") - .setParam("severities", "MAJOR,MINOR") - .setParam("languages", "xoo,polop,palap") - .setParam(WebService.Param.FACETS, "statuses,severities,resolutions,projectUuids,rules,fileUuids,assignees,assigned_to_me,languages,actionPlans") - .execute() - .assertJson(this.getClass(), "display_zero_facets.json"); - } - - @Test - public void assignedToMe_facet_must_escape_login_of_authenticated_user() throws Exception { - // login looks like an invalid regexp - userSessionRule.logIn("foo["); - - // should not fail - wsTester.newRequest() - .setParam(WebService.Param.FACETS, "assigned_to_me") - .execute() - .assertJson(this.getClass(), "assignedToMe_facet_must_escape_login_of_authenticated_user.json"); - - } - - @Test - public void filter_by_assigned_to_me() throws Exception { - db.userDao().insert(session, new UserDto().setLogin("john").setName("John").setEmail("john@email.com")); - - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "PROJECT_ID").setDbKey("PROJECT_KEY")); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); - RuleDto rule = newRule(); - IssueDto issue1 = IssueTesting.newDto(rule, file, project) - .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) - .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) - .setEffort(10L) - .setStatus("OPEN") - .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") - .setSeverity("MAJOR") - .setAssignee("john"); - IssueDto issue2 = IssueTesting.newDto(rule, file, project) - .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) - .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) - .setEffort(10L) - .setStatus("OPEN") - .setKee("7b112bd4-b650-4037-80bc-82fd47d4eac2") - .setSeverity("MAJOR") - .setAssignee("alice"); - IssueDto issue3 = IssueTesting.newDto(rule, file, project) - .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) - .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) - .setEffort(10L) - .setStatus("OPEN") - .setKee("82fd47d4-4037-b650-80bc-7b112bd4eac2") - .setSeverity("MAJOR"); - db.issueDao().insert(session, issue1, issue2, issue3); - session.commit(); - indexIssues(); - - userSessionRule.logIn("john"); - wsTester.newRequest() - .setParam("resolved", "false") - .setParam("assignees", "__me__") - .setParam(WebService.Param.FACETS, "assignees,assigned_to_me") - .execute() - .assertJson(this.getClass(), "filter_by_assigned_to_me.json"); - } - - @Test - public void filter_by_assigned_to_me_unauthenticated() throws Exception { - userSessionRule.logIn(); - - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); - RuleDto rule = newRule(); - IssueDto issue1 = IssueTesting.newDto(rule, file, project) - .setStatus("OPEN") - .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") - .setAssignee("john"); - IssueDto issue2 = IssueTesting.newDto(rule, file, project) - .setStatus("OPEN") - .setKee("7b112bd4-b650-4037-80bc-82fd47d4eac2") - .setAssignee("alice"); - IssueDto issue3 = IssueTesting.newDto(rule, file, project) - .setStatus("OPEN") - .setKee("82fd47d4-4037-b650-80bc-7b112bd4eac2"); - db.issueDao().insert(session, issue1, issue2, issue3); - session.commit(); - indexIssues(); - - wsTester.newRequest() - .setParam("resolved", "false") - .setParam("assignees", "__me__") - .execute() - .assertJson(this.getClass(), "empty_result.json"); - } - - @Test - public void assigned_to_me_facet_is_sticky_relative_to_assignees() throws Exception { - db.userDao().insert(session, new UserDto().setLogin("alice").setName("Alice").setEmail("alice@email.com")); - - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); - RuleDto rule = newRule(); - IssueDto issue1 = IssueTesting.newDto(rule, file, project) - .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) - .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) - .setEffort(10L) - .setStatus("OPEN") - .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") - .setSeverity("MAJOR") - .setAssignee("john-bob.polop"); - IssueDto issue2 = IssueTesting.newDto(rule, file, project) - .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) - .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) - .setEffort(10L) - .setStatus("OPEN") - .setKee("7b112bd4-b650-4037-80bc-82fd47d4eac2") - .setSeverity("MAJOR") - .setAssignee("alice"); - IssueDto issue3 = IssueTesting.newDto(rule, file, project) - .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) - .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) - .setEffort(10L) - .setStatus("OPEN") - .setKee("82fd47d4-4037-b650-80bc-7b112bd4eac2") - .setSeverity("MAJOR"); - db.issueDao().insert(session, issue1, issue2, issue3); - session.commit(); - indexIssues(); - - userSessionRule.logIn("john-bob.polop"); - wsTester.newRequest() - .setParam("resolved", "false") - .setParam("assignees", "alice") - .setParam(WebService.Param.FACETS, "assignees,assigned_to_me") - .execute() - .assertJson(this.getClass(), "assigned_to_me_facet_sticky.json"); - } - - @Test - public void sort_by_updated_at() throws Exception { - RuleDto rule = newRule(); - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); - db.issueDao().insert(session, IssueTesting.newDto(rule, file, project) - .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac1") - .setIssueUpdateDate(DateUtils.parseDateTime("2014-11-02T00:00:00+0100"))); - db.issueDao().insert(session, IssueTesting.newDto(rule, file, project) - .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") - .setIssueUpdateDate(DateUtils.parseDateTime("2014-11-01T00:00:00+0100"))); - db.issueDao().insert(session, IssueTesting.newDto(rule, file, project) - .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac3") - .setIssueUpdateDate(DateUtils.parseDateTime("2014-11-03T00:00:00+0100"))); - session.commit(); - indexIssues(); - - wsTester.newRequest() - .setParam("sort", IssueQuery.SORT_BY_UPDATE_DATE) - .setParam("asc", "false") - .execute() - .assertJson(this.getClass(), "sort_by_updated_at.json"); - } - - @Test - public void paging() throws Exception { - RuleDto rule = newRule(); - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); - for (int i = 0; i < 12; i++) { - IssueDto issue = IssueTesting.newDto(rule, file, project); - db.issueDao().insert(session, issue); - } - session.commit(); - indexIssues(); - - wsTester.newRequest() - .setParam(WebService.Param.PAGE, "2") - .setParam(WebService.Param.PAGE_SIZE, "9") - .execute() - .assertJson(this.getClass(), "paging.json"); - } - - @Test - public void paging_with_page_size_to_minus_one() throws Exception { - RuleDto rule = newRule(); - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); - for (int i = 0; i < 12; i++) { - IssueDto issue = IssueTesting.newDto(rule, file, project); - db.issueDao().insert(session, issue); - } - session.commit(); - indexIssues(); - - wsTester.newRequest() - .setParam(WebService.Param.PAGE, "1") - .setParam(WebService.Param.PAGE_SIZE, "-1") - .execute() - .assertJson(this.getClass(), "paging_with_page_size_to_minus_one.json"); - } - - @Test - public void deprecated_paging() throws Exception { - RuleDto rule = newRule(); - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "PROJECT_ID").setDbKey("PROJECT_KEY")); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); - for (int i = 0; i < 12; i++) { - IssueDto issue = IssueTesting.newDto(rule, file, project); - db.issueDao().insert(session, issue); - } - session.commit(); - indexIssues(); - - wsTester.newRequest() - .setParam(PARAM_PAGE_INDEX, "2") - .setParam(PARAM_PAGE_SIZE, "9") - .execute() - .assertJson(this.getClass(), "deprecated_paging.json"); - } - - @Test - public void default_page_size_is_100() throws Exception { - wsTester.newRequest() - .execute() - .assertJson(this.getClass(), "default_page_size_is_100.json"); - } - - @Test - public void display_deprecated_debt_fields() throws Exception { - ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); - indexPermissions(); - ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); - IssueDto issue = IssueTesting.newDto(newRule(), file, project) - .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) - .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) - .setEffort(10L) - .setStatus("OPEN") - .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") - .setSeverity("MAJOR"); - db.issueDao().insert(session, issue); - session.commit(); - indexIssues(); - - userSessionRule.logIn("john"); - wsTester.newRequest() - .setParam("resolved", "false") - .setParam(WebService.Param.FACETS, "severities") - .setParam("facetMode", DEPRECATED_FACET_MODE_DEBT) - .execute() - .assertJson(this.getClass(), "display_deprecated_debt_fields.json"); - } - - @Test - public void fail_when_invalid_format() throws Exception { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Date 'wrong-date-input' cannot be parsed as either a date or date+time"); - - wsTester.newRequest() - .setParam(PARAM_CREATED_AFTER, "wrong-date-input") - .execute(); - } - - private RuleDto newRule() { - RuleDto rule = RuleTesting.newXooX1() - .setName("Rule name") - .setDescription("Rule desc") - .setStatus(RuleStatus.READY); - dbTester.rules().insert(rule.getDefinition()); - return rule; - } - - private void indexPermissions() { - permissionIndexer.indexOnStartup(permissionIndexer.getIndexTypes()); - } - - private void indexIssues() { - issueIndexer.indexOnStartup(issueIndexer.getIndexTypes()); - } - - private void grantPermissionToAnyone(ComponentDto project, String permission) { - db.groupPermissionDao().insert(session, - new GroupPermissionDto() - .setOrganizationUuid(project.getOrganizationUuid()) - .setGroupId(null) - .setResourceId(project.getId()) - .setRole(permission)); - session.commit(); - userSessionRule.logIn().addProjectPermission(permission, project); - } - - private ComponentDto insertComponent(ComponentDto component) { - db.componentDao().insert(session, component); - session.commit(); - return component; - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java index 20cf8e1ea69..f264318b94b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java @@ -19,33 +19,104 @@ */ package org.sonar.server.issue.ws; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.sonar.api.config.internal.MapSettings; +import org.sonar.api.issue.Issue; +import org.sonar.api.resources.Languages; +import org.sonar.api.rule.RuleStatus; import org.sonar.api.server.ws.WebService; -import org.sonar.api.server.ws.WebService.Param; +import org.sonar.api.utils.DateUtils; +import org.sonar.api.utils.Durations; +import org.sonar.api.utils.System2; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.component.ComponentDto; +import org.sonar.db.component.ComponentTesting; +import org.sonar.db.issue.IssueChangeDto; +import org.sonar.db.issue.IssueDto; +import org.sonar.db.issue.IssueTesting; +import org.sonar.db.organization.OrganizationDao; +import org.sonar.db.organization.OrganizationDto; +import org.sonar.db.organization.OrganizationTesting; +import org.sonar.db.permission.GroupPermissionDto; +import org.sonar.db.rule.RuleDto; +import org.sonar.db.rule.RuleTesting; +import org.sonar.db.user.UserDto; +import org.sonar.server.es.EsTester; +import org.sonar.server.es.SearchOptions; +import org.sonar.server.es.StartupIndexer; +import org.sonar.server.issue.ActionFinder; +import org.sonar.server.issue.IssueFieldsSetter; +import org.sonar.server.issue.IssueQuery; import org.sonar.server.issue.IssueQueryFactory; +import org.sonar.server.issue.TransitionService; import org.sonar.server.issue.index.IssueIndex; +import org.sonar.server.issue.index.IssueIndexDefinition; +import org.sonar.server.issue.index.IssueIndexer; +import org.sonar.server.issue.index.IssueIteratorFactory; +import org.sonar.server.issue.workflow.FunctionExecutor; +import org.sonar.server.issue.workflow.IssueWorkflow; +import org.sonar.server.permission.index.AuthorizationTypeSupport; +import org.sonar.server.permission.index.PermissionIndexer; import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.TestResponse; import org.sonar.server.ws.WsActionTester; +import org.sonar.server.ws.WsResponseCommonFormat; +import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; +import static org.sonar.api.web.UserRole.ISSUE_ADMIN; +import static org.sonarqube.ws.client.issue.IssuesWsParameters.DEPRECATED_FACET_MODE_DEBT; +import static org.sonarqube.ws.client.issue.IssuesWsParameters.FACET_MODE_EFFORT; +import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ADDITIONAL_FIELDS; +import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMPONENTS; +import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_AFTER; +import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_HIDE_COMMENTS; +import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PAGE_INDEX; +import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PAGE_SIZE; public class SearchActionTest { + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + @Rule + public DbTester db = DbTester.create(); + @Rule + public EsTester es = new EsTester(new IssueIndexDefinition(new MapSettings().asConfig())); @Rule public ExpectedException expectedException = ExpectedException.none(); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); + private DbClient dbClient = db.getDbClient(); + private DbSession session = db.getSession(); + private IssueIndex issueIndex = new IssueIndex(es.client(), System2.INSTANCE, userSessionRule, new AuthorizationTypeSupport(userSessionRule)); + private IssueIndexer issueIndexer = new IssueIndexer(es.client(), dbClient, new IssueIteratorFactory(dbClient)); + private IssueQueryFactory issueQueryFactory = new IssueQueryFactory(dbClient, System2.INSTANCE, userSessionRule); + private IssueFieldsSetter issueFieldsSetter = new IssueFieldsSetter(); + private IssueWorkflow issueWorkflow = new IssueWorkflow(new FunctionExecutor(issueFieldsSetter), issueFieldsSetter); + private SearchResponseLoader searchResponseLoader = new SearchResponseLoader(userSessionRule, dbClient, new ActionFinder(userSessionRule), new TransitionService(userSessionRule, issueWorkflow)); + private Languages languages = new Languages(); + private SearchResponseFormat searchResponseFormat = new SearchResponseFormat(new Durations(), new WsResponseCommonFormat(languages), languages, new AvatarResolverImpl()); + private WsActionTester ws = new WsActionTester(new SearchAction(userSessionRule, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat)); + private OrganizationDto defaultOrganization; + private OrganizationDto otherOrganization1; + private OrganizationDto otherOrganization2; + private StartupIndexer permissionIndexer = new PermissionIndexer(dbClient, es.client(), issueIndexer); - private IssueIndex index = mock(IssueIndex.class); - private IssueQueryFactory issueQueryFactory = mock(IssueQueryFactory.class); - private SearchResponseLoader searchResponseLoader = mock(SearchResponseLoader.class); - private SearchResponseFormat searchResponseFormat = mock(SearchResponseFormat.class); - private SearchAction underTest = new SearchAction(userSession, index, issueQueryFactory, searchResponseLoader, searchResponseFormat); - private WsActionTester ws = new WsActionTester(underTest); + @Before + public void setUp() { + OrganizationDao organizationDao = dbClient.organizationDao(); + this.defaultOrganization = db.getDefaultOrganization(); + this.otherOrganization1 = OrganizationTesting.newOrganizationDto().setKey("my-org-1"); + this.otherOrganization2 = OrganizationTesting.newOrganizationDto().setKey("my-org-2"); + organizationDao.insert(session, this.otherOrganization1, false); + organizationDao.insert(session, this.otherOrganization2, false); + session.commit(); + issueWorkflow.start(); + } @Test public void test_definition() { @@ -62,8 +133,585 @@ public class SearchActionTest { "organization", "p", "projectUuids", "projects", "ps", "resolutions", "resolved", "rules", "s", "severities", "sinceLeakPeriod", "statuses", "tags", "types"); assertThat(def.param("organization")) - .matches(Param::isInternal) + .matches(WebService.Param::isInternal) .matches(p -> p.since().equals("6.4")); } + @Test + public void empty_search() throws Exception { + TestResponse result = ws.newRequest() + .execute(); + + assertThat(result).isNotNull(); + result.assertJson(this.getClass(), "empty_result.json"); + } + + @Test + public void response_contains_all_fields_except_additional_fields() throws Exception { + dbClient.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com")); + dbClient.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); + + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project) + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") + .setEffort(10L) + .setMessage("the message") + .setStatus(Issue.STATUS_RESOLVED) + .setResolution(Issue.RESOLUTION_FIXED) + .setSeverity("MAJOR") + .setAuthorLogin("John") + .setAssignee("simon") + .setTags(asList("bug", "owasp")) + .setIssueCreationDate(DateUtils.parseDateTime("2014-09-04T00:00:00+0100")) + .setIssueUpdateDate(DateUtils.parseDateTime("2017-12-04T00:00:00+0100")); + dbClient.issueDao().insert(session, issue); + session.commit(); + issueIndexer.indexOnStartup(issueIndexer.getIndexTypes()); + + ws.newRequest().execute() + .assertJson(this.getClass(), "response_contains_all_fields_except_additional_fields.json"); + } + + @Test + public void issue_with_comments() throws Exception { + dbClient.userDao().insert(session, new UserDto().setLogin("john").setName("John")); + dbClient.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); + + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project) + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); + dbClient.issueDao().insert(session, issue); + + dbClient.issueChangeDao().insert(session, + new IssueChangeDto().setIssueKey(issue.getKey()) + .setKey("COMMENT-ABCD") + .setChangeData("*My comment*") + .setChangeType(IssueChangeDto.TYPE_COMMENT) + .setUserLogin("john") + .setCreatedAt(DateUtils.parseDateTime("2014-09-09T12:00:00+0000").getTime())); + dbClient.issueChangeDao().insert(session, + new IssueChangeDto().setIssueKey(issue.getKey()) + .setKey("COMMENT-ABCE") + .setChangeData("Another comment") + .setChangeType(IssueChangeDto.TYPE_COMMENT) + .setUserLogin("fabrice") + .setCreatedAt(DateUtils.parseDateTime("2014-09-10T12:00:00+0000").getTime())); + session.commit(); + indexIssues(); + + userSessionRule.logIn("john"); + ws.newRequest() + .setParam("additionalFields", "comments,users") + .execute() + .assertJson(this.getClass(), "issue_with_comments.json"); + } + + @Test + public void issue_with_comment_hidden() throws Exception { + dbClient.userDao().insert(session, new UserDto().setLogin("john").setName("John").setEmail("john@email.com")); + dbClient.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); + + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project) + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"); + dbClient.issueDao().insert(session, issue); + + dbClient.issueChangeDao().insert(session, + new IssueChangeDto().setIssueKey(issue.getKey()) + .setKey("COMMENT-ABCD") + .setChangeData("*My comment*") + .setChangeType(IssueChangeDto.TYPE_COMMENT) + .setUserLogin("john") + .setCreatedAt(DateUtils.parseDateTime("2014-09-09T12:00:00+0000").getTime())); + dbClient.issueChangeDao().insert(session, + new IssueChangeDto().setIssueKey(issue.getKey()) + .setKey("COMMENT-ABCE") + .setChangeData("Another comment") + .setChangeType(IssueChangeDto.TYPE_COMMENT) + .setUserLogin("fabrice") + .setCreatedAt(DateUtils.parseDateTime("2014-09-10T19:10:03+0000").getTime())); + session.commit(); + indexIssues(); + + userSessionRule.logIn("john"); + TestResponse result = ws.newRequest().setParam(PARAM_HIDE_COMMENTS, "true").execute(); + result.assertJson(this.getClass(), "issue_with_comment_hidden.json"); + assertThat(result.getInput()).doesNotContain("fabrice"); + } + + @Test + public void load_additional_fields() throws Exception { + dbClient.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com")); + dbClient.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY").setLanguage("java")); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY").setLanguage("js")); + + IssueDto issue = IssueTesting.newDto(newRule(), file, project) + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") + .setAuthorLogin("John") + .setAssignee("simon"); + dbClient.issueDao().insert(session, issue); + session.commit(); + indexIssues(); + + userSessionRule.logIn("john"); + ws.newRequest() + .setParam("additionalFields", "_all").execute() + .assertJson(this.getClass(), "load_additional_fields.json"); + } + + @Test + public void load_additional_fields_with_issue_admin_permission() throws Exception { + dbClient.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com")); + dbClient.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com")); + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY").setLanguage("java")); + grantPermissionToAnyone(project, ISSUE_ADMIN); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY").setLanguage("js")); + + IssueDto issue = IssueTesting.newDto(newRule(), file, project) + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") + .setAuthorLogin("John") + .setAssignee("simon"); + dbClient.issueDao().insert(session, issue); + session.commit(); + indexIssues(); + + userSessionRule.logIn("john") + .addProjectPermission(ISSUE_ADMIN, project); // granted by Anyone + ws.newRequest() + .setParam("additionalFields", "_all").execute() + .assertJson(this.getClass(), "load_additional_fields_with_issue_admin_permission.json"); + } + + @Test + public void issue_on_removed_file() throws Exception { + RuleDto rule = newRule(); + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); + indexPermissions(); + ComponentDto removedFile = insertComponent(ComponentTesting.newFileDto(project, null).setUuid("REMOVED_FILE_ID") + .setDbKey("REMOVED_FILE_KEY") + .setEnabled(false)); + + IssueDto issue = IssueTesting.newDto(rule, removedFile, project) + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") + .setComponent(removedFile) + .setStatus("OPEN").setResolution("OPEN") + .setSeverity("MAJOR") + .setIssueCreationDate(DateUtils.parseDateTime("2014-09-04T00:00:00+0100")) + .setIssueUpdateDate(DateUtils.parseDateTime("2017-12-04T00:00:00+0100")); + dbClient.issueDao().insert(session, issue); + session.commit(); + indexIssues(); + + ws.newRequest() + .execute() + .assertJson(this.getClass(), "issue_on_removed_file.json"); + } + + @Test + public void apply_paging_with_one_component() throws Exception { + RuleDto rule = newRule(); + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); + for (int i = 0; i < SearchOptions.MAX_LIMIT + 1; i++) { + IssueDto issue = IssueTesting.newDto(rule, file, project); + dbClient.issueDao().insert(session, issue); + } + session.commit(); + indexIssues(); + + ws.newRequest().setParam(PARAM_COMPONENTS, file.getDbKey()).execute() + .assertJson(this.getClass(), "apply_paging_with_one_component.json"); + } + + @Test + public void components_contains_sub_projects() throws Exception { + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("ProjectHavingModule")); + indexPermissions(); + ComponentDto module = insertComponent(ComponentTesting.newModuleDto(project).setDbKey("ModuleHavingFile")); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(module, null, "BCDE").setDbKey("FileLinkedToModule")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project); + dbClient.issueDao().insert(session, issue); + session.commit(); + indexIssues(); + + ws.newRequest().setParam(PARAM_ADDITIONAL_FIELDS, "_all").execute() + .assertJson(this.getClass(), "components_contains_sub_projects.json"); + } + + @Test + public void display_facets() throws Exception { + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project) + .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) + .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) + .setEffort(10L) + .setStatus("OPEN") + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") + .setSeverity("MAJOR"); + dbClient.issueDao().insert(session, issue); + session.commit(); + indexIssues(); + + userSessionRule.logIn("john"); + ws.newRequest() + .setParam("resolved", "false") + .setParam(WebService.Param.FACETS, "statuses,severities,resolutions,projectUuids,rules,fileUuids,assignees,languages,actionPlans,types") + .execute() + .assertJson(this.getClass(), "display_facets.json"); + } + + @Test + public void display_facets_in_effort_mode() throws Exception { + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project) + .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) + .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) + .setEffort(10L) + .setStatus("OPEN") + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") + .setSeverity("MAJOR"); + dbClient.issueDao().insert(session, issue); + session.commit(); + indexIssues(); + + userSessionRule.logIn("john"); + ws.newRequest() + .setParam("resolved", "false") + .setParam(WebService.Param.FACETS, "statuses,severities,resolutions,projectUuids,rules,fileUuids,assignees,languages,actionPlans") + .setParam("facetMode", FACET_MODE_EFFORT) + .execute() + .assertJson(this.getClass(), "display_facets_effort.json"); + } + + @Test + public void display_zero_valued_facets_for_selected_items() throws Exception { + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project) + .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) + .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) + .setEffort(10L) + .setStatus("OPEN") + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") + .setSeverity("MAJOR"); + dbClient.issueDao().insert(session, issue); + session.commit(); + indexIssues(); + + userSessionRule.logIn("john"); + ws.newRequest() + .setParam("resolved", "false") + .setParam("severities", "MAJOR,MINOR") + .setParam("languages", "xoo,polop,palap") + .setParam(WebService.Param.FACETS, "statuses,severities,resolutions,projectUuids,rules,fileUuids,assignees,assigned_to_me,languages,actionPlans") + .execute() + .assertJson(this.getClass(), "display_zero_facets.json"); + } + + @Test + public void assignedToMe_facet_must_escape_login_of_authenticated_user() throws Exception { + // login looks like an invalid regexp + userSessionRule.logIn("foo["); + + // should not fail + ws.newRequest() + .setParam(WebService.Param.FACETS, "assigned_to_me") + .execute() + .assertJson(this.getClass(), "assignedToMe_facet_must_escape_login_of_authenticated_user.json"); + + } + + @Test + public void filter_by_assigned_to_me() throws Exception { + dbClient.userDao().insert(session, new UserDto().setLogin("john").setName("John").setEmail("john@email.com")); + + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "PROJECT_ID").setDbKey("PROJECT_KEY")); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); + RuleDto rule = newRule(); + IssueDto issue1 = IssueTesting.newDto(rule, file, project) + .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) + .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) + .setEffort(10L) + .setStatus("OPEN") + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") + .setSeverity("MAJOR") + .setAssignee("john"); + IssueDto issue2 = IssueTesting.newDto(rule, file, project) + .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) + .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) + .setEffort(10L) + .setStatus("OPEN") + .setKee("7b112bd4-b650-4037-80bc-82fd47d4eac2") + .setSeverity("MAJOR") + .setAssignee("alice"); + IssueDto issue3 = IssueTesting.newDto(rule, file, project) + .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) + .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) + .setEffort(10L) + .setStatus("OPEN") + .setKee("82fd47d4-4037-b650-80bc-7b112bd4eac2") + .setSeverity("MAJOR"); + dbClient.issueDao().insert(session, issue1, issue2, issue3); + session.commit(); + indexIssues(); + + userSessionRule.logIn("john"); + ws.newRequest() + .setParam("resolved", "false") + .setParam("assignees", "__me__") + .setParam(WebService.Param.FACETS, "assignees,assigned_to_me") + .execute() + .assertJson(this.getClass(), "filter_by_assigned_to_me.json"); + } + + @Test + public void filter_by_assigned_to_me_unauthenticated() throws Exception { + userSessionRule.logIn(); + + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); + RuleDto rule = newRule(); + IssueDto issue1 = IssueTesting.newDto(rule, file, project) + .setStatus("OPEN") + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") + .setAssignee("john"); + IssueDto issue2 = IssueTesting.newDto(rule, file, project) + .setStatus("OPEN") + .setKee("7b112bd4-b650-4037-80bc-82fd47d4eac2") + .setAssignee("alice"); + IssueDto issue3 = IssueTesting.newDto(rule, file, project) + .setStatus("OPEN") + .setKee("82fd47d4-4037-b650-80bc-7b112bd4eac2"); + dbClient.issueDao().insert(session, issue1, issue2, issue3); + session.commit(); + indexIssues(); + + ws.newRequest() + .setParam("resolved", "false") + .setParam("assignees", "__me__") + .execute() + .assertJson(this.getClass(), "empty_result.json"); + } + + @Test + public void assigned_to_me_facet_is_sticky_relative_to_assignees() throws Exception { + dbClient.userDao().insert(session, new UserDto().setLogin("alice").setName("Alice").setEmail("alice@email.com")); + + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); + RuleDto rule = newRule(); + IssueDto issue1 = IssueTesting.newDto(rule, file, project) + .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) + .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) + .setEffort(10L) + .setStatus("OPEN") + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") + .setSeverity("MAJOR") + .setAssignee("john-bob.polop"); + IssueDto issue2 = IssueTesting.newDto(rule, file, project) + .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) + .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) + .setEffort(10L) + .setStatus("OPEN") + .setKee("7b112bd4-b650-4037-80bc-82fd47d4eac2") + .setSeverity("MAJOR") + .setAssignee("alice"); + IssueDto issue3 = IssueTesting.newDto(rule, file, project) + .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) + .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) + .setEffort(10L) + .setStatus("OPEN") + .setKee("82fd47d4-4037-b650-80bc-7b112bd4eac2") + .setSeverity("MAJOR"); + dbClient.issueDao().insert(session, issue1, issue2, issue3); + session.commit(); + indexIssues(); + + userSessionRule.logIn("john-bob.polop"); + ws.newRequest() + .setParam("resolved", "false") + .setParam("assignees", "alice") + .setParam(WebService.Param.FACETS, "assignees,assigned_to_me") + .execute() + .assertJson(this.getClass(), "assigned_to_me_facet_sticky.json"); + } + + @Test + public void sort_by_updated_at() throws Exception { + RuleDto rule = newRule(); + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); + dbClient.issueDao().insert(session, IssueTesting.newDto(rule, file, project) + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac1") + .setIssueUpdateDate(DateUtils.parseDateTime("2014-11-02T00:00:00+0100"))); + dbClient.issueDao().insert(session, IssueTesting.newDto(rule, file, project) + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") + .setIssueUpdateDate(DateUtils.parseDateTime("2014-11-01T00:00:00+0100"))); + dbClient.issueDao().insert(session, IssueTesting.newDto(rule, file, project) + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac3") + .setIssueUpdateDate(DateUtils.parseDateTime("2014-11-03T00:00:00+0100"))); + session.commit(); + indexIssues(); + + ws.newRequest() + .setParam("sort", IssueQuery.SORT_BY_UPDATE_DATE) + .setParam("asc", "false") + .execute() + .assertJson(this.getClass(), "sort_by_updated_at.json"); + } + + @Test + public void paging() throws Exception { + RuleDto rule = newRule(); + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); + for (int i = 0; i < 12; i++) { + IssueDto issue = IssueTesting.newDto(rule, file, project); + dbClient.issueDao().insert(session, issue); + } + session.commit(); + indexIssues(); + + ws.newRequest() + .setParam(WebService.Param.PAGE, "2") + .setParam(WebService.Param.PAGE_SIZE, "9") + .execute() + .assertJson(this.getClass(), "paging.json"); + } + + @Test + public void paging_with_page_size_to_minus_one() throws Exception { + RuleDto rule = newRule(); + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "PROJECT_ID").setDbKey("PROJECT_KEY")); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); + for (int i = 0; i < 12; i++) { + IssueDto issue = IssueTesting.newDto(rule, file, project); + dbClient.issueDao().insert(session, issue); + } + session.commit(); + indexIssues(); + + ws.newRequest() + .setParam(WebService.Param.PAGE, "1") + .setParam(WebService.Param.PAGE_SIZE, "-1") + .execute() + .assertJson(this.getClass(), "paging_with_page_size_to_minus_one.json"); + } + + @Test + public void deprecated_paging() throws Exception { + RuleDto rule = newRule(); + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "PROJECT_ID").setDbKey("PROJECT_KEY")); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); + for (int i = 0; i < 12; i++) { + IssueDto issue = IssueTesting.newDto(rule, file, project); + dbClient.issueDao().insert(session, issue); + } + session.commit(); + indexIssues(); + + ws.newRequest() + .setParam(PARAM_PAGE_INDEX, "2") + .setParam(PARAM_PAGE_SIZE, "9") + .execute() + .assertJson(this.getClass(), "deprecated_paging.json"); + } + + @Test + public void default_page_size_is_100() throws Exception { + ws.newRequest() + .execute() + .assertJson(this.getClass(), "default_page_size_is_100.json"); + } + + @Test + public void display_deprecated_debt_fields() throws Exception { + ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "PROJECT_ID").setDbKey("PROJECT_KEY")); + indexPermissions(); + ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); + IssueDto issue = IssueTesting.newDto(newRule(), file, project) + .setIssueCreationDate(DateUtils.parseDate("2014-09-04")) + .setIssueUpdateDate(DateUtils.parseDate("2017-12-04")) + .setEffort(10L) + .setStatus("OPEN") + .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2") + .setSeverity("MAJOR"); + dbClient.issueDao().insert(session, issue); + session.commit(); + indexIssues(); + + userSessionRule.logIn("john"); + ws.newRequest() + .setParam("resolved", "false") + .setParam(WebService.Param.FACETS, "severities") + .setParam("facetMode", DEPRECATED_FACET_MODE_DEBT) + .execute() + .assertJson(this.getClass(), "display_deprecated_debt_fields.json"); + } + + @Test + public void fail_when_invalid_format() throws Exception { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Date 'wrong-date-input' cannot be parsed as either a date or date+time"); + + ws.newRequest() + .setParam(PARAM_CREATED_AFTER, "wrong-date-input") + .execute(); + } + + private RuleDto newRule() { + RuleDto rule = RuleTesting.newXooX1() + .setName("Rule name") + .setDescription("Rule desc") + .setStatus(RuleStatus.READY); + db.rules().insert(rule.getDefinition()); + return rule; + } + + private void indexPermissions() { + permissionIndexer.indexOnStartup(permissionIndexer.getIndexTypes()); + } + + private void indexIssues() { + issueIndexer.indexOnStartup(issueIndexer.getIndexTypes()); + } + + private void grantPermissionToAnyone(ComponentDto project, String permission) { + dbClient.groupPermissionDao().insert(session, + new GroupPermissionDto() + .setOrganizationUuid(project.getOrganizationUuid()) + .setGroupId(null) + .setResourceId(project.getId()) + .setRole(permission)); + session.commit(); + userSessionRule.logIn().addProjectPermission(permission, project); + } + + private ComponentDto insertComponent(ComponentDto component) { + dbClient.componentDao().insert(session, component); + session.commit(); + return component; + } } diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/apply_paging_with_multiple_components.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/apply_paging_with_multiple_components.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/apply_paging_with_multiple_components.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/apply_paging_with_multiple_components.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/apply_paging_with_one_component.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/apply_paging_with_one_component.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/apply_paging_with_one_component.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/apply_paging_with_one_component.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/assignedToMe_facet_must_escape_login_of_authenticated_user.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/assignedToMe_facet_must_escape_login_of_authenticated_user.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/assignedToMe_facet_must_escape_login_of_authenticated_user.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/assignedToMe_facet_must_escape_login_of_authenticated_user.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/assigned_to_me_facet_sticky.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/assigned_to_me_facet_sticky.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/assigned_to_me_facet_sticky.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/assigned_to_me_facet_sticky.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/components_contains_sub_projects.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/components_contains_sub_projects.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/components_contains_sub_projects.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/components_contains_sub_projects.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/default_page_size_is_100.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/default_page_size_is_100.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/default_page_size_is_100.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/default_page_size_is_100.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/deprecated_paging.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/deprecated_paging.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/deprecated_paging.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/deprecated_paging.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/display_deprecated_debt_fields.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/display_deprecated_debt_fields.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/display_deprecated_debt_fields.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/display_deprecated_debt_fields.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/display_facets.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/display_facets.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/display_facets.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/display_facets.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/display_facets_effort.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/display_facets_effort.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/display_facets_effort.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/display_facets_effort.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/display_zero_facets.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/display_zero_facets.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/display_zero_facets.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/display_zero_facets.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/empty_result.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/empty_result.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/empty_result.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/empty_result.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/filter_by_assigned_to_me.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/filter_by_assigned_to_me.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/filter_by_assigned_to_me.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/filter_by_assigned_to_me.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/hide_rules.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/hide_rules.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/hide_rules.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/hide_rules.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/ignore_paging_with_one_component.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/ignore_paging_with_one_component.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/ignore_paging_with_one_component.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/ignore_paging_with_one_component.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/issue_on_removed_file.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/issue_on_removed_file.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/issue_on_removed_file.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/issue_on_removed_file.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/issue_with_comment_hidden.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/issue_with_comment_hidden.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/issue_with_comment_hidden.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/issue_with_comment_hidden.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/issue_with_comments.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/issue_with_comments.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/issue_with_comments.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/issue_with_comments.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/load_additional_fields.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/load_additional_fields.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/load_additional_fields.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/load_additional_fields.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/load_additional_fields_with_issue_admin_permission.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/load_additional_fields_with_issue_admin_permission.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/load_additional_fields_with_issue_admin_permission.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/load_additional_fields_with_issue_admin_permission.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/no_issue.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/no_issue.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/no_issue.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/no_issue.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/paging.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/paging.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/paging.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/paging.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/paging_with_page_size_to_minus_one.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/paging_with_page_size_to_minus_one.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/paging_with_page_size_to_minus_one.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/paging_with_page_size_to_minus_one.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/response_contains_all_fields_except_additional_fields.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/response_contains_all_fields_except_additional_fields.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/response_contains_all_fields_except_additional_fields.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/response_contains_all_fields_except_additional_fields.json diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/sort_by_updated_at.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/sort_by_updated_at.json similarity index 100% rename from server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/sort_by_updated_at.json rename to server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionTest/sort_by_updated_at.json -- 2.39.5