From fd899b2b8bfbb33299e8188e0481c49cc5e1a7b5 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Portier Date: Tue, 17 Dec 2024 19:44:34 +0100 Subject: [PATCH] feat (core): Provide URLParameter helper to add a query param to a list --- .../com/sinch/sdk/core/http/URLParameter.java | 13 ++++- .../sdk/core/http/URLParameterUtils.java | 25 ++++++++- .../InstantToIso8601SerializerTest.java | 2 - .../sinch/sdk/core/http/URLParameterTest.java | 44 +++++++++++++++ .../sdk/core/http/URLParameterUtilsTest.java | 55 +++++++++++++++++++ 5 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 core/src/test/java/com/sinch/sdk/core/http/URLParameterTest.java diff --git a/core/src/main/com/sinch/sdk/core/http/URLParameter.java b/core/src/main/com/sinch/sdk/core/http/URLParameter.java index 82a54171f..c84d4c2b9 100644 --- a/core/src/main/com/sinch/sdk/core/http/URLParameter.java +++ b/core/src/main/com/sinch/sdk/core/http/URLParameter.java @@ -69,6 +69,17 @@ public enum STYLE { SIMPLE, SPACE_DELIMITED, PIPE_DELIMITED, - DEEP_OBJECT + DEEP_OBJECT; } + + // the following constants do not follow java standard by purpose + // Aim is to have direct access to OpenApi Spec authorized values as constant without overhead + // ref: https://spec.openapis.org/oas/latest.html#style-values + public static final STYLE matrix = STYLE.MATRIX; + public static final STYLE label = STYLE.LABEL; + public static final STYLE form = STYLE.FORM; + public static final STYLE simple = STYLE.SIMPLE; + public static final STYLE spaceDelimited = STYLE.SPACE_DELIMITED; + public static final STYLE pipeDelimited = STYLE.PIPE_DELIMITED; + public static final STYLE deepObject = STYLE.DEEP_OBJECT; } diff --git a/core/src/main/com/sinch/sdk/core/http/URLParameterUtils.java b/core/src/main/com/sinch/sdk/core/http/URLParameterUtils.java index 7ced9d8b9..6def5f845 100644 --- a/core/src/main/com/sinch/sdk/core/http/URLParameterUtils.java +++ b/core/src/main/com/sinch/sdk/core/http/URLParameterUtils.java @@ -1,6 +1,9 @@ package com.sinch.sdk.core.http; +import com.sinch.sdk.core.databind.QueryParameterSerializer; import com.sinch.sdk.core.exceptions.ApiException; +import com.sinch.sdk.core.http.URLParameter.STYLE; +import com.sinch.sdk.core.models.OptionalValue; import com.sinch.sdk.core.utils.EnumDynamic; import com.sinch.sdk.core.utils.StringUtil; import java.io.UnsupportedEncodingException; @@ -8,6 +11,7 @@ import java.security.InvalidParameterException; import java.util.Arrays; import java.util.Collection; +import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -26,7 +30,7 @@ public static String encodeParametersAsString(Collection parameter .collect(Collectors.joining("&")); } - public static Optional encode(URLParameter parameter) { + protected static Optional encode(URLParameter parameter) { if (null == parameter || StringUtil.isEmpty(parameter.getName()) @@ -195,7 +199,7 @@ private static Optional encodeObject(URLParameter parameter) { throw new ApiException("Not yet implemented '" + parameter + "'"); } - public static String encodeParameterValue(String value) { + private static String encodeParameterValue(String value) { try { return URLEncoder.encode(value, "UTF-8").replaceAll("\\.", "%2E"); @@ -203,4 +207,21 @@ public static String encodeParameterValue(String value) { return value; } } + + public static void addQueryParam( + OptionalValue optionalValue, + String paramName, + STYLE paramStyle, + QueryParameterSerializer serializer, + List queryParametersList, + boolean explode) { + optionalValue.ifPresent( + value -> + queryParametersList.add( + new URLParameter( + paramName, + null == serializer ? value : serializer.apply(value), + paramStyle, + explode))); + } } diff --git a/core/src/test/java/com/sinch/sdk/core/databind/query_parameter/InstantToIso8601SerializerTest.java b/core/src/test/java/com/sinch/sdk/core/databind/query_parameter/InstantToIso8601SerializerTest.java index 430eedfb9..2806c58a1 100644 --- a/core/src/test/java/com/sinch/sdk/core/databind/query_parameter/InstantToIso8601SerializerTest.java +++ b/core/src/test/java/com/sinch/sdk/core/databind/query_parameter/InstantToIso8601SerializerTest.java @@ -1,7 +1,5 @@ package com.sinch.sdk.core.databind.query_parameter; -import static org.junit.jupiter.api.Assertions.*; - import com.sinch.sdk.core.TestHelpers; import java.time.Instant; import org.junit.jupiter.api.Assertions; diff --git a/core/src/test/java/com/sinch/sdk/core/http/URLParameterTest.java b/core/src/test/java/com/sinch/sdk/core/http/URLParameterTest.java new file mode 100644 index 000000000..f39bcf295 --- /dev/null +++ b/core/src/test/java/com/sinch/sdk/core/http/URLParameterTest.java @@ -0,0 +1,44 @@ +package com.sinch.sdk.core.http; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.sinch.sdk.core.http.URLParameter.STYLE; +import org.junit.jupiter.api.Test; + +class URLParameterTest { + + @Test + void matrix() { + assertEquals(STYLE.MATRIX, URLParameter.matrix); + } + + @Test + void label() { + assertEquals(STYLE.LABEL, URLParameter.label); + } + + @Test + void form() { + assertEquals(STYLE.FORM, URLParameter.form); + } + + @Test + void simple() { + assertEquals(STYLE.SIMPLE, URLParameter.simple); + } + + @Test + void spaceDelimited() { + assertEquals(STYLE.SPACE_DELIMITED, URLParameter.spaceDelimited); + } + + @Test + void pipeDelimited() { + assertEquals(STYLE.PIPE_DELIMITED, URLParameter.pipeDelimited); + } + + @Test + void deepObject() { + assertEquals(STYLE.DEEP_OBJECT, URLParameter.deepObject); + } +} diff --git a/core/src/test/java/com/sinch/sdk/core/http/URLParameterUtilsTest.java b/core/src/test/java/com/sinch/sdk/core/http/URLParameterUtilsTest.java index 35b582384..0d977de46 100644 --- a/core/src/test/java/com/sinch/sdk/core/http/URLParameterUtilsTest.java +++ b/core/src/test/java/com/sinch/sdk/core/http/URLParameterUtilsTest.java @@ -1,10 +1,18 @@ package com.sinch.sdk.core.http; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import com.sinch.sdk.core.TestHelpers; +import com.sinch.sdk.core.databind.query_parameter.InstantToIso8601Serializer; import com.sinch.sdk.core.exceptions.ApiException; +import com.sinch.sdk.core.http.URLParameter.STYLE; +import com.sinch.sdk.core.models.OptionalValue; +import java.time.Instant; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Optional; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -374,4 +382,51 @@ void encodePipeDelimitedArrayExplode() { URLParameter.STYLE.PIPE_DELIMITED, true))); } + + @Test + void addQueryParamNotPresent() { + + // Collections.emptyList() is not modifiable and will throw an exception if trying to add an + // entry + assertDoesNotThrow( + () -> + URLParameterUtils.addQueryParam( + OptionalValue.empty(), + "foo name", + STYLE.DEEP_OBJECT, + null, + Collections.emptyList(), + false), + "Ignored empty value"); + } + + @Test + void addQueryParamInteger() { + ArrayList list = new ArrayList<>(); + + URLParameterUtils.addQueryParam( + OptionalValue.of(15), "foo name", STYLE.DEEP_OBJECT, null, list, true); + assertEquals(1, list.size()); + + TestHelpers.recursiveEquals( + list.get(0), new URLParameter("foo name", 15, STYLE.DEEP_OBJECT, true)); + } + + @Test + void addQueryParamInstant() { + ArrayList list = new ArrayList<>(); + + URLParameterUtils.addQueryParam( + OptionalValue.of(Instant.parse("2024-05-04T10:00:00.123Z")), + "foo name", + STYLE.DEEP_OBJECT, + InstantToIso8601Serializer.getInstance(), + list, + true); + assertEquals(1, list.size()); + + TestHelpers.recursiveEquals( + list.get(0), + new URLParameter("foo name", "2024-05-04T10:00:00.123Z", STYLE.DEEP_OBJECT, true)); + } }