Update functions to match the bit.ly API. Closes #14

This commit is contained in:
Erik C. Thauvin 2024-05-18 17:01:01 -07:00
parent 9a17fbe8e7
commit 55bc8d9e6a
Signed by: erik
GPG key ID: 776702A6A2DA330E
4 changed files with 104 additions and 145 deletions

View file

@ -61,7 +61,6 @@ open class Bitlinks(private val accessToken: String) {
* @param bitlink A Bitlink made of the domain and hash.
* @param unit A [unit of time][Units].
* @param units An integer representing the time units to query data for. Pass -1 to return all units available.
* @param size The quantity of items to be be returned.
* @param unit_reference An ISO-8601 timestamp, indicating the most recent time for which to pull metrics.
* Will default to current time.
* @param toJson Returns the full JSON response if `true`.
@ -73,7 +72,6 @@ open class Bitlinks(private val accessToken: String) {
bitlink: String,
unit: Units = Units.DAY,
units: Int = -1,
size: Int = 50,
unit_reference: String = Constants.EMPTY,
toJson: Boolean = false
): String {
@ -85,8 +83,7 @@ open class Bitlinks(private val accessToken: String) {
mapOf(
"unit" to unit.toString().lowercase(),
"units" to units.toString(),
"size" to size.toString(),
"unit_reference" to unit_reference
"unit_reference" to URLEncoder.encode(unit_reference, StandardCharsets.UTF_8)
),
Methods.GET
)
@ -106,12 +103,12 @@ open class Bitlinks(private val accessToken: String) {
@Synchronized
fun create(config: CreateConfig): String {
return create(
config.long_url,
config.domain,
config.title,
config.group_guid,
config.title,
config.tags,
config.deepLinks,
config.long_url,
config.toJson
)
}
@ -121,20 +118,20 @@ open class Bitlinks(private val accessToken: String) {
*
* See the [Bit.ly API](https://dev.bitly.com/api-reference#createFullBitlink) for more information.
*
* @param long_url The long URL.
* @param domain A branded short domain or `bit.ly` by default.
* @param group_guid A GUID for a Bitly group.
* @param long_url The long URL.
* @param toJson Returns the full JSON response if `true`.
* @return The shortened URL or an empty string on error.
*/
@Synchronized
fun create(
long_url: String,
domain: String = Constants.EMPTY,
title: String = Constants.EMPTY,
group_guid: String = Constants.EMPTY,
title: String = Constants.EMPTY,
tags: Array<String> = emptyArray(),
deeplinks: Array<Map<String, String>> = emptyArray(),
long_url: String,
toJson: Boolean = false
): String {
var link = if (toJson) Constants.EMPTY_JSON else Constants.EMPTY
@ -144,8 +141,8 @@ open class Bitlinks(private val accessToken: String) {
"bitlinks".toEndPoint(),
mutableMapOf<String, Any>("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 (title.isNotBlank()) put("title", title)
if (tags.isNotEmpty()) put("tags", tags)
if (deeplinks.isNotEmpty()) put("deeplinks", deeplinks)
}
@ -211,8 +208,8 @@ open class Bitlinks(private val accessToken: String) {
* See the [Bit.ly API](https://dev.bitly.com/api-reference#createBitlink) for more information.
*
* @param long_url The long URL.
* @param group_guid A GUID for a Bitly group.
* @param domain A branded short domain or `bit.ly` by default.
* @param group_guid A GUID for a Bitly group.
* @param toJson Returns the full JSON response if `true`.
* @return The short URL or the [long_url] on error.
*/
@ -220,8 +217,8 @@ open class Bitlinks(private val accessToken: String) {
@JvmOverloads
fun shorten(
long_url: String,
group_guid: String = Constants.EMPTY,
domain: String = Constants.EMPTY,
group_guid: String = Constants.EMPTY,
toJson: Boolean = false
): String {
var bitlink = if (toJson) Constants.EMPTY_JSON else long_url
@ -231,8 +228,8 @@ open class Bitlinks(private val accessToken: String) {
}
} else {
val params = mutableMapOf("long_url" to long_url).apply {
if (group_guid.isNotBlank()) put("group_guid", group_guid)
if (domain.isNotBlank()) put("domain", domain)
if (group_guid.isNotBlank()) put("group_guid", group_guid)
}
lastCallResponse = Utils.call(accessToken, "shorten".toEndPoint(), params)
@ -256,18 +253,10 @@ open class Bitlinks(private val accessToken: String) {
fun update(config: UpdateConfig): String {
return update(
config.bitlink,
config.references,
config.title,
config.archived,
config.tags,
config.created_at,
config.title,
config.deepLinks,
config.created_by,
config.long_url,
config.client_id,
config.custom_bitlinks,
config.link,
config.id,
config.toJson
)
}
@ -284,36 +273,20 @@ open class Bitlinks(private val accessToken: String) {
@Synchronized
fun update(
bitlink: String,
references: Map<String, String> = emptyMap(),
title: String = Constants.EMPTY,
archived: Boolean = false,
tags: Array<String> = emptyArray(),
created_at: String = Constants.EMPTY,
title: String = Constants.EMPTY,
deeplinks: Array<Map<String, String>> = emptyArray(),
created_by: String = Constants.EMPTY,
long_url: String = Constants.EMPTY,
client_id: String = Constants.EMPTY,
custom_bitlinks: Array<String> = 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<String, Any>().apply {
if (references.isNotEmpty()) put("references", references)
if (title.isNotBlank()) put("title", title)
if (archived) put("archived", true)
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
)

View file

@ -36,46 +36,67 @@ import net.thauvin.erik.bitly.Constants
/**
* Provides a builder to create a Bitlink.
*/
class CreateConfig private constructor(
val domain: String,
val title: String,
val group_guid: String,
val tags: Array<String>,
val deepLinks: Array<Map<String, String>>,
val long_url: String,
class CreateConfig private constructor(builder: Builder) {
val domain: String
val group_guid: String
val title: String
val tags: Array<String>
val deepLinks: Array<Map<String, String>>
val long_url: String
val toJson: Boolean
) {
init {
domain = builder.domain
group_guid = builder.group_guid
title = builder.title
tags = builder.tags
deepLinks = builder.deeplinks
long_url = builder.long_url
toJson = builder.toJson
}
/**
* Configures the creation parameters of a Bitlink.
*
* See the [Bit.ly API](https://dev.bitly.com/api-reference#createFullBitlink) for more information.
**/
@Suppress("ArrayInDataClass")
data class Builder(
private var domain: String = Constants.EMPTY,
private var title: String = Constants.EMPTY,
private var group_guid: String = Constants.EMPTY,
private var tags: Array<String> = emptyArray(),
private var deeplinks: Array<Map<String, String>> = emptyArray(),
private var long_url: String = Constants.EMPTY,
private var toJson: Boolean = false
) {
data class Builder(var long_url: String) {
var domain: String = Constants.EMPTY
var group_guid: String = Constants.EMPTY
var title: String = Constants.EMPTY
var tags: Array<String> = emptyArray()
var deeplinks: Array<Map<String, String>> = emptyArray()
var toJson: Boolean = false
/**
* A branded short domain or `bit.ly` by default.
*/
fun domain(domain: String) = apply { this.domain = domain }
fun title(title: String) = apply { this.title = title }
/**
* Always include a specific group and custom domain in your shorten calls.
*/
fun groupGuid(group_guid: String) = apply { this.group_guid = group_guid }
fun title(title: String) = apply { this.title = title }
fun tags(tags: Array<String>) = apply { this.tags = tags }
fun deeplinks(deeplinks: Array<Map<String, String>>) = apply { this.deeplinks = deeplinks }
/**
* The long URL.
*/
fun longUrl(long_url: String) = apply { this.long_url = long_url }
/**
* Returns the full JSON response if `true`.
*/
fun toJson(toJson: Boolean) = apply { this.toJson = toJson }
fun build() = CreateConfig(
domain,
title,
group_guid,
tags,
deeplinks,
long_url,
toJson
)
/**
* Builds the configuration.
*/
fun build() = CreateConfig(this)
}
}

View file

@ -36,74 +36,53 @@ import net.thauvin.erik.bitly.Constants
/**
* Provides a builder to update a Bitlink.
*/
class UpdateConfig private constructor(
val bitlink: String,
val references: Map<String, String>,
val archived: Boolean,
val tags: Array<String>,
val created_at: String,
val title: String,
val deepLinks: Array<Map<String, String>>,
val created_by: String,
val long_url: String,
val client_id: String,
val custom_bitlinks: Array<String>,
val link: String,
val id: String,
val toJson: Boolean,
) {
class UpdateConfig private constructor(builder: Builder) {
val bitlink: String
val title: String
val archived: Boolean
val tags: Array<String>
val deepLinks: Array<Map<String, String>>
val toJson: Boolean
init {
bitlink = builder.bitlink
title = builder.title
archived = builder.archived
tags = builder.tags
deepLinks = builder.deeplinks
toJson = builder.toJson
}
/**
* Configures the update parameters of a Bitlink.
*
* See the [Bit.ly API](https://dev.bitly.com/api-reference#updateBitlink) for more information.
**/
@Suppress("ArrayInDataClass")
data class Builder(
private var bitlink: String = Constants.EMPTY,
private var references: Map<String, String> = emptyMap(),
private var archived: Boolean = false,
private var tags: Array<String> = emptyArray(),
private var created_at: String = Constants.EMPTY,
private var title: String = Constants.EMPTY,
private var deeplinks: Array<Map<String, String>> = emptyArray(),
private var created_by: String = Constants.EMPTY,
private var long_url: String = Constants.EMPTY,
private var client_id: String = Constants.EMPTY,
private var custom_bitlinks: Array<String> = emptyArray(),
private var link: String = Constants.EMPTY,
private var id: String = Constants.EMPTY,
private var toJson: Boolean = false
) {
data class Builder(var bitlink: String) {
var title: String = Constants.EMPTY
var archived: Boolean = false
var tags: Array<String> = emptyArray()
var deeplinks: Array<Map<String, String>> = emptyArray()
var toJson: Boolean = false
/**
* A Bitlink made of the domain and hash.
*/
fun bitlink(bitlink: String) = apply { this.bitlink = bitlink }
fun references(references: Map<String, String>) = apply { this.references = references }
fun title(title: String) = apply { this.title = title }
fun archived(archived: Boolean) = apply { this.archived = archived }
fun tags(tags: Array<String>) = apply { this.tags = tags }
fun createdAt(createdAt: String) = apply { this.created_at = createdAt }
fun title(title: String) = apply { this.title = title }
fun deepLinks(deepLinks: Array<Map<String, String>>) = apply { this.deeplinks = deepLinks }
fun createdBy(createdBy: String) = apply { this.created_by = createdBy }
fun longUrl(longUrl: String) = apply { this.long_url = longUrl }
fun clientId(clientId: String) = apply { this.client_id = clientId }
fun customBitlinks(customBitlinks: Array<String>) = apply { this.custom_bitlinks = customBitlinks }
fun link(link: String) = apply { this.link = link }
fun id(id: String) = apply { this.id = id }
/**
* Returns the full JSON response if `true`.
*/
fun toJson(toJson: Boolean) = apply { this.toJson = toJson }
fun build() = UpdateConfig(
bitlink,
references,
archived,
tags,
created_at,
title,
deeplinks,
created_by,
long_url,
client_id,
custom_bitlinks,
link,
id,
toJson
)
/**
* Builds the configuration.
*/
fun build() = UpdateConfig(this)
}
}

View file

@ -200,15 +200,15 @@ class BitlyTest {
@Test
fun `create bitlink with config`() {
var config = CreateConfig.Builder().longUrl(longUrl).build()
var config = CreateConfig.Builder(longUrl).build()
assertThat(bitly.bitlinks().create(config), "create(config)")
.matches("https://\\w+.\\w{2}/\\w{7}".toRegex())
config = CreateConfig.Builder()
config = CreateConfig.Builder(longUrl)
.domain("bit.ly")
.title("Erik's Blog")
.tags(arrayOf("erik", "thauvin", "blog", "weblog"))
.longUrl(longUrl).build()
.build()
assertEquals(
shortUrl,
bitly.bitlinks().create(config)
@ -237,18 +237,12 @@ class BitlyTest {
assertThat(bl.update(shortUrl, tags = emptyArray(), toJson = true), "update(tags)")
.contains("\"tags\":[]")
bl.update(shortUrl, link = longUrl)
assertThat(bl.lastCallResponse).prop(CallResponse::isSuccessful).isTrue()
assertEquals(Constants.FALSE, bl.update("bit.ly/407GjJU", id = "foo"))
}
@Test
fun `update bitlink with config`() {
val bl = bitly.bitlinks()
var config = UpdateConfig.Builder()
.bitlink(shortUrl)
var config = UpdateConfig.Builder(shortUrl)
.title("Erik's Weblog")
.tags(arrayOf("blog", "weblog"))
.archived(true)
@ -256,19 +250,11 @@ class BitlyTest {
assertEquals(Constants.TRUE, bl.update(config))
config = UpdateConfig.Builder()
.bitlink(shortUrl)
config = UpdateConfig.Builder(shortUrl)
.toJson(true)
.build()
assertThat(bl.update(config), "update(tags)").contains("\"tags\":[]")
config = UpdateConfig.Builder()
.bitlink(shortUrl)
.link(longUrl)
.build()
assertEquals(Constants.TRUE, bl.update(config))
}
@Test