Add PayPalLineItemInput with localized description

This commit is contained in:
Chris Eager
2026-02-06 12:09:25 -06:00
committed by Chris Eager
parent 118b1d31cf
commit 39beb59b58
9 changed files with 129 additions and 15 deletions

View File

@@ -94,6 +94,7 @@ import org.whispersystems.textsecuregcm.subscriptions.PaymentMethod;
import org.whispersystems.textsecuregcm.subscriptions.PaymentProvider;
import org.whispersystems.textsecuregcm.subscriptions.PaymentStatus;
import org.whispersystems.textsecuregcm.subscriptions.ProcessorCustomer;
import org.whispersystems.textsecuregcm.subscriptions.PayPalDonationsTranslator;
import org.whispersystems.textsecuregcm.subscriptions.StripeManager;
import org.whispersystems.textsecuregcm.subscriptions.SubscriptionInvalidArgumentsException;
import org.whispersystems.textsecuregcm.subscriptions.SubscriptionNotFoundException;
@@ -132,6 +133,8 @@ class SubscriptionControllerTest {
private static final OneTimeDonationsManager ONE_TIME_DONATIONS_MANAGER = mock(OneTimeDonationsManager.class);
private static final BadgeTranslator BADGE_TRANSLATOR = mock(BadgeTranslator.class);
private static final BankMandateTranslator BANK_MANDATE_TRANSLATOR = mock(BankMandateTranslator.class);
private static final PayPalDonationsTranslator PAYPAL_ONE_TIME_DONATION_LINE_ITEM_TRANSLATOR = mock(
PayPalDonationsTranslator.class);
private static final DynamicConfigurationManager<DynamicConfiguration> DYNAMIC_CONFIGURATION_MANAGER = mock(DynamicConfigurationManager.class);
private final static SubscriptionController SUBSCRIPTION_CONTROLLER = new SubscriptionController(CLOCK,
SUBSCRIPTION_CONFIG, ONETIME_CONFIG,
@@ -139,7 +142,8 @@ class SubscriptionControllerTest {
ZK_OPS, ISSUED_RECEIPTS_MANAGER), STRIPE_MANAGER, BRAINTREE_MANAGER, PLAY_MANAGER, APPSTORE_MANAGER,
BADGE_TRANSLATOR, BANK_MANDATE_TRANSLATOR, DYNAMIC_CONFIGURATION_MANAGER);
private static final OneTimeDonationController ONE_TIME_CONTROLLER = new OneTimeDonationController(CLOCK,
ONETIME_CONFIG, STRIPE_MANAGER, BRAINTREE_MANAGER, ZK_OPS, ISSUED_RECEIPTS_MANAGER, ONE_TIME_DONATIONS_MANAGER);
ONETIME_CONFIG, STRIPE_MANAGER, BRAINTREE_MANAGER, PAYPAL_ONE_TIME_DONATION_LINE_ITEM_TRANSLATOR,
ZK_OPS, ISSUED_RECEIPTS_MANAGER, ONE_TIME_DONATIONS_MANAGER);
private static final ResourceExtension RESOURCE_EXTENSION = ResourceExtension.builder()
.addProperty(ServerProperties.UNWRAP_COMPLETION_STAGE_IN_WRITER_ENABLE, Boolean.TRUE)
.addProvider(AuthHelper.getAuthFilter())
@@ -154,10 +158,12 @@ class SubscriptionControllerTest {
@BeforeEach
void setUp() {
reset(CLOCK, SUBSCRIPTIONS, STRIPE_MANAGER, BRAINTREE_MANAGER, ZK_OPS, ISSUED_RECEIPTS_MANAGER, BADGE_TRANSLATOR);
reset(CLOCK, SUBSCRIPTIONS, STRIPE_MANAGER, BRAINTREE_MANAGER, ZK_OPS, ISSUED_RECEIPTS_MANAGER, BADGE_TRANSLATOR,
PAYPAL_ONE_TIME_DONATION_LINE_ITEM_TRANSLATOR);
when(STRIPE_MANAGER.getProvider()).thenReturn(PaymentProvider.STRIPE);
when(BRAINTREE_MANAGER.getProvider()).thenReturn(PaymentProvider.BRAINTREE);
when(PAYPAL_ONE_TIME_DONATION_LINE_ITEM_TRANSLATOR.translate(any(), any())).thenReturn("Donation to Signal Technology Foundation");
final DynamicConfiguration dynamicConfiguration = mock(DynamicConfiguration.class);
when(dynamicConfiguration.getBackupConfiguration())
.thenReturn(new DynamicBackupConfiguration(null, null, null, null, MAX_TOTAL_BACKUP_MEDIA_BYTES));
@@ -277,7 +283,7 @@ class SubscriptionControllerTest {
final PayPalOneTimePaymentApprovalDetails payPalOneTimePaymentApprovalDetails = mock(PayPalOneTimePaymentApprovalDetails.class);
when(BRAINTREE_MANAGER.getSupportedCurrenciesForPaymentMethod(PaymentMethod.PAYPAL))
.thenReturn(Set.of("usd", "jpy", "bif", "eur"));
when(BRAINTREE_MANAGER.createOneTimePayment(anyString(), anyLong(), anyString(), anyString(), anyString()))
when(BRAINTREE_MANAGER.createOneTimePayment(anyString(), anyLong(), anyString(), anyString(), anyString(), anyString()))
.thenReturn(CompletableFuture.completedFuture(payPalOneTimePaymentApprovalDetails));
when(payPalOneTimePaymentApprovalDetails.approvalUrl()).thenReturn("approvalUrl");
when(payPalOneTimePaymentApprovalDetails.paymentId()).thenReturn("someId");

View File

@@ -34,6 +34,7 @@ class BraintreeGraphqlClientTest {
private static final String RETURN_URL = "https://example.com/return";
private static final String CANCEL_URL = "https://example.com/cancel";
private static final String LOCALE = "xx";
private static final String LOCALIZED_LINE_ITEM_NAME = "Donation to Signal Technology Foundation";
private FaultTolerantHttpClient httpClient;
private BraintreeGraphqlClient braintreeGraphqlClient;
@@ -61,7 +62,7 @@ class BraintreeGraphqlClientTest {
final CompletableFuture<CreatePayPalOneTimePaymentMutation.CreatePayPalOneTimePayment> future = braintreeGraphqlClient.createPayPalOneTimePayment(
BigDecimal.ONE, CURRENCY,
RETURN_URL, CANCEL_URL, LOCALE);
RETURN_URL, CANCEL_URL, LOCALE, LOCALIZED_LINE_ITEM_NAME);
assertTimeoutPreemptively(Duration.ofSeconds(3), () -> {
final CreatePayPalOneTimePaymentMutation.CreatePayPalOneTimePayment result = future.get();
@@ -87,7 +88,7 @@ class BraintreeGraphqlClientTest {
final CompletableFuture<CreatePayPalOneTimePaymentMutation.CreatePayPalOneTimePayment> future = braintreeGraphqlClient.createPayPalOneTimePayment(
BigDecimal.ONE, CURRENCY,
RETURN_URL, CANCEL_URL, LOCALE);
RETURN_URL, CANCEL_URL, LOCALE, LOCALIZED_LINE_ITEM_NAME);
assertTimeoutPreemptively(Duration.ofSeconds(3), () -> {
@@ -111,7 +112,7 @@ class BraintreeGraphqlClientTest {
final CompletableFuture<CreatePayPalOneTimePaymentMutation.CreatePayPalOneTimePayment> future = braintreeGraphqlClient.createPayPalOneTimePayment(
BigDecimal.ONE, CURRENCY,
RETURN_URL, CANCEL_URL, LOCALE);
RETURN_URL, CANCEL_URL, LOCALE, LOCALIZED_LINE_ITEM_NAME);
assertTimeoutPreemptively(Duration.ofSeconds(3), () -> {

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2026 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.subscriptions;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import org.junit.jupiter.api.Test;
import org.signal.i18n.HeaderControlledResourceBundleLookup;
class PayPalDonationsTranslatorTest {
private final PayPalDonationsTranslator translator = new PayPalDonationsTranslator(
new HeaderControlledResourceBundleLookup());
@Test
void testTranslate() {
assertEquals("Donation to Signal Technology Foundation",
translator.translate(List.of(Locale.ROOT), PayPalDonationsTranslator.ONE_TIME_DONATION_LINE_ITEM_KEY));
}
@Test
void testTranslateUnknownKey() {
assertThrows(MissingResourceException.class, () -> translator.translate(List.of(Locale.ROOT), "unknown-key"));
}
}