Mark LevelConfiguration#name as deprecated

This commit is contained in:
Chris Eager 2024-10-07 16:56:22 -05:00 committed by Jon Chambers
parent e277281d18
commit 3a604464b5
6 changed files with 55 additions and 124 deletions

View File

@ -95,7 +95,6 @@ import org.whispersystems.textsecuregcm.backup.BackupsDb;
import org.whispersystems.textsecuregcm.backup.Cdn3BackupCredentialGenerator;
import org.whispersystems.textsecuregcm.backup.Cdn3RemoteStorageManager;
import org.whispersystems.textsecuregcm.badges.ConfiguredProfileBadgeConverter;
import org.whispersystems.textsecuregcm.badges.ResourceBundleLevelTranslator;
import org.whispersystems.textsecuregcm.calls.routing.CallDnsRecordsManager;
import org.whispersystems.textsecuregcm.calls.routing.CallRoutingTableManager;
import org.whispersystems.textsecuregcm.calls.routing.DynamicConfigTurnRouter;
@ -374,8 +373,6 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
new HeaderControlledResourceBundleLookup();
ConfiguredProfileBadgeConverter profileBadgeConverter = new ConfiguredProfileBadgeConverter(
clock, config.getBadges(), headerControlledResourceBundleLookup);
ResourceBundleLevelTranslator resourceBundleLevelTranslator = new ResourceBundleLevelTranslator(
headerControlledResourceBundleLookup);
BankMandateTranslator bankMandateTranslator = new BankMandateTranslator(headerControlledResourceBundleLookup);
environment.lifecycle().manage(new ManagedAwsCrt());
@ -1146,7 +1143,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
zkReceiptOperations, issuedReceiptsManager);
commonControllers.add(new SubscriptionController(clock, config.getSubscription(), config.getOneTimeDonations(),
subscriptionManager, stripeManager, braintreeManager, googlePlayBillingManager, appleAppStoreManager,
profileBadgeConverter, resourceBundleLevelTranslator, bankMandateTranslator));
profileBadgeConverter, bankMandateTranslator));
commonControllers.add(new OneTimeDonationController(clock, config.getOneTimeDonations(), stripeManager, braintreeManager,
zkReceiptOperations, issuedReceiptsManager, oneTimeDonationsManager));
}

View File

@ -1,32 +0,0 @@
/*
* Copyright 2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.badges;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.ResourceBundle;
import javax.annotation.Nonnull;
import org.signal.i18n.HeaderControlledResourceBundleLookup;
public class ResourceBundleLevelTranslator implements LevelTranslator {
private static final String BASE_NAME = "org.signal.subscriptions.Subscriptions";
private final HeaderControlledResourceBundleLookup headerControlledResourceBundleLookup;
public ResourceBundleLevelTranslator(
@Nonnull final HeaderControlledResourceBundleLookup headerControlledResourceBundleLookup) {
this.headerControlledResourceBundleLookup = Objects.requireNonNull(headerControlledResourceBundleLookup);
}
@Override
public String translate(final List<Locale> acceptableLanguages, final String badgeId) {
final ResourceBundle resourceBundle = headerControlledResourceBundleLookup.getResourceBundle(BASE_NAME,
acceptableLanguages);
return resourceBundle.getString(badgeId);
}
}

View File

@ -60,7 +60,6 @@ import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialResponse;
import org.whispersystems.textsecuregcm.auth.AuthenticatedDevice;
import org.whispersystems.textsecuregcm.backup.BackupManager;
import org.whispersystems.textsecuregcm.badges.BadgeTranslator;
import org.whispersystems.textsecuregcm.badges.LevelTranslator;
import org.whispersystems.textsecuregcm.configuration.OneTimeDonationConfiguration;
import org.whispersystems.textsecuregcm.configuration.OneTimeDonationCurrencyConfiguration;
import org.whispersystems.textsecuregcm.configuration.SubscriptionConfiguration;
@ -104,7 +103,6 @@ public class SubscriptionController {
private final GooglePlayBillingManager googlePlayBillingManager;
private final AppleAppStoreManager appleAppStoreManager;
private final BadgeTranslator badgeTranslator;
private final LevelTranslator levelTranslator;
private final BankMandateTranslator bankMandateTranslator;
static final String RECEIPT_ISSUED_COUNTER_NAME = MetricsUtil.name(SubscriptionController.class, "receiptIssued");
static final String PROCESSOR_TAG_NAME = "processor";
@ -121,7 +119,6 @@ public class SubscriptionController {
@Nonnull GooglePlayBillingManager googlePlayBillingManager,
@Nonnull AppleAppStoreManager appleAppStoreManager,
@Nonnull BadgeTranslator badgeTranslator,
@Nonnull LevelTranslator levelTranslator,
@Nonnull BankMandateTranslator bankMandateTranslator) {
this.subscriptionManager = subscriptionManager;
this.clock = Objects.requireNonNull(clock);
@ -132,7 +129,6 @@ public class SubscriptionController {
this.googlePlayBillingManager = Objects.requireNonNull(googlePlayBillingManager);
this.appleAppStoreManager = appleAppStoreManager;
this.badgeTranslator = Objects.requireNonNull(badgeTranslator);
this.levelTranslator = Objects.requireNonNull(levelTranslator);
this.bankMandateTranslator = Objects.requireNonNull(bankMandateTranslator);
}
@ -183,7 +179,7 @@ public class SubscriptionController {
subscriptionConfiguration.getDonationLevels().forEach((levelId, levelConfig) -> {
final LevelConfiguration levelConfiguration = new LevelConfiguration(
levelTranslator.translate(acceptableLanguages, levelConfig.badge()),
"" /* deprecated and unused */,
badgeTranslator.translate(acceptableLanguages, levelConfig.badge()));
donationLevels.put(String.valueOf(levelId), levelConfiguration);
});
@ -192,7 +188,7 @@ public class SubscriptionController {
oneTimeDonationConfiguration.boost().badge());
donationLevels.put(String.valueOf(oneTimeDonationConfiguration.boost().level()),
new LevelConfiguration(
boostBadge.getName(),
"" /* deprecated and unused */,
// NB: the one-time badges are PurchasableBadge, which has a `duration` field
new PurchasableBadge(
boostBadge,
@ -201,7 +197,7 @@ public class SubscriptionController {
final Badge giftBadge = badgeTranslator.translate(acceptableLanguages, oneTimeDonationConfiguration.gift().badge());
donationLevels.put(String.valueOf(oneTimeDonationConfiguration.gift().level()),
new LevelConfiguration(
giftBadge.getName(),
"" /* deprecated and unused */,
new PurchasableBadge(
giftBadge,
oneTimeDonationConfiguration.gift().expiration())));
@ -504,6 +500,7 @@ public class SubscriptionController {
@Schema(description = "Configuration for a donation level - use to present appropriate client interfaces")
public record LevelConfiguration(
@Deprecated(forRemoval = true) // may be removed after 2025-01-28
@Schema(description = "The localized name for the level")
String name,
@Schema(description = "The displayable badge associated with the level")

View File

@ -1,13 +0,0 @@
#
# Copyright 2021 Signal Messenger, LLC
# SPDX-License-Identifier: AGPL-3.0-only
#
# These are deprecated, will be unused by clients in a future update, and can be removed in ~April 2023.
# First subscription level
R_LOW = Sustainer 1
# Second subscription level
R_MED = Sustainer 2
# Third subscription level
R_HIGH = Sustainer 3

View File

@ -67,7 +67,6 @@ import org.signal.libsignal.zkgroup.receipts.ServerZkReceiptOperations;
import org.whispersystems.textsecuregcm.auth.AuthenticatedDevice;
import org.whispersystems.textsecuregcm.backup.BackupManager;
import org.whispersystems.textsecuregcm.badges.BadgeTranslator;
import org.whispersystems.textsecuregcm.badges.LevelTranslator;
import org.whispersystems.textsecuregcm.configuration.OneTimeDonationConfiguration;
import org.whispersystems.textsecuregcm.configuration.SubscriptionConfiguration;
import org.whispersystems.textsecuregcm.controllers.SubscriptionController.GetBankMandateResponse;
@ -87,14 +86,14 @@ import org.whispersystems.textsecuregcm.subscriptions.BankMandateTranslator;
import org.whispersystems.textsecuregcm.subscriptions.BraintreeManager;
import org.whispersystems.textsecuregcm.subscriptions.BraintreeManager.PayPalOneTimePaymentApprovalDetails;
import org.whispersystems.textsecuregcm.subscriptions.ChargeFailure;
import org.whispersystems.textsecuregcm.subscriptions.CustomerAwareSubscriptionPaymentProcessor;
import org.whispersystems.textsecuregcm.subscriptions.GooglePlayBillingManager;
import org.whispersystems.textsecuregcm.subscriptions.PaymentDetails;
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.StripeManager;
import org.whispersystems.textsecuregcm.subscriptions.PaymentProvider;
import org.whispersystems.textsecuregcm.subscriptions.CustomerAwareSubscriptionPaymentProcessor;
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
import org.whispersystems.textsecuregcm.util.MockUtils;
import org.whispersystems.textsecuregcm.util.SystemMapper;
@ -123,15 +122,12 @@ class SubscriptionControllerTest {
private static final IssuedReceiptsManager ISSUED_RECEIPTS_MANAGER = mock(IssuedReceiptsManager.class);
private static final OneTimeDonationsManager ONE_TIME_DONATIONS_MANAGER = mock(OneTimeDonationsManager.class);
private static final BadgeTranslator BADGE_TRANSLATOR = mock(BadgeTranslator.class);
private static final LevelTranslator LEVEL_TRANSLATOR = mock(LevelTranslator.class);
private static final BankMandateTranslator BANK_MANDATE_TRANSLATOR = mock(BankMandateTranslator.class);
private final static SubscriptionController SUBSCRIPTION_CONTROLLER = new SubscriptionController(CLOCK,
SUBSCRIPTION_CONFIG, ONETIME_CONFIG,
new SubscriptionManager(SUBSCRIPTIONS,
List.of(STRIPE_MANAGER, BRAINTREE_MANAGER, PLAY_MANAGER, APPSTORE_MANAGER),
ZK_OPS, ISSUED_RECEIPTS_MANAGER),
STRIPE_MANAGER, BRAINTREE_MANAGER, PLAY_MANAGER, APPSTORE_MANAGER,
BADGE_TRANSLATOR, LEVEL_TRANSLATOR, BANK_MANDATE_TRANSLATOR);
new SubscriptionManager(SUBSCRIPTIONS, List.of(STRIPE_MANAGER, BRAINTREE_MANAGER, PLAY_MANAGER, APPSTORE_MANAGER),
ZK_OPS, ISSUED_RECEIPTS_MANAGER), STRIPE_MANAGER, BRAINTREE_MANAGER, PLAY_MANAGER, APPSTORE_MANAGER,
BADGE_TRANSLATOR, BANK_MANDATE_TRANSLATOR);
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);
private static final ResourceExtension RESOURCE_EXTENSION = ResourceExtension.builder()
@ -148,17 +144,14 @@ class SubscriptionControllerTest {
@BeforeEach
void setUp() {
reset(CLOCK, SUBSCRIPTIONS, STRIPE_MANAGER, BRAINTREE_MANAGER, ZK_OPS, ISSUED_RECEIPTS_MANAGER,
BADGE_TRANSLATOR, LEVEL_TRANSLATOR);
reset(CLOCK, SUBSCRIPTIONS, STRIPE_MANAGER, BRAINTREE_MANAGER, ZK_OPS, ISSUED_RECEIPTS_MANAGER, BADGE_TRANSLATOR);
when(STRIPE_MANAGER.getProvider()).thenReturn(PaymentProvider.STRIPE);
when(BRAINTREE_MANAGER.getProvider()).thenReturn(PaymentProvider.BRAINTREE);
List.of(STRIPE_MANAGER, BRAINTREE_MANAGER)
.forEach(manager -> {
when(manager.supportsPaymentMethod(any()))
.thenCallRealMethod();
});
.forEach(manager -> when(manager.supportsPaymentMethod(any()))
.thenCallRealMethod());
when(STRIPE_MANAGER.getSupportedCurrenciesForPaymentMethod(PaymentMethod.CARD))
.thenReturn(Set.of("usd", "jpy", "bif", "eur"));
when(STRIPE_MANAGER.getSupportedCurrenciesForPaymentMethod(PaymentMethod.SEPA_DEBIT))
@ -512,13 +505,12 @@ class SubscriptionControllerTest {
assertThat(response.getStatus()).isEqualTo(400);
assertThat(response.readEntity(SubscriptionController.SetSubscriptionLevelErrorResponse.class))
.satisfies(errorResponse -> {
assertThat(errorResponse.errors())
.anySatisfy(error -> {
assertThat(error.type()).isEqualTo(
SubscriptionController.SetSubscriptionLevelErrorResponse.Error.Type.PAYMENT_REQUIRES_ACTION);
});
});
.satisfies(errorResponse ->
assertThat(errorResponse.errors())
.anySatisfy(error ->
assertThat(error.type())
.isEqualTo(
SubscriptionController.SetSubscriptionLevelErrorResponse.Error.Type.PAYMENT_REQUIRES_ACTION)));
}
}
@ -1087,9 +1079,6 @@ class SubscriptionControllerTest {
when(BADGE_TRANSLATOR.translate(any(), eq("GIFT"))).thenReturn(new Badge("GIFT", "gift1", "gift1", "gift1",
List.of("l", "m", "h", "x", "xx", "xxx"), "SVG",
List.of(new BadgeSvg("sl", "sd"), new BadgeSvg("ml", "md"), new BadgeSvg("ll", "ld"))));
when(LEVEL_TRANSLATOR.translate(any(), eq("B1"))).thenReturn("Z1");
when(LEVEL_TRANSLATOR.translate(any(), eq("B2"))).thenReturn("Z2");
when(LEVEL_TRANSLATOR.translate(any(), eq("B3"))).thenReturn("Z3");
GetSubscriptionConfigurationResponse response = RESOURCE_EXTENSION.target("/v1/subscription/configuration")
.request()
@ -1159,44 +1148,41 @@ class SubscriptionControllerTest {
});
assertThat(response.levels()).containsKeys("1", "5", "15", "35", "100").satisfies(levelsMap -> {
assertThat(levelsMap).extractingByKey("1").satisfies(level -> {
assertThat(level.name()).isEqualTo("boost1"); // level name is the same as badge name
assertThat(level).extracting(SubscriptionController.LevelConfiguration::badge).satisfies(badge -> {
assertThat(badge.getId()).isEqualTo("BOOST");
assertThat(badge.getName()).isEqualTo("boost1");
});
});
assertThat(levelsMap).extractingByKey("1").satisfies(
level -> assertThat(level).extracting(SubscriptionController.LevelConfiguration::badge)
.satisfies(badge -> {
assertThat(badge.getId()).isEqualTo("BOOST");
assertThat(badge.getName()).isEqualTo("boost1");
}));
assertThat(levelsMap).extractingByKey("100").satisfies(level -> {
assertThat(level.name()).isEqualTo("gift1"); // level name is the same as badge name
assertThat(level).extracting(SubscriptionController.LevelConfiguration::badge).satisfies(badge -> {
assertThat(badge.getId()).isEqualTo("GIFT");
assertThat(badge.getName()).isEqualTo("gift1");
});
});
assertThat(levelsMap).extractingByKey("100").satisfies(
level -> assertThat(level).extracting(SubscriptionController.LevelConfiguration::badge)
.satisfies(badge -> {
assertThat(badge.getId()).isEqualTo("GIFT");
assertThat(badge.getName()).isEqualTo("gift1");
}));
assertThat(levelsMap).extractingByKey("5").satisfies(level -> {
assertThat(level.name()).isEqualTo("Z1");
assertThat(level).extracting(SubscriptionController.LevelConfiguration::badge).satisfies(badge -> {
assertThat(badge.getId()).isEqualTo("B1");
assertThat(badge.getName()).isEqualTo("name1");
});
assertThat(level).extracting(SubscriptionController.LevelConfiguration::badge)
.satisfies(badge -> {
assertThat(badge.getId()).isEqualTo("B1");
assertThat(badge.getName()).isEqualTo("name1");
});
});
assertThat(levelsMap).extractingByKey("15").satisfies(level -> {
assertThat(level.name()).isEqualTo("Z2");
assertThat(level).extracting(SubscriptionController.LevelConfiguration::badge).satisfies(badge -> {
assertThat(badge.getId()).isEqualTo("B2");
assertThat(badge.getName()).isEqualTo("name2");
});
});
assertThat(levelsMap).extractingByKey("15").satisfies(level ->
assertThat(level).extracting(SubscriptionController.LevelConfiguration::badge)
.satisfies(badge -> {
assertThat(badge.getId()).isEqualTo("B2");
assertThat(badge.getName()).isEqualTo("name2");
}));
assertThat(levelsMap).extractingByKey("35").satisfies(level -> {
assertThat(level.name()).isEqualTo("Z3");
assertThat(level).extracting(SubscriptionController.LevelConfiguration::badge).satisfies(badge -> {
assertThat(badge.getId()).isEqualTo("B3");
assertThat(badge.getName()).isEqualTo("name3");
});
assertThat(level).extracting(SubscriptionController.LevelConfiguration::badge)
.satisfies(badge -> {
assertThat(badge.getId()).isEqualTo("B3");
assertThat(badge.getName()).isEqualTo("name3");
});
});
});
@ -1214,21 +1200,17 @@ class SubscriptionControllerTest {
assertThat(genericResponse.get("levels")).satisfies(levels -> {
final Set<String> oneTimeLevels = Set.of("1", "100");
oneTimeLevels.forEach(oneTimeLevel -> {
assertThat((Map<String, Map<String, Map<String, Object>>>) levels).extractingByKey(oneTimeLevel)
.satisfies(level -> {
assertThat(level.get("badge")).containsKeys("duration");
});
});
oneTimeLevels.forEach(
oneTimeLevel -> assertThat((Map<String, Map<String, Map<String, Object>>>) levels)
.extractingByKey(oneTimeLevel)
.satisfies(level -> assertThat(level.get("badge")).containsKeys("duration")));
((Map<String, ?>) levels).keySet().stream()
.filter(Predicate.not(oneTimeLevels::contains))
.forEach(subscriptionLevel -> {
assertThat((Map<String, Map<String, Map<String, Object>>>) levels).extractingByKey(subscriptionLevel)
.satisfies(level -> {
assertThat(level.get("badge")).doesNotContainKeys("duration");
});
});
.forEach(subscriptionLevel ->
assertThat((Map<String, Map<String, Map<String, Object>>>) levels)
.extractingByKey(subscriptionLevel)
.satisfies(level -> assertThat(level.get("badge")).doesNotContainKeys("duration")));
});
}