From ee3d422d0dca4e4868ebb3fe3bc92991cb5912b0 Mon Sep 17 00:00:00 2001 From: Kittinun Vantasin Date: Sat, 6 May 2017 22:47:42 +0800 Subject: [PATCH] :sparkles: Add PATCH method for Fuel (#156) --- build.gradle | 2 +- .../kotlin/com/github/kittinunf/fuel/Fuel.kt | 21 ++++ .../com/github/kittinunf/fuel/core/Request.kt | 1 + .../kittinunf/fuel/toolbox/HttpClient.kt | 3 +- ...questPathStringConvertibleExtensionTest.kt | 35 ++++++ .../fuel/RequestStringExtensionTest.kt | 30 +++++- .../com/github/kittinunf/fuel/RequestTest.kt | 100 +++++++++++++++++- .../java/com/example/fuel/MainActivity.java | 2 + 8 files changed, 187 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index d390cded1..4e7e87314 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:2.3.0' + classpath 'com.android.tools.build:gradle:2.3.1' classpath 'com.dicedmelon.gradle:jacoco-android:0.1.1' classpath 'com.novoda:bintray-release:0.3.4' diff --git a/fuel/src/main/kotlin/com/github/kittinunf/fuel/Fuel.kt b/fuel/src/main/kotlin/com/github/kittinunf/fuel/Fuel.kt index ee9f8ac9a..c835340b9 100644 --- a/fuel/src/main/kotlin/com/github/kittinunf/fuel/Fuel.kt +++ b/fuel/src/main/kotlin/com/github/kittinunf/fuel/Fuel.kt @@ -59,6 +59,17 @@ class Fuel { return request(Method.PUT, convertible, parameters) } + //patch + @JvmStatic @JvmOverloads + fun patch(path: String, parameters: List>? = null): Request { + return request(Method.PATCH, path, parameters) + } + + @JvmStatic @JvmOverloads + fun patch(convertible: PathStringConvertible, parameters: List>? = null): Request { + return request(Method.PATCH, convertible, parameters) + } + //delete @JvmStatic @JvmOverloads fun delete(path: String, parameters: List>? = null): Request { @@ -151,6 +162,16 @@ fun Fuel.PathStringConvertible.httpPut(parameter: List>? = nu return Fuel.put(this, parameter) } +@JvmOverloads +fun String.httpPatch(parameters: List>? = null): Request { + return Fuel.patch(this, parameters) +} + +@JvmOverloads +fun Fuel.PathStringConvertible.httpPatch(parameter: List>? = null): Request { + return Fuel.patch(this, parameter) +} + @JvmOverloads fun String.httpDelete(parameters: List>? = null): Request { return Fuel.delete(this, parameters) diff --git a/fuel/src/main/kotlin/com/github/kittinunf/fuel/core/Request.kt b/fuel/src/main/kotlin/com/github/kittinunf/fuel/core/Request.kt index 5c2f98a4f..0c8c267ab 100644 --- a/fuel/src/main/kotlin/com/github/kittinunf/fuel/core/Request.kt +++ b/fuel/src/main/kotlin/com/github/kittinunf/fuel/core/Request.kt @@ -242,6 +242,7 @@ class Request : Fuel.RequestConvertible { fun responseString(handler: Handler) = response(stringDeserializer(), handler) + @JvmOverloads fun responseString(charset: Charset = Charsets.UTF_8) = response(stringDeserializer(charset)) //object diff --git a/fuel/src/main/kotlin/com/github/kittinunf/fuel/toolbox/HttpClient.kt b/fuel/src/main/kotlin/com/github/kittinunf/fuel/toolbox/HttpClient.kt index fedcf1e1b..6412dda68 100644 --- a/fuel/src/main/kotlin/com/github/kittinunf/fuel/toolbox/HttpClient.kt +++ b/fuel/src/main/kotlin/com/github/kittinunf/fuel/toolbox/HttpClient.kt @@ -29,12 +29,13 @@ class HttpClient(val proxy: Proxy? = null) : Client { readTimeout = timeoutRead doInput = true useCaches = false - requestMethod = request.httpMethod.value + requestMethod = if (request.httpMethod == Method.PATCH) Method.POST.value else request.httpMethod.value setDoOutput(connection, request.httpMethod) instanceFollowRedirects = false for ((key, value) in request.httpHeaders) { setRequestProperty(key, value) } + if (request.httpMethod == Method.PATCH) setRequestProperty("X-HTTP-Method-Override", "PATCH") setBodyIfAny(connection, request.httpBody) } diff --git a/fuel/src/test/kotlin/com/github/kittinunf/fuel/RequestPathStringConvertibleExtensionTest.kt b/fuel/src/test/kotlin/com/github/kittinunf/fuel/RequestPathStringConvertibleExtensionTest.kt index 2f1325efd..e8837c0d3 100644 --- a/fuel/src/test/kotlin/com/github/kittinunf/fuel/RequestPathStringConvertibleExtensionTest.kt +++ b/fuel/src/test/kotlin/com/github/kittinunf/fuel/RequestPathStringConvertibleExtensionTest.kt @@ -28,6 +28,12 @@ class RequestPathStringConvertibleExtensionTest : BaseTestCase() { override val path = "/$relativePath" } + enum class MockBin(path: String) : Fuel.PathStringConvertible { + PATH(""); + + override val path = "https://mockbin.org/request/$path" + } + @Test fun httpGetRequestWithSharedInstance() { var request: Request? = null @@ -111,6 +117,35 @@ class RequestPathStringConvertibleExtensionTest : BaseTestCase() { assertThat(string, containsString("https")) } + @Test + fun httpPatchRequestWithSharedInstance() { + var request: Request? = null + var response: Response? = null + var data: Any? = null + var error: FuelError? = null + + MockBin.PATH.httpPatch().responseString { req, res, result -> + request = req + response = res + + val (d, err) = result + data = d + error = err + } + + val string = data as String + + assertThat(request, notNullValue()) + assertThat(response, notNullValue()) + assertThat(error, nullValue()) + assertThat(data, notNullValue()) + + val statusCode = HttpURLConnection.HTTP_OK + assertThat(response?.httpStatusCode, isEqualTo(statusCode)) + + assertThat(string, containsString("https")) + } + @Test fun httpDeleteRequestWithSharedInstance() { var request: Request? = null diff --git a/fuel/src/test/kotlin/com/github/kittinunf/fuel/RequestStringExtensionTest.kt b/fuel/src/test/kotlin/com/github/kittinunf/fuel/RequestStringExtensionTest.kt index 7678f9659..3b13df74a 100644 --- a/fuel/src/test/kotlin/com/github/kittinunf/fuel/RequestStringExtensionTest.kt +++ b/fuel/src/test/kotlin/com/github/kittinunf/fuel/RequestStringExtensionTest.kt @@ -1,6 +1,10 @@ package com.github.kittinunf.fuel -import com.github.kittinunf.fuel.core.* +import com.github.kittinunf.fuel.core.FuelError +import com.github.kittinunf.fuel.core.FuelManager +import com.github.kittinunf.fuel.core.Method +import com.github.kittinunf.fuel.core.Request +import com.github.kittinunf.fuel.core.Response import org.hamcrest.CoreMatchers.notNullValue import org.hamcrest.CoreMatchers.nullValue import org.junit.Assert.assertThat @@ -89,6 +93,30 @@ class RequestStringExtensionTest : BaseTestCase() { assertThat(response?.httpStatusCode, isEqualTo(statusCode)) } + @Test + fun httpPatch() { + var request: Request? = null + var response: Response? = null + var data: Any? = null + var error: FuelError? = null + + "https://mockbin.org/request".httpPatch().responseString { req, res, result -> + request = req + response = res + val (d, err) = result + data = d + error = err + } + + assertThat(request, notNullValue()) + assertThat(response, notNullValue()) + assertThat(error, nullValue()) + assertThat(data, notNullValue()) + + val statusCode = HttpURLConnection.HTTP_OK + assertThat(response?.httpStatusCode, isEqualTo(statusCode)) + } + @Test fun httpDelete() { var request: Request? = null diff --git a/fuel/src/test/kotlin/com/github/kittinunf/fuel/RequestTest.kt b/fuel/src/test/kotlin/com/github/kittinunf/fuel/RequestTest.kt index bce384b64..1df05d971 100644 --- a/fuel/src/test/kotlin/com/github/kittinunf/fuel/RequestTest.kt +++ b/fuel/src/test/kotlin/com/github/kittinunf/fuel/RequestTest.kt @@ -10,6 +10,11 @@ import org.hamcrest.CoreMatchers.* import org.junit.Assert.assertThat import org.junit.Test import java.net.HttpURLConnection +import java.security.SecureRandom +import java.security.cert.X509Certificate +import javax.net.ssl.SSLContext +import javax.net.ssl.TrustManager +import javax.net.ssl.X509TrustManager import org.hamcrest.CoreMatchers.`is` as isEqualTo class RequestTest : BaseTestCase() { @@ -20,11 +25,18 @@ class RequestTest : BaseTestCase() { USER_AGENT("user-agent"), POST("post"), PUT("put"), + PATCH("patch"), DELETE("delete"); override val path = "https://httpbin.org/$relativePath" } + enum class MockBin(path: String) : Fuel.PathStringConvertible { + PATH(""); + + override val path = "http://mockbin.org/request/$path" + } + class HttpBinConvertible(val method: Method, val relativePath: String) : Fuel.RequestConvertible { override val request = createRequest() @@ -38,6 +50,23 @@ class RequestTest : BaseTestCase() { } } + init { + val acceptsAllTrustManager = object : X509TrustManager { + override fun checkServerTrusted(chain: Array?, authType: String?) {} + + override fun getAcceptedIssuers(): Array? = null + + override fun checkClientTrusted(chain: Array?, authType: String?) {} + } + + manager.socketFactory = { + val context = SSLContext.getInstance("TLS") + context.init(null, arrayOf(acceptsAllTrustManager), SecureRandom()) + SSLContext.setDefault(context) + context.socketFactory + }() + } + @Test fun httpGetRequestWithDataResponse() { var request: Request? = null @@ -131,7 +160,7 @@ class RequestTest : BaseTestCase() { val paramKey = "foo" val paramValue = "bar" - manager.request(Method.GET, "http://httpbin.org/get", listOf(paramKey to paramValue)).responseString { req, res, result -> + manager.request(Method.POST, "http://httpbin.org/post", listOf(paramKey to paramValue)).responseString { req, res, result -> request = req response = res @@ -221,6 +250,40 @@ class RequestTest : BaseTestCase() { assertThat(string, containsString(paramValue)) } + @Test + fun httpPatchRequestWithParameters() { + var request: Request? = null + var response: Response? = null + var data: Any? = null + var error: FuelError? = null + + val paramKey = "foo2" + val paramValue = "bar2" + + // for some reason httpbin doesn't support underlying POST for PATCH endpoint + manager.request(Method.PATCH, "http://mockbin.org/request", listOf(paramKey to paramValue)).responseString { req, res, result -> + request = req + response = res + + val (d, err) = result + data = d + error = err + } + + val string = data as String + + assertThat(request, notNullValue()) + assertThat(response, notNullValue()) + assertThat(error, nullValue()) + assertThat(data, notNullValue()) + + val statusCode = HttpURLConnection.HTTP_OK + assertThat(response?.httpStatusCode, isEqualTo(statusCode)) + + assertThat(string, containsString(paramKey)) + assertThat(string, containsString(paramValue)) + } + @Test fun httpDeleteRequestWithParameters() { var request: Request? = null @@ -287,7 +350,7 @@ class RequestTest : BaseTestCase() { } @Test - fun httpGetRequestWithPathStringConvertible() { + fun httpGetRequestUserAgentWithPathStringConvertible() { var request: Request? = null var response: Response? = null var data: Any? = null @@ -343,7 +406,37 @@ class RequestTest : BaseTestCase() { } @Test - fun httpGetRequestWithRequestConvertibleAndOverriddenParameters() { + fun httpPatchRequestWithRequestConvertible() { + var request: Request? = null + var response: Response? = null + var data: Any? = null + var error: FuelError? = null + + val paramKey = "foo" + val paramValue = "bar" + + manager.request(Method.PATCH, MockBin.PATH, listOf(paramKey to paramValue)).responseString { req, res, result -> + request = req + response = res + + result.fold({ + data = it + }, { + error = it + }) + } + + assertThat(request, notNullValue()) + assertThat(response, notNullValue()) + assertThat(error, nullValue()) + assertThat(data, notNullValue()) + + val statusCode = HttpURLConnection.HTTP_OK + assertThat(response?.httpStatusCode, isEqualTo(statusCode)) + } + + @Test + fun httpPostRequestWithRequestConvertibleAndOverriddenParameters() { var request: Request? = null var response: Response? = null var data: Any? = null @@ -391,7 +484,6 @@ class RequestTest : BaseTestCase() { request.cancel() - println(request.cUrlString()) assertThat(request, notNullValue()) assertThat(response, nullValue()) assertThat(data, nullValue()) diff --git a/sample-java/src/main/java/com/example/fuel/MainActivity.java b/sample-java/src/main/java/com/example/fuel/MainActivity.java index 14aac034d..56ad213b8 100644 --- a/sample-java/src/main/java/com/example/fuel/MainActivity.java +++ b/sample-java/src/main/java/com/example/fuel/MainActivity.java @@ -63,6 +63,8 @@ public void success(@NotNull Request request, @NotNull Response response, String } }); + Fuel.get("http://httpbin.org/get", params).responseString(); + //put Fuel.put("http://httpbin.org/put").responseString(new Handler() { @Override