From 4fa39ba530c3cc42c16d05bece11c978aa8d0143 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 26 Feb 2020 01:49:16 -0800 Subject: [PATCH] Added expand method. --- .../kotlin/net/thauvin/erik/bitly/Bitly.kt | 72 ++++++++++++++----- .../net/thauvin/erik/bitly/BitlyTest.kt | 43 ++++------- 2 files changed, 70 insertions(+), 45 deletions(-) diff --git a/src/main/kotlin/net/thauvin/erik/bitly/Bitly.kt b/src/main/kotlin/net/thauvin/erik/bitly/Bitly.kt index dc3988d..b094b2d 100644 --- a/src/main/kotlin/net/thauvin/erik/bitly/Bitly.kt +++ b/src/main/kotlin/net/thauvin/erik/bitly/Bitly.kt @@ -161,7 +161,7 @@ open class Bitly() { * @param method The submission [Method][Methods]. * @return The response (JSON) from the API. */ - fun executeCall(endPoint: String, params: Map, method: Methods = Methods.POST): String { + fun call(endPoint: String, params: Map, method: Methods = Methods.POST): String { var response = "" if (endPoint.isBlank()) { logger.severe("Please specify a valid API endpoint.") @@ -209,6 +209,42 @@ open class Bitly() { return response } + /** + * Expands a Bitlink. + * + * See the [Bit.ly API](https://dev.bitly.com/v4/#operation/expandBitlink) for more information. + * + * @param bitlink_id The bitlink ID. + * @param isJson Returns the full JSON API response if `true` + * @return THe long URL or JSON API response. + */ + @JvmOverloads + fun expand(bitlink_id: String, isJson: Boolean = false): String { + var longUrl = if (isJson) "{}" else "" + if (bitlink_id.isNotBlank()) { + val response = call( + buildEndPointUrl("/expand"), + mapOf( + Pair( + "bitlink_id", + bitlink_id.removePrefix("http://").removePrefix("https://") + ) + ), + Methods.POST + ) + longUrl = parseJsonResponse(response, "long_url", longUrl, isJson) + } + + return longUrl + } + + private fun JSONObject.getString(key: String, default: String): String { + return if (this.has(key)) + this.getString(key) + else + default + } + /** * Shortens a long URL. * @@ -216,7 +252,7 @@ open class Bitly() { * * @param long_url The long URL. * @param group_guid The group UID. - * @param domain The domain, defaults to `bit.ly`. + * @param domain The domain for the short URL, defaults to `bit.ly`. * @param isJson Returns the full JSON API response if `true` * @return THe short URL or JSON API response. */ @@ -235,22 +271,9 @@ open class Bitly() { } params["long_url"] = long_url - val response = executeCall(buildEndPointUrl("/shorten"), params) + val response = call(buildEndPointUrl("/shorten"), params) - if (response.isNotEmpty()) { - if (isJson) { - bitlink = response - } else { - try { - val json = JSONObject(response) - if (json.has("link")) { - bitlink = json.getString("link") - } - } catch (ignore: JSONException) { - logger.severe("An error occurred parsing the response from bitly.") - } - } - } + bitlink = parseJsonResponse(response, "link", bitlink, isJson) } return bitlink @@ -274,6 +297,21 @@ open class Bitly() { } } + private fun parseJsonResponse(response: String, key: String, default: String, isJson: Boolean): String { + if (response.isNotEmpty()) { + if (isJson) { + return response + } else { + try { + return JSONObject(response).getString(key, default) + } catch (ignore: JSONException) { + logger.severe("An error occurred parsing the response from bitly.") + } + } + } + return default + } + private fun validateUrl(url: String): Boolean { var isValid = url.isNotBlank() if (isValid) { diff --git a/src/test/kotlin/net/thauvin/erik/bitly/BitlyTest.kt b/src/test/kotlin/net/thauvin/erik/bitly/BitlyTest.kt index 055034a..075686a 100644 --- a/src/test/kotlin/net/thauvin/erik/bitly/BitlyTest.kt +++ b/src/test/kotlin/net/thauvin/erik/bitly/BitlyTest.kt @@ -34,34 +34,20 @@ package net.thauvin.erik.bitly import org.junit.Before import java.io.File -import java.io.FileInputStream -import java.util.Properties import java.util.logging.Level import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue -fun getKey(key: String): String { - var value = System.getenv(key) ?: "" - if (value.isBlank()) { - val localProps = File("local.properties") - if (localProps.exists()) - localProps.apply { - if (exists()) { - FileInputStream(this).use { fis -> - Properties().apply { - load(fis) - value = getProperty(key, "") - } - } - } - } - } - return value -} - class BitlyTest { - private val bitly = Bitly(getKey(Bitly.Constants.ENV_ACCESS_TOKEN)) + private val bitly = with(File("local.properties")) { + if (exists()) { + Bitly(toPath()) + } else { + Bitly() + } + } + private val blog = "https://erik.thauvin.net/blog" @Before fun before() { @@ -76,7 +62,7 @@ class BitlyTest { if (System.getenv("CI") == "true") { test.accessToken = "" } - assertEquals("", test.shorten("https://erik.thauvin.net/blog/")) + assertEquals("", test.shorten(blog)) } @Test @@ -91,17 +77,18 @@ class BitlyTest { } @Test - fun `blog should be valid`() { - assertEquals("http://bit.ly/2SVHsnd", bitly.shorten("https://erik.thauvin.net/blog/", domain = "bit.ly")) + fun `shorten = expand`() { + val shortUrl = bitly.shorten(blog, domain = "bit.ly") + assertEquals(blog, bitly.expand(shortUrl)) } @Test - fun `blog as json`() { - assertTrue(bitly.shorten("https://erik.thauvin.net/blog/", isJson = true).startsWith("{\"created_at\":")) + fun `as json`() { + assertTrue(bitly.shorten(blog, isJson = true).startsWith("{\"created_at\":")) } @Test fun `get user`() { - assertTrue(bitly.executeCall(bitly.buildEndPointUrl("user"), emptyMap(), Methods.GET).contains("\"login\":")) + assertTrue(bitly.call(bitly.buildEndPointUrl("user"), emptyMap(), Methods.GET).contains("\"login\":")) } }