diff --git a/build.gradle.kts b/build.gradle.kts index b3c6965..f593e7c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ plugins { } group = "net.djvk" -version = "1.1.2" +version = "1.2.0" java.sourceCompatibility = JavaVersion.VERSION_17 repositories { diff --git a/src/main/kotlin/net/djvk/fireflyPlaidConnector2/transactions/PersonalFinanceCategoryEnum.kt b/src/main/kotlin/net/djvk/fireflyPlaidConnector2/transactions/PersonalFinanceCategoryEnum.kt index 139b11a..96fc6d6 100644 --- a/src/main/kotlin/net/djvk/fireflyPlaidConnector2/transactions/PersonalFinanceCategoryEnum.kt +++ b/src/main/kotlin/net/djvk/fireflyPlaidConnector2/transactions/PersonalFinanceCategoryEnum.kt @@ -2,6 +2,7 @@ package net.djvk.fireflyPlaidConnector2.transactions import net.djvk.fireflyPlaidConnector2.api.plaid.models.PersonalFinanceCategory import net.djvk.fireflyPlaidConnector2.constants.Direction +import org.slf4j.LoggerFactory /** * Possible values of [PersonalFinanceCategory] @@ -154,16 +155,25 @@ enum class PersonalFinanceCategoryEnum(val primary: Primary, val detailed: Detai OTHER(Primary.OTHER, OtherDetailed.OTHER); companion object { + private val logger = LoggerFactory.getLogger(this::class.java) + fun from(categoryModel: PersonalFinanceCategory): PersonalFinanceCategoryEnum { - // Special case to handle what I believe is a Plaid bug I saw in the wild - if (categoryModel.primary == Primary.TRAVEL.name && - categoryModel.detailed == TRANSPORTATION_PUBLIC_TRANSIT.name) { - return TRANSPORTATION_PUBLIC_TRANSIT - } // Business as usual - return values().find { + return entries.find { it.primary.name == categoryModel.primary && it.name == categoryModel.detailed } + // Fallback to handle random Plaid bugs + ?: run { + val fallback = entries.find { it.name == categoryModel.detailed } + if (fallback != null) { + logger.warn( + "Invalid personal finance category $categoryModel; falling back to likely " + + "correct value $fallback" + ) + } + fallback + } + // Give up ?: throw IllegalArgumentException("Failed to convert personal finance category $categoryModel to enum") } } diff --git a/src/test/kotlin/net/djvk/fireflyPlaidConnector2/transactions/PersonalFinanceCategoryEnumTest.kt b/src/test/kotlin/net/djvk/fireflyPlaidConnector2/transactions/PersonalFinanceCategoryEnumTest.kt new file mode 100644 index 0000000..95a5a46 --- /dev/null +++ b/src/test/kotlin/net/djvk/fireflyPlaidConnector2/transactions/PersonalFinanceCategoryEnumTest.kt @@ -0,0 +1,81 @@ +package net.djvk.fireflyPlaidConnector2.transactions + +import net.djvk.fireflyPlaidConnector2.api.plaid.models.PersonalFinanceCategory +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.Arguments +import org.junit.jupiter.params.provider.MethodSource +import kotlin.test.assertNotNull + +internal class PersonalFinanceCategoryEnumTest { + companion object { + @JvmStatic + fun provideFrom(): List { + return listOf( + Arguments.of( +// testName: String, + "Normal", +// input: PersonalFinanceCategory, + PersonalFinanceCategory("RENT_AND_UTILITIES", "RENT_AND_UTILITIES_GAS_AND_ELECTRICITY"), +// expectedResult: PersonalFinanceCategoryEnum?, + PersonalFinanceCategoryEnum.RENT_AND_UTILITIES_GAS_AND_ELECTRICITY, +// expectedException: Boolean, + false, + ), + Arguments.of( +// testName: String, + "Goofy edge case", +// input: PersonalFinanceCategory, + PersonalFinanceCategory("TRAVEL", "TRANSPORTATION_PUBLIC_TRANSIT"), +// expectedResult: PersonalFinanceCategoryEnum?, + PersonalFinanceCategoryEnum.TRANSPORTATION_PUBLIC_TRANSIT, +// expectedException: Boolean, + false, + ), + Arguments.of( +// testName: String, + "Invalid primary", +// input: PersonalFinanceCategory, + PersonalFinanceCategory("TACOS", "FAST_FOOD"), +// expectedResult: PersonalFinanceCategoryEnum?, + null, +// expectedException: Boolean, + true, + ), + Arguments.of( +// testName: String, + "Invalid detailed", +// input: PersonalFinanceCategory, + PersonalFinanceCategory("FOOD_AND_DRINK", "TACOS"), +// expectedResult: PersonalFinanceCategoryEnum?, + null, +// expectedException: Boolean, + true, + ), + ) + } + } + + @ParameterizedTest(name = "{index} => {0}") + @MethodSource("provideFrom") + fun from( + testName: String, + input: PersonalFinanceCategory, + expectedResult: PersonalFinanceCategoryEnum?, + expectedException: Boolean, + ) { + var actualException: Exception? = null + var actual: PersonalFinanceCategoryEnum? = null + try { + actual = PersonalFinanceCategoryEnum.from(input) + } catch (e: Exception) { + actualException = e + } + + if (expectedException) { + assertNotNull(actualException) + } else { + assertEquals(expectedResult, actual) + } + } +}