Skip to content

Commit

Permalink
forex country info (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
psuzn authored Jan 4, 2024
1 parent 08cdb08 commit 1e06ca9
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,10 @@ data class ForexRate(
val rates: List<ConversionRate>
)

data class ConversionRate(val currency: String, val rate: Float)
data class ConversionRate(
val currency: String,
val symbol: String,
val name: String,
val flag: String,
val rate: Float
)
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import org.kodein.di.instance
import java.time.Duration
import java.time.OffsetDateTime
import java.time.ZoneOffset
import java.util.Currency
import java.util.Locale
import java.util.UUID

class ForexFetcher(
Expand Down Expand Up @@ -57,10 +59,23 @@ class ForexFetcher(
val epochSeconds = response.getLong("timestamp")
val usdRate = response.getJsonObject("rates").getNumber("USD").toFloat()

val currencyLocale = Locale.getAvailableLocales().associateBy {
kotlin.runCatching { Currency.getInstance(it) }.getOrNull() ?: Locale.getDefault()
}

return ForexRate(
timestamp = OffsetDateTime.ofInstant(java.time.Instant.ofEpochSecond(epochSeconds), ZoneOffset.UTC),
rates = response.getJsonObject("rates").map {
ConversionRate(it.key, (it.value as Number).toFloat() / usdRate)
val currency = kotlin.runCatching { Currency.getInstance(it.key) }.getOrNull()
val locale = currencyLocale.getOrDefault(currency, Locale.US)

ConversionRate(
currency = it.key,
symbol = currency?.getSymbol(locale) ?: "$",
name = currency?.displayName ?: it.key,
flag = locale.flagEmoji,
rate = (it.value as Number).toFloat() / usdRate
)
}
)
}
Expand Down Expand Up @@ -89,3 +104,10 @@ suspend fun KeyValuesRepository.getForexRate(): ForexRate? = get(KEY_FOREX_RATE)
}

suspend fun KeyValuesRepository.saveForexRate(forexRate: ForexRate) = set(KEY_FOREX_RATE, Json.encode(forexRate))

private val Locale.flagEmoji: String
get() {
val firstLetter = Character.codePointAt(country, 0) - 0x41 + 0x1F1E6
val secondLetter = Character.codePointAt(country, 1) - 0x41 + 0x1F1E6
return String(Character.toChars(firstLetter)) + String(Character.toChars(secondLetter))
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,38 @@ import me.sujanpoudel.playdeals.IntegrationTest
import me.sujanpoudel.playdeals.domain.ConversionRate
import me.sujanpoudel.playdeals.domain.ForexRate
import me.sujanpoudel.playdeals.get
import me.sujanpoudel.playdeals.jobs.getForexRate
import me.sujanpoudel.playdeals.jobs.saveForexRate
import me.sujanpoudel.playdeals.repositories.KeyValuesRepository
import org.junit.jupiter.api.Test
import java.time.OffsetDateTime
import java.time.ZoneOffset

class GetForexApiTest(vertx: Vertx) : IntegrationTest(vertx) {

@Test
fun `Key value repo should properly store the forex rate`() = runTest {
val repository = di.get<KeyValuesRepository>()

val forexRate = ForexRate(
timestamp = OffsetDateTime.now().withOffsetSameInstant(ZoneOffset.UTC),
rates = listOf(ConversionRate("USD", "$", "US Dollar", "🇺🇸", 1.1f))
)
repository.saveForexRate(forexRate)

val savedForexRate = repository.getForexRate()

savedForexRate shouldBe forexRate
}

@Test
fun `should return forex if there is data`() = runTest {
val repository = di.get<KeyValuesRepository>()

val forexRate = ForexRate(OffsetDateTime.now(), listOf(ConversionRate("USD", 1.1f)))
val forexRate = ForexRate(
timestamp = OffsetDateTime.now().withOffsetSameInstant(ZoneOffset.UTC),
rates = listOf(ConversionRate("USD", "$", "US Dollar", "🇺🇸", 1.1f))
)

repository.saveForexRate(forexRate)

Expand All @@ -28,11 +49,14 @@ class GetForexApiTest(vertx: Vertx) : IntegrationTest(vertx) {
.bodyAsJsonObject()

response.getJsonObject("data").also { data ->
OffsetDateTime.parse(data.getString("timestamp")).toEpochSecond() shouldBe forexRate.timestamp.toEpochSecond()
OffsetDateTime.parse(data.getString("timestamp")) shouldBe forexRate.timestamp
data.getJsonArray("rates").also { rates ->
rates.size() shouldBe 1
(rates.first() as JsonObject).also { rate ->
rate.getString("currency") shouldBe "USD"
rate.getString("symbol") shouldBe "$"
rate.getString("name") shouldBe "US Dollar"
rate.getString("flag") shouldBe "🇺🇸"
rate.getFloat("rate") shouldBe 1.1f
}
}
Expand Down

0 comments on commit 1e06ca9

Please sign in to comment.