aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java19
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java4
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java29
-rw-r--r--server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java136
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java11
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java106
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesWsParameters.java2
7 files changed, 283 insertions, 24 deletions
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java
index 635d536adb1..73af0581ff8 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java
@@ -43,6 +43,7 @@ public class SearchRequest {
private List<String> facets;
private List<String> files;
private List<String> issues;
+ private Boolean inNewCodePeriod;
private Set<String> scopes;
private List<String> languages;
private Boolean onComponentOnly;
@@ -298,11 +299,19 @@ public class SearchRequest {
return this;
}
+ /**
+ * @deprecated since 9.4 - replaced by getInNewCodePeriod()
+ */
+ @Deprecated(since = "9.4")
@CheckForNull
public Boolean getSinceLeakPeriod() {
return sinceLeakPeriod;
}
+ /**
+ * @deprecated since 9.4 - replaced by setInNewCodePeriod()
+ */
+ @Deprecated(since = "9.4")
public SearchRequest setSinceLeakPeriod(@Nullable Boolean sinceLeakPeriod) {
this.sinceLeakPeriod = sinceLeakPeriod;
return this;
@@ -447,4 +456,14 @@ public class SearchRequest {
this.timeZone = timeZone;
return this;
}
+
+ @CheckForNull
+ public Boolean getInNewCodePeriod() {
+ return inNewCodePeriod;
+ }
+
+ public SearchRequest setInNewCodePeriod(@Nullable Boolean inNewCodePeriod) {
+ this.inNewCodePeriod = inNewCodePeriod;
+ return this;
+ }
}
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java
index bdfe716bc3e..73b402692ea 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java
@@ -47,7 +47,8 @@ public class SearchRequestTest {
.setCreatedBefore("2013-04-17T09:08:24+0200")
.setRules(asList("key-a", "key-b"))
.setSort("CREATION_DATE")
- .setAsc(true);
+ .setAsc(true)
+ .setInNewCodePeriod(true);
assertThat(underTest.getIssues()).containsOnlyOnce("anIssueKey");
assertThat(underTest.getSeverities()).containsExactly("MAJOR", "MINOR");
@@ -67,6 +68,7 @@ public class SearchRequestTest {
assertThat(underTest.getRules()).containsExactly("key-a", "key-b");
assertThat(underTest.getSort()).isEqualTo("CREATION_DATE");
assertThat(underTest.getAsc()).isTrue();
+ assertThat(underTest.getInNewCodePeriod()).isTrue();
}
@Test
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java
index 97a95a5477a..9d5ec45406d 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java
@@ -77,6 +77,7 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMPONENT_K
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMPONENT_UUIDS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_AFTER;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_IN_LAST;
+import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_IN_NEW_CODE_PERIOD;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SINCE_LEAK_PERIOD;
/**
@@ -181,15 +182,16 @@ public class IssueQueryFactory {
Date createdAfter = parseStartingDateOrDateTime(request.getCreatedAfter(), timeZone);
String createdInLast = request.getCreatedInLast();
- if (request.getSinceLeakPeriod() == null || !request.getSinceLeakPeriod()) {
+ if (notInNewCodePeriod(request)) {
checkArgument(createdAfter == null || createdInLast == null, format("Parameters %s and %s cannot be set simultaneously", PARAM_CREATED_AFTER, PARAM_CREATED_IN_LAST));
setCreatedAfterFromDates(builder, createdAfter, createdInLast, true);
} else {
// If the filter is on leak period
- checkArgument(createdAfter == null, "Parameters '%s' and '%s' cannot be set simultaneously", PARAM_CREATED_AFTER, PARAM_SINCE_LEAK_PERIOD);
- checkArgument(createdInLast == null, format("Parameters %s and %s cannot be set simultaneously", PARAM_CREATED_IN_LAST, PARAM_SINCE_LEAK_PERIOD));
+ checkArgument(createdAfter == null, "Parameters '%s' and '%s' or '%s' cannot be set simultaneously", PARAM_CREATED_AFTER, PARAM_IN_NEW_CODE_PERIOD, PARAM_SINCE_LEAK_PERIOD);
+ checkArgument(createdInLast == null,
+ format("Parameters '%s' and '%s' or '%s' cannot be set simultaneously", PARAM_CREATED_IN_LAST, PARAM_IN_NEW_CODE_PERIOD, PARAM_SINCE_LEAK_PERIOD));
- checkArgument(componentUuids.size() == 1, "One and only one component must be provided when searching since leak period");
+ checkArgument(componentUuids.size() == 1, "One and only one component must be provided when searching in new code period");
ComponentDto component = componentUuids.iterator().next();
if (!QUALIFIERS_WITHOUT_LEAK_PERIOD.contains(component.qualifier()) && request.getPullRequest() == null) {
@@ -206,6 +208,23 @@ public class IssueQueryFactory {
}
}
+ private static boolean notInNewCodePeriod(SearchRequest request) {
+ Boolean sinceLeakPeriod = request.getSinceLeakPeriod();
+ Boolean inNewCodePeriod = request.getInNewCodePeriod();
+
+ checkArgument(validPeriodParameterValues(sinceLeakPeriod, inNewCodePeriod),
+ "If both provided, the following parameters %s and %s must match.", PARAM_SINCE_LEAK_PERIOD, PARAM_IN_NEW_CODE_PERIOD);
+
+ sinceLeakPeriod = Boolean.TRUE.equals(sinceLeakPeriod);
+ inNewCodePeriod = Boolean.TRUE.equals(inNewCodePeriod);
+
+ return !sinceLeakPeriod && !inNewCodePeriod;
+ }
+
+ private static boolean validPeriodParameterValues(@Nullable Boolean sinceLeakPeriod, @Nullable Boolean inNewCodePeriod) {
+ return atMostOneNonNullElement(sinceLeakPeriod, inNewCodePeriod) || !Boolean.logicalXor(sinceLeakPeriod, inNewCodePeriod);
+ }
+
private Date findCreatedAfterFromComponentUuid(Optional<SnapshotDto> snapshot) {
return snapshot.map(s -> longToDate(s.getPeriodDate())).orElseGet(() -> new Date(clock.millis()));
}
@@ -344,7 +363,7 @@ public class IssueQueryFactory {
}
private void addCreatedAfterByProjects(IssueQuery.Builder builder, DbSession dbSession, SearchRequest request, Set<String> applicationUuids) {
- if (request.getSinceLeakPeriod() == null || !request.getSinceLeakPeriod() || request.getPullRequest() != null) {
+ if (notInNewCodePeriod(request) || request.getPullRequest() != null) {
return;
}
diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java
index edb0d518841..dbc9f40ecae 100644
--- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java
+++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java
@@ -168,6 +168,28 @@ public class IssueQueryFactoryTest {
}
@Test
+ public void in_new_code_period_start_date_is_exclusive() {
+ long newCodePeriodStart = addDays(new Date(), -14).getTime();
+
+ ComponentDto project = db.components().insertPublicProject();
+ ComponentDto file = db.components().insertComponent(newFileDto(project));
+
+ SnapshotDto analysis = db.components().insertSnapshot(project, s -> s.setPeriodDate(newCodePeriodStart));
+
+ SearchRequest request = new SearchRequest()
+ .setComponentUuids(Collections.singletonList(file.uuid()))
+ .setOnComponentOnly(true)
+ .setInNewCodePeriod(true);
+
+ IssueQuery query = underTest.create(request);
+
+ assertThat(query.componentUuids()).containsOnly(file.uuid());
+ assertThat(query.createdAfter().date()).isEqualTo(new Date(newCodePeriodStart));
+ assertThat(query.createdAfter().inclusive()).isFalse();
+ assertThat(query.newCodeOnReference()).isNull();
+ }
+
+ @Test
public void leak_period_does_not_rely_on_date_for_reference_branch() {
long leakPeriodStart = addDays(new Date(), -14).getTime();
@@ -190,6 +212,27 @@ public class IssueQueryFactoryTest {
}
@Test
+ public void new_code_period_does_not_rely_on_date_for_reference_branch() {
+
+ ComponentDto project = db.components().insertPublicProject();
+ ComponentDto file = db.components().insertComponent(newFileDto(project));
+
+ SnapshotDto analysis = db.components().insertSnapshot(project, s -> s.setPeriodMode(REFERENCE_BRANCH.name())
+ .setPeriodParam("master"));
+
+ SearchRequest request = new SearchRequest()
+ .setComponentUuids(Collections.singletonList(file.uuid()))
+ .setOnComponentOnly(true)
+ .setInNewCodePeriod(true);
+
+ IssueQuery query = underTest.create(request);
+
+ assertThat(query.componentUuids()).containsOnly(file.uuid());
+ assertThat(query.newCodeOnReference()).isTrue();
+ assertThat(query.createdAfter()).isNull();
+ }
+
+ @Test
public void dates_are_inclusive() {
when(clock.getZone()).thenReturn(ZoneId.of("Europe/Paris"));
SearchRequest request = new SearchRequest()
@@ -365,6 +408,37 @@ public class IssueQueryFactoryTest {
}
@Test
+ public void application_search_project_issues_in_new_code() {
+ Date now = new Date();
+ when(clock.millis()).thenReturn(now.getTime());
+ ComponentDto project1 = db.components().insertPublicProject();
+ SnapshotDto analysis1 = db.components().insertSnapshot(project1, s -> s.setPeriodDate(addDays(now, -14).getTime()));
+ ComponentDto project2 = db.components().insertPublicProject();
+ db.components().insertSnapshot(project2, s -> s.setPeriodDate(null));
+ ComponentDto project3 = db.components().insertPublicProject();
+ ComponentDto project4 = db.components().insertPublicProject();
+ SnapshotDto analysis2 = db.components().insertSnapshot(project4,
+ s -> s.setPeriodMode(REFERENCE_BRANCH.name()).setPeriodParam("master"));
+ ComponentDto application = db.components().insertPublicApplication();
+ db.components().insertComponents(newProjectCopy("PC1", project1, application));
+ db.components().insertComponents(newProjectCopy("PC2", project2, application));
+ db.components().insertComponents(newProjectCopy("PC3", project3, application));
+ db.components().insertComponents(newProjectCopy("PC4", project4, application));
+ userSession.registerApplication(application, project1, project2, project3, project4);
+
+ IssueQuery result = underTest.create(new SearchRequest()
+ .setComponentUuids(singletonList(application.uuid()))
+ .setInNewCodePeriod(true));
+
+ assertThat(result.createdAfterByProjectUuids()).hasSize(1);
+ assertThat(result.createdAfterByProjectUuids().entrySet()).extracting(Map.Entry::getKey, e -> e.getValue().date(), e -> e.getValue().inclusive()).containsOnly(
+ tuple(project1.uuid(), new Date(analysis1.getPeriodDate()), false));
+ assertThat(result.newCodeOnReferenceByProjectUuids()).hasSize(1);
+ assertThat(result.newCodeOnReferenceByProjectUuids()).containsOnly(project4.uuid());
+ assertThat(result.viewUuids()).containsExactlyInAnyOrder(application.uuid());
+ }
+
+ @Test
public void return_empty_results_if_not_allowed_to_search_for_subview() {
ComponentDto view = db.components().insertPrivatePortfolio();
ComponentDto subView = db.components().insertComponent(newSubPortfolio(view));
@@ -606,14 +680,56 @@ public class IssueQueryFactoryTest {
.setSinceLeakPeriod(true)
.setCreatedAfter("2013-07-25T07:35:00+0100")))
.isInstanceOf(IllegalArgumentException.class)
- .hasMessageContaining("Parameters 'createdAfter' and 'sinceLeakPeriod' cannot be set simultaneously");
+ .hasMessageContaining("Parameters 'createdAfter' and 'inNewCodePeriod' or 'sinceLeakPeriod' cannot be set simultaneously");
+ }
+
+ @Test
+ public void fail_if_in_new_code_period_and_created_after_set_at_the_same_time() {
+ SearchRequest searchRequest = new SearchRequest()
+ .setInNewCodePeriod(true)
+ .setCreatedAfter("2013-07-25T07:35:00+0100");
+
+ assertThatThrownBy(() -> underTest.create(searchRequest))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Parameters 'createdAfter' and 'inNewCodePeriod' or 'sinceLeakPeriod' cannot be set simultaneously");
+ }
+
+ @Test
+ public void fail_if_since_leak_period_and_created_in_last_set_at_the_same_time() {
+ SearchRequest searchRequest = new SearchRequest()
+ .setSinceLeakPeriod(true)
+ .setCreatedInLast("1y2m3w4d");
+
+ assertThatThrownBy(() -> underTest.create(searchRequest))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Parameters 'createdInLast' and 'inNewCodePeriod' or 'sinceLeakPeriod' cannot be set simultaneously");
+ }
+
+ @Test
+ public void fail_if_in_new_code_period_and_created_in_last_set_at_the_same_time() {
+ SearchRequest searchRequest = new SearchRequest()
+ .setInNewCodePeriod(true)
+ .setCreatedInLast("1y2m3w4d");
+
+ assertThatThrownBy(() -> underTest.create(searchRequest))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Parameters 'createdInLast' and 'inNewCodePeriod' or 'sinceLeakPeriod' cannot be set simultaneously");
}
@Test
public void fail_if_no_component_provided_with_since_leak_period() {
assertThatThrownBy(() -> underTest.create(new SearchRequest().setSinceLeakPeriod(true)))
.isInstanceOf(IllegalArgumentException.class)
- .hasMessageContaining("One and only one component must be provided when searching since leak period");
+ .hasMessageContaining("One and only one component must be provided when searching in new code period");
+ }
+
+ @Test
+ public void fail_if_no_component_provided_with_in_new_code_period() {
+ SearchRequest searchRequest = new SearchRequest().setInNewCodePeriod(true);
+
+ assertThatThrownBy(() -> underTest.create(searchRequest))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("One and only one component must be provided when searching in new code period");
}
@Test
@@ -625,7 +741,21 @@ public class IssueQueryFactoryTest {
.setSinceLeakPeriod(true)
.setComponents(asList(project1.getKey(), project2.getKey()))))
.isInstanceOf(IllegalArgumentException.class)
- .hasMessageContaining("One and only one component must be provided when searching since leak period");
+ .hasMessageContaining("One and only one component must be provided when searching in new code period");
+ }
+
+ @Test
+ public void fail_if_several_components_provided_with_in_new_code_period() {
+ ComponentDto project1 = db.components().insertPrivateProject();
+ ComponentDto project2 = db.components().insertPrivateProject();
+
+ SearchRequest searchRequest = new SearchRequest()
+ .setInNewCodePeriod(true)
+ .setComponents(asList(project1.getKey(), project2.getKey()));
+
+ assertThatThrownBy(() -> underTest.create(searchRequest))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("One and only one component must be provided when searching in new code period");
}
@Test
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java
index bba59cc0594..11b0987297f 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java
@@ -107,6 +107,7 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_IN_
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CWE;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_DIRECTORIES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_FILES;
+import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_IN_NEW_CODE_PERIOD;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ISSUES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_LANGUAGES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ON_COMPONENT_ONLY;
@@ -188,6 +189,7 @@ public class SearchAction implements IssuesWsAction {
+ "<br/>When issue indexation is in progress returns 503 service unavailable HTTP code.")
.setSince("3.6")
.setChangelog(
+ new Change("9.4", format("Parameter '%s' is deprecated, please use '%s' instead", PARAM_SINCE_LEAK_PERIOD, PARAM_IN_NEW_CODE_PERIOD)),
new Change("9.2", "Response field 'quickFixAvailable' added"),
new Change("9.1", "Deprecated parameters 'authors', 'facetMode' and 'moduleUuids' were dropped"),
new Change("8.6", "Parameter 'timeZone' added"),
@@ -308,8 +310,12 @@ public class SearchAction implements IssuesWsAction {
action.createParam(PARAM_SINCE_LEAK_PERIOD)
.setDescription("To retrieve issues created since the leak period.<br>" +
"If this parameter is set to a truthy value, createdAfter must not be set and one component uuid or key must be provided.")
+ .setBooleanPossibleValues();
+ action.createParam(PARAM_IN_NEW_CODE_PERIOD)
+ .setDescription("To retrieve issues created in the new code period.<br>" +
+ "If this parameter is set to a truthy value, createdAfter must not be set and one component uuid or key must be provided.")
.setBooleanPossibleValues()
- .setDefaultValue("false");
+ .setSince("9.4");
action.createParam(PARAM_TIMEZONE)
.setDescription(
"To resolve dates passed to '" + PARAM_CREATED_AFTER + "' or '" + PARAM_CREATED_BEFORE + "' (does not apply to datetime) and to compute creation date histogram")
@@ -509,6 +515,7 @@ public class SearchAction implements IssuesWsAction {
.setDirectories(request.paramAsStrings(PARAM_DIRECTORIES))
.setFacets(request.paramAsStrings(FACETS))
.setFiles(request.paramAsStrings(PARAM_FILES))
+ .setInNewCodePeriod(request.paramAsBoolean(PARAM_IN_NEW_CODE_PERIOD))
.setIssues(request.paramAsStrings(PARAM_ISSUES))
.setScopes(request.paramAsStrings(PARAM_SCOPES))
.setLanguages(request.paramAsStrings(PARAM_LANGUAGES))
@@ -521,7 +528,7 @@ public class SearchAction implements IssuesWsAction {
.setResolutions(request.paramAsStrings(PARAM_RESOLUTIONS))
.setResolved(request.paramAsBoolean(PARAM_RESOLVED))
.setRules(request.paramAsStrings(PARAM_RULES))
- .setSinceLeakPeriod(request.mandatoryParamAsBoolean(PARAM_SINCE_LEAK_PERIOD))
+ .setSinceLeakPeriod(request.paramAsBoolean(PARAM_SINCE_LEAK_PERIOD))
.setSort(request.param(Param.SORT))
.setSeverities(request.paramAsStrings(PARAM_SEVERITIES))
.setStatuses(request.paramAsStrings(PARAM_STATUSES))
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java
index c412d2b4879..1472c038a33 100644
--- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java
+++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java
@@ -110,6 +110,7 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ASSIGNEES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMPONENT_KEYS;
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_IN_NEW_CODE_PERIOD;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PULL_REQUEST;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_RULES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SINCE_LEAK_PERIOD;
@@ -558,7 +559,7 @@ public class SearchActionTest {
}
@Test
- public void filter_by_leak_period() {
+ public void filter_by_new_code_period() {
UserDto john = db.users().insertUser(u -> u.setLogin("john").setName("John").setEmail("john@email.com"));
UserDto alice = db.users().insertUser(u -> u.setLogin("alice").setName("Alice").setEmail("alice@email.com"));
ComponentDto project = db.components().insertComponent(ComponentTesting.newPublicProjectDto("PROJECT_ID").setDbKey("PROJECT_KEY"));
@@ -594,6 +595,38 @@ public class SearchActionTest {
.setParam(PARAM_COMPONENT_KEYS, "PROJECT_KEY")
.execute()
.assertJson(this.getClass(), "filter_by_leak_period.json");
+
+ ws.newRequest()
+ .setParam(PARAM_IN_NEW_CODE_PERIOD, "true")
+ .setParam(PARAM_COMPONENT_KEYS, "PROJECT_KEY")
+ .execute()
+ .assertJson(this.getClass(), "filter_by_leak_period.json");
+
+ ws.newRequest()
+ .setParam(PARAM_IN_NEW_CODE_PERIOD, "true")
+ .setParam(PARAM_SINCE_LEAK_PERIOD, "true")
+ .setParam(PARAM_COMPONENT_KEYS, "PROJECT_KEY")
+ .execute()
+ .assertJson(this.getClass(), "filter_by_leak_period.json");
+ }
+
+ @Test
+ public void explicit_false_value_for_new_code_period_parameters_has_no_effect() {
+ ws.newRequest()
+ .setParam(PARAM_IN_NEW_CODE_PERIOD, "false")
+ .execute()
+ .assertJson(this.getClass(), "default_page_size_is_100.json");
+
+ ws.newRequest()
+ .setParam(PARAM_SINCE_LEAK_PERIOD, "false")
+ .execute()
+ .assertJson(this.getClass(), "default_page_size_is_100.json");
+
+ ws.newRequest()
+ .setParam(PARAM_IN_NEW_CODE_PERIOD, "false")
+ .setParam(PARAM_SINCE_LEAK_PERIOD, "false")
+ .execute()
+ .assertJson(this.getClass(), "default_page_size_is_100.json");
}
@Test
@@ -632,6 +665,19 @@ public class SearchActionTest {
.setParam(PARAM_SINCE_LEAK_PERIOD, "true")
.execute()
.assertJson(this.getClass(), "empty_result.json");
+
+ ws.newRequest()
+ .setParam(PARAM_COMPONENT_KEYS, "PROJECT_KEY")
+ .setParam(PARAM_IN_NEW_CODE_PERIOD, "true")
+ .execute()
+ .assertJson(this.getClass(), "empty_result.json");
+
+ ws.newRequest()
+ .setParam(PARAM_COMPONENT_KEYS, "PROJECT_KEY")
+ .setParam(PARAM_SINCE_LEAK_PERIOD, "true")
+ .setParam(PARAM_IN_NEW_CODE_PERIOD, "true")
+ .execute()
+ .assertJson(this.getClass(), "empty_result.json");
}
@Test
@@ -672,6 +718,21 @@ public class SearchActionTest {
.setParam(PARAM_SINCE_LEAK_PERIOD, "true")
.execute()
.assertJson(this.getClass(), "filter_by_leak_period_has_no_effect_on_prs.json");
+
+ ws.newRequest()
+ .setParam(PARAM_COMPONENT_KEYS, "PROJECT_KEY")
+ .setParam(PARAM_PULL_REQUEST, "pr")
+ .setParam(PARAM_IN_NEW_CODE_PERIOD, "true")
+ .execute()
+ .assertJson(this.getClass(), "filter_by_leak_period_has_no_effect_on_prs.json");
+
+ ws.newRequest()
+ .setParam(PARAM_COMPONENT_KEYS, "PROJECT_KEY")
+ .setParam(PARAM_PULL_REQUEST, "pr")
+ .setParam(PARAM_SINCE_LEAK_PERIOD, "true")
+ .setParam(PARAM_IN_NEW_CODE_PERIOD, "true")
+ .execute()
+ .assertJson(this.getClass(), "filter_by_leak_period_has_no_effect_on_prs.json");
}
@Test
@@ -1257,12 +1318,12 @@ public class SearchActionTest {
@Test
public void paging_with_page_size_to_minus_one() {
- assertThatThrownBy(() -> {
- ws.newRequest()
- .setParam(WebService.Param.PAGE, "1")
- .setParam(WebService.Param.PAGE_SIZE, "-1")
- .execute();
- })
+
+ TestRequest requestWithNegativePageSize = ws.newRequest()
+ .setParam(WebService.Param.PAGE, "1")
+ .setParam(WebService.Param.PAGE_SIZE, "-1");
+
+ assertThatThrownBy(requestWithNegativePageSize::execute)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Page size must be between 1 and 500 (got -1)");
}
@@ -1299,11 +1360,10 @@ public class SearchActionTest {
@Test
public void fail_when_invalid_format() {
- assertThatThrownBy(() -> {
- ws.newRequest()
- .setParam(PARAM_CREATED_AFTER, "wrong-date-input")
- .execute();
- })
+ TestRequest invalidFormatRequest = ws.newRequest()
+ .setParam(PARAM_CREATED_AFTER, "wrong-date-input");
+
+ assertThatThrownBy(invalidFormatRequest::execute)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Date 'wrong-date-input' cannot be parsed as either a date or date+time");
}
@@ -1321,7 +1381,7 @@ public class SearchActionTest {
"additionalFields", "asc", "assigned", "assignees", "author", "componentKeys", "branch", "pullRequest", "createdAfter", "createdAt",
"createdBefore", "createdInLast", "directories", "facets", "files", "issues", "scopes", "languages", "onComponentOnly",
"p", "projects", "ps", "resolutions", "resolved", "rules", "s", "severities", "sinceLeakPeriod", "statuses", "tags", "types", "owaspTop10", "sansTop25",
- "cwe", "sonarsourceSecurity", "timeZone");
+ "cwe", "sonarsourceSecurity", "timeZone", "inNewCodePeriod");
WebService.Param branch = def.param(PARAM_BRANCH);
assertThat(branch.isInternal()).isFalse();
@@ -1333,6 +1393,26 @@ public class SearchActionTest {
"This parameter is mostly used by the Issues page, please prefer usage of the componentKeys parameter. If this parameter is set, projectUuids must not be set.");
}
+ @Test
+ public void fail_when_mismatching_sinceLeakPeriod_and_inNewCodePeriod() {
+
+ TestRequest requestLeakTrueNewCodeFalse = ws.newRequest()
+ .setParam(PARAM_SINCE_LEAK_PERIOD, "true")
+ .setParam(PARAM_IN_NEW_CODE_PERIOD, "false");
+
+ assertThatThrownBy(requestLeakTrueNewCodeFalse::execute)
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("If both provided, the following parameters sinceLeakPeriod and inNewCodePeriod must match.");
+
+ TestRequest requestLeakFalseNewCodeTrue = ws.newRequest()
+ .setParam(PARAM_SINCE_LEAK_PERIOD, "false")
+ .setParam(PARAM_IN_NEW_CODE_PERIOD, "true");
+
+ assertThatThrownBy(requestLeakFalseNewCodeTrue::execute)
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("If both provided, the following parameters sinceLeakPeriod and inNewCodePeriod must match.");
+ }
+
private RuleDto newIssueRule() {
RuleDto rule = RuleTesting.newXooX1()
.setName("Rule name")
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesWsParameters.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesWsParameters.java
index cdd9de19c1d..008a8ebc59d 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesWsParameters.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesWsParameters.java
@@ -89,7 +89,9 @@ public class IssuesWsParameters {
public static final String PARAM_CREATED_AT = "createdAt";
public static final String PARAM_CREATED_BEFORE = "createdBefore";
public static final String PARAM_CREATED_IN_LAST = "createdInLast";
+ @Deprecated
public static final String PARAM_SINCE_LEAK_PERIOD = "sinceLeakPeriod";
+ public static final String PARAM_IN_NEW_CODE_PERIOD = "inNewCodePeriod";
public static final String PARAM_ASC = "asc";
public static final String PARAM_ADDITIONAL_FIELDS = "additionalFields";
public static final String PARAM_TIMEZONE = "timeZone";