Move common subscription management out of controller

This commit is contained in:
Ravi Khadiwala
2024-08-14 10:14:18 -05:00
committed by ravi-signal
parent a8eaf2d0ad
commit 97e566d470
21 changed files with 1242 additions and 948 deletions

View File

@@ -74,10 +74,12 @@ import org.whispersystems.textsecuregcm.controllers.SubscriptionController.GetSu
import org.whispersystems.textsecuregcm.entities.Badge;
import org.whispersystems.textsecuregcm.entities.BadgeSvg;
import org.whispersystems.textsecuregcm.mappers.CompletionExceptionMapper;
import org.whispersystems.textsecuregcm.mappers.SubscriptionExceptionMapper;
import org.whispersystems.textsecuregcm.mappers.SubscriptionProcessorExceptionMapper;
import org.whispersystems.textsecuregcm.storage.IssuedReceiptsManager;
import org.whispersystems.textsecuregcm.storage.OneTimeDonationsManager;
import org.whispersystems.textsecuregcm.storage.SubscriptionManager;
import org.whispersystems.textsecuregcm.storage.Subscriptions;
import org.whispersystems.textsecuregcm.subscriptions.BankMandateTranslator;
import org.whispersystems.textsecuregcm.subscriptions.BraintreeManager;
import org.whispersystems.textsecuregcm.subscriptions.BraintreeManager.PayPalOneTimePaymentApprovalDetails;
@@ -87,10 +89,11 @@ import org.whispersystems.textsecuregcm.subscriptions.PaymentMethod;
import org.whispersystems.textsecuregcm.subscriptions.PaymentStatus;
import org.whispersystems.textsecuregcm.subscriptions.ProcessorCustomer;
import org.whispersystems.textsecuregcm.subscriptions.StripeManager;
import org.whispersystems.textsecuregcm.subscriptions.SubscriptionProcessor;
import org.whispersystems.textsecuregcm.subscriptions.PaymentProvider;
import org.whispersystems.textsecuregcm.subscriptions.SubscriptionProcessorException;
import org.whispersystems.textsecuregcm.subscriptions.SubscriptionProcessorManager;
import org.whispersystems.textsecuregcm.subscriptions.SubscriptionPaymentProcessor;
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
import org.whispersystems.textsecuregcm.util.MockUtils;
import org.whispersystems.textsecuregcm.util.SystemMapper;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
@@ -103,9 +106,11 @@ class SubscriptionControllerTest {
private static final SubscriptionConfiguration SUBSCRIPTION_CONFIG = ConfigHelper.getSubscriptionConfig();
private static final OneTimeDonationConfiguration ONETIME_CONFIG = ConfigHelper.getOneTimeConfig();
private static final SubscriptionManager SUBSCRIPTION_MANAGER = mock(SubscriptionManager.class);
private static final StripeManager STRIPE_MANAGER = mock(StripeManager.class);
private static final BraintreeManager BRAINTREE_MANAGER = mock(BraintreeManager.class);
private static final Subscriptions SUBSCRIPTIONS = mock(Subscriptions.class);
private static final StripeManager STRIPE_MANAGER = MockUtils.buildMock(StripeManager.class, mgr ->
when(mgr.getProvider()).thenReturn(PaymentProvider.STRIPE));
private static final BraintreeManager BRAINTREE_MANAGER = MockUtils.buildMock(BraintreeManager.class, mgr ->
when(mgr.getProvider()).thenReturn(PaymentProvider.BRAINTREE));
private static final PaymentIntent PAYMENT_INTENT = mock(PaymentIntent.class);
private static final ServerZkReceiptOperations ZK_OPS = mock(ServerZkReceiptOperations.class);
private static final IssuedReceiptsManager ISSUED_RECEIPTS_MANAGER = mock(IssuedReceiptsManager.class);
@@ -113,17 +118,19 @@ class SubscriptionControllerTest {
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 static final SubscriptionController SUBSCRIPTION_CONTROLLER = new SubscriptionController(
CLOCK, SUBSCRIPTION_CONFIG, ONETIME_CONFIG, SUBSCRIPTION_MANAGER, STRIPE_MANAGER, BRAINTREE_MANAGER, ZK_OPS,
ISSUED_RECEIPTS_MANAGER, BADGE_TRANSLATOR, LEVEL_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 final static SubscriptionController SUBSCRIPTION_CONTROLLER = new SubscriptionController(CLOCK, SUBSCRIPTION_CONFIG,
ONETIME_CONFIG, new SubscriptionManager(SUBSCRIPTIONS, List.of(STRIPE_MANAGER, BRAINTREE_MANAGER), ZK_OPS,
ISSUED_RECEIPTS_MANAGER), STRIPE_MANAGER, BRAINTREE_MANAGER, BADGE_TRANSLATOR, LEVEL_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()
.addProperty(ServerProperties.UNWRAP_COMPLETION_STAGE_IN_WRITER_ENABLE, Boolean.TRUE)
.addProvider(AuthHelper.getAuthFilter())
.addProvider(CompletionExceptionMapper.class)
.addProvider(SubscriptionProcessorExceptionMapper.class)
.addProvider(new AuthValueFactoryProvider.Binder<>(AuthenticatedDevice.class))
.addProvider(SubscriptionExceptionMapper.class)
.setMapper(SystemMapper.jsonMapper())
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
.addResource(SUBSCRIPTION_CONTROLLER)
@@ -132,11 +139,11 @@ class SubscriptionControllerTest {
@BeforeEach
void setUp() {
reset(CLOCK, SUBSCRIPTION_MANAGER, STRIPE_MANAGER, BRAINTREE_MANAGER, ZK_OPS, ISSUED_RECEIPTS_MANAGER,
reset(CLOCK, SUBSCRIPTIONS, STRIPE_MANAGER, BRAINTREE_MANAGER, ZK_OPS, ISSUED_RECEIPTS_MANAGER,
BADGE_TRANSLATOR, LEVEL_TRANSLATOR);
when(STRIPE_MANAGER.getProcessor()).thenReturn(SubscriptionProcessor.STRIPE);
when(BRAINTREE_MANAGER.getProcessor()).thenReturn(SubscriptionProcessor.BRAINTREE);
when(STRIPE_MANAGER.getProvider()).thenReturn(PaymentProvider.STRIPE);
when(BRAINTREE_MANAGER.getProvider()).thenReturn(PaymentProvider.BRAINTREE);
List.of(STRIPE_MANAGER, BRAINTREE_MANAGER)
.forEach(manager -> {
@@ -328,7 +335,7 @@ class SubscriptionControllerTest {
when(BRAINTREE_MANAGER.captureOneTimePayment(anyString(), anyString(), anyString(), anyString(), anyLong(),
anyLong(), any()))
.thenReturn(CompletableFuture.failedFuture(new SubscriptionProcessorException(SubscriptionProcessor.BRAINTREE,
.thenReturn(CompletableFuture.failedFuture(new SubscriptionProcessorException(PaymentProvider.BRAINTREE,
new ChargeFailure("2046", "Declined", null, null, null))));
final Response response = RESOURCE_EXTENSION.target("/v1/subscription/boost/paypal/confirm")
@@ -373,26 +380,26 @@ class SubscriptionControllerTest {
Arrays.fill(subscriberUserAndKey, (byte) 1);
subscriberId = Base64.getEncoder().encodeToString(subscriberUserAndKey);
final ProcessorCustomer processorCustomer = new ProcessorCustomer("testCustomerId", SubscriptionProcessor.STRIPE);
final ProcessorCustomer processorCustomer = new ProcessorCustomer("testCustomerId", PaymentProvider.STRIPE);
final Map<String, AttributeValue> dynamoItem = Map.of(SubscriptionManager.KEY_PASSWORD, b(new byte[16]),
SubscriptionManager.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
SubscriptionManager.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond()),
SubscriptionManager.KEY_PROCESSOR_ID_CUSTOMER_ID, b(processorCustomer.toDynamoBytes())
final Map<String, AttributeValue> dynamoItem = Map.of(Subscriptions.KEY_PASSWORD, b(new byte[16]),
Subscriptions.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
Subscriptions.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond()),
Subscriptions.KEY_PROCESSOR_ID_CUSTOMER_ID, b(processorCustomer.toDynamoBytes())
);
final SubscriptionManager.Record record = SubscriptionManager.Record.from(
final Subscriptions.Record record = Subscriptions.Record.from(
Arrays.copyOfRange(subscriberUserAndKey, 0, 16), dynamoItem);
when(SUBSCRIPTION_MANAGER.get(eq(Arrays.copyOfRange(subscriberUserAndKey, 0, 16)), any()))
.thenReturn(CompletableFuture.completedFuture(SubscriptionManager.GetResult.found(record)));
when(SUBSCRIPTIONS.get(eq(Arrays.copyOfRange(subscriberUserAndKey, 0, 16)), any()))
.thenReturn(CompletableFuture.completedFuture(Subscriptions.GetResult.found(record)));
when(SUBSCRIPTION_MANAGER.subscriptionCreated(any(), any(), any(), anyLong()))
when(SUBSCRIPTIONS.subscriptionCreated(any(), any(), any(), anyLong()))
.thenReturn(CompletableFuture.completedFuture(null));
}
@Test
void createSubscriptionSuccess() {
when(STRIPE_MANAGER.createSubscription(any(), any(), anyLong(), anyLong()))
.thenReturn(CompletableFuture.completedFuture(mock(SubscriptionProcessorManager.SubscriptionId.class)));
.thenReturn(CompletableFuture.completedFuture(mock(SubscriptionPaymentProcessor.SubscriptionId.class)));
final String level = String.valueOf(levelId);
final String idempotencyKey = UUID.randomUUID().toString();
@@ -407,7 +414,7 @@ class SubscriptionControllerTest {
@Test
void createSubscriptionProcessorDeclined() {
when(STRIPE_MANAGER.createSubscription(any(), any(), anyLong(), anyLong()))
.thenReturn(CompletableFuture.failedFuture(new SubscriptionProcessorException(SubscriptionProcessor.STRIPE,
.thenReturn(CompletableFuture.failedFuture(new SubscriptionProcessorException(PaymentProvider.STRIPE,
new ChargeFailure("card_declined", "Insufficient funds", null, null, null))));
final String level = String.valueOf(levelId);
@@ -434,15 +441,15 @@ class SubscriptionControllerTest {
Arrays.fill(subscriberUserAndKey, (byte) 1);
subscriberId = Base64.getEncoder().encodeToString(subscriberUserAndKey);
final Map<String, AttributeValue> dynamoItem = Map.of(SubscriptionManager.KEY_PASSWORD, b(new byte[16]),
SubscriptionManager.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
SubscriptionManager.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond())
final Map<String, AttributeValue> dynamoItem = Map.of(Subscriptions.KEY_PASSWORD, b(new byte[16]),
Subscriptions.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
Subscriptions.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond())
// missing processor:customer field
);
final SubscriptionManager.Record record = SubscriptionManager.Record.from(
final Subscriptions.Record record = Subscriptions.Record.from(
Arrays.copyOfRange(subscriberUserAndKey, 0, 16), dynamoItem);
when(SUBSCRIPTION_MANAGER.get(eq(Arrays.copyOfRange(subscriberUserAndKey, 0, 16)), any()))
.thenReturn(CompletableFuture.completedFuture(SubscriptionManager.GetResult.found(record)));
when(SUBSCRIPTIONS.get(eq(Arrays.copyOfRange(subscriberUserAndKey, 0, 16)), any()))
.thenReturn(CompletableFuture.completedFuture(Subscriptions.GetResult.found(record)));
final String level = String.valueOf(levelId);
final String idempotencyKey = UUID.randomUUID().toString();
@@ -490,16 +497,16 @@ class SubscriptionControllerTest {
Arrays.fill(subscriberUserAndKey, (byte) 1);
final String subscriberId = Base64.getEncoder().encodeToString(subscriberUserAndKey);
when(SUBSCRIPTION_MANAGER.get(any(), any())).thenReturn(CompletableFuture.completedFuture(
SubscriptionManager.GetResult.NOT_STORED));
when(SUBSCRIPTIONS.get(any(), any())).thenReturn(CompletableFuture.completedFuture(
Subscriptions.GetResult.NOT_STORED));
final Map<String, AttributeValue> dynamoItem = Map.of(SubscriptionManager.KEY_PASSWORD, b(new byte[16]),
SubscriptionManager.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
SubscriptionManager.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond())
final Map<String, AttributeValue> dynamoItem = Map.of(Subscriptions.KEY_PASSWORD, b(new byte[16]),
Subscriptions.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
Subscriptions.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond())
);
final SubscriptionManager.Record record = SubscriptionManager.Record.from(
final Subscriptions.Record record = Subscriptions.Record.from(
Arrays.copyOfRange(subscriberUserAndKey, 0, 16), dynamoItem);
when(SUBSCRIPTION_MANAGER.create(any(), any(), any())).thenReturn(CompletableFuture.completedFuture(record));
when(SUBSCRIPTIONS.create(any(), any(), any())).thenReturn(CompletableFuture.completedFuture(record));
final Response createResponse = RESOURCE_EXTENSION.target(String.format("/v1/subscription/%s", subscriberId))
.request()
@@ -507,9 +514,9 @@ class SubscriptionControllerTest {
assertThat(createResponse.getStatus()).isEqualTo(200);
// creating should be idempotent
when(SUBSCRIPTION_MANAGER.get(any(), any())).thenReturn(CompletableFuture.completedFuture(
SubscriptionManager.GetResult.found(record)));
when(SUBSCRIPTION_MANAGER.accessedAt(any(), any())).thenReturn(CompletableFuture.completedFuture(null));
when(SUBSCRIPTIONS.get(any(), any())).thenReturn(CompletableFuture.completedFuture(
Subscriptions.GetResult.found(record)));
when(SUBSCRIPTIONS.accessedAt(any(), any())).thenReturn(CompletableFuture.completedFuture(null));
final Response idempotentCreateResponse = RESOURCE_EXTENSION.target(
String.format("/v1/subscription/%s", subscriberId))
@@ -519,9 +526,9 @@ class SubscriptionControllerTest {
// when the manager returns `null`, it means there was a password mismatch from the storage layer `create`.
// this could happen if there is a race between two concurrent `create` requests for the same user ID
when(SUBSCRIPTION_MANAGER.get(any(), any())).thenReturn(CompletableFuture.completedFuture(
SubscriptionManager.GetResult.NOT_STORED));
when(SUBSCRIPTION_MANAGER.create(any(), any(), any())).thenReturn(CompletableFuture.completedFuture(null));
when(SUBSCRIPTIONS.get(any(), any())).thenReturn(CompletableFuture.completedFuture(
Subscriptions.GetResult.NOT_STORED));
when(SUBSCRIPTIONS.create(any(), any(), any())).thenReturn(CompletableFuture.completedFuture(null));
final Response managerCreateNullResponse = RESOURCE_EXTENSION.target(
String.format("/v1/subscription/%s", subscriberId))
@@ -535,8 +542,8 @@ class SubscriptionControllerTest {
final String mismatchedSubscriberId = Base64.getEncoder().encodeToString(subscriberUserAndMismatchedKey);
// a password mismatch for an existing record
when(SUBSCRIPTION_MANAGER.get(any(), any())).thenReturn(CompletableFuture.completedFuture(
SubscriptionManager.GetResult.PASSWORD_MISMATCH));
when(SUBSCRIPTIONS.get(any(), any())).thenReturn(CompletableFuture.completedFuture(
Subscriptions.GetResult.PASSWORD_MISMATCH));
final Response passwordMismatchResponse = RESOURCE_EXTENSION.target(
String.format("/v1/subscription/%s", mismatchedSubscriberId))
@@ -565,16 +572,16 @@ class SubscriptionControllerTest {
final String subscriberId = Base64.getEncoder().encodeToString(subscriberUserAndKey);
when(CLOCK.instant()).thenReturn(Instant.now());
when(SUBSCRIPTION_MANAGER.get(any(), any())).thenReturn(CompletableFuture.completedFuture(
SubscriptionManager.GetResult.NOT_STORED));
when(SUBSCRIPTIONS.get(any(), any())).thenReturn(CompletableFuture.completedFuture(
Subscriptions.GetResult.NOT_STORED));
final Map<String, AttributeValue> dynamoItem = Map.of(SubscriptionManager.KEY_PASSWORD, b(new byte[16]),
SubscriptionManager.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
SubscriptionManager.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond())
final Map<String, AttributeValue> dynamoItem = Map.of(Subscriptions.KEY_PASSWORD, b(new byte[16]),
Subscriptions.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
Subscriptions.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond())
);
final SubscriptionManager.Record record = SubscriptionManager.Record.from(
final Subscriptions.Record record = Subscriptions.Record.from(
Arrays.copyOfRange(subscriberUserAndKey, 0, 16), dynamoItem);
when(SUBSCRIPTION_MANAGER.create(any(), any(), any(Instant.class)))
when(SUBSCRIPTIONS.create(any(), any(), any(Instant.class)))
.thenReturn(CompletableFuture.completedFuture(record));
final Response createSubscriberResponse = RESOURCE_EXTENSION
@@ -584,22 +591,22 @@ class SubscriptionControllerTest {
assertThat(createSubscriberResponse.getStatus()).isEqualTo(200);
when(SUBSCRIPTION_MANAGER.get(any(), any()))
.thenReturn(CompletableFuture.completedFuture(SubscriptionManager.GetResult.found(record)));
when(SUBSCRIPTIONS.get(any(), any()))
.thenReturn(CompletableFuture.completedFuture(Subscriptions.GetResult.found(record)));
final String customerId = "some-customer-id";
final ProcessorCustomer customer = new ProcessorCustomer(
customerId, SubscriptionProcessor.STRIPE);
customerId, PaymentProvider.STRIPE);
when(STRIPE_MANAGER.createCustomer(any(), any()))
.thenReturn(CompletableFuture.completedFuture(customer));
final Map<String, AttributeValue> dynamoItemWithProcessorCustomer = new HashMap<>(dynamoItem);
dynamoItemWithProcessorCustomer.put(SubscriptionManager.KEY_PROCESSOR_ID_CUSTOMER_ID,
b(new ProcessorCustomer(customerId, SubscriptionProcessor.STRIPE).toDynamoBytes()));
final SubscriptionManager.Record recordWithCustomerId = SubscriptionManager.Record.from(record.user,
dynamoItemWithProcessorCustomer.put(Subscriptions.KEY_PROCESSOR_ID_CUSTOMER_ID,
b(new ProcessorCustomer(customerId, PaymentProvider.STRIPE).toDynamoBytes()));
final Subscriptions.Record recordWithCustomerId = Subscriptions.Record.from(record.user,
dynamoItemWithProcessorCustomer);
when(SUBSCRIPTION_MANAGER.setProcessorAndCustomerId(any(SubscriptionManager.Record.class), any(),
when(SUBSCRIPTIONS.setProcessorAndCustomerId(any(Subscriptions.Record.class), any(),
any(Instant.class)))
.thenReturn(CompletableFuture.completedFuture(recordWithCustomerId));
@@ -613,7 +620,7 @@ class SubscriptionControllerTest {
.post(Entity.json(""))
.readEntity(SubscriptionController.CreatePaymentMethodResponse.class);
assertThat(createPaymentMethodResponse.processor()).isEqualTo(SubscriptionProcessor.STRIPE);
assertThat(createPaymentMethodResponse.processor()).isEqualTo(PaymentProvider.STRIPE);
assertThat(createPaymentMethodResponse.clientSecret()).isEqualTo(clientSecret);
}
@@ -625,19 +632,19 @@ class SubscriptionControllerTest {
Arrays.fill(subscriberUserAndKey, (byte) 1);
final String subscriberId = Base64.getEncoder().encodeToString(subscriberUserAndKey);
final Map<String, AttributeValue> dynamoItem = Map.of(SubscriptionManager.KEY_PASSWORD, b(new byte[16]),
SubscriptionManager.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
SubscriptionManager.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond())
final Map<String, AttributeValue> dynamoItem = Map.of(Subscriptions.KEY_PASSWORD, b(new byte[16]),
Subscriptions.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
Subscriptions.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond())
);
final SubscriptionManager.Record record = SubscriptionManager.Record.from(
final Subscriptions.Record record = Subscriptions.Record.from(
Arrays.copyOfRange(subscriberUserAndKey, 0, 16), dynamoItem);
when(SUBSCRIPTION_MANAGER.create(any(), any(), any(Instant.class)))
when(SUBSCRIPTIONS.create(any(), any(), any(Instant.class)))
.thenReturn(CompletableFuture.completedFuture(record));
// set up mocks
when(CLOCK.instant()).thenReturn(Instant.now());
when(SUBSCRIPTION_MANAGER.get(any(), any()))
.thenReturn(CompletableFuture.completedFuture(SubscriptionManager.GetResult.found(record)));
when(SUBSCRIPTIONS.get(any(), any()))
.thenReturn(CompletableFuture.completedFuture(Subscriptions.GetResult.found(record)));
final Response response = RESOURCE_EXTENSION
.target(String.format("/v1/subscription/%s/level/%d/%s/%s", subscriberId, 5, "usd", "abcd"))
@@ -661,26 +668,26 @@ class SubscriptionControllerTest {
final String subscriberId = Base64.getEncoder().encodeToString(subscriberUserAndKey);
final String customerId = "customer";
final Map<String, AttributeValue> dynamoItem = Map.of(SubscriptionManager.KEY_PASSWORD, b(new byte[16]),
SubscriptionManager.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
SubscriptionManager.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond()),
SubscriptionManager.KEY_PROCESSOR_ID_CUSTOMER_ID,
b(new ProcessorCustomer(customerId, SubscriptionProcessor.BRAINTREE).toDynamoBytes())
final Map<String, AttributeValue> dynamoItem = Map.of(Subscriptions.KEY_PASSWORD, b(new byte[16]),
Subscriptions.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
Subscriptions.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond()),
Subscriptions.KEY_PROCESSOR_ID_CUSTOMER_ID,
b(new ProcessorCustomer(customerId, PaymentProvider.BRAINTREE).toDynamoBytes())
);
final SubscriptionManager.Record record = SubscriptionManager.Record.from(
final Subscriptions.Record record = Subscriptions.Record.from(
Arrays.copyOfRange(subscriberUserAndKey, 0, 16), dynamoItem);
when(SUBSCRIPTION_MANAGER.create(any(), any(), any(Instant.class)))
when(SUBSCRIPTIONS.create(any(), any(), any(Instant.class)))
.thenReturn(CompletableFuture.completedFuture(record));
// set up mocks
when(CLOCK.instant()).thenReturn(Instant.now());
when(SUBSCRIPTION_MANAGER.get(any(), any()))
.thenReturn(CompletableFuture.completedFuture(SubscriptionManager.GetResult.found(record)));
when(SUBSCRIPTIONS.get(any(), any()))
.thenReturn(CompletableFuture.completedFuture(Subscriptions.GetResult.found(record)));
when(BRAINTREE_MANAGER.createSubscription(any(), any(), anyLong(), anyLong()))
.thenReturn(CompletableFuture.completedFuture(new SubscriptionProcessorManager.SubscriptionId(
.thenReturn(CompletableFuture.completedFuture(new SubscriptionPaymentProcessor.SubscriptionId(
"subscription")));
when(SUBSCRIPTION_MANAGER.subscriptionCreated(any(), any(), any(), anyLong()))
when(SUBSCRIPTIONS.subscriptionCreated(any(), any(), any(), anyLong()))
.thenReturn(CompletableFuture.completedFuture(null));
final Response response = RESOURCE_EXTENSION
@@ -710,36 +717,36 @@ class SubscriptionControllerTest {
final String customerId = "customer";
final String existingSubscriptionId = "existingSubscription";
final Map<String, AttributeValue> dynamoItem = Map.of(SubscriptionManager.KEY_PASSWORD, b(new byte[16]),
SubscriptionManager.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
SubscriptionManager.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond()),
SubscriptionManager.KEY_PROCESSOR_ID_CUSTOMER_ID,
b(new ProcessorCustomer(customerId, SubscriptionProcessor.BRAINTREE).toDynamoBytes()),
SubscriptionManager.KEY_SUBSCRIPTION_ID, s(existingSubscriptionId)
final Map<String, AttributeValue> dynamoItem = Map.of(Subscriptions.KEY_PASSWORD, b(new byte[16]),
Subscriptions.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
Subscriptions.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond()),
Subscriptions.KEY_PROCESSOR_ID_CUSTOMER_ID,
b(new ProcessorCustomer(customerId, PaymentProvider.BRAINTREE).toDynamoBytes()),
Subscriptions.KEY_SUBSCRIPTION_ID, s(existingSubscriptionId)
);
final SubscriptionManager.Record record = SubscriptionManager.Record.from(
final Subscriptions.Record record = Subscriptions.Record.from(
Arrays.copyOfRange(subscriberUserAndKey, 0, 16), dynamoItem);
when(SUBSCRIPTION_MANAGER.create(any(), any(), any(Instant.class)))
when(SUBSCRIPTIONS.create(any(), any(), any(Instant.class)))
.thenReturn(CompletableFuture.completedFuture(record));
// set up mocks
when(CLOCK.instant()).thenReturn(Instant.now());
when(SUBSCRIPTION_MANAGER.get(any(), any()))
.thenReturn(CompletableFuture.completedFuture(SubscriptionManager.GetResult.found(record)));
when(SUBSCRIPTIONS.get(any(), any()))
.thenReturn(CompletableFuture.completedFuture(Subscriptions.GetResult.found(record)));
final Object subscriptionObj = new Object();
when(BRAINTREE_MANAGER.getSubscription(any()))
.thenReturn(CompletableFuture.completedFuture(subscriptionObj));
when(BRAINTREE_MANAGER.getLevelAndCurrencyForSubscription(subscriptionObj))
.thenReturn(CompletableFuture.completedFuture(
new SubscriptionProcessorManager.LevelAndCurrency(existingLevel, existingCurrency)));
new SubscriptionPaymentProcessor.LevelAndCurrency(existingLevel, existingCurrency)));
final String updatedSubscriptionId = "updatedSubscriptionId";
if (expectUpdate) {
when(BRAINTREE_MANAGER.updateSubscription(any(), any(), anyLong(), anyString()))
.thenReturn(CompletableFuture.completedFuture(new SubscriptionProcessorManager.SubscriptionId(
.thenReturn(CompletableFuture.completedFuture(new SubscriptionPaymentProcessor.SubscriptionId(
updatedSubscriptionId)));
when(SUBSCRIPTION_MANAGER.subscriptionLevelChanged(any(), any(), anyLong(), anyString()))
when(SUBSCRIPTIONS.subscriptionLevelChanged(any(), any(), anyLong(), anyString()))
.thenReturn(CompletableFuture.completedFuture(null));
}
@@ -755,7 +762,7 @@ class SubscriptionControllerTest {
if (expectUpdate) {
verify(BRAINTREE_MANAGER).updateSubscription(any(), any(), eq(requestLevel), eq(idempotencyKey));
verify(SUBSCRIPTION_MANAGER).subscriptionLevelChanged(any(), any(), eq(requestLevel), eq(updatedSubscriptionId));
verify(SUBSCRIPTIONS).subscriptionLevelChanged(any(), any(), eq(requestLevel), eq(updatedSubscriptionId));
}
verifyNoMoreInteractions(BRAINTREE_MANAGER);
@@ -787,27 +794,27 @@ class SubscriptionControllerTest {
final String customerId = "customer";
final String existingSubscriptionId = "existingSubscription";
final Map<String, AttributeValue> dynamoItem = Map.of(SubscriptionManager.KEY_PASSWORD, b(new byte[16]),
SubscriptionManager.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
SubscriptionManager.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond()),
SubscriptionManager.KEY_PROCESSOR_ID_CUSTOMER_ID,
b(new ProcessorCustomer(customerId, SubscriptionProcessor.BRAINTREE).toDynamoBytes()),
SubscriptionManager.KEY_SUBSCRIPTION_ID, s(existingSubscriptionId));
final SubscriptionManager.Record record = SubscriptionManager.Record.from(
final Map<String, AttributeValue> dynamoItem = Map.of(Subscriptions.KEY_PASSWORD, b(new byte[16]),
Subscriptions.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
Subscriptions.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond()),
Subscriptions.KEY_PROCESSOR_ID_CUSTOMER_ID,
b(new ProcessorCustomer(customerId, PaymentProvider.BRAINTREE).toDynamoBytes()),
Subscriptions.KEY_SUBSCRIPTION_ID, s(existingSubscriptionId));
final Subscriptions.Record record = Subscriptions.Record.from(
Arrays.copyOfRange(subscriberUserAndKey, 0, 16), dynamoItem);
when(SUBSCRIPTION_MANAGER.create(any(), any(), any(Instant.class)))
when(SUBSCRIPTIONS.create(any(), any(), any(Instant.class)))
.thenReturn(CompletableFuture.completedFuture(record));
when(CLOCK.instant()).thenReturn(Instant.now());
when(SUBSCRIPTION_MANAGER.get(any(), any()))
.thenReturn(CompletableFuture.completedFuture(SubscriptionManager.GetResult.found(record)));
when(SUBSCRIPTIONS.get(any(), any()))
.thenReturn(CompletableFuture.completedFuture(Subscriptions.GetResult.found(record)));
final Object subscriptionObj = new Object();
when(BRAINTREE_MANAGER.getSubscription(any()))
.thenReturn(CompletableFuture.completedFuture(subscriptionObj));
when(BRAINTREE_MANAGER.getLevelAndCurrencyForSubscription(subscriptionObj))
.thenReturn(CompletableFuture.completedFuture(
new SubscriptionProcessorManager.LevelAndCurrency(201, "usd")));
new SubscriptionPaymentProcessor.LevelAndCurrency(201, "usd")));
// Try to change from a backup subscription (201) to a donation subscription (5)
final Response response = RESOURCE_EXTENSION
@@ -833,13 +840,13 @@ class SubscriptionControllerTest {
final String customerId = "customer";
final String subscriptionId = "subscriptionId";
final Map<String, AttributeValue> dynamoItem = Map.of(SubscriptionManager.KEY_PASSWORD, b(new byte[16]),
SubscriptionManager.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
SubscriptionManager.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond()),
SubscriptionManager.KEY_PROCESSOR_ID_CUSTOMER_ID,
b(new ProcessorCustomer(customerId, SubscriptionProcessor.BRAINTREE).toDynamoBytes()),
SubscriptionManager.KEY_SUBSCRIPTION_ID, s(subscriptionId));
final SubscriptionManager.Record record = SubscriptionManager.Record.from(
final Map<String, AttributeValue> dynamoItem = Map.of(Subscriptions.KEY_PASSWORD, b(new byte[16]),
Subscriptions.KEY_CREATED_AT, n(Instant.now().getEpochSecond()),
Subscriptions.KEY_ACCESSED_AT, n(Instant.now().getEpochSecond()),
Subscriptions.KEY_PROCESSOR_ID_CUSTOMER_ID,
b(new ProcessorCustomer(customerId, PaymentProvider.BRAINTREE).toDynamoBytes()),
Subscriptions.KEY_SUBSCRIPTION_ID, s(subscriptionId));
final Subscriptions.Record record = Subscriptions.Record.from(
Arrays.copyOfRange(subscriberUserAndKey, 0, 16), dynamoItem);
final ReceiptCredentialRequest receiptRequest = new ClientZkReceiptOperations(
ServerSecretParams.generate().getPublicParams()).createReceiptCredentialRequestContext(
@@ -847,15 +854,15 @@ class SubscriptionControllerTest {
final ReceiptCredentialResponse receiptCredentialResponse = mock(ReceiptCredentialResponse.class);
when(CLOCK.instant()).thenReturn(Instant.now());
when(SUBSCRIPTION_MANAGER.get(any(), any()))
.thenReturn(CompletableFuture.completedFuture(SubscriptionManager.GetResult.found(record)));
when(SUBSCRIPTIONS.get(any(), any()))
.thenReturn(CompletableFuture.completedFuture(Subscriptions.GetResult.found(record)));
when(BRAINTREE_MANAGER.getReceiptItem(subscriptionId)).thenReturn(
CompletableFuture.completedFuture(new SubscriptionProcessorManager.ReceiptItem(
CompletableFuture.completedFuture(new SubscriptionPaymentProcessor.ReceiptItem(
"itemId",
Instant.ofEpochSecond(10).plus(Duration.ofDays(1)),
level
)));
when(ISSUED_RECEIPTS_MANAGER.recordIssuance(eq("itemId"), eq(SubscriptionProcessor.BRAINTREE), eq(receiptRequest), any()))
when(ISSUED_RECEIPTS_MANAGER.recordIssuance(eq("itemId"), eq(PaymentProvider.BRAINTREE), eq(receiptRequest), any()))
.thenReturn(CompletableFuture.completedFuture(null));
when(ZK_OPS.issueReceiptCredential(any(), anyLong(), eq(level))).thenReturn(receiptCredentialResponse);
when(receiptCredentialResponse.serialize()).thenReturn(new byte[0]);

View File

@@ -330,21 +330,21 @@ public final class DynamoDbExtensionSchema {
List.of()),
SUBSCRIPTIONS("subscriptions_test",
SubscriptionManager.KEY_USER,
Subscriptions.KEY_USER,
null,
List.of(
AttributeDefinition.builder()
.attributeName(SubscriptionManager.KEY_USER)
.attributeName(Subscriptions.KEY_USER)
.attributeType(ScalarAttributeType.B)
.build(),
AttributeDefinition.builder()
.attributeName(SubscriptionManager.KEY_PROCESSOR_ID_CUSTOMER_ID)
.attributeName(Subscriptions.KEY_PROCESSOR_ID_CUSTOMER_ID)
.attributeType(ScalarAttributeType.B)
.build()),
List.of(GlobalSecondaryIndex.builder()
.indexName(SubscriptionManager.INDEX_NAME)
.indexName(Subscriptions.INDEX_NAME)
.keySchema(KeySchemaElement.builder()
.attributeName(SubscriptionManager.KEY_PROCESSOR_ID_CUSTOMER_ID)
.attributeName(Subscriptions.KEY_PROCESSOR_ID_CUSTOMER_ID)
.keyType(KeyType.HASH)
.build())
.projection(Projection.builder()

View File

@@ -19,7 +19,7 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialRequest;
import org.whispersystems.textsecuregcm.storage.DynamoDbExtensionSchema.Tables;
import org.whispersystems.textsecuregcm.subscriptions.SubscriptionProcessor;
import org.whispersystems.textsecuregcm.subscriptions.PaymentProvider;
import org.whispersystems.textsecuregcm.util.TestRandomUtil;
class IssuedReceiptsManagerTest {
@@ -47,19 +47,19 @@ class IssuedReceiptsManagerTest {
Instant now = Instant.ofEpochSecond(NOW_EPOCH_SECONDS);
byte[] request1 = TestRandomUtil.nextBytes(20);
when(receiptCredentialRequest.serialize()).thenReturn(request1);
CompletableFuture<Void> future = issuedReceiptsManager.recordIssuance("item-1", SubscriptionProcessor.STRIPE,
CompletableFuture<Void> future = issuedReceiptsManager.recordIssuance("item-1", PaymentProvider.STRIPE,
receiptCredentialRequest, now);
assertThat(future).succeedsWithin(Duration.ofSeconds(3));
// same request should succeed
future = issuedReceiptsManager.recordIssuance("item-1", SubscriptionProcessor.STRIPE, receiptCredentialRequest,
future = issuedReceiptsManager.recordIssuance("item-1", PaymentProvider.STRIPE, receiptCredentialRequest,
now);
assertThat(future).succeedsWithin(Duration.ofSeconds(3));
// same item with new request should fail
byte[] request2 = TestRandomUtil.nextBytes(20);
when(receiptCredentialRequest.serialize()).thenReturn(request2);
future = issuedReceiptsManager.recordIssuance("item-1", SubscriptionProcessor.STRIPE, receiptCredentialRequest,
future = issuedReceiptsManager.recordIssuance("item-1", PaymentProvider.STRIPE, receiptCredentialRequest,
now);
assertThat(future).failsWithin(Duration.ofSeconds(3)).
withThrowableOfType(Throwable.class).
@@ -70,7 +70,7 @@ class IssuedReceiptsManagerTest {
"status 409"));
// different item with new request should be okay though
future = issuedReceiptsManager.recordIssuance("item-2", SubscriptionProcessor.STRIPE, receiptCredentialRequest,
future = issuedReceiptsManager.recordIssuance("item-2", PaymentProvider.STRIPE, receiptCredentialRequest,
now);
assertThat(future).succeedsWithin(Duration.ofSeconds(3));
}

View File

@@ -6,9 +6,9 @@
package org.whispersystems.textsecuregcm.storage;
import static org.assertj.core.api.Assertions.assertThat;
import static org.whispersystems.textsecuregcm.storage.SubscriptionManager.GetResult.Type.FOUND;
import static org.whispersystems.textsecuregcm.storage.SubscriptionManager.GetResult.Type.NOT_STORED;
import static org.whispersystems.textsecuregcm.storage.SubscriptionManager.GetResult.Type.PASSWORD_MISMATCH;
import static org.whispersystems.textsecuregcm.storage.Subscriptions.GetResult.Type.FOUND;
import static org.whispersystems.textsecuregcm.storage.Subscriptions.GetResult.Type.NOT_STORED;
import static org.whispersystems.textsecuregcm.storage.Subscriptions.GetResult.Type.PASSWORD_MISMATCH;
import java.security.SecureRandom;
import java.time.Duration;
@@ -25,13 +25,13 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.whispersystems.textsecuregcm.storage.DynamoDbExtensionSchema.Tables;
import org.whispersystems.textsecuregcm.storage.SubscriptionManager.GetResult;
import org.whispersystems.textsecuregcm.storage.SubscriptionManager.Record;
import org.whispersystems.textsecuregcm.storage.Subscriptions.GetResult;
import org.whispersystems.textsecuregcm.storage.Subscriptions.Record;
import org.whispersystems.textsecuregcm.subscriptions.ProcessorCustomer;
import org.whispersystems.textsecuregcm.subscriptions.SubscriptionProcessor;
import org.whispersystems.textsecuregcm.subscriptions.PaymentProvider;
import org.whispersystems.textsecuregcm.util.TestRandomUtil;
class SubscriptionManagerTest {
class SubscriptionsTest {
private static final long NOW_EPOCH_SECONDS = 1_500_000_000L;
private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(3);
@@ -44,7 +44,7 @@ class SubscriptionManagerTest {
byte[] password;
String customer;
Instant created;
SubscriptionManager subscriptionManager;
Subscriptions subscriptions;
@BeforeEach
void beforeEach() {
@@ -52,7 +52,7 @@ class SubscriptionManagerTest {
password = TestRandomUtil.nextBytes(16);
customer = Base64.getEncoder().encodeToString(TestRandomUtil.nextBytes(16));
created = Instant.ofEpochSecond(NOW_EPOCH_SECONDS);
subscriptionManager = new SubscriptionManager(
subscriptions = new Subscriptions(
Tables.SUBSCRIPTIONS.tableName(), DYNAMO_DB_EXTENSION.getDynamoDbAsyncClient());
}
@@ -63,29 +63,29 @@ class SubscriptionManagerTest {
Instant created1 = Instant.ofEpochSecond(NOW_EPOCH_SECONDS);
Instant created2 = Instant.ofEpochSecond(NOW_EPOCH_SECONDS + 1);
CompletableFuture<GetResult> getFuture = subscriptionManager.get(user, password1);
CompletableFuture<GetResult> getFuture = subscriptions.get(user, password1);
assertThat(getFuture).succeedsWithin(DEFAULT_TIMEOUT).satisfies(getResult -> {
assertThat(getResult.type).isEqualTo(NOT_STORED);
assertThat(getResult.record).isNull();
});
getFuture = subscriptionManager.get(user, password2);
getFuture = subscriptions.get(user, password2);
assertThat(getFuture).succeedsWithin(DEFAULT_TIMEOUT).satisfies(getResult -> {
assertThat(getResult.type).isEqualTo(NOT_STORED);
assertThat(getResult.record).isNull();
});
CompletableFuture<SubscriptionManager.Record> createFuture =
subscriptionManager.create(user, password1, created1);
CompletableFuture<Subscriptions.Record> createFuture =
subscriptions.create(user, password1, created1);
Consumer<Record> recordRequirements = checkFreshlyCreatedRecord(user, password1, created1);
assertThat(createFuture).succeedsWithin(DEFAULT_TIMEOUT).satisfies(recordRequirements);
// password check fails so this should return null
createFuture = subscriptionManager.create(user, password2, created2);
createFuture = subscriptions.create(user, password2, created2);
assertThat(createFuture).succeedsWithin(DEFAULT_TIMEOUT).isNull();
// password check matches, but the record already exists so nothing should get updated
createFuture = subscriptionManager.create(user, password1, created2);
createFuture = subscriptions.create(user, password1, created2);
assertThat(createFuture).succeedsWithin(DEFAULT_TIMEOUT).satisfies(recordRequirements);
}
@@ -93,20 +93,20 @@ class SubscriptionManagerTest {
void testGet() {
byte[] wrongUser = TestRandomUtil.nextBytes(16);
byte[] wrongPassword = TestRandomUtil.nextBytes(16);
assertThat(subscriptionManager.create(user, password, created)).succeedsWithin(DEFAULT_TIMEOUT);
assertThat(subscriptions.create(user, password, created)).succeedsWithin(DEFAULT_TIMEOUT);
assertThat(subscriptionManager.get(user, password)).succeedsWithin(DEFAULT_TIMEOUT).satisfies(getResult -> {
assertThat(subscriptions.get(user, password)).succeedsWithin(DEFAULT_TIMEOUT).satisfies(getResult -> {
assertThat(getResult.type).isEqualTo(FOUND);
assertThat(getResult.record).isNotNull().satisfies(checkFreshlyCreatedRecord(user, password, created));
});
assertThat(subscriptionManager.get(user, wrongPassword)).succeedsWithin(DEFAULT_TIMEOUT)
assertThat(subscriptions.get(user, wrongPassword)).succeedsWithin(DEFAULT_TIMEOUT)
.satisfies(getResult -> {
assertThat(getResult.type).isEqualTo(PASSWORD_MISMATCH);
assertThat(getResult.record).isNull();
});
assertThat(subscriptionManager.get(wrongUser, password)).succeedsWithin(DEFAULT_TIMEOUT)
assertThat(subscriptions.get(wrongUser, password)).succeedsWithin(DEFAULT_TIMEOUT)
.satisfies(getResult -> {
assertThat(getResult.type).isEqualTo(NOT_STORED);
assertThat(getResult.record).isNull();
@@ -116,25 +116,25 @@ class SubscriptionManagerTest {
@Test
void testSetCustomerIdAndProcessor() throws Exception {
Instant subscriptionUpdated = Instant.ofEpochSecond(NOW_EPOCH_SECONDS + 1);
assertThat(subscriptionManager.create(user, password, created)).succeedsWithin(DEFAULT_TIMEOUT);
assertThat(subscriptions.create(user, password, created)).succeedsWithin(DEFAULT_TIMEOUT);
final CompletableFuture<GetResult> getUser = subscriptionManager.get(user, password);
final CompletableFuture<GetResult> getUser = subscriptions.get(user, password);
assertThat(getUser).succeedsWithin(DEFAULT_TIMEOUT);
final Record userRecord = getUser.get().record;
assertThat(subscriptionManager.setProcessorAndCustomerId(userRecord,
new ProcessorCustomer(customer, SubscriptionProcessor.STRIPE),
assertThat(subscriptions.setProcessorAndCustomerId(userRecord,
new ProcessorCustomer(customer, PaymentProvider.STRIPE),
subscriptionUpdated)).succeedsWithin(DEFAULT_TIMEOUT)
.hasFieldOrPropertyWithValue("processorCustomer",
Optional.of(new ProcessorCustomer(customer, SubscriptionProcessor.STRIPE)));
Optional.of(new ProcessorCustomer(customer, PaymentProvider.STRIPE)));
final Condition<Throwable> clientError409Condition = new Condition<>(e ->
e instanceof ClientErrorException cee && cee.getResponse().getStatus() == 409, "Client error: 409");
// changing the customer ID is not permitted
assertThat(
subscriptionManager.setProcessorAndCustomerId(userRecord,
new ProcessorCustomer(customer + "1", SubscriptionProcessor.STRIPE),
subscriptions.setProcessorAndCustomerId(userRecord,
new ProcessorCustomer(customer + "1", PaymentProvider.STRIPE),
subscriptionUpdated)).failsWithin(DEFAULT_TIMEOUT)
.withThrowableOfType(ExecutionException.class)
.withCauseInstanceOf(ClientErrorException.class)
@@ -143,16 +143,16 @@ class SubscriptionManagerTest {
// calling setProcessorAndCustomerId() with the same customer ID is also an error
assertThat(
subscriptionManager.setProcessorAndCustomerId(userRecord,
new ProcessorCustomer(customer, SubscriptionProcessor.STRIPE),
subscriptions.setProcessorAndCustomerId(userRecord,
new ProcessorCustomer(customer, PaymentProvider.STRIPE),
subscriptionUpdated)).failsWithin(DEFAULT_TIMEOUT)
.withThrowableOfType(ExecutionException.class)
.withCauseInstanceOf(ClientErrorException.class)
.extracting(Throwable::getCause)
.satisfies(clientError409Condition);
assertThat(subscriptionManager.getSubscriberUserByProcessorCustomer(
new ProcessorCustomer(customer, SubscriptionProcessor.STRIPE)))
assertThat(subscriptions.getSubscriberUserByProcessorCustomer(
new ProcessorCustomer(customer, PaymentProvider.STRIPE)))
.succeedsWithin(DEFAULT_TIMEOUT).
isEqualTo(user);
}
@@ -160,17 +160,17 @@ class SubscriptionManagerTest {
@Test
void testLookupByCustomerId() throws Exception {
Instant subscriptionUpdated = Instant.ofEpochSecond(NOW_EPOCH_SECONDS + 1);
assertThat(subscriptionManager.create(user, password, created)).succeedsWithin(DEFAULT_TIMEOUT);
assertThat(subscriptions.create(user, password, created)).succeedsWithin(DEFAULT_TIMEOUT);
final CompletableFuture<GetResult> getUser = subscriptionManager.get(user, password);
final CompletableFuture<GetResult> getUser = subscriptions.get(user, password);
assertThat(getUser).succeedsWithin(DEFAULT_TIMEOUT);
final Record userRecord = getUser.get().record;
assertThat(subscriptionManager.setProcessorAndCustomerId(userRecord,
new ProcessorCustomer(customer, SubscriptionProcessor.STRIPE),
assertThat(subscriptions.setProcessorAndCustomerId(userRecord,
new ProcessorCustomer(customer, PaymentProvider.STRIPE),
subscriptionUpdated)).succeedsWithin(DEFAULT_TIMEOUT);
assertThat(subscriptionManager.getSubscriberUserByProcessorCustomer(
new ProcessorCustomer(customer, SubscriptionProcessor.STRIPE))).
assertThat(subscriptions.getSubscriberUserByProcessorCustomer(
new ProcessorCustomer(customer, PaymentProvider.STRIPE))).
succeedsWithin(DEFAULT_TIMEOUT).
isEqualTo(user);
}
@@ -178,9 +178,9 @@ class SubscriptionManagerTest {
@Test
void testCanceledAt() {
Instant canceled = Instant.ofEpochSecond(NOW_EPOCH_SECONDS + 42);
assertThat(subscriptionManager.create(user, password, created)).succeedsWithin(DEFAULT_TIMEOUT);
assertThat(subscriptionManager.canceledAt(user, canceled)).succeedsWithin(DEFAULT_TIMEOUT);
assertThat(subscriptionManager.get(user, password)).succeedsWithin(DEFAULT_TIMEOUT).satisfies(getResult -> {
assertThat(subscriptions.create(user, password, created)).succeedsWithin(DEFAULT_TIMEOUT);
assertThat(subscriptions.canceledAt(user, canceled)).succeedsWithin(DEFAULT_TIMEOUT);
assertThat(subscriptions.get(user, password)).succeedsWithin(DEFAULT_TIMEOUT).satisfies(getResult -> {
assertThat(getResult).isNotNull();
assertThat(getResult.type).isEqualTo(FOUND);
assertThat(getResult.record).isNotNull().satisfies(record -> {
@@ -196,10 +196,10 @@ class SubscriptionManagerTest {
String subscriptionId = Base64.getEncoder().encodeToString(TestRandomUtil.nextBytes(16));
Instant subscriptionCreated = Instant.ofEpochSecond(NOW_EPOCH_SECONDS + 1);
long level = 42;
assertThat(subscriptionManager.create(user, password, created)).succeedsWithin(DEFAULT_TIMEOUT);
assertThat(subscriptionManager.subscriptionCreated(user, subscriptionId, subscriptionCreated, level)).
assertThat(subscriptions.create(user, password, created)).succeedsWithin(DEFAULT_TIMEOUT);
assertThat(subscriptions.subscriptionCreated(user, subscriptionId, subscriptionCreated, level)).
succeedsWithin(DEFAULT_TIMEOUT);
assertThat(subscriptionManager.get(user, password)).succeedsWithin(DEFAULT_TIMEOUT).satisfies(getResult -> {
assertThat(subscriptions.get(user, password)).succeedsWithin(DEFAULT_TIMEOUT).satisfies(getResult -> {
assertThat(getResult).isNotNull();
assertThat(getResult.type).isEqualTo(FOUND);
assertThat(getResult.record).isNotNull().satisfies(record -> {
@@ -217,12 +217,12 @@ class SubscriptionManagerTest {
Instant at = Instant.ofEpochSecond(NOW_EPOCH_SECONDS + 500);
long level = 1776;
String updatedSubscriptionId = "new";
assertThat(subscriptionManager.create(user, password, created)).succeedsWithin(DEFAULT_TIMEOUT);
assertThat(subscriptionManager.subscriptionCreated(user, "original", created, level - 1)).succeedsWithin(
assertThat(subscriptions.create(user, password, created)).succeedsWithin(DEFAULT_TIMEOUT);
assertThat(subscriptions.subscriptionCreated(user, "original", created, level - 1)).succeedsWithin(
DEFAULT_TIMEOUT);
assertThat(subscriptionManager.subscriptionLevelChanged(user, at, level, updatedSubscriptionId)).succeedsWithin(
assertThat(subscriptions.subscriptionLevelChanged(user, at, level, updatedSubscriptionId)).succeedsWithin(
DEFAULT_TIMEOUT);
assertThat(subscriptionManager.get(user, password)).succeedsWithin(DEFAULT_TIMEOUT).satisfies(getResult -> {
assertThat(subscriptions.get(user, password)).succeedsWithin(DEFAULT_TIMEOUT).satisfies(getResult -> {
assertThat(getResult).isNotNull();
assertThat(getResult.type).isEqualTo(FOUND);
assertThat(getResult.record).isNotNull().satisfies(record -> {
@@ -237,7 +237,7 @@ class SubscriptionManagerTest {
@Test
void testProcessorAndCustomerId() {
final ProcessorCustomer processorCustomer =
new ProcessorCustomer("abc", SubscriptionProcessor.STRIPE);
new ProcessorCustomer("abc", PaymentProvider.STRIPE);
assertThat(processorCustomer.toDynamoBytes()).isEqualTo(new byte[]{1, 97, 98, 99});
}

View File

@@ -8,9 +8,9 @@ class ProcessorCustomerTest {
@Test
void toDynamoBytes() {
final ProcessorCustomer processorCustomer = new ProcessorCustomer("Test", SubscriptionProcessor.BRAINTREE);
final ProcessorCustomer processorCustomer = new ProcessorCustomer("Test", PaymentProvider.BRAINTREE);
assertArrayEquals(new byte[] { SubscriptionProcessor.BRAINTREE.getId(), 'T', 'e', 's', 't' },
assertArrayEquals(new byte[] { PaymentProvider.BRAINTREE.getId(), 'T', 'e', 's', 't' },
processorCustomer.toDynamoBytes());
}
}