diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml
index b805dc4..717fd7b 100644
--- a/config/detekt/baseline.xml
+++ b/config/detekt/baseline.xml
@@ -19,8 +19,8 @@
FunctionParameterNaming:UpdateDeeplinks.kt$UpdateDeeplinks$brand_guid: String
FunctionParameterNaming:UpdateDeeplinks.kt$UpdateDeeplinks$install_type: InstallType
FunctionParameterNaming:UpdateDeeplinks.kt$UpdateDeeplinks$install_url: String
- LongParameterList:Bitlinks.kt$Bitlinks$( bitlink: String, title: String = Constants.EMPTY, archived: Boolean = false, tags: Array<String> = emptyArray(), deeplinks: UpdateDeeplinks = UpdateDeeplinks(), toJson: Boolean = false )
- LongParameterList:Bitlinks.kt$Bitlinks$( long_url: String, domain: String = Constants.EMPTY, group_guid: String = Constants.EMPTY, title: String = Constants.EMPTY, tags: Array<String> = emptyArray(), deeplinks: CreateDeeplinks = CreateDeeplinks(), toJson: Boolean = false )
+ LongParameterList:Bitlinks.kt$Bitlinks$( bitlink: String, title: String = Constants.EMPTY, archived: Boolean = false, tags: List<String> = emptyList(), deeplinks: UpdateDeeplinks = UpdateDeeplinks(), toJson: Boolean = false )
+ LongParameterList:Bitlinks.kt$Bitlinks$( long_url: String, domain: String = Constants.EMPTY, group_guid: String = Constants.EMPTY, title: String = Constants.EMPTY, tags: List<String> = emptyList(), deeplinks: CreateDeeplinks = CreateDeeplinks(), toJson: Boolean = false )
MagicNumber:CallResponse.kt$CallResponse$200
MagicNumber:CallResponse.kt$CallResponse$201
MagicNumber:CallResponse.kt$CallResponse$299
diff --git a/src/main/kotlin/net/thauvin/erik/bitly/Bitlinks.kt b/src/main/kotlin/net/thauvin/erik/bitly/Bitlinks.kt
index 78ec984..f7cb3a4 100644
--- a/src/main/kotlin/net/thauvin/erik/bitly/Bitlinks.kt
+++ b/src/main/kotlin/net/thauvin/erik/bitly/Bitlinks.kt
@@ -136,7 +136,7 @@ open class Bitlinks(private val accessToken: String) {
domain: String = Constants.EMPTY,
group_guid: String = Constants.EMPTY,
title: String = Constants.EMPTY,
- tags: Array = emptyArray(),
+ tags: List = emptyList(),
deeplinks: CreateDeeplinks = CreateDeeplinks(),
toJson: Boolean = false
): String {
@@ -282,7 +282,7 @@ open class Bitlinks(private val accessToken: String) {
bitlink: String,
title: String = Constants.EMPTY,
archived: Boolean = false,
- tags: Array = emptyArray(),
+ tags: List = emptyList(),
deeplinks: UpdateDeeplinks = UpdateDeeplinks(),
toJson: Boolean = false
): String {
diff --git a/src/main/kotlin/net/thauvin/erik/bitly/Utils.kt b/src/main/kotlin/net/thauvin/erik/bitly/Utils.kt
index dca27c2..956a640 100644
--- a/src/main/kotlin/net/thauvin/erik/bitly/Utils.kt
+++ b/src/main/kotlin/net/thauvin/erik/bitly/Utils.kt
@@ -124,7 +124,7 @@ object Utils {
var message = response.message
var description = ""
var json = Constants.EMPTY_JSON
- response.body?.string()?.let { body ->
+ response.body.string().let { body ->
json = body
if (!response.isSuccessful && body.isNotEmpty()) {
try {
diff --git a/src/main/kotlin/net/thauvin/erik/bitly/config/CreateConfig.kt b/src/main/kotlin/net/thauvin/erik/bitly/config/CreateConfig.kt
index 25503b7..928cee1 100644
--- a/src/main/kotlin/net/thauvin/erik/bitly/config/CreateConfig.kt
+++ b/src/main/kotlin/net/thauvin/erik/bitly/config/CreateConfig.kt
@@ -60,7 +60,7 @@ class CreateConfig private constructor(builder: Builder) {
var domain: String = Constants.EMPTY
var group_guid: String = Constants.EMPTY
var title: String = Constants.EMPTY
- var tags: Array = emptyArray()
+ var tags: List = emptyList()
var deeplinks: CreateDeeplinks = CreateDeeplinks()
var toJson: Boolean = false
@@ -76,7 +76,7 @@ class CreateConfig private constructor(builder: Builder) {
fun title(title: String): Builder = apply { this.title = title }
- fun tags(tags: Array): Builder = apply { this.tags = tags }
+ fun tags(tags: List): Builder = apply { this.tags = tags }
fun deeplinks(deeplinks: CreateDeeplinks): Builder = apply { this.deeplinks = deeplinks }
diff --git a/src/main/kotlin/net/thauvin/erik/bitly/config/UpdateConfig.kt b/src/main/kotlin/net/thauvin/erik/bitly/config/UpdateConfig.kt
index d531d1b..52ba5ab 100644
--- a/src/main/kotlin/net/thauvin/erik/bitly/config/UpdateConfig.kt
+++ b/src/main/kotlin/net/thauvin/erik/bitly/config/UpdateConfig.kt
@@ -57,7 +57,7 @@ class UpdateConfig private constructor(builder: Builder) {
data class Builder(var bitlink: String) {
var title: String = Constants.EMPTY
var archived: Boolean = false
- var tags: Array = emptyArray()
+ var tags: List = emptyList()
var deeplinks: UpdateDeeplinks = UpdateDeeplinks()
var toJson: Boolean = false
@@ -68,7 +68,7 @@ class UpdateConfig private constructor(builder: Builder) {
fun title(title: String): Builder = apply { this.title = title }
fun archived(archived: Boolean): Builder = apply { this.archived = archived }
- fun tags(tags: Array): Builder = apply { this.tags = tags }
+ fun tags(tags: List): Builder = apply { this.tags = tags }
fun deeplinks(deeplinks: UpdateDeeplinks): Builder = apply { this.deeplinks = deeplinks }
/**
diff --git a/src/test/kotlin/net/thauvin/erik/bitly/BitlinksTests.kt b/src/test/kotlin/net/thauvin/erik/bitly/BitlinksTests.kt
index ac33bd3..9c0bec0 100644
--- a/src/test/kotlin/net/thauvin/erik/bitly/BitlinksTests.kt
+++ b/src/test/kotlin/net/thauvin/erik/bitly/BitlinksTests.kt
@@ -47,10 +47,12 @@ import org.junit.jupiter.api.Test
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable
import org.junit.jupiter.api.extension.ExtendWith
import java.io.File
+import java.util.*
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue
+
@ExtendWith(BeforeAllTests::class)
class BitlinksTests {
private val bitly = with(File("local.properties")) {
@@ -91,9 +93,113 @@ class BitlinksTests {
}
}
+ @Nested
+ @DisplayName("Constructor Tests")
+ inner class ConstructorTests {
+ @Test
+ fun `Constructor with access token string should set the token correctly`() {
+ // Arrange
+ val expectedToken = "my-secret-token"
+
+ // Act
+ val bitly = Bitly(expectedToken)
+
+ // Assert
+ assertThat(bitly.accessToken).isEqualTo(expectedToken)
+ }
+
+ @Test
+ fun `Constructor with Path should not change token if file does not exist`() {
+ // Arrange
+ val nonExistentPath = File("non/existent/path/file.properties").toPath()
+ val bitlyWithDefaultToken = Bitly()
+ val initialToken = bitlyWithDefaultToken.accessToken
+
+ // Act
+ val bitly = Bitly(nonExistentPath)
+
+ // Assert
+ assertThat(bitly.accessToken).isEqualTo(initialToken)
+ }
+
+ @Test
+ fun `Constructor with Properties and custom key should set token correctly`() {
+ // Arrange
+ val customKey = "MY_CUSTOM_BITLY_KEY"
+ val expectedToken = "token-from-custom-key"
+ val properties = Properties().apply {
+ setProperty(customKey, expectedToken)
+ }
+
+ // Act
+ val bitly = Bitly(properties, customKey)
+
+ // Assert
+ assertThat(bitly.accessToken).isEqualTo(expectedToken)
+ }
+
+ @Test
+ fun `Constructor with Properties should keep default token if key not found`() {
+ // Arrange
+ val properties = Properties() // Empty properties
+ val bitlyWithDefaultToken = Bitly() // Has "" as token by default
+ val initialToken = bitlyWithDefaultToken.accessToken
+
+ // Act
+ val bitly = Bitly(properties, "non-existent-key")
+
+ // Assert
+ // The token should remain the default empty string
+ assertThat(bitly.accessToken).isEqualTo(initialToken)
+ }
+
+ @Test
+ fun `Constructor with Properties should set token using default key`() {
+ // Arrange
+ val expectedToken = "token-from-props"
+ val properties = Properties().apply {
+ setProperty(Constants.ENV_ACCESS_TOKEN, expectedToken)
+ }
+
+ // Act
+ val bitly = Bitly(properties)
+
+ // Assert
+ assertThat(bitly.accessToken).isEqualTo(expectedToken)
+ }
+
+ @Test
+ fun `Default constructor should default to empty string if no token is provided`() {
+ // Arrange: Ensure no env var or system property is set
+ System.clearProperty(Constants.ENV_ACCESS_TOKEN)
+ // Note: Testing environment variables directly is often avoided in unit tests.
+ // This test verifies the fallback mechanism.
+
+ // Act
+ val bitly = Bitly()
+
+ // Assert
+ assertThat(bitly.accessToken).isEmpty()
+ }
+
+ @Test
+ fun `Default constructor should use system property if env var is not set`() {
+ // Arrange
+ val expectedToken = "token-from-property"
+ System.setProperty(Constants.ENV_ACCESS_TOKEN, expectedToken)
+
+ // Act
+ val bitly = Bitly()
+
+ // Assert
+ assertThat(bitly.accessToken).isEqualTo(expectedToken)
+ }
+ }
+
@Nested
@DisplayName("Create Bitlink Tests")
inner class CreateBitlinkTests {
+
@Test
fun `Create bitlink`() {
assertThat(bitly.bitlinks().create(long_url = longUrl), "create(longUrl)")
@@ -103,7 +209,7 @@ class BitlinksTests {
bitly.bitlinks().create(
domain = "bit.ly",
title = "Erik's Blog",
- tags = arrayOf("erik", "thauvin", "blog", "weblog"),
+ tags = listOf("erik", "thauvin", "blog", "weblog"),
long_url = longUrl
)
)
@@ -118,7 +224,7 @@ class BitlinksTests {
config = CreateConfig.Builder(longUrl)
.domain("bit.ly")
.title("Erik's Blog")
- .tags(arrayOf("erik", "thauvin", "blog", "weblog"))
+ .tags(listOf("erik", "thauvin", "blog", "weblog"))
.build()
assertEquals(
shortUrl,
@@ -148,6 +254,7 @@ class BitlinksTests {
@Nested
@DisplayName("Expand Test")
inner class ExpandTests {
+
@Test
fun `Expand as json`() {
assertTrue(
@@ -165,6 +272,7 @@ class BitlinksTests {
@Nested
@DisplayName("Shorten Tests")
inner class ShortenTests {
+
@Test
fun `Shorten as json`() {
assertTrue(
@@ -218,17 +326,18 @@ class BitlinksTests {
@Nested
@DisplayName("Update Bitlink Tests")
inner class UpdateBitlinkTests {
+
@Test
fun `Update bitlink`() {
val bl = bitly.bitlinks()
assertEquals(
Constants.TRUE,
bl.update(
- shortUrl, title = "Erik's Weblog", tags = arrayOf("blog", "weblog"), archived = true
+ shortUrl, title = "Erik's Weblog", tags = listOf("blog", "weblog"), archived = true
)
)
- assertThat(bl.update(shortUrl, tags = emptyArray(), toJson = true), "update(tags)")
+ assertThat(bl.update(shortUrl, tags = emptyList(), toJson = true), "update(tags)")
.contains("\"tags\":[]")
}
@@ -237,7 +346,7 @@ class BitlinksTests {
val bl = bitly.bitlinks()
var config = UpdateConfig.Builder(shortUrl)
.archived(true)
- .tags(arrayOf("blog", "weblog"))
+ .tags(listOf("blog", "weblog"))
.title("Erik's Weblog")
.build()
@@ -279,6 +388,7 @@ class BitlinksTests {
@Nested
@DisplayName("Validation Tests")
inner class ValidationTests {
+
@Test
fun `Empty URL should not shorten`() {
assertEquals(Constants.EMPTY, bitly.bitlinks().shorten(Constants.EMPTY))
@@ -289,13 +399,6 @@ class BitlinksTests {
assertEquals(shortUrl, bitly.bitlinks().shorten(shortUrl))
}
- @Test
- fun `Token not specified with API call`() {
- assertFailsWith(IllegalArgumentException::class, "Utils.call()") {
- Utils.call("", "foo")
- }
- }
-
@Test
@DisableOnCi
fun `Token not specified`() {
@@ -316,6 +419,13 @@ class BitlinksTests {
}
}
+ @Test
+ fun `Token not specified with API call`() {
+ assertFailsWith(IllegalArgumentException::class, "Utils.call()") {
+ Utils.call("", "foo")
+ }
+ }
+
@Test
fun `Token should be valid`() {
val test = Bitly().apply { accessToken = "12345679" }
diff --git a/src/test/kotlin/net/thauvin/erik/bitly/UtilsTests.kt b/src/test/kotlin/net/thauvin/erik/bitly/UtilsTests.kt
index a9a878b..66f31e5 100644
--- a/src/test/kotlin/net/thauvin/erik/bitly/UtilsTests.kt
+++ b/src/test/kotlin/net/thauvin/erik/bitly/UtilsTests.kt
@@ -51,6 +51,11 @@ class UtilsTests {
assertThat("".toEndPoint()).isEqualTo("")
}
+ @Test
+ fun `Convert endpoint with blank string`() {
+ assertThat(" ".toEndPoint()).isEqualTo(" ")
+ }
+
@Test
fun `Convert endpoint with full URL`() {
assertThat("https://example.com/path".toEndPoint()).isEqualTo("https://example.com/path")
@@ -102,13 +107,17 @@ class UtilsTests {
}
}
- @Test
- fun `Validate invalid URL`() {
- assertFalse("this is a test".isValidUrl(), "invalid url")
- }
+ @Nested
+ @DisplayName("URL Validation Tests")
+ inner class URLValidationTests {
+ @Test
+ fun `Validate invalid URL`() {
+ assertFalse("this is a test".isValidUrl(), "invalid url")
+ }
- @Test
- fun `Validate URL`() {
- assertTrue("https://www.example.com".isValidUrl(), "valid url")
+ @Test
+ fun `Validate URL`() {
+ assertTrue("https://www.example.com".isValidUrl(), "valid url")
+ }
}
}
diff --git a/src/test/kotlin/net/thauvin/erik/bitly/config/ConfigTests.kt b/src/test/kotlin/net/thauvin/erik/bitly/config/ConfigTests.kt
index 09c45ed..42f9b13 100644
--- a/src/test/kotlin/net/thauvin/erik/bitly/config/ConfigTests.kt
+++ b/src/test/kotlin/net/thauvin/erik/bitly/config/ConfigTests.kt
@@ -61,7 +61,7 @@ class ConfigTests {
.deeplinks(deeplinks)
.domain("domain")
.groupGuid("group_guid")
- .tags(arrayOf("tag", "tag2"))
+ .tags(listOf("tag", "tag2"))
.title("title")
.build()
@@ -70,13 +70,13 @@ class ConfigTests {
prop(CreateConfig::domain).isEqualTo("domain")
prop(CreateConfig::group_guid).isEqualTo("group_guid")
prop(CreateConfig::long_url).isEqualTo("long_url")
- prop(CreateConfig::tags).isEqualTo(arrayOf("tag", "tag2"))
+ prop(CreateConfig::tags).isEqualTo(listOf("tag", "tag2"))
prop(CreateConfig::title).isEqualTo("title")
prop(CreateConfig::toJson).isEqualTo(false)
}
val map = mapOf(
- "deeplinks" to arrayOf(deeplinks.links()),
+ "deeplinks" to listOf(deeplinks.links()),
"domain" to config.domain,
"group_guid" to config.group_guid,
"long_url" to config.long_url,
@@ -103,7 +103,7 @@ class ConfigTests {
val config = UpdateConfig.Builder("blink")
.archived(true)
.deeplinks(deeplinks)
- .tags(arrayOf("tag", "tag2"))
+ .tags(listOf("tag", "tag2"))
.title("title")
.build()
@@ -111,7 +111,7 @@ class ConfigTests {
prop(UpdateConfig::archived).isTrue()
prop(UpdateConfig::bitlink).isEqualTo("blink")
prop(UpdateConfig::deeplinks).isEqualTo(deeplinks)
- prop(UpdateConfig::tags).isEqualTo(arrayOf("tag", "tag2"))
+ prop(UpdateConfig::tags).isEqualTo(listOf("tag", "tag2"))
prop(UpdateConfig::title).isEqualTo("title")
prop(UpdateConfig::toJson).isEqualTo(false)
}
@@ -119,7 +119,7 @@ class ConfigTests {
val map = mapOf(
"archived" to config.archived,
"bitlink" to config.bitlink,
- "deeplinks" to arrayOf(deeplinks.links()),
+ "deeplinks" to listOf(deeplinks.links()),
"tags" to config.tags,
"title" to config.title
)
@@ -145,7 +145,7 @@ class ConfigTests {
.deeplinks(deeplinks)
.domain("domain")
.groupGuid("group_guid")
- .tags(arrayOf("tag", "tag2"))
+ .tags(listOf("tag", "tag2"))
.title("title")
.toJson(true)
@@ -154,7 +154,7 @@ class ConfigTests {
prop(CreateConfig.Builder::domain).isEqualTo("domain")
prop(CreateConfig.Builder::group_guid).isEqualTo("group_guid")
prop(CreateConfig.Builder::long_url).isEqualTo("long_url")
- prop(CreateConfig.Builder::tags).isEqualTo(arrayOf("tag", "tag2"))
+ prop(CreateConfig.Builder::tags).isEqualTo(listOf("tag", "tag2"))
prop(CreateConfig.Builder::title).isEqualTo("title")
prop(CreateConfig.Builder::toJson).isTrue()
}
@@ -172,7 +172,7 @@ class ConfigTests {
prop(CreateConfig.Builder::domain).isEqualTo(Constants.EMPTY)
prop(CreateConfig.Builder::group_guid).isEqualTo(Constants.EMPTY)
prop(CreateConfig.Builder::title).isEqualTo(Constants.EMPTY)
- prop(CreateConfig.Builder::tags).isEqualTo(emptyArray())
+ prop(CreateConfig.Builder::tags).isEqualTo(emptyList())
prop(CreateConfig.Builder::deeplinks).prop(CreateDeeplinks::links).isEqualTo(CreateDeeplinks().links())
prop(CreateConfig.Builder::toJson).isEqualTo(false)
}
@@ -189,7 +189,7 @@ class ConfigTests {
val config = UpdateConfig.Builder("bitlink")
.title("title")
.archived(true)
- .tags(arrayOf("tag", "tag2"))
+ .tags(listOf("tag", "tag2"))
.deeplinks(deeplinks)
.toJson(true)
@@ -197,7 +197,7 @@ class ConfigTests {
prop(UpdateConfig.Builder::bitlink).isEqualTo("bitlink")
prop(UpdateConfig.Builder::title).isEqualTo("title")
prop(UpdateConfig.Builder::archived).isTrue()
- prop(UpdateConfig.Builder::tags).isEqualTo(arrayOf("tag", "tag2"))
+ prop(UpdateConfig.Builder::tags).isEqualTo(listOf("tag", "tag2"))
prop(UpdateConfig.Builder::deeplinks).isEqualTo(deeplinks)
prop(UpdateConfig.Builder::toJson).isTrue()
}
@@ -214,7 +214,7 @@ class ConfigTests {
prop(UpdateConfig.Builder::bitlink).isEqualTo("bitlink")
prop(UpdateConfig.Builder::title).isEqualTo(Constants.EMPTY)
prop(UpdateConfig.Builder::archived).isEqualTo(false)
- prop(UpdateConfig.Builder::tags).isEqualTo(emptyArray())
+ prop(UpdateConfig.Builder::tags).isEqualTo(emptyList())
prop(UpdateConfig.Builder::deeplinks).prop(UpdateDeeplinks::links).isEqualTo(UpdateDeeplinks().links())
prop(UpdateConfig.Builder::toJson).isEqualTo(false)
}