summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTorsten Grote <t@grobox.de>2020-07-06 09:58:14 -0300
committerTorsten Grote <t@grobox.de>2020-07-06 09:58:14 -0300
commitbdfbb18fe62e93cdabfa779866d8c04a67585145 (patch)
tree7a50b87294f464af862f22c273bdb1fa295447b2 /src
parentc8791545fe56f84a54d6700e833000ec379b7ee0 (diff)
downloadwallet-kotlin-bdfbb18fe62e93cdabfa779866d8c04a67585145.tar.gz
wallet-kotlin-bdfbb18fe62e93cdabfa779866d8c04a67585145.tar.bz2
wallet-kotlin-bdfbb18fe62e93cdabfa779866d8c04a67585145.zip
Use custom serializer for Amount and improve withdrawal info test
Diffstat (limited to 'src')
-rw-r--r--src/commonMain/kotlin/net/taler/wallet/kotlin/Amount.kt16
-rw-r--r--src/commonMain/kotlin/net/taler/wallet/kotlin/operations/Withdraw.kt51
-rw-r--r--src/commonTest/kotlin/net/taler/wallet/kotlin/TestUtils.kt37
-rw-r--r--src/commonTest/kotlin/net/taler/wallet/kotlin/operations/WithdrawTest.kt40
4 files changed, 91 insertions, 53 deletions
diff --git a/src/commonMain/kotlin/net/taler/wallet/kotlin/Amount.kt b/src/commonMain/kotlin/net/taler/wallet/kotlin/Amount.kt
index a078089..87c147d 100644
--- a/src/commonMain/kotlin/net/taler/wallet/kotlin/Amount.kt
+++ b/src/commonMain/kotlin/net/taler/wallet/kotlin/Amount.kt
@@ -16,6 +16,11 @@
package net.taler.wallet.kotlin
+import kotlinx.serialization.Decoder
+import kotlinx.serialization.Encoder
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.Serializer
import net.taler.wallet.kotlin.crypto.CryptoImpl.Companion.toByteArray
import kotlin.math.floor
import kotlin.math.pow
@@ -24,6 +29,7 @@ import kotlin.math.roundToInt
class AmountParserException(msg: String? = null, cause: Throwable? = null) : Exception(msg, cause)
class AmountOverflowException(msg: String? = null, cause: Throwable? = null) : Exception(msg, cause)
+@Serializable
data class Amount(
/**
* name of the currency using either a three-character ISO 4217 currency code,
@@ -48,7 +54,8 @@ data class Amount(
val fraction: Int
) : Comparable<Amount> {
- companion object {
+ @Serializer(forClass = Amount::class)
+ companion object : KSerializer<Amount> {
private const val FRACTIONAL_BASE: Int = 100000000 // 1e8
@@ -114,6 +121,13 @@ data class Amount(
return fraction
}
+ override fun serialize(encoder: Encoder, value: Amount) {
+ encoder.encodeString(value.toJSONString())
+ }
+
+ override fun deserialize(decoder: Decoder): Amount {
+ return fromJSONString(decoder.decodeString())
+ }
}
val amountStr: String
diff --git a/src/commonMain/kotlin/net/taler/wallet/kotlin/operations/Withdraw.kt b/src/commonMain/kotlin/net/taler/wallet/kotlin/operations/Withdraw.kt
index 3fc4321..b002e32 100644
--- a/src/commonMain/kotlin/net/taler/wallet/kotlin/operations/Withdraw.kt
+++ b/src/commonMain/kotlin/net/taler/wallet/kotlin/operations/Withdraw.kt
@@ -15,6 +15,7 @@
*/
package net.taler.wallet.kotlin.operations
+
import io.ktor.client.HttpClient
import io.ktor.client.features.json.JsonFeature
import io.ktor.client.features.json.serializer.KotlinxSerializer
@@ -28,13 +29,24 @@ class Withdraw(
private val httpClient: HttpClient = HttpClient { install(JsonFeature) { serializer = KotlinxSerializer() } }
) {
+ data class BankDetails(
+ val amount: Amount,
+ val selectionDone: Boolean,
+ val transferDone: Boolean,
+ val senderWire: String?,
+ val suggestedExchange: String?,
+ val confirmTransferUrl: String?,
+ val wireTypes: List<String>,
+ val extractedStatusUrl: String
+ )
+
@Serializable
- data class Response(
+ private data class Response(
@SerialName("selection_done")
val selectionDone: Boolean,
@SerialName("transfer_done")
val transferDone: Boolean,
- val amount: String, // TODO Amount
+ val amount: Amount,
@SerialName("wire_types")
val wireTypes: List<String>,
@SerialName("sender_wire")
@@ -43,32 +55,23 @@ class Withdraw(
val suggestedExchange: String?,
@SerialName("confirm_transfer_url")
val confirmTransferUrl: String?
- )
-
- data class BankDetails(
- val selectionDone: Boolean,
- val transferDone: Boolean,
- val amount: Amount,
- val senderWire: String?,
- val suggestedExchange: String?,
- val confirmTransferUrl: String?,
- val wireTypes: List<String>,
- val extractedStatusUrl: String
- )
+ ) {
+ fun toBankDetails(extractedStatusUrl: String) = BankDetails(
+ amount = amount,
+ confirmTransferUrl = confirmTransferUrl,
+ extractedStatusUrl = extractedStatusUrl,
+ selectionDone = selectionDone,
+ senderWire = senderWire,
+ suggestedExchange = suggestedExchange,
+ transferDone = transferDone,
+ wireTypes = wireTypes
+ )
+ }
suspend fun getBankInfo(talerWithdrawUri: String): BankDetails {
val url = parseWithdrawUri(talerWithdrawUri) ?: throw Error("Can't parse URI $talerWithdrawUri")
val response: Response = httpClient.get(url)
- return BankDetails(
- amount = Amount.fromJSONString(response.amount),
- confirmTransferUrl = response.confirmTransferUrl,
- extractedStatusUrl = url,
- selectionDone = response.selectionDone,
- senderWire = response.senderWire,
- suggestedExchange = response.suggestedExchange,
- transferDone = response.transferDone,
- wireTypes = response.wireTypes
- )
+ return response.toBankDetails(url)
}
}
diff --git a/src/commonTest/kotlin/net/taler/wallet/kotlin/TestUtils.kt b/src/commonTest/kotlin/net/taler/wallet/kotlin/TestUtils.kt
index ec12556..857c56c 100644
--- a/src/commonTest/kotlin/net/taler/wallet/kotlin/TestUtils.kt
+++ b/src/commonTest/kotlin/net/taler/wallet/kotlin/TestUtils.kt
@@ -16,9 +16,44 @@
package net.taler.wallet.kotlin
+import io.ktor.client.HttpClient
+import io.ktor.client.engine.mock.MockEngine
+import io.ktor.client.engine.mock.MockEngineConfig
+import io.ktor.client.engine.mock.respond
+import io.ktor.client.engine.mock.respondError
+import io.ktor.client.features.json.JsonFeature
+import io.ktor.http.ContentType.Application
+import io.ktor.http.HttpStatusCode.Companion.InternalServerError
+import io.ktor.http.Url
+import io.ktor.http.fullPath
+import io.ktor.http.headersOf
+import io.ktor.http.hostWithPort
import kotlinx.coroutines.CoroutineScope
/**
* Workaround to use suspending functions in unit tests
*/
-expect fun runCoroutine(block: suspend (scope : CoroutineScope) -> Unit)
+expect fun runCoroutine(block: suspend (scope: CoroutineScope) -> Unit)
+
+fun getMockHttpClient(): HttpClient = HttpClient(MockEngine) {
+ install(JsonFeature)
+ engine {
+ addHandler { error("No test handler added") }
+ }
+}
+
+fun HttpClient.giveJsonResponse(url: String, jsonProducer: () -> String) {
+ val httpConfig = engineConfig as MockEngineConfig
+ httpConfig.requestHandlers.removeAt(0)
+ httpConfig.requestHandlers.add { request ->
+ if (request.url.fullUrl == url) {
+ val headers = headersOf("Content-Type" to listOf(Application.Json.toString()))
+ respond(jsonProducer(), headers = headers)
+ } else {
+ respondError(InternalServerError, "Unexpected URL: ${request.url.fullUrl}")
+ }
+ }
+}
+
+private val Url.hostWithPortIfRequired: String get() = if (port == protocol.defaultPort) host else hostWithPort
+private val Url.fullUrl: String get() = "${protocol.name}://$hostWithPortIfRequired$fullPath"
diff --git a/src/commonTest/kotlin/net/taler/wallet/kotlin/operations/WithdrawTest.kt b/src/commonTest/kotlin/net/taler/wallet/kotlin/operations/WithdrawTest.kt
index 83c55a6..b5f8553 100644
--- a/src/commonTest/kotlin/net/taler/wallet/kotlin/operations/WithdrawTest.kt
+++ b/src/commonTest/kotlin/net/taler/wallet/kotlin/operations/WithdrawTest.kt
@@ -16,14 +16,9 @@
package net.taler.wallet.kotlin.operations
-import io.ktor.client.HttpClient
-import io.ktor.client.engine.mock.MockEngine
-import io.ktor.client.engine.mock.MockEngineConfig
-import io.ktor.client.engine.mock.respond
-import io.ktor.client.features.json.JsonFeature
-import io.ktor.http.ContentType
-import io.ktor.http.headersOf
import net.taler.wallet.kotlin.Amount
+import net.taler.wallet.kotlin.getMockHttpClient
+import net.taler.wallet.kotlin.giveJsonResponse
import net.taler.wallet.kotlin.operations.Withdraw.BankDetails
import net.taler.wallet.kotlin.runCoroutine
import kotlin.test.Test
@@ -31,13 +26,7 @@ import kotlin.test.assertEquals
internal class WithdrawTest {
- private val httpClient = HttpClient(MockEngine) {
- install(JsonFeature)
- engine {
- addHandler { error("No test handler added") }
- }
- }
- private val httpConfig = httpClient.engineConfig as MockEngineConfig
+ private val httpClient = getMockHttpClient()
private val withdraw = Withdraw(httpClient)
@Test
@@ -52,19 +41,16 @@ internal class WithdrawTest {
transferDone = false,
wireTypes = listOf("x-taler-bank")
)
- val json = """{
- "selection_done": ${bankDetails.selectionDone},
- "transfer_done": ${bankDetails.transferDone},
- "amount": "${bankDetails.amount.toJSONString()}",
- "wire_types": ["${bankDetails.wireTypes[0]}"],
- "sender_wire": "${bankDetails.senderWire}",
- "suggested_exchange": "${bankDetails.suggestedExchange}",
- "confirm_transfer_url": "${bankDetails.confirmTransferUrl}"
- }""".trimIndent()
- httpConfig.requestHandlers.removeAt(0)
- httpConfig.requestHandlers.add {
- val headers = headersOf("Content-Type" to listOf(ContentType.Application.Json.toString()))
- respond(json, headers = headers)
+ httpClient.giveJsonResponse(bankDetails.extractedStatusUrl) {
+ """{
+ "selection_done": ${bankDetails.selectionDone},
+ "transfer_done": ${bankDetails.transferDone},
+ "amount": "${bankDetails.amount.toJSONString()}",
+ "wire_types": ["${bankDetails.wireTypes[0]}"],
+ "sender_wire": "${bankDetails.senderWire}",
+ "suggested_exchange": "${bankDetails.suggestedExchange}",
+ "confirm_transfer_url": "${bankDetails.confirmTransferUrl}"
+ }""".trimIndent()
}
runCoroutine {
val details =