From 191b09060b2639613cd3cf507fb9f5ca1d9164c5 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Mon, 3 Jan 2022 12:22:07 -0800 Subject: [PATCH] Cleanup. --- .idea/bitly-shorten.iml | 9 ++ .idea/modules.xml | 8 ++ .../kotlin/net/thauvin/erik/bitly/Bitlinks.kt | 134 +++++++++--------- .../kotlin/net/thauvin/erik/bitly/Bitly.kt | 2 +- .../kotlin/net/thauvin/erik/bitly/Utils.kt | 8 +- .../net/thauvin/erik/bitly/BitlyTest.kt | 67 ++++++--- 6 files changed, 132 insertions(+), 96 deletions(-) create mode 100644 .idea/bitly-shorten.iml create mode 100644 .idea/modules.xml diff --git a/.idea/bitly-shorten.iml b/.idea/bitly-shorten.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/bitly-shorten.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..edbcc81 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/kotlin/net/thauvin/erik/bitly/Bitlinks.kt b/src/main/kotlin/net/thauvin/erik/bitly/Bitlinks.kt index 58bd057..e74877a 100644 --- a/src/main/kotlin/net/thauvin/erik/bitly/Bitlinks.kt +++ b/src/main/kotlin/net/thauvin/erik/bitly/Bitlinks.kt @@ -69,25 +69,25 @@ open class Bitlinks(private val accessToken: String) { @Synchronized @JvmOverloads fun clicks( - bitlink: String, - unit: Units = Units.DAY, - units: Int = -1, - size: Int = 50, - unit_reference: String = Constants.EMPTY, - toJson: Boolean = false + bitlink: String, + unit: Units = Units.DAY, + units: Int = -1, + size: Int = 50, + unit_reference: String = Constants.EMPTY, + toJson: Boolean = false ): String { var clicks = if (toJson) Constants.EMPTY_JSON else Constants.EMPTY if (bitlink.isNotBlank()) { lastCallResponse = Utils.call( - accessToken, - ("/bitlinks/${bitlink.removeHttp()}/clicks/summary").toEndPoint(), - mapOf( - "unit" to unit.toString().lowercase(), - "units" to units.toString(), - "size" to size.toString(), - "unit_reference" to unit_reference - ), - Methods.GET + accessToken, + ("/bitlinks/${bitlink.removeHttp()}/clicks/summary").toEndPoint(), + mapOf( + "unit" to unit.toString().lowercase(), + "units" to units.toString(), + "size" to size.toString(), + "unit_reference" to unit_reference + ), + Methods.GET ) clicks = parseJsonResponse(lastCallResponse, "total_clicks", clicks, toJson) } @@ -108,26 +108,26 @@ open class Bitlinks(private val accessToken: String) { @Synchronized @JvmOverloads fun create( - domain: String = Constants.EMPTY, - title: String = Constants.EMPTY, - group_guid: String = Constants.EMPTY, - tags: Array = emptyArray(), - deeplinks: Array> = emptyArray(), - long_url: String, - toJson: Boolean = false + domain: String = Constants.EMPTY, + title: String = Constants.EMPTY, + group_guid: String = Constants.EMPTY, + tags: Array = emptyArray(), + deeplinks: Array> = emptyArray(), + long_url: String, + toJson: Boolean = false ): String { var link = if (toJson) Constants.EMPTY_JSON else Constants.EMPTY if (long_url.isNotBlank()) { lastCallResponse = Utils.call( - accessToken, - "/bitlinks".toEndPoint(), - mutableMapOf("long_url" to long_url).apply { - if (domain.isNotBlank()) put("domain", domain) - if (title.isNotBlank()) put("title", title) - if (group_guid.isNotBlank()) put("group_guid", group_guid) - if (tags.isNotEmpty()) put("tags", tags) - if (deeplinks.isNotEmpty()) put("deeplinks", deeplinks) - } + accessToken, + "/bitlinks".toEndPoint(), + mutableMapOf("long_url" to long_url).apply { + if (domain.isNotBlank()) put("domain", domain) + if (title.isNotBlank()) put("title", title) + if (group_guid.isNotBlank()) put("group_guid", group_guid) + if (tags.isNotEmpty()) put("tags", tags) + if (deeplinks.isNotEmpty()) put("deeplinks", deeplinks) + } ) link = parseJsonResponse(lastCallResponse, "link", link, toJson) } @@ -149,9 +149,9 @@ open class Bitlinks(private val accessToken: String) { var longUrl = if (toJson) Constants.EMPTY_JSON else Constants.EMPTY if (bitlink_id.isNotBlank()) { lastCallResponse = Utils.call( - accessToken, - "/expand".toEndPoint(), - mapOf("bitlink_id" to bitlink_id.removeHttp()) + accessToken, + "/expand".toEndPoint(), + mapOf("bitlink_id" to bitlink_id.removeHttp()) ) longUrl = parseJsonResponse(lastCallResponse, "long_url", longUrl, toJson) } @@ -198,10 +198,10 @@ open class Bitlinks(private val accessToken: String) { @Synchronized @JvmOverloads fun shorten( - long_url: String, - group_guid: String = Constants.EMPTY, - domain: String = Constants.EMPTY, - toJson: Boolean = false + long_url: String, + group_guid: String = Constants.EMPTY, + domain: String = Constants.EMPTY, + toJson: Boolean = false ): String { var bitlink = if (toJson) Constants.EMPTY_JSON else long_url if (!long_url.isValidUrl()) { @@ -234,39 +234,39 @@ open class Bitlinks(private val accessToken: String) { @Synchronized @JvmOverloads fun update( - bitlink: String, - references: Map = emptyMap(), - archived: Boolean = false, - tags: Array = emptyArray(), - created_at: String = Constants.EMPTY, - title: String = Constants.EMPTY, - deeplinks: Array> = emptyArray(), - created_by: String = Constants.EMPTY, - long_url: String = Constants.EMPTY, - client_id: String = Constants.EMPTY, - custom_bitlinks: Array = emptyArray(), - link: String = Constants.EMPTY, - id: String = Constants.EMPTY, - toJson: Boolean = false + bitlink: String, + references: Map = emptyMap(), + archived: Boolean = false, + tags: Array = emptyArray(), + created_at: String = Constants.EMPTY, + title: String = Constants.EMPTY, + deeplinks: Array> = emptyArray(), + created_by: String = Constants.EMPTY, + long_url: String = Constants.EMPTY, + client_id: String = Constants.EMPTY, + custom_bitlinks: Array = emptyArray(), + link: String = Constants.EMPTY, + id: String = Constants.EMPTY, + toJson: Boolean = false ): String { var result = if (toJson) Constants.EMPTY_JSON else Constants.FALSE if (bitlink.isNotBlank()) { lastCallResponse = Utils.call( - accessToken, "/bitlinks/${bitlink.removeHttp()}".toEndPoint(), mutableMapOf().apply { - if (references.isNotEmpty()) put("references", references) - if (archived) put("archived", archived) - if (tags.isNotEmpty()) put("tags", tags) - if (created_at.isNotBlank()) put("created_at", created_at) - if (title.isNotBlank()) put("title", title) - if (deeplinks.isNotEmpty()) put("deeplinks", deeplinks) - if (created_by.isNotBlank()) put("created_by", created_by) - if (long_url.isNotBlank()) put("long_url", long_url) - if (client_id.isNotBlank()) put("client_id", client_id) - if (custom_bitlinks.isNotEmpty()) put("custom_bitlinks", custom_bitlinks) - if (link.isNotBlank()) put("link", link) - if (id.isNotBlank()) put("id", id) - }, - Methods.PATCH + accessToken, "/bitlinks/${bitlink.removeHttp()}".toEndPoint(), mutableMapOf().apply { + if (references.isNotEmpty()) put("references", references) + if (archived) put("archived", archived) + if (tags.isNotEmpty()) put("tags", tags) + if (created_at.isNotBlank()) put("created_at", created_at) + if (title.isNotBlank()) put("title", title) + if (deeplinks.isNotEmpty()) put("deeplinks", deeplinks) + if (created_by.isNotBlank()) put("created_by", created_by) + if (long_url.isNotBlank()) put("long_url", long_url) + if (client_id.isNotBlank()) put("client_id", client_id) + if (custom_bitlinks.isNotEmpty()) put("custom_bitlinks", custom_bitlinks) + if (link.isNotBlank()) put("link", link) + if (id.isNotBlank()) put("id", id) + }, + Methods.PATCH ) if (lastCallResponse.isSuccessful) { diff --git a/src/main/kotlin/net/thauvin/erik/bitly/Bitly.kt b/src/main/kotlin/net/thauvin/erik/bitly/Bitly.kt index c602867..8c665e4 100644 --- a/src/main/kotlin/net/thauvin/erik/bitly/Bitly.kt +++ b/src/main/kotlin/net/thauvin/erik/bitly/Bitly.kt @@ -49,7 +49,7 @@ open class Bitly() { * [Authentication](https://dev.bitly.com/docs/getting-started/authentication). **/ var accessToken: String = System.getenv(Constants.ENV_ACCESS_TOKEN) - ?: (System.getProperty(Constants.ENV_ACCESS_TOKEN) ?: Constants.EMPTY) + ?: (System.getProperty(Constants.ENV_ACCESS_TOKEN) ?: Constants.EMPTY) /** * Creates a new instance using an [API Access Token][accessToken]. diff --git a/src/main/kotlin/net/thauvin/erik/bitly/Utils.kt b/src/main/kotlin/net/thauvin/erik/bitly/Utils.kt index 98e14c3..8c74770 100644 --- a/src/main/kotlin/net/thauvin/erik/bitly/Utils.kt +++ b/src/main/kotlin/net/thauvin/erik/bitly/Utils.kt @@ -50,7 +50,7 @@ import java.util.logging.Logger open class Utils private constructor() { companion object { /** The logger instance. */ - val logger: Logger by lazy { Logger.getLogger(Bitly::class.java.name) } + val logger: Logger by lazy { Logger.getLogger(Utils::class.java.name) } /** * Executes an API call. @@ -70,8 +70,7 @@ open class Utils private constructor() { ): CallResponse { val response = CallResponse() if (validateCall(accessToken, endPoint)) { - val apiUrl = endPoint.toHttpUrlOrNull() - if (apiUrl != null) { + endPoint.toHttpUrlOrNull()?.let { apiUrl -> val builder = when (method) { Methods.POST, Methods.PATCH -> { val formBody = JSONObject(params).toString() @@ -117,8 +116,7 @@ open class Utils private constructor() { } private fun parseBody(endPoint: String, result: Response): String { - val body = result.body?.string() - if (body != null) { + result.body?.string()?.let { body -> if (!result.isSuccessful && body.isNotEmpty()) { try { with(JSONObject(body)) { diff --git a/src/test/kotlin/net/thauvin/erik/bitly/BitlyTest.kt b/src/test/kotlin/net/thauvin/erik/bitly/BitlyTest.kt index d2657b0..454418f 100644 --- a/src/test/kotlin/net/thauvin/erik/bitly/BitlyTest.kt +++ b/src/test/kotlin/net/thauvin/erik/bitly/BitlyTest.kt @@ -32,16 +32,14 @@ package net.thauvin.erik.bitly +import net.thauvin.erik.bitly.Utils.Companion.isValidUrl import net.thauvin.erik.bitly.Utils.Companion.removeHttp import net.thauvin.erik.bitly.Utils.Companion.toEndPoint import org.json.JSONObject import org.junit.Before import java.io.File import java.util.logging.Level -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertNotEquals -import kotlin.test.assertTrue +import kotlin.test.* class BitlyTest { private val bitly = with(File("local.properties")) { @@ -74,8 +72,8 @@ class BitlyTest { fun `token should be valid`() { val test = Bitly().apply { accessToken = "12345679" } assertEquals( - "{\"message\":\"FORBIDDEN\"}", - test.bitlinks().shorten("https://erik.thauvin.net/blog", toJson = true) + "{\"message\":\"FORBIDDEN\"}", + test.bitlinks().shorten("https://erik.thauvin.net/blog", toJson = true) ) } @@ -89,6 +87,11 @@ class BitlyTest { assertEquals(shortUrl, bitly.bitlinks().shorten(shortUrl)) } + @Test + fun `endPoint should be specified`() { + assertFalse(bitly.call("").isSuccessful) + } + @Test fun `shorten = expand`() { val shortUrl = bitly.bitlinks().shorten(longUrl, domain = "bit.ly") @@ -102,19 +105,23 @@ class BitlyTest { @Test fun `get user`() { - assertTrue(bitly.call("/user".toEndPoint(), method = Methods.GET).isSuccessful) + assertTrue(bitly.call("user".toEndPoint(), method = Methods.GET).isSuccessful) + assertTrue( + Utils.call(bitly.accessToken, "/user".toEndPoint(), method = Methods.GET).isSuccessful, + "call(/user)" + ) } @Test fun `created by`() { assertEquals( - "ethauvin", - JSONObject( - bitly.call( - "/bitlinks/${shortUrl.removeHttp()}".toEndPoint(), - method = Methods.GET - ).body - ).getString("created_by") + "ethauvin", + JSONObject( + bitly.call( + "/bitlinks/${shortUrl.removeHttp()}".toEndPoint(), + method = Methods.GET + ).body + ).getString("created_by") ) } @@ -154,14 +161,18 @@ class BitlyTest { @Test fun `create bitlink`() { + assertTrue( + bitly.bitlinks().create(long_url = longUrl).matches("https://\\w+.\\w{2}/\\w{7}".toRegex()), + "just long_url" + ) assertEquals( - shortUrl, - bitly.bitlinks().create( - domain = "bit.ly", - title = "Erik's Blog", - tags = arrayOf("erik", "thauvin", "blog", "weblog"), - long_url = longUrl - ) + shortUrl, + bitly.bitlinks().create( + domain = "bit.ly", + title = "Erik's Blog", + tags = arrayOf("erik", "thauvin", "blog", "weblog"), + long_url = longUrl + ) ) } @@ -169,11 +180,21 @@ class BitlyTest { fun `update bitlink`() { val bl = bitly.bitlinks() assertEquals( - Constants.TRUE, - bl.update(shortUrl, title = "Erik's Weblog", tags = arrayOf("blog", "weblog")) + Constants.TRUE, + bl.update(shortUrl, title = "Erik's Weblog", tags = arrayOf("blog", "weblog")) + ) + + assertTrue( + bl.update(shortUrl, tags = emptyArray(), toJson = true).contains("\"tags\":[]"), "update tags toJson" ) bl.update(shortUrl, link = longUrl) assertTrue(bl.lastCallResponse.isUnprocessableEntity, "422 Unprocessable") } + + @Test + fun `validate URL`() { + assertTrue("https://www.example.com".isValidUrl(), "valid url") + assertFalse("this is a test".isValidUrl(), "invalid url") + } }