taler-android

Android apps for GNU Taler (wallet, PoS, cashier)
Log | Files | Refs | README | LICENSE

commit de4c0c14d901204cfbdc410f8f516662c3c6b6ac
parent 52eb8888d7ca8d5880d84c4e30b2e7ef5e577474
Author: Bohdan Potuzhnyi <bohdan.potuzhnyi@gmail.com>
Date:   Tue,  9 Jun 2026 15:44:12 +0200

[pos] fix tests

Diffstat:
Mmerchant-terminal/src/main/java/net/taler/merchantpos/MainActivity.kt | 8+++++---
Mmerchant-terminal/src/main/java/net/taler/merchantpos/order/OrderFragment.kt | 3++-
Dmerchant-terminal/src/main/res/layout-sw600dp/fragment_amount_entry.xml | 276-------------------------------------------------------------------------------
Mmerchant-terminal/src/test/java/net/taler/merchantpos/order/OrderManagerTest.kt | 13++++++++-----
4 files changed, 15 insertions(+), 285 deletions(-)

diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/MainActivity.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/MainActivity.kt @@ -31,6 +31,7 @@ import android.widget.FrameLayout import android.widget.Toast import android.widget.Toast.LENGTH_SHORT import androidx.activity.compose.BackHandler +import androidx.activity.compose.LocalActivity import androidx.activity.compose.setContent import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity @@ -329,10 +330,11 @@ private fun MerchantTerminalApp( (currentRoute == PosDestination.Settings.route || currentRoute == PosDestination.Config.route) val screenTitle = when (currentRoute) { PosDestination.Order.route -> currentOrder?.let { - context.getString(R.string.order_label_title, it.title) + stringResource(R.string.order_label_title, it.title) } ?: stringResource(R.string.menu_order) else -> stringResource(currentRoute.titleResId()) } + val reloadingMessage = stringResource(R.string.toast_reloading) val drawerItems = listOf( PosDestination.AmountEntry, @@ -478,7 +480,7 @@ private fun MerchantTerminalApp( viewModel.configManager.reloadConfig() Toast.makeText( context, - context.getString(R.string.toast_reloading), + reloadingMessage, Toast.LENGTH_LONG, ).show() }, @@ -601,7 +603,7 @@ private fun FragmentScreenHost( routeTag: String, createFragment: () -> Fragment, ) { - val activity = LocalContext.current as MainActivity + val activity = LocalActivity.current as? MainActivity ?: return val fragmentManager = activity.supportFragmentManager val containerId = remember(routeTag) { View.generateViewId() } val fragmentTag = remember(routeTag, containerId) { "$routeTag-$containerId" } diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderFragment.kt @@ -24,6 +24,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.IntrinsicSize @@ -198,7 +199,7 @@ private fun OrderRoute( } PosTheme { - BoxWithConstraints( + Box( modifier = Modifier .fillMaxSize() .statusBarsPadding(), diff --git a/merchant-terminal/src/main/res/layout-sw600dp/fragment_amount_entry.xml b/merchant-terminal/src/main/res/layout-sw600dp/fragment_amount_entry.xml @@ -1,276 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:padding="16dp"> - - <TextView - android:id="@+id/amountView" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:ellipsize="start" - android:gravity="end" - android:maxLines="1" - android:paddingHorizontal="12dp" - android:textAppearance="?attr/textAppearanceHeadlineLarge" - android:textSize="56sp" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintEnd_toStartOf="@+id/currencyLayout" - app:layout_constraintHorizontal_chainStyle="packed" - tools:text="12.34" /> - - <com.google.android.material.textfield.TextInputLayout - android:id="@+id/currencyLayout" - style="@style/Widget.Material3.TextInputLayout.OutlinedBox.Dense" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - app:boxBackgroundMode="outline" - app:endIconMode="dropdown_menu" - app:layout_constraintTop_toTopOf="@+id/amountView" - app:layout_constraintBottom_toBottomOf="@+id/amountView" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toEndOf="@+id/amountView"> - - <com.google.android.material.textfield.MaterialAutoCompleteTextView - android:id="@+id/currencyView" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:inputType="none" - android:paddingHorizontal="16dp" - tools:text="EUR" /> - </com.google.android.material.textfield.TextInputLayout> - - <androidx.constraintlayout.widget.Guideline - android:id="@+id/guidelineNumpadStart" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:orientation="vertical" - app:layout_constraintGuide_percent="0.2" /> - - <androidx.constraintlayout.widget.Guideline - android:id="@+id/guidelineNumpadEnd" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:orientation="vertical" - app:layout_constraintGuide_percent="0.8" /> - - <androidx.constraintlayout.widget.Guideline - android:id="@+id/guidelineCharge" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:orientation="horizontal" - app:layout_constraintGuide_percent="0.8" /> - - <androidx.constraintlayout.widget.ConstraintLayout - android:id="@+id/numpad" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_marginTop="16dp" - android:layout_marginBottom="12dp" - app:layout_constraintBottom_toTopOf="@+id/guidelineCharge" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintEnd_toStartOf="@+id/guidelineNumpadEnd" - app:layout_constraintStart_toEndOf="@+id/guidelineNumpadStart" - app:layout_constraintTop_toBottomOf="@+id/amountView"> - - <com.google.android.material.button.MaterialButton - android:id="@+id/key1" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_margin="4dp" - android:text="1" - android:textColor="@color/amount_entry_key_text" - android:textSize="@dimen/amount_entry_key_text_size" - app:backgroundTint="@color/amount_entry_key_background" - app:layout_constraintEnd_toStartOf="@+id/key2" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toTopOf="@+id/key4" - app:layout_constraintHorizontal_chainStyle="spread" - app:layout_constraintVertical_chainStyle="spread" /> - - <com.google.android.material.button.MaterialButton - android:id="@+id/key2" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_margin="4dp" - android:text="2" - android:textColor="@color/amount_entry_key_text" - android:textSize="@dimen/amount_entry_key_text_size" - app:backgroundTint="@color/amount_entry_key_background" - app:layout_constraintEnd_toStartOf="@+id/key3" - app:layout_constraintStart_toEndOf="@+id/key1" - app:layout_constraintTop_toTopOf="@+id/key1" - app:layout_constraintBottom_toBottomOf="@+id/key1" /> - - <com.google.android.material.button.MaterialButton - android:id="@+id/key3" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_margin="4dp" - android:text="3" - android:textColor="@color/amount_entry_key_text" - android:textSize="@dimen/amount_entry_key_text_size" - app:backgroundTint="@color/amount_entry_key_background" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toEndOf="@+id/key2" - app:layout_constraintTop_toTopOf="@+id/key1" - app:layout_constraintBottom_toBottomOf="@+id/key1" /> - - <com.google.android.material.button.MaterialButton - android:id="@+id/key4" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_margin="4dp" - android:text="4" - android:textColor="@color/amount_entry_key_text" - android:textSize="@dimen/amount_entry_key_text_size" - app:backgroundTint="@color/amount_entry_key_background" - app:layout_constraintEnd_toStartOf="@+id/key5" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/key1" - app:layout_constraintBottom_toTopOf="@+id/key7" - app:layout_constraintHorizontal_chainStyle="spread" /> - - <com.google.android.material.button.MaterialButton - android:id="@+id/key5" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_margin="4dp" - android:text="5" - android:textColor="@color/amount_entry_key_text" - android:textSize="@dimen/amount_entry_key_text_size" - app:backgroundTint="@color/amount_entry_key_background" - app:layout_constraintEnd_toStartOf="@+id/key6" - app:layout_constraintStart_toEndOf="@+id/key4" - app:layout_constraintTop_toTopOf="@+id/key4" - app:layout_constraintBottom_toBottomOf="@+id/key4" /> - - <com.google.android.material.button.MaterialButton - android:id="@+id/key6" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_margin="4dp" - android:text="6" - android:textColor="@color/amount_entry_key_text" - android:textSize="@dimen/amount_entry_key_text_size" - app:backgroundTint="@color/amount_entry_key_background" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toEndOf="@+id/key5" - app:layout_constraintTop_toTopOf="@+id/key4" - app:layout_constraintBottom_toBottomOf="@+id/key4" /> - - <com.google.android.material.button.MaterialButton - android:id="@+id/key7" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_margin="4dp" - android:text="7" - android:textColor="@color/amount_entry_key_text" - android:textSize="@dimen/amount_entry_key_text_size" - app:backgroundTint="@color/amount_entry_key_background" - app:layout_constraintEnd_toStartOf="@+id/key8" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/key4" - app:layout_constraintBottom_toTopOf="@+id/keyClear" - app:layout_constraintHorizontal_chainStyle="spread" /> - - <com.google.android.material.button.MaterialButton - android:id="@+id/key8" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_margin="4dp" - android:text="8" - android:textColor="@color/amount_entry_key_text" - android:textSize="@dimen/amount_entry_key_text_size" - app:backgroundTint="@color/amount_entry_key_background" - app:layout_constraintEnd_toStartOf="@+id/key9" - app:layout_constraintStart_toEndOf="@+id/key7" - app:layout_constraintTop_toTopOf="@+id/key7" - app:layout_constraintBottom_toBottomOf="@+id/key7" /> - - <com.google.android.material.button.MaterialButton - android:id="@+id/key9" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_margin="4dp" - android:text="9" - android:textColor="@color/amount_entry_key_text" - android:textSize="@dimen/amount_entry_key_text_size" - app:backgroundTint="@color/amount_entry_key_background" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toEndOf="@+id/key8" - app:layout_constraintTop_toTopOf="@+id/key7" - app:layout_constraintBottom_toBottomOf="@+id/key7" /> - - <com.google.android.material.button.MaterialButton - android:id="@+id/keyClear" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_margin="4dp" - android:singleLine="true" - android:text="@string/amount_entry_clear" - android:textColor="@color/amount_entry_key_text" - android:textSize="22sp" - app:backgroundTint="@color/amount_entry_key_background" - app:layout_constraintEnd_toStartOf="@+id/key0" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/key7" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintHorizontal_chainStyle="spread" /> - - <com.google.android.material.button.MaterialButton - android:id="@+id/key0" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_margin="4dp" - android:text="0" - android:textColor="@color/amount_entry_key_text" - android:textSize="@dimen/amount_entry_key_text_size" - app:backgroundTint="@color/amount_entry_key_background" - app:layout_constraintEnd_toStartOf="@+id/keyBackspace" - app:layout_constraintStart_toEndOf="@+id/keyClear" - app:layout_constraintTop_toTopOf="@+id/keyClear" - app:layout_constraintBottom_toBottomOf="@+id/keyClear" /> - - <com.google.android.material.button.MaterialButton - android:id="@+id/keyBackspace" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_margin="4dp" - android:contentDescription="@string/amount_entry_backspace" - android:gravity="center" - android:padding="0dp" - android:singleLine="true" - android:text="" - app:backgroundTint="@color/amount_entry_key_background" - app:icon="@drawable/ic_backspace" - app:iconGravity="textStart" - app:iconPadding="0dp" - app:iconSize="34dp" - app:iconTint="@color/amount_entry_key_text" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toEndOf="@+id/key0" - app:layout_constraintTop_toTopOf="@+id/keyClear" - app:layout_constraintBottom_toBottomOf="@+id/keyClear" /> - </androidx.constraintlayout.widget.ConstraintLayout> - - <Button - android:id="@+id/chargeButton" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_marginBottom="8dp" - android:backgroundTint="@color/complete_button_bottom" - android:text="@string/amount_entry_create_order_charge" - android:textAllCaps="false" - android:textSize="20sp" - app:layout_constraintTop_toBottomOf="@+id/guidelineCharge" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@+id/guidelineNumpadEnd" - app:layout_constraintStart_toEndOf="@+id/guidelineNumpadStart" /> - -</androidx.constraintlayout.widget.ConstraintLayout> diff --git a/merchant-terminal/src/test/java/net/taler/merchantpos/order/OrderManagerTest.kt b/merchant-terminal/src/test/java/net/taler/merchantpos/order/OrderManagerTest.kt @@ -77,14 +77,17 @@ class OrderManagerTest { } @Test - fun `config test currency mismatch`() = runBlocking { + fun `currency mismatch product is accepted but unavailable`() = runBlocking { val products = listOf(posConfig.products[0].copy(price = Amount("WRONGCUR", 1, 0))) val config = posConfig.copy(products = products) val result = orderManager.onConfigurationReceived(config, "KUDOS", null) - val expectedStr = app.getString( - R.string.config_error_currency, "foo", "WRONGCUR", "KUDOS" - ) - assertEquals(expectedStr, result) + shadowMainLooper().idle() + + assertNull(result) + val product = orderManager.products.awaitValue().single() + assertEquals("WRONGCUR", product.price.currency) + assertTrue(product.currencyMismatch) + assertFalse(product.availableToSell) } // TODO: re-enable test based on orderManager.categories contents!