Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

country info on forex exchange rate #49

Merged
merged 1 commit into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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