From 7b0215a1b0090ea709e12e226ab0486072606aca Mon Sep 17 00:00:00 2001 From: AndrewGiddings-at-BankCheck <107408308+AndrewGiddings-at-BankCheck@users.noreply.github.com> Date: Tue, 14 Jun 2022 16:34:01 +0100 Subject: [PATCH 1/2] Update URIConfigurator.java Suggested fix for issues #360 and #339. Preserves duplicate params with names ending in `[]` (needed for free-form Redmine queries), while still removing others. --- .../redmineapi/internal/URIConfigurator.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/taskadapter/redmineapi/internal/URIConfigurator.java b/src/main/java/com/taskadapter/redmineapi/internal/URIConfigurator.java index e99c5892..e190b666 100644 --- a/src/main/java/com/taskadapter/redmineapi/internal/URIConfigurator.java +++ b/src/main/java/com/taskadapter/redmineapi/internal/URIConfigurator.java @@ -39,6 +39,7 @@ import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; +import java.util.stream.Stream; public class URIConfigurator { private static final String URL_POSTFIX = ".json"; @@ -97,7 +98,7 @@ public URI createURI(String query, RequestParam... param) { */ private URI createURI(String query, Collection origParams) { - var distinctParams = distinct(origParams); + var distinctParams = dedup(origParams); var nameValueParams = toNameValue(distinctParams); try { var builder = new URIBuilder(baseURL.toURI()); @@ -120,6 +121,25 @@ static Collection distinct(Collection origParams) { .values(); } + /** + * Gives a list of parameters with any duplicates removed. + *
+ * Parameters are considered to be duplicates if they have the same parameter name; + * however, parameters with names ending in "[]" will NOT be removed, as that indicates + * an array element which may be repeated. (In particular, free-form Redmine queries + * all have a parameter called "f[]", and so those must be preserved.) + *
+ * This does NOT preserve the order of parameters. + */ + static Collection dedup(Collection origParams) { + var repeatableParams = origParams.stream() + .filter(param -> param != null && param.getName().endsWith("[]")); + var distinctNonRepeatableParams = distinct(origParams).stream() + .filter(param -> param != null && !param.getName().endsWith("[]")); + return Stream.concat(repeatableParams, distinctNonRepeatableParams) + .collect(Collectors.toList()); + } + static Collection toNameValue(Collection origParams) { return origParams .stream() From b53b60320de04a88106b77e2a57241fc45053254 Mon Sep 17 00:00:00 2001 From: AndrewGiddings-at-BankCheck <107408308+AndrewGiddings-at-BankCheck@users.noreply.github.com> Date: Tue, 14 Jun 2022 16:35:44 +0100 Subject: [PATCH 2/2] Update URIConfiguratorTest.java Add unit tests for URIConfigurator.dedup(). --- .../internal/URIConfiguratorTest.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/test/java/com/taskadapter/redmineapi/internal/URIConfiguratorTest.java b/src/test/java/com/taskadapter/redmineapi/internal/URIConfiguratorTest.java index 96b656a1..d6a21366 100644 --- a/src/test/java/com/taskadapter/redmineapi/internal/URIConfiguratorTest.java +++ b/src/test/java/com/taskadapter/redmineapi/internal/URIConfiguratorTest.java @@ -14,6 +14,8 @@ public class URIConfiguratorTest { private static final RequestParam param1 = new RequestParam("name1", "value1"); private static final RequestParam param2 = new RequestParam("name3", "value3"); private static final RequestParam param2WithDifferentValue = new RequestParam("name3", "anotherValue3"); + private static final RequestParam arrayParam1 = new RequestParam("name4[]", "value4"); + private static final RequestParam arrayParam1WithDifferentValue = new RequestParam("name4[]", "anotherValue4"); private static final RequestParam nullParam = null; @Test @@ -44,6 +46,24 @@ public void distinctWithDifferentNamesSameValuesShouldKeepAllItems() { "two", "value")); } + @Test + public void dedupRemovesDuplicates() { + List params = Arrays.asList(param2, param2WithDifferentValue); + assertThat(URIConfigurator.dedup(params)).containsOnly(param2); + } + + @Test + public void dedupDoesNotRemoveArrays() { + List params = Arrays.asList(arrayParam1, arrayParam1WithDifferentValue); + assertThat(URIConfigurator.dedup(params)).containsAll(params); + } + + @Test + public void dedupWithDifferentNamesSameValuesShouldKeepAllItems() { + List params = Arrays.asList(param1, param2, arrayParam1); + assertThat(URIConfigurator.dedup(params)).containsAll(params); + } + @Test public void toNameValueConvertsCollection() { assertThat(URIConfigurator.toNameValue(Arrays.asList(param1, param2))).containsOnly(