Update integration test with post-registration change number waiting period

This commit is contained in:
Chris Eager 2026-05-18 10:03:52 -05:00 committed by Chris Eager
parent dd29ee1f27
commit d41c73917f
5 changed files with 59 additions and 11 deletions

View File

@ -5,14 +5,20 @@
package org.signal.integration;
import io.lettuce.core.resource.ClientResources;
import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.signal.integration.config.Config;
import org.whispersystems.textsecuregcm.metrics.NoopAwsSdkMetricPublisher;
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisClusterClient;
import org.whispersystems.textsecuregcm.registration.VerificationSession;
import org.whispersystems.textsecuregcm.storage.ChangeNumberWaitingPeriodManager;
import org.whispersystems.textsecuregcm.storage.PhoneNumberIdentifiers;
import org.whispersystems.textsecuregcm.storage.RegistrationRecoveryPasswords;
import org.whispersystems.textsecuregcm.storage.RegistrationRecoveryPasswordsManager;
@ -31,6 +37,7 @@ public class IntegrationTools {
private final PhoneNumberIdentifiers phoneNumberIdentifiers;
private final ChangeNumberWaitingPeriodManager changeNumberWaitingPeriodManager;
public static IntegrationTools create(final Config config) {
final AwsCredentialsProvider credentialsProvider = DefaultCredentialsProvider.builder().build();
@ -44,20 +51,28 @@ public class IntegrationTools {
final VerificationSessions verificationSessions = new VerificationSessions(
dynamoDbAsyncClient, config.dynamoDbTables().verificationSessions(), Clock.systemUTC());
final FaultTolerantRedisClusterClient rateLimitersClient = new FaultTolerantRedisClusterClient(
"rateLimiters",
config.redis().rateLimiters(),
ClientResources.builder());
return new IntegrationTools(
new RegistrationRecoveryPasswordsManager(registrationRecoveryPasswords),
new VerificationSessionManager(verificationSessions),
new PhoneNumberIdentifiers(dynamoDbAsyncClient, config.dynamoDbTables().phoneNumberIdentifiers())
new PhoneNumberIdentifiers(dynamoDbAsyncClient, config.dynamoDbTables().phoneNumberIdentifiers()),
new ChangeNumberWaitingPeriodManager(rateLimitersClient, Duration.ZERO)
);
}
private IntegrationTools(
final RegistrationRecoveryPasswordsManager registrationRecoveryPasswordsManager,
final VerificationSessionManager verificationSessionManager,
final PhoneNumberIdentifiers phoneNumberIdentifiers) {
final PhoneNumberIdentifiers phoneNumberIdentifiers,
final ChangeNumberWaitingPeriodManager changeNumberWaitingPeriodManager) {
this.registrationRecoveryPasswordsManager = registrationRecoveryPasswordsManager;
this.verificationSessionManager = verificationSessionManager;
this.phoneNumberIdentifiers = phoneNumberIdentifiers;
this.changeNumberWaitingPeriodManager = changeNumberWaitingPeriodManager;
}
public CompletableFuture<Void> populateRecoveryPassword(final String phoneNumber, final byte[] password) {
@ -71,4 +86,13 @@ public class IntegrationTools {
return verificationSessionManager.findForId(sessionId)
.thenApply(maybeSession -> maybeSession.map(VerificationSession::pushChallenge));
}
public void clearChangeNumberWaitingPeriod(TestUser user) {
try {
changeNumberWaitingPeriodManager.handleAccountCreated(user.aciUuid(), Instant.now().minus(Duration.ofDays(1)))
.get(5, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -128,6 +128,10 @@ public final class Operations {
return recoveryPassword;
}
public static void clearChangeNumberWaitingPeriod(final TestUser user) {
INTEGRATION_TOOLS.clearChangeNumberWaitingPeriod(user);
}
public static <T> T sendEmptyRequestAuthenticated(
final String endpoint,
final String method,

View File

@ -15,5 +15,6 @@ public record Config(@NotBlank String domain,
@NotNull @Valid DynamoDbClientFactory dynamoDbClient,
@NotNull @Valid DynamoDbTables dynamoDbTables,
@NotBlank String prescribedRegistrationNumber,
@NotBlank String prescribedRegistrationCode) {
@NotBlank String prescribedRegistrationCode,
@NotNull @Valid Redis redis) {
}

View File

@ -0,0 +1,13 @@
/*
* Copyright 2026 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.signal.integration.config;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import org.whispersystems.textsecuregcm.configuration.RedisClusterConfiguration;
public record Redis(@NotNull @Valid RedisClusterConfiguration rateLimiters) {
}

View File

@ -62,14 +62,20 @@ public class AccountTest {
Map.of(Device.PRIMARY_ID, Operations.generateSignedKEMPreKey(2, pniIdentityKeyPair)),
Map.of(Device.PRIMARY_ID, 17));
final AccountIdentityResponse accountIdentityResponse =
Operations.apiPut("/v2/accounts/number", changeNumberRequest)
.authorized(user)
.executeExpectSuccess(AccountIdentityResponse.class);
try {
Operations.clearChangeNumberWaitingPeriod(user);
assertEquals(user.aciUuid(), accountIdentityResponse.uuid());
assertNotEquals(user.pniUuid(), accountIdentityResponse.pni());
assertEquals(targetNumber, accountIdentityResponse.number());
final AccountIdentityResponse accountIdentityResponse =
Operations.apiPut("/v2/accounts/number", changeNumberRequest)
.authorized(user)
.executeExpectSuccess(AccountIdentityResponse.class);
assertEquals(user.aciUuid(), accountIdentityResponse.uuid());
assertNotEquals(user.pniUuid(), accountIdentityResponse.pni());
assertEquals(targetNumber, accountIdentityResponse.number());
} finally {
Operations.deleteUser(user);
}
}
@Test