diff options
-rw-r--r-- | .idea/misc.xml | 2 | ||||
-rw-r--r-- | app/src/main/java/net/taler/wallet/history/HistoryEvent.kt | 122 | ||||
-rw-r--r-- | app/src/main/java/net/taler/wallet/history/WalletHistoryAdapter.kt | 92 | ||||
-rw-r--r-- | app/src/main/res/drawable/history_payment_aborted.xml | 9 | ||||
-rw-r--r-- | app/src/main/res/drawable/history_refund.xml | 9 | ||||
-rw-r--r-- | app/src/main/res/drawable/history_tip_accepted.xml | 9 | ||||
-rw-r--r-- | app/src/main/res/drawable/history_tip_declined.xml | 9 | ||||
-rw-r--r-- | app/src/main/res/drawable/ic_directions.xml | 9 | ||||
-rw-r--r-- | app/src/main/res/layout/history_payment.xml (renamed from app/src/main/res/layout/history_payment_sent.xml) | 0 | ||||
-rw-r--r-- | app/src/main/res/layout/history_receive.xml (renamed from app/src/main/res/layout/history_withdrawn.xml) | 9 | ||||
-rw-r--r-- | app/src/main/res/values/strings.xml | 5 | ||||
-rw-r--r-- | app/src/main/res/values/styles.xml | 2 | ||||
-rw-r--r-- | app/src/test/java/net/taler/wallet/history/HistoryEventTest.kt | 130 |
13 files changed, 381 insertions, 26 deletions
diff --git a/.idea/misc.xml b/.idea/misc.xml index b6ea2b1..7bfef59 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <project version="4"> - <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="JDK" project-jdk-type="JavaSDK"> + <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK"> <output url="file://$PROJECT_DIR$/build/classes" /> </component> <component name="ProjectType"> diff --git a/app/src/main/java/net/taler/wallet/history/HistoryEvent.kt b/app/src/main/java/net/taler/wallet/history/HistoryEvent.kt index b21147a..24b7936 100644 --- a/app/src/main/java/net/taler/wallet/history/HistoryEvent.kt +++ b/app/src/main/java/net/taler/wallet/history/HistoryEvent.kt @@ -87,6 +87,19 @@ typealias History = ArrayList<HistoryEvent> include = PROPERTY, property = "type" ) +/** missing: +AuditorComplaintSent = "auditor-complained-sent", +AuditorComplaintProcessed = "auditor-complaint-processed", +AuditorTrustAdded = "auditor-trust-added", +AuditorTrustRemoved = "auditor-trust-removed", +ExchangeTermsAccepted = "exchange-terms-accepted", +ExchangePolicyChanged = "exchange-policy-changed", +ExchangeTrustAdded = "exchange-trust-added", +ExchangeTrustRemoved = "exchange-trust-removed", +FundsDepositedToSelf = "funds-deposited-to-self", +FundsRecouped = "funds-recouped", +ReserveCreated = "reserve-created", + */ @JsonSubTypes( Type(value = ExchangeAddedEvent::class, name = "exchange-added"), Type(value = ExchangeUpdatedEvent::class, name = "exchange-updated"), @@ -94,7 +107,12 @@ typealias History = ArrayList<HistoryEvent> Type(value = HistoryWithdrawnEvent::class, name = "withdrawn"), Type(value = HistoryOrderAcceptedEvent::class, name = "order-accepted"), Type(value = HistoryOrderRefusedEvent::class, name = "order-refused"), + Type(value = HistoryOrderRedirectedEvent::class, name = "order-redirected"), Type(value = HistoryPaymentSentEvent::class, name = "payment-sent"), + Type(value = HistoryPaymentAbortedEvent::class, name = "payment-aborted"), + Type(value = HistoryTipAcceptedEvent::class, name = "tip-accepted"), + Type(value = HistoryTipDeclinedEvent::class, name = "tip-declined"), + Type(value = HistoryRefundedEvent::class, name = "refund"), Type(value = HistoryRefreshedEvent::class, name = "refreshed") ) @JsonIgnoreProperties( @@ -176,7 +194,7 @@ class HistoryWithdrawnEvent( */ val amountWithdrawnEffective: String ) : HistoryEvent(timestamp) { - override val layout = R.layout.history_withdrawn + override val layout = R.layout.history_receive override val title = R.string.history_event_withdrawn override val icon = R.drawable.history_withdrawn override val showToUser = true @@ -231,12 +249,30 @@ class HistoryPaymentSentEvent( */ val sessionId: String? ) : HistoryEvent(timestamp) { - override val layout = R.layout.history_payment_sent + override val layout = R.layout.history_payment override val title = R.string.history_event_payment_sent override val icon = R.drawable.ic_cash_usd_outline override val showToUser = true } +@JsonTypeName("payment-aborted") +class HistoryPaymentAbortedEvent( + timestamp: Timestamp, + /** + * Condensed info about the order that we already paid for. + */ + val orderShortInfo: OrderShortInfo, + /** + * Amount that was lost due to refund and refreshing fees. + */ + val amountLost: String +) : HistoryEvent(timestamp) { + override val layout = R.layout.history_payment + override val title = R.string.history_event_payment_aborted + override val icon = R.drawable.history_payment_aborted + override val showToUser = true +} + @JsonTypeName("refreshed") class HistoryRefreshedEvent( timestamp: Timestamp, @@ -266,6 +302,88 @@ class HistoryRefreshedEvent( override val title = R.string.history_event_refreshed } +@JsonTypeName("order-redirected") +class HistoryOrderRedirectedEvent( + timestamp: Timestamp, + /** + * Condensed info about the new order that contains a + * product (identified by the fulfillment URL) that we've already paid for. + */ + val newOrderShortInfo: OrderShortInfo, + /** + * Condensed info about the order that we already paid for. + */ + val alreadyPaidOrderShortInfo: OrderShortInfo +) : HistoryEvent(timestamp) { + override val icon = R.drawable.ic_directions + override val title = R.string.history_event_order_redirected +} + +@JsonTypeName("tip-accepted") +class HistoryTipAcceptedEvent( + timestamp: Timestamp, + /** + * Unique identifier for the tip to query more information. + */ + val tipId: String, + /** + * Raw amount of the tip, without extra fees that apply. + */ + val tipRaw: String +) : HistoryEvent(timestamp) { + override val icon = R.drawable.history_tip_accepted + override val title = R.string.history_event_tip_accepted + override val layout = R.layout.history_receive + override val showToUser = true +} + +@JsonTypeName("tip-declined") +class HistoryTipDeclinedEvent( + timestamp: Timestamp, + /** + * Unique identifier for the tip to query more information. + */ + val tipId: String, + /** + * Raw amount of the tip, without extra fees that apply. + */ + val tipAmount: String +) : HistoryEvent(timestamp) { + override val icon = R.drawable.history_tip_declined + override val title = R.string.history_event_tip_declined + override val layout = R.layout.history_receive + override val showToUser = true +} + +@JsonTypeName("refund") +class HistoryRefundedEvent( + timestamp: Timestamp, + val orderShortInfo: OrderShortInfo, + /** + * Unique identifier for this refund. + * (Identifies multiple refund permissions that were obtained at once.) + */ + val refundGroupId: String, + /** + * Part of the refund that couldn't be applied because + * the refund permissions were expired. + */ + val amountRefundedInvalid: String, + /** + * Amount that has been refunded by the merchant. + */ + val amountRefundedRaw: String, + /** + * Amount will be added to the wallet's balance after fees and refreshing. + */ + val amountRefundedEffective: String +) : HistoryEvent(timestamp) { + override val icon = R.drawable.history_refund + override val title = R.string.history_event_refund + override val layout = R.layout.history_receive + override val showToUser = true +} + @JsonTypeInfo( use = NAME, include = PROPERTY, diff --git a/app/src/main/java/net/taler/wallet/history/WalletHistoryAdapter.kt b/app/src/main/java/net/taler/wallet/history/WalletHistoryAdapter.kt index 4cc35f7..5781f4f 100644 --- a/app/src/main/java/net/taler/wallet/history/WalletHistoryAdapter.kt +++ b/app/src/main/java/net/taler/wallet/history/WalletHistoryAdapter.kt @@ -16,15 +16,20 @@ package net.taler.wallet.history +import android.graphics.Paint.STRIKE_THRU_TEXT_FLAG import android.text.format.DateUtils.* import android.view.LayoutInflater import android.view.View +import android.view.View.GONE +import android.view.View.VISIBLE import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.annotation.CallSuper +import androidx.core.net.toUri import androidx.recyclerview.widget.RecyclerView.Adapter import androidx.recyclerview.widget.RecyclerView.ViewHolder +import net.taler.wallet.ParsedAmount import net.taler.wallet.ParsedAmount.Companion.parseAmount import net.taler.wallet.R @@ -41,8 +46,8 @@ internal class WalletHistoryAdapter(private var history: History = History()) : override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HistoryEventViewHolder { val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false) return when (viewType) { - R.layout.history_withdrawn -> HistoryWithdrawnViewHolder(view) - R.layout.history_payment_sent -> HistoryPaymentSentViewHolder(view) + R.layout.history_receive -> HistoryReceiveViewHolder(view) + R.layout.history_payment -> HistoryPaymentViewHolder(view) else -> GenericHistoryEventViewHolder(view) } } @@ -103,6 +108,7 @@ internal class GenericHistoryEventViewHolder(v: View) : HistoryEventViewHolder(v is HistoryPaymentSentEvent -> event.orderShortInfo.summary is HistoryOrderAcceptedEvent -> event.orderShortInfo.summary is HistoryOrderRefusedEvent -> event.orderShortInfo.summary + is HistoryOrderRedirectedEvent -> event.newOrderShortInfo.summary is HistoryRefreshedEvent -> { "${parseAmount(event.amountRefreshedRaw)} - ${parseAmount(event.amountRefreshedEffective)}" } @@ -112,46 +118,98 @@ internal class GenericHistoryEventViewHolder(v: View) : HistoryEventViewHolder(v } -internal class HistoryWithdrawnViewHolder(v: View) : HistoryEventViewHolder(v) { +internal class HistoryReceiveViewHolder(v: View) : HistoryEventViewHolder(v) { - private val exchangeUrl: TextView = v.findViewById(R.id.exchangeUrl) + private val summary: TextView = v.findViewById(R.id.summary) private val amountWithdrawn: TextView = v.findViewById(R.id.amountWithdrawn) private val feeLabel: TextView = v.findViewById(R.id.feeLabel) private val fee: TextView = v.findViewById(R.id.fee) override fun bind(event: HistoryEvent) { super.bind(event) - event as HistoryWithdrawnEvent + when(event) { + is HistoryWithdrawnEvent -> bind(event) + is HistoryRefundedEvent -> bind(event) + is HistoryTipAcceptedEvent -> bind(event) + is HistoryTipDeclinedEvent -> bind(event) + } + } + + private fun bind(event: HistoryWithdrawnEvent) { + title.text = getHostname(event.exchangeBaseUrl) + summary.setText(event.title) - exchangeUrl.text = event.exchangeBaseUrl val parsedEffective = parseAmount(event.amountWithdrawnEffective) val parsedRaw = parseAmount(event.amountWithdrawnRaw) - amountWithdrawn.text = "+${parsedRaw.toString()}" - val calculatedFee = parsedRaw - parsedEffective + showAmounts(parsedEffective, parsedRaw) + } + + private fun bind(event: HistoryRefundedEvent) { + title.text = event.orderShortInfo.summary + summary.setText(event.title) + + val parsedEffective = parseAmount(event.amountRefundedEffective) + val parsedRaw = parseAmount(event.amountRefundedRaw) + showAmounts(parsedEffective, parsedRaw) + } + + private fun bind(event: HistoryTipAcceptedEvent) { + title.setText(event.title) + summary.text = null + val amount = parseAmount(event.tipRaw) + showAmounts(amount, amount) + } + + private fun bind(event: HistoryTipDeclinedEvent) { + title.setText(event.title) + summary.text = null + val amount = parseAmount(event.tipAmount) + showAmounts(amount, amount) + amountWithdrawn.paintFlags = amountWithdrawn.paintFlags or STRIKE_THRU_TEXT_FLAG + } + + private fun showAmounts(effective: ParsedAmount, raw: ParsedAmount) { + amountWithdrawn.text = "+$raw" + val calculatedFee = raw - effective if (calculatedFee.isZero()) { - fee.visibility = View.GONE - feeLabel.visibility = View.GONE + fee.visibility = GONE + feeLabel.visibility = GONE } else { - fee.text = "-${calculatedFee.toString()}" - fee.visibility = View.VISIBLE - feeLabel.visibility = View.VISIBLE + fee.text = "-$calculatedFee" + fee.visibility = VISIBLE + feeLabel.visibility = VISIBLE } + amountWithdrawn.paintFlags = fee.paintFlags + } + + private fun getHostname(url: String): String { + return url.toUri().host!! } } -internal class HistoryPaymentSentViewHolder(v: View) : HistoryEventViewHolder(v) { +internal class HistoryPaymentViewHolder(v: View) : HistoryEventViewHolder(v) { private val summary: TextView = v.findViewById(R.id.summary) private val amountPaidWithFees: TextView = v.findViewById(R.id.amountPaidWithFees) override fun bind(event: HistoryEvent) { super.bind(event) - event as HistoryPaymentSentEvent + summary.setText(event.title) + when(event) { + is HistoryPaymentSentEvent -> bind(event) + is HistoryPaymentAbortedEvent -> bind(event) + } + } + private fun bind(event: HistoryPaymentSentEvent) { title.text = event.orderShortInfo.summary - summary.setText(event.title) - amountPaidWithFees.text = "-${parseAmount(event.amountPaidWithFees).toString()}" + amountPaidWithFees.text = "-${parseAmount(event.amountPaidWithFees)}" + } + + private fun bind(event: HistoryPaymentAbortedEvent) { + title.text = event.orderShortInfo.summary + amountPaidWithFees.text = "-${parseAmount(event.amountLost)}" } } diff --git a/app/src/main/res/drawable/history_payment_aborted.xml b/app/src/main/res/drawable/history_payment_aborted.xml new file mode 100644 index 0000000..ffe74a5 --- /dev/null +++ b/app/src/main/res/drawable/history_payment_aborted.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#000" + android:pathData="M15.46 18.12L16.88 19.54L19 17.41L21.12 19.54L22.54 18.12L20.41 16L22.54 13.88L21.12 12.46L19 14.59L16.88 12.46L15.46 13.88L17.59 16M14.97 11.62C14.86 10.28 13.58 8.97 12 9C10.3 9.04 9 10.3 9 12C9 13.7 10.3 14.94 12 15C12.39 15 12.77 14.92 13.14 14.77C13.41 13.67 13.86 12.63 14.97 11.62M13 16H7C7 14.9 6.1 14 5 14V10C6.1 10 7 9.1 7 8H17C17 9.1 17.9 10 19 10V10.05C19.67 10.06 20.34 10.18 21 10.4V6H3V18H13.32C13.1 17.33 13 16.66 13 16Z" /> +</vector> diff --git a/app/src/main/res/drawable/history_refund.xml b/app/src/main/res/drawable/history_refund.xml new file mode 100644 index 0000000..0d2a946 --- /dev/null +++ b/app/src/main/res/drawable/history_refund.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#000" + android:pathData="M3,11H21V23H3V11M12,15A2,2 0 0,1 14,17A2,2 0 0,1 12,19A2,2 0 0,1 10,17A2,2 0 0,1 12,15M7,13A2,2 0 0,1 5,15V19A2,2 0 0,1 7,21H17A2,2 0 0,1 19,19V15A2,2 0 0,1 17,13H7M17,5V10H15.5V6.5H9.88L12.3,8.93L11.24,10L7,5.75L11.24,1.5L12.3,2.57L9.88,5H17Z" /> +</vector> diff --git a/app/src/main/res/drawable/history_tip_accepted.xml b/app/src/main/res/drawable/history_tip_accepted.xml new file mode 100644 index 0000000..b4a0934 --- /dev/null +++ b/app/src/main/res/drawable/history_tip_accepted.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#000" + android:pathData="M18,21L15,18L18,15V17H22V19H18V21M10,4A4,4 0 0,1 14,8A4,4 0 0,1 10,12A4,4 0 0,1 6,8A4,4 0 0,1 10,4M10,14C11.15,14 12.25,14.12 13.24,14.34C12.46,15.35 12,16.62 12,18C12,18.7 12.12,19.37 12.34,20H2V18C2,15.79 5.58,14 10,14Z" /> +</vector> diff --git a/app/src/main/res/drawable/history_tip_declined.xml b/app/src/main/res/drawable/history_tip_declined.xml new file mode 100644 index 0000000..6d490f9 --- /dev/null +++ b/app/src/main/res/drawable/history_tip_declined.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#000" + android:pathData="M10 4A4 4 0 0 0 6 8A4 4 0 0 0 10 12A4 4 0 0 0 14 8A4 4 0 0 0 10 4M17.5 13C15 13 13 15 13 17.5C13 20 15 22 17.5 22C20 22 22 20 22 17.5C22 15 20 13 17.5 13M10 14C5.58 14 2 15.79 2 18V20H11.5A6.5 6.5 0 0 1 11 17.5A6.5 6.5 0 0 1 11.95 14.14C11.32 14.06 10.68 14 10 14M17.5 14.5C19.16 14.5 20.5 15.84 20.5 17.5C20.5 18.06 20.35 18.58 20.08 19L16 14.92C16.42 14.65 16.94 14.5 17.5 14.5M14.92 16L19 20.08C18.58 20.35 18.06 20.5 17.5 20.5C15.84 20.5 14.5 19.16 14.5 17.5C14.5 16.94 14.65 16.42 14.92 16Z" /> +</vector> diff --git a/app/src/main/res/drawable/ic_directions.xml b/app/src/main/res/drawable/ic_directions.xml new file mode 100644 index 0000000..739dd20 --- /dev/null +++ b/app/src/main/res/drawable/ic_directions.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF000000" + android:pathData="M21.71,11.29l-9,-9c-0.39,-0.39 -1.02,-0.39 -1.41,0l-9,9c-0.39,0.39 -0.39,1.02 0,1.41l9,9c0.39,0.39 1.02,0.39 1.41,0l9,-9c0.39,-0.38 0.39,-1.01 0,-1.41zM14,14.5V12h-4v3H8v-4c0,-0.55 0.45,-1 1,-1h5V7.5l3.5,3.5 -3.5,3.5z"/> +</vector> diff --git a/app/src/main/res/layout/history_payment_sent.xml b/app/src/main/res/layout/history_payment.xml index cf03998..cf03998 100644 --- a/app/src/main/res/layout/history_payment_sent.xml +++ b/app/src/main/res/layout/history_payment.xml diff --git a/app/src/main/res/layout/history_withdrawn.xml b/app/src/main/res/layout/history_receive.xml index 75bae07..5b86e6a 100644 --- a/app/src/main/res/layout/history_withdrawn.xml +++ b/app/src/main/res/layout/history_receive.xml @@ -23,16 +23,17 @@ <TextView android:id="@+id/title" style="@style/HistoryTitle" - android:layout_width="wrap_content" + android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" android:text="@string/history_event_withdrawn" - android:visibility="gone" + app:layout_constraintEnd_toStartOf="@+id/amountWithdrawn" app:layout_constraintStart_toEndOf="@+id/icon" app:layout_constraintTop_toTopOf="parent" /> <TextView - android:id="@+id/exchangeUrl" + android:id="@+id/summary" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" @@ -71,8 +72,6 @@ android:textColor="@color/green" android:textSize="16sp" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintHorizontal_bias="1.0" - app:layout_constraintStart_toEndOf="@+id/title" app:layout_constraintTop_toTopOf="parent" tools:text="10 TESTKUDOS" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6a92705..1d006ab 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -21,9 +21,14 @@ <string name="history_event_exchange_updated">Exchange Updated</string> <string name="history_event_reserve_balance_updated">Reserve Balance Updated</string> <string name="history_event_payment_sent">Payment</string> + <string name="history_event_payment_aborted">Payment Aborted</string> <string name="history_event_withdrawn">Withdraw</string> <string name="history_event_order_accepted">Order Confirmed</string> <string name="history_event_order_refused">Order Cancelled</string> + <string name="history_event_tip_accepted">Tip Accepted</string> + <string name="history_event_tip_declined">Tip Declined</string> + <string name="history_event_order_redirected">Order Redirected</string> + <string name="history_event_refund">Refund</string> <string name="history_event_refreshed">Refresh</string> <string name="history_fee_label">Fee:</string> <string name="history_show_all">Show All</string> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 619c0c9..f2eca8b 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -15,7 +15,7 @@ <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/> <style name="HistoryTitle"> - <item name="android:textSize">18sp</item> + <item name="android:textSize">17sp</item> <item name="android:textColor">?android:textColorPrimary</item> </style> diff --git a/app/src/test/java/net/taler/wallet/history/HistoryEventTest.kt b/app/src/test/java/net/taler/wallet/history/HistoryEventTest.kt index d6d68f1..f3d1a5e 100644 --- a/app/src/test/java/net/taler/wallet/history/HistoryEventTest.kt +++ b/app/src/test/java/net/taler/wallet/history/HistoryEventTest.kt @@ -284,6 +284,96 @@ class HistoryEventTest { } @Test + fun `test HistoryPaymentAbortedEvent`() { + val json = """{ + "type": "payment-aborted", + "eventId": "payment-sent;898724XGQ1GGMZB4WY3KND582NSP74FZ60BX0Y87FF81H0FJ8XD0", + "orderShortInfo": { + "amount": "${orderShortInfo.amount}", + "orderId": "${orderShortInfo.orderId}", + "merchantBaseUrl": "${orderShortInfo.merchantBaseUrl}", + "proposalId": "${orderShortInfo.proposalId}", + "summary": "${orderShortInfo.summary}" + }, + "timestamp": { + "t_ms": $timestamp + }, + "amountLost": "KUDOS:0.1" + }""".trimIndent() + val event: HistoryPaymentAbortedEvent = mapper.readValue(json) + + assertEquals(orderShortInfo, event.orderShortInfo) + assertEquals("KUDOS:0.1", event.amountLost) + assertEquals(timestamp, event.timestamp.ms) + } + + @Test + fun `test HistoryTipAcceptedEvent`() { + val json = """{ + "type": "tip-accepted", + "timestamp": { + "t_ms": $timestamp + }, + "eventId": "tip-accepted;898724XGQ1GGMZB4WY3KND582NSP74FZ60BX0Y87FF81H0FJ8XD0", + "tipId": "tip-accepted;898724XGQ1GGMZB4WY3KND582NSP74FZ60BX0Y87FF81H0FJ8XD0", + "tipRaw": "KUDOS:4" + }""".trimIndent() + val event: HistoryTipAcceptedEvent = mapper.readValue(json) + + assertEquals("tip-accepted;898724XGQ1GGMZB4WY3KND582NSP74FZ60BX0Y87FF81H0FJ8XD0", event.tipId) + assertEquals("KUDOS:4", event.tipRaw) + assertEquals(timestamp, event.timestamp.ms) + } + + @Test + fun `test HistoryTipDeclinedEvent`() { + val json = """{ + "type": "tip-declined", + "timestamp": { + "t_ms": $timestamp + }, + "eventId": "tip-accepted;898724XGQ1GGMZB4WY3KND582NSP74FZ60BX0Y87FF81H0FJ8XD0", + "tipId": "tip-accepted;998724XGQ1GGMZB4WY3KND582NSP74FZ60BX0Y87FF81H0FJ8XD0", + "tipAmount": "KUDOS:4" + }""".trimIndent() + val event: HistoryTipDeclinedEvent = mapper.readValue(json) + + assertEquals("tip-accepted;998724XGQ1GGMZB4WY3KND582NSP74FZ60BX0Y87FF81H0FJ8XD0", event.tipId) + assertEquals("KUDOS:4", event.tipAmount) + assertEquals(timestamp, event.timestamp.ms) + } + + @Test + fun `test HistoryRefundedEvent`() { + val json = """{ + "type": "refund", + "eventId": "refund;898724XGQ1GGMZB4WY3KND582NSP74FZ60BX0Y87FF81H0FJ8XD0", + "refundGroupId": "refund;998724", + "orderShortInfo": { + "amount": "${orderShortInfo.amount}", + "orderId": "${orderShortInfo.orderId}", + "merchantBaseUrl": "${orderShortInfo.merchantBaseUrl}", + "proposalId": "${orderShortInfo.proposalId}", + "summary": "${orderShortInfo.summary}" + }, + "timestamp": { + "t_ms": $timestamp + }, + "amountRefundedRaw": "KUDOS:1.0", + "amountRefundedInvalid": "KUDOS:0.5", + "amountRefundedEffective": "KUDOS:0.4" + }""".trimIndent() + val event: HistoryRefundedEvent = mapper.readValue(json) + + assertEquals("refund;998724", event.refundGroupId) + assertEquals("KUDOS:1.0", event.amountRefundedRaw) + assertEquals("KUDOS:0.5", event.amountRefundedInvalid) + assertEquals("KUDOS:0.4", event.amountRefundedEffective) + assertEquals(orderShortInfo, event.orderShortInfo) + assertEquals(timestamp, event.timestamp.ms) + } + + @Test fun `test HistoryRefreshedEvent`() { val json = """{ "type": "refreshed", @@ -312,6 +402,46 @@ class HistoryEventTest { } @Test + fun `test HistoryOrderRedirectedEvent`() { + val json = """{ + "type": "order-redirected", + "eventId": "order-redirected;621J6D5SXG7M17TYA26945DYKNQZPW4600MZ1W8MADA1RRR49F8G", + "alreadyPaidOrderShortInfo": { + "amount": "KUDOS:0.5", + "orderId": "2019.354-01P25CD66P8NG", + "merchantBaseUrl": "https://backend.demo.taler.net/public/instances/FSF/", + "proposalId": "898724XGQ1GGMZB4WY3KND582NSP74FZ60BX0Y87FF81H0FJ8XD0", + "summary": "Essay: 1. The Free Software Definition" + }, + "newOrderShortInfo": { + "amount": "KUDOS:0.5", + "orderId": "2019.364-01M4QH6KPMJY4", + "merchantBaseUrl": "https://backend.demo.taler.net/public/instances/FSF/", + "proposalId": "621J6D5SXG7M17TYA26945DYKNQZPW4600MZ1W8MADA1RRR49F8G", + "summary": "Essay: 1. The Free Software Definition" + }, + "timestamp": { + "t_ms": $timestamp + } + }""".trimIndent() + val event: HistoryOrderRedirectedEvent = mapper.readValue(json) + + assertEquals("898724XGQ1GGMZB4WY3KND582NSP74FZ60BX0Y87FF81H0FJ8XD0", event.alreadyPaidOrderShortInfo.proposalId) + assertEquals("https://backend.demo.taler.net/public/instances/FSF/", event.alreadyPaidOrderShortInfo.merchantBaseUrl) + assertEquals("2019.354-01P25CD66P8NG", event.alreadyPaidOrderShortInfo.orderId) + assertEquals("KUDOS:0.5", event.alreadyPaidOrderShortInfo.amount) + assertEquals("Essay: 1. The Free Software Definition", event.alreadyPaidOrderShortInfo.summary) + + assertEquals("621J6D5SXG7M17TYA26945DYKNQZPW4600MZ1W8MADA1RRR49F8G", event.newOrderShortInfo.proposalId) + assertEquals("https://backend.demo.taler.net/public/instances/FSF/", event.newOrderShortInfo.merchantBaseUrl) + assertEquals("2019.364-01M4QH6KPMJY4", event.newOrderShortInfo.orderId) + assertEquals("KUDOS:0.5", event.newOrderShortInfo.amount) + assertEquals("Essay: 1. The Free Software Definition", event.newOrderShortInfo.summary) + + assertEquals(timestamp, event.timestamp.ms) + } + + @Test fun `test list of events as History`() { val builtIn = Random.nextBoolean() val json = """[ |