mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-22 03:28:00 +01:00
Consolidate account creation/directory updates into AccountsManager
This commit is contained in:
@@ -40,7 +40,7 @@ public class DirectoryQueueTest {
|
||||
when(account.isEnabled()).thenReturn(accountEnabled);
|
||||
when(account.isDiscoverableByPhoneNumber()).thenReturn(accountDiscoverableByPhoneNumber);
|
||||
|
||||
directoryQueue.refreshRegisteredUser(account);
|
||||
directoryQueue.refreshAccount(account);
|
||||
|
||||
final ArgumentCaptor<SendMessageBatchRequest> requestCaptor = ArgumentCaptor.forClass(SendMessageBatchRequest.class);
|
||||
verify(sqs).sendMessageBatch(requestCaptor.capture());
|
||||
@@ -68,7 +68,7 @@ public class DirectoryQueueTest {
|
||||
when(undiscoverableAccount.isEnabled()).thenReturn(true);
|
||||
when(undiscoverableAccount.isDiscoverableByPhoneNumber()).thenReturn(false);
|
||||
|
||||
directoryQueue.refreshRegisteredUsers(List.of(discoverableAccount, undiscoverableAccount));
|
||||
directoryQueue.refreshAccounts(List.of(discoverableAccount, undiscoverableAccount));
|
||||
|
||||
final ArgumentCaptor<SendMessageBatchRequest> requestCaptor = ArgumentCaptor.forClass(SendMessageBatchRequest.class);
|
||||
verify(sqs).sendMessageBatch(requestCaptor.capture());
|
||||
@@ -97,7 +97,7 @@ public class DirectoryQueueTest {
|
||||
when(account.isEnabled()).thenReturn(true);
|
||||
when(account.isDiscoverableByPhoneNumber()).thenReturn(true);
|
||||
|
||||
directoryQueue.refreshRegisteredUser(account);
|
||||
directoryQueue.refreshAccount(account);
|
||||
|
||||
final ArgumentCaptor<SendMessageBatchRequest> requestCaptor = ArgumentCaptor.forClass(SendMessageBatchRequest.class);
|
||||
verify(sqs, times(2)).sendMessageBatch(requestCaptor.capture());
|
||||
|
||||
@@ -44,6 +44,7 @@ import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials;
|
||||
import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration;
|
||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicAccountsDynamoDbMigrationConfiguration;
|
||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
||||
import org.whispersystems.textsecuregcm.entities.AccountAttributes;
|
||||
import org.whispersystems.textsecuregcm.entities.SignedPreKey;
|
||||
import org.whispersystems.textsecuregcm.experiment.ExperimentEnrollmentManager;
|
||||
import org.whispersystems.textsecuregcm.securebackup.SecureBackupClient;
|
||||
@@ -154,6 +155,7 @@ class AccountsManagerConcurrentModificationIntegrationTest {
|
||||
mock(MessagesManager.class),
|
||||
mock(UsernamesManager.class),
|
||||
mock(ProfilesManager.class),
|
||||
mock(StoredVerificationCodeManager.class),
|
||||
mock(SecureStorageClient.class),
|
||||
mock(SecureBackupClient.class),
|
||||
experimentEnrollmentManager,
|
||||
@@ -164,9 +166,30 @@ class AccountsManagerConcurrentModificationIntegrationTest {
|
||||
@Test
|
||||
void testConcurrentUpdate() throws IOException {
|
||||
|
||||
final UUID uuid = UUID.randomUUID();
|
||||
final UUID uuid;
|
||||
{
|
||||
final Account account = accountsManager.update(
|
||||
accountsManager.create("+14155551212", "password", null, new AccountAttributes()),
|
||||
a -> {
|
||||
a.setUnidentifiedAccessKey(new byte[16]);
|
||||
|
||||
accountsManager.create(generateAccount("+14155551212", uuid));
|
||||
final Random random = new Random();
|
||||
final SignedPreKey signedPreKey = new SignedPreKey(random.nextInt(), "testPublicKey-" + random.nextInt(),
|
||||
"testSignature-" + random.nextInt());
|
||||
|
||||
a.removeDevice(1);
|
||||
a.addDevice(new Device(1, "testName-" + random.nextInt(), "testAuthToken-" + random.nextInt(),
|
||||
"testSalt-" + random.nextInt(),
|
||||
"testGcmId-" + random.nextInt(), "testApnId-" + random.nextInt(), "testVoipApnId-" + random.nextInt(),
|
||||
random.nextBoolean(), random.nextInt(), signedPreKey, random.nextInt(), random.nextInt(),
|
||||
"testUserAgent-" + random.nextInt(), 0,
|
||||
new Device.DeviceCapabilities(random.nextBoolean(), random.nextBoolean(), random.nextBoolean(),
|
||||
random.nextBoolean(), random.nextBoolean(), random.nextBoolean(),
|
||||
random.nextBoolean(), random.nextBoolean())));
|
||||
});
|
||||
|
||||
uuid = account.getUuid();
|
||||
}
|
||||
|
||||
final String profileName = "name";
|
||||
final String avatar = "avatar";
|
||||
@@ -249,26 +272,4 @@ class AccountsManagerConcurrentModificationIntegrationTest {
|
||||
accountsManager.updateDevice(account, deviceId, deviceMutation);
|
||||
}, mutationExecutor);
|
||||
}
|
||||
|
||||
private Account generateAccount(String number, UUID uuid) {
|
||||
Device device = generateDevice(1);
|
||||
return generateAccount(number, uuid, Collections.singleton(device));
|
||||
}
|
||||
|
||||
private Account generateAccount(String number, UUID uuid, Set<Device> devices) {
|
||||
byte[] unidentifiedAccessKey = new byte[16];
|
||||
Random random = new Random(System.currentTimeMillis());
|
||||
Arrays.fill(unidentifiedAccessKey, (byte)random.nextInt(255));
|
||||
|
||||
return new Account(number, uuid, devices, unidentifiedAccessKey);
|
||||
}
|
||||
|
||||
private Device generateDevice(long id) {
|
||||
Random random = new Random(System.currentTimeMillis());
|
||||
SignedPreKey signedPreKey = new SignedPreKey(random.nextInt(), "testPublicKey-" + random.nextInt(), "testSignature-" + random.nextInt());
|
||||
return new Device(id, "testName-" + random.nextInt(), "testAuthToken-" + random.nextInt(), "testSalt-" + random.nextInt(),
|
||||
"testGcmId-" + random.nextInt(), "testApnId-" + random.nextInt(), "testVoipApnId-" + random.nextInt(), random.nextBoolean(), random.nextInt(), signedPreKey, random.nextInt(), random.nextInt(), "testUserAgent-" + random.nextInt() , 0, new Device.DeviceCapabilities(random.nextBoolean(), random.nextBoolean(), random.nextBoolean(), random.nextBoolean(), random.nextBoolean(), random.nextBoolean(),
|
||||
random.nextBoolean(), random.nextBoolean()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,8 +10,17 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.whispersystems.textsecuregcm.tests.util.AccountsHelper.eqUuid;
|
||||
import static org.mockito.Mockito.anyLong;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
|
||||
@@ -42,7 +51,7 @@ import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.ArgumentMatcher;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials;
|
||||
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount;
|
||||
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialGenerator;
|
||||
@@ -70,14 +79,11 @@ import org.whispersystems.textsecuregcm.push.GcmMessage;
|
||||
import org.whispersystems.textsecuregcm.recaptcha.RecaptchaClient;
|
||||
import org.whispersystems.textsecuregcm.sms.SmsSender;
|
||||
import org.whispersystems.textsecuregcm.sms.TwilioVerifyExperimentEnrollmentManager;
|
||||
import org.whispersystems.textsecuregcm.sqs.DirectoryQueue;
|
||||
import org.whispersystems.textsecuregcm.storage.AbusiveHostRule;
|
||||
import org.whispersystems.textsecuregcm.storage.AbusiveHostRules;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
||||
import org.whispersystems.textsecuregcm.storage.KeysDynamoDb;
|
||||
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
||||
import org.whispersystems.textsecuregcm.storage.StoredVerificationCodeManager;
|
||||
import org.whispersystems.textsecuregcm.storage.UsernamesManager;
|
||||
import org.whispersystems.textsecuregcm.tests.util.AccountsHelper;
|
||||
@@ -121,9 +127,6 @@ class AccountControllerTest {
|
||||
private static RateLimiter autoBlockLimiter = mock(RateLimiter.class);
|
||||
private static RateLimiter usernameSetLimiter = mock(RateLimiter.class);
|
||||
private static SmsSender smsSender = mock(SmsSender.class);
|
||||
private static DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
private static MessagesManager storedMessages = mock(MessagesManager.class);
|
||||
private static KeysDynamoDb keys = mock(KeysDynamoDb.class);
|
||||
private static TurnTokenGenerator turnTokenGenerator = mock(TurnTokenGenerator.class);
|
||||
private static Account senderPinAccount = mock(Account.class);
|
||||
private static Account senderRegLockAccount = mock(Account.class);
|
||||
@@ -155,9 +158,6 @@ class AccountControllerTest {
|
||||
abusiveHostRules,
|
||||
rateLimiters,
|
||||
smsSender,
|
||||
directoryQueue,
|
||||
storedMessages,
|
||||
keys,
|
||||
dynamicConfigurationManager,
|
||||
turnTokenGenerator,
|
||||
new HashMap<>(),
|
||||
@@ -218,6 +218,14 @@ class AccountControllerTest {
|
||||
when(accountsManager.get(eq(SENDER_HAS_STORAGE))).thenReturn(Optional.of(senderHasStorage));
|
||||
when(accountsManager.get(eq(SENDER_TRANSFER))).thenReturn(Optional.of(senderTransfer));
|
||||
|
||||
when(accountsManager.create(any(), any(), any(), any())).thenAnswer((Answer<Account>) invocation -> {
|
||||
final Account account = mock(Account.class);
|
||||
when(account.getUuid()).thenReturn(UUID.randomUUID());
|
||||
when(account.getNumber()).thenReturn(invocation.getArgument(0, String.class));
|
||||
|
||||
return account;
|
||||
});
|
||||
|
||||
when(usernamesManager.put(eq(AuthHelper.VALID_UUID), eq("n00bkiller"))).thenReturn(true);
|
||||
when(usernamesManager.put(eq(AuthHelper.VALID_UUID), eq("takenusername"))).thenReturn(false);
|
||||
|
||||
@@ -261,9 +269,6 @@ class AccountControllerTest {
|
||||
autoBlockLimiter,
|
||||
usernameSetLimiter,
|
||||
smsSender,
|
||||
directoryQueue,
|
||||
storedMessages,
|
||||
keys,
|
||||
turnTokenGenerator,
|
||||
senderPinAccount,
|
||||
senderRegLockAccount,
|
||||
@@ -922,23 +927,13 @@ class AccountControllerTest {
|
||||
Optional.of(new StoredVerificationCode("1234", System.currentTimeMillis(), "1234-push", "VerificationSid")));;
|
||||
}
|
||||
|
||||
AccountCreationResult result =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "1234"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 2222, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "1234"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(), MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
|
||||
|
||||
assertThat(result.getUuid()).isNotNull();
|
||||
assertThat(result.isStorageCapable()).isFalse();
|
||||
|
||||
final ArgumentCaptor<Account> accountArgumentCaptor = ArgumentCaptor.forClass(Account.class);
|
||||
|
||||
verify(accountsManager, times(1)).create(accountArgumentCaptor.capture());
|
||||
verify(directoryQueue, times(1)).refreshRegisteredUser(argThat(account -> SENDER.equals(account.getNumber())));
|
||||
|
||||
assertThat(accountArgumentCaptor.getValue().isDiscoverableByPhoneNumber()).isTrue();
|
||||
verify(accountsManager).create(eq(SENDER), eq("bar"), any(), any());
|
||||
|
||||
if (enrolledInVerifyExperiment) {
|
||||
verify(smsSender).reportVerificationSucceeded("VerificationSid");
|
||||
@@ -946,52 +941,14 @@ class AccountControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVerifyCodeUndiscoverable() throws Exception {
|
||||
AccountCreationResult result =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "1234"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 2222, null, null, null, false, null),
|
||||
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
|
||||
|
||||
assertThat(result.getUuid()).isNotNull();
|
||||
assertThat(result.isStorageCapable()).isFalse();
|
||||
|
||||
final ArgumentCaptor<Account> accountArgumentCaptor = ArgumentCaptor.forClass(Account.class);
|
||||
|
||||
verify(accountsManager, times(1)).create(accountArgumentCaptor.capture());
|
||||
verify(directoryQueue, times(1)).refreshRegisteredUser(argThat(account -> SENDER.equals(account.getNumber())));
|
||||
|
||||
assertThat(accountArgumentCaptor.getValue().isDiscoverableByPhoneNumber()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVerifySupportsStorage() throws Exception {
|
||||
AccountCreationResult result =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "666666"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_HAS_STORAGE, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 2222, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
|
||||
|
||||
assertThat(result.getUuid()).isNotNull();
|
||||
assertThat(result.isStorageCapable()).isTrue();
|
||||
|
||||
verify(accountsManager, times(1)).create(isA(Account.class));
|
||||
verify(directoryQueue, times(1)).refreshRegisteredUser(argThat(account -> SENDER_HAS_STORAGE.equals(account.getNumber())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVerifyCodeOld() throws Exception {
|
||||
void testVerifyCodeOld() {
|
||||
Response response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "1234"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_OLD, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 2222, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
.target(String.format("/v1/accounts/code/%s", "1234"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_OLD, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 2222, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(403);
|
||||
|
||||
@@ -999,14 +956,14 @@ class AccountControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVerifyBadCode() throws Exception {
|
||||
void testVerifyBadCode() {
|
||||
Response response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "1111"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
.target(String.format("/v1/accounts/code/%s", "1111"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(403);
|
||||
|
||||
@@ -1017,11 +974,11 @@ class AccountControllerTest {
|
||||
void testVerifyPin() throws Exception {
|
||||
AccountCreationResult result =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "333333"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_PIN, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, "31337", null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
|
||||
.target(String.format("/v1/accounts/code/%s", "333333"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_PIN, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, "31337", null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
|
||||
|
||||
assertThat(result.getUuid()).isNotNull();
|
||||
|
||||
@@ -1032,11 +989,11 @@ class AccountControllerTest {
|
||||
void testVerifyRegistrationLock() throws Exception {
|
||||
AccountCreationResult result =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "666666"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, Hex.toStringCondensed(registration_lock_key), true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
|
||||
.target(String.format("/v1/accounts/code/%s", "666666"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, Hex.toStringCondensed(registration_lock_key), true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
|
||||
|
||||
assertThat(result.getUuid()).isNotNull();
|
||||
|
||||
@@ -1045,36 +1002,24 @@ class AccountControllerTest {
|
||||
|
||||
@Test
|
||||
void testVerifyRegistrationLockSetsRegistrationLockOnNewAccount() throws Exception {
|
||||
|
||||
AccountCreationResult result =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "666666"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, Hex.toStringCondensed(registration_lock_key), true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
|
||||
.target(String.format("/v1/accounts/code/%s", "666666"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, Hex.toStringCondensed(registration_lock_key), true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
|
||||
|
||||
assertThat(result.getUuid()).isNotNull();
|
||||
|
||||
verify(pinLimiter).validate(eq(SENDER_REG_LOCK));
|
||||
|
||||
verify(accountsManager).create(argThat(new ArgumentMatcher<>() {
|
||||
@Override
|
||||
public boolean matches(final Account account) {
|
||||
final StoredRegistrationLock regLock = account.getRegistrationLock();
|
||||
return regLock.requiresClientRegistrationLock() && regLock.verify(Hex.toStringCondensed(registration_lock_key), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Account that has registration lock set";
|
||||
}
|
||||
}));
|
||||
|
||||
verify(accountsManager).create(eq(SENDER_REG_LOCK), eq("bar"), any(), argThat(
|
||||
attributes -> Hex.toStringCondensed(registration_lock_key).equals(attributes.getRegistrationLock())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVerifyRegistrationLockOld() throws Exception {
|
||||
void testVerifyRegistrationLockOld() {
|
||||
StoredRegistrationLock lock = senderRegLockAccount.getRegistrationLock();
|
||||
|
||||
try {
|
||||
@@ -1082,11 +1027,11 @@ class AccountControllerTest {
|
||||
|
||||
AccountCreationResult result =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "666666"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
|
||||
.target(String.format("/v1/accounts/code/%s", "666666"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
|
||||
|
||||
assertThat(result.getUuid()).isNotNull();
|
||||
|
||||
@@ -1100,11 +1045,11 @@ class AccountControllerTest {
|
||||
void testVerifyWrongPin() throws Exception {
|
||||
Response response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "333333"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_PIN, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, "31338", null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
.target(String.format("/v1/accounts/code/%s", "333333"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_PIN, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, "31338", null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(423);
|
||||
|
||||
@@ -1115,12 +1060,12 @@ class AccountControllerTest {
|
||||
void testVerifyWrongRegistrationLock() throws Exception {
|
||||
Response response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "666666"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null,
|
||||
Hex.toStringCondensed(new byte[32]), null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
.target(String.format("/v1/accounts/code/%s", "666666"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null,
|
||||
Hex.toStringCondensed(new byte[32]), null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(423);
|
||||
|
||||
@@ -1131,11 +1076,11 @@ class AccountControllerTest {
|
||||
void testVerifyNoPin() throws Exception {
|
||||
Response response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "333333"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_PIN, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
.target(String.format("/v1/accounts/code/%s", "333333"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_PIN, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(423);
|
||||
|
||||
@@ -1149,11 +1094,11 @@ class AccountControllerTest {
|
||||
void testVerifyNoRegistrationLock() throws Exception {
|
||||
Response response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "666666"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
.target(String.format("/v1/accounts/code/%s", "666666"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(423);
|
||||
|
||||
@@ -1172,11 +1117,11 @@ class AccountControllerTest {
|
||||
void testVerifyLimitPin() throws Exception {
|
||||
Response response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "444444"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_OVER_PIN, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, "31337", null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
.target(String.format("/v1/accounts/code/%s", "444444"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_OVER_PIN, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, "31337", null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(413);
|
||||
|
||||
@@ -1190,11 +1135,11 @@ class AccountControllerTest {
|
||||
|
||||
AccountCreationResult result =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "444444"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_OVER_PIN, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
|
||||
.target(String.format("/v1/accounts/code/%s", "444444"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_OVER_PIN, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
|
||||
|
||||
assertThat(result.getUuid()).isNotNull();
|
||||
|
||||
@@ -1208,13 +1153,13 @@ class AccountControllerTest {
|
||||
when(senderTransfer.isTransferSupported()).thenReturn(true);
|
||||
|
||||
final Response response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "1234"))
|
||||
.queryParam("transfer", true)
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_TRANSFER, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 2222, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "1234"))
|
||||
.queryParam("transfer", true)
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_TRANSFER, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 2222, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(409);
|
||||
}
|
||||
@@ -1224,13 +1169,13 @@ class AccountControllerTest {
|
||||
when(senderTransfer.isTransferSupported()).thenReturn(false);
|
||||
|
||||
final Response response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "1234"))
|
||||
.queryParam("transfer", true)
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_TRANSFER, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 2222, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "1234"))
|
||||
.queryParam("transfer", true)
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_TRANSFER, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 2222, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
@@ -1240,41 +1185,14 @@ class AccountControllerTest {
|
||||
when(senderTransfer.isTransferSupported()).thenReturn(true);
|
||||
|
||||
final Response response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "1234"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_TRANSFER, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 2222, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVerifyReregistration() throws InterruptedException {
|
||||
final UUID existingUuid = UUID.randomUUID();
|
||||
final Account existingAccount = mock(Account.class);
|
||||
|
||||
when(existingAccount.getUuid()).thenReturn(existingUuid);
|
||||
when(accountsManager.get(SENDER)).thenReturn(Optional.of(existingAccount));
|
||||
|
||||
AccountCreationResult result =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/code/%s", "1234"))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER, "bar"))
|
||||
.header("Authorization", AuthHelper.getAuthHeader(SENDER_TRANSFER, "bar"))
|
||||
.put(Entity.entity(new AccountAttributes(false, 2222, null, null, null, true, null),
|
||||
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
final ArgumentCaptor<Account> accountArgumentCaptor = ArgumentCaptor.forClass(Account.class);
|
||||
|
||||
verify(accountsManager, times(1)).create(accountArgumentCaptor.capture());
|
||||
verify(directoryQueue, times(1)).refreshRegisteredUser(argThat(account -> SENDER.equals(account.getNumber())));
|
||||
|
||||
verify(storedMessages).clear(existingUuid);
|
||||
verify(keys).delete(existingAccount);
|
||||
|
||||
assertThat(accountArgumentCaptor.getValue().isDiscoverableByPhoneNumber()).isTrue();
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1388,7 +1306,6 @@ class AccountControllerTest {
|
||||
|
||||
verify(AuthHelper.DISABLED_DEVICE, times(1)).setGcmId(eq("c00lz0rz"));
|
||||
verify(accountsManager, times(1)).updateDevice(eq(AuthHelper.DISABLED_ACCOUNT), anyLong(), any());
|
||||
verify(directoryQueue, never()).refreshRegisteredUser(any(Account.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1404,7 +1321,6 @@ class AccountControllerTest {
|
||||
|
||||
verify(AuthHelper.DISABLED_DEVICE, times(1)).setGcmId(eq("z000"));
|
||||
verify(accountsManager, times(1)).updateDevice(eq(AuthHelper.DISABLED_ACCOUNT), anyLong(), any());
|
||||
verify(directoryQueue, never()).refreshRegisteredUser(any(Account.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1421,7 +1337,6 @@ class AccountControllerTest {
|
||||
verify(AuthHelper.DISABLED_DEVICE, times(1)).setApnId(eq("first"));
|
||||
verify(AuthHelper.DISABLED_DEVICE, times(1)).setVoipApnId(eq("second"));
|
||||
verify(accountsManager, times(1)).updateDevice(eq(AuthHelper.DISABLED_ACCOUNT), anyLong(), any());
|
||||
verify(directoryQueue, never()).refreshRegisteredUser(any(Account.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1438,7 +1353,6 @@ class AccountControllerTest {
|
||||
verify(AuthHelper.DISABLED_DEVICE, times(1)).setApnId(eq("first"));
|
||||
verify(AuthHelper.DISABLED_DEVICE, times(1)).setVoipApnId(null);
|
||||
verify(accountsManager, times(1)).updateDevice(eq(AuthHelper.DISABLED_ACCOUNT), anyLong(), any());
|
||||
verify(directoryQueue, never()).refreshRegisteredUser(any(Account.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1455,7 +1369,6 @@ class AccountControllerTest {
|
||||
verify(AuthHelper.DISABLED_DEVICE, times(1)).setApnId(eq("third"));
|
||||
verify(AuthHelper.DISABLED_DEVICE, times(1)).setVoipApnId(eq("fourth"));
|
||||
verify(accountsManager, times(1)).updateDevice(eq(AuthHelper.DISABLED_ACCOUNT), anyLong(), any());
|
||||
verify(directoryQueue, never()).refreshRegisteredUser(any(Account.class));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@@ -1566,7 +1479,6 @@ class AccountControllerTest {
|
||||
.put(Entity.json(new AccountAttributes(false, 2222, null, null, null, true, null)));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(204);
|
||||
verify(directoryQueue, never()).refreshRegisteredUser(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1579,7 +1491,6 @@ class AccountControllerTest {
|
||||
.put(Entity.json(new AccountAttributes(false, 2222, null, null, null, true, null)));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(204);
|
||||
verify(directoryQueue, times(1)).refreshRegisteredUser(eqUuid(AuthHelper.UNDISCOVERABLE_ACCOUNT));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1592,7 +1503,6 @@ class AccountControllerTest {
|
||||
.put(Entity.json(new AccountAttributes(false, 2222, null, null, null, false, null)));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(204);
|
||||
verify(directoryQueue, times(1)).refreshRegisteredUser(eqUuid(AuthHelper.VALID_ACCOUNT));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -45,7 +45,6 @@ import org.whispersystems.textsecuregcm.entities.DeviceResponse;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiter;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.mappers.DeviceLimitExceededExceptionMapper;
|
||||
import org.whispersystems.textsecuregcm.sqs.DirectoryQueue;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
@@ -65,11 +64,10 @@ class DeviceControllerTest {
|
||||
AccountsManager accounts,
|
||||
MessagesManager messages,
|
||||
KeysDynamoDb keys,
|
||||
DirectoryQueue cdsSender,
|
||||
RateLimiters rateLimiters,
|
||||
Map<String, Integer> deviceConfiguration)
|
||||
{
|
||||
super(pendingDevices, accounts, messages, keys, cdsSender, rateLimiters, deviceConfiguration);
|
||||
super(pendingDevices, accounts, messages, keys, rateLimiters, deviceConfiguration);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,7 +80,6 @@ class DeviceControllerTest {
|
||||
private static AccountsManager accountsManager = mock(AccountsManager.class );
|
||||
private static MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
private static KeysDynamoDb keys = mock(KeysDynamoDb.class);
|
||||
private static DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
private static RateLimiters rateLimiters = mock(RateLimiters.class );
|
||||
private static RateLimiter rateLimiter = mock(RateLimiter.class );
|
||||
private static Account account = mock(Account.class );
|
||||
@@ -100,7 +97,6 @@ class DeviceControllerTest {
|
||||
accountsManager,
|
||||
messagesManager,
|
||||
keys,
|
||||
directoryQueue,
|
||||
rateLimiters,
|
||||
deviceConfiguration))
|
||||
.build();
|
||||
@@ -142,7 +138,6 @@ class DeviceControllerTest {
|
||||
accountsManager,
|
||||
messagesManager,
|
||||
keys,
|
||||
directoryQueue,
|
||||
rateLimiters,
|
||||
rateLimiter,
|
||||
account,
|
||||
|
||||
@@ -57,7 +57,6 @@ import org.whispersystems.textsecuregcm.limits.RateLimitChallengeManager;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiter;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.mappers.RateLimitChallengeExceptionMapper;
|
||||
import org.whispersystems.textsecuregcm.sqs.DirectoryQueue;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
@@ -92,7 +91,6 @@ class KeysControllerTest {
|
||||
|
||||
private final static KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class );
|
||||
private final static AccountsManager accounts = mock(AccountsManager.class );
|
||||
private final static DirectoryQueue directoryQueue = mock(DirectoryQueue.class );
|
||||
private final static PreKeyRateLimiter preKeyRateLimiter = mock(PreKeyRateLimiter.class );
|
||||
private final static RateLimitChallengeManager rateLimitChallengeManager = mock(RateLimitChallengeManager.class );
|
||||
private final static Account existsAccount = mock(Account.class );
|
||||
@@ -107,7 +105,7 @@ class KeysControllerTest {
|
||||
.addProvider(new PolymorphicAuthValueFactoryProvider.Binder<>(ImmutableSet.of(Account.class, DisabledPermittedAccount.class)))
|
||||
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
|
||||
.addResource(new RateLimitChallengeExceptionMapper(rateLimitChallengeManager))
|
||||
.addResource(new KeysController(rateLimiters, keysDynamoDb, accounts, directoryQueue, preKeyRateLimiter, dynamicConfigurationManager, rateLimitChallengeManager))
|
||||
.addResource(new KeysController(rateLimiters, keysDynamoDb, accounts, preKeyRateLimiter, dynamicConfigurationManager, rateLimitChallengeManager))
|
||||
.build();
|
||||
|
||||
@BeforeEach
|
||||
@@ -184,7 +182,6 @@ class KeysControllerTest {
|
||||
reset(
|
||||
keysDynamoDb,
|
||||
accounts,
|
||||
directoryQueue,
|
||||
preKeyRateLimiter,
|
||||
existsAccount,
|
||||
rateLimiters,
|
||||
|
||||
@@ -19,8 +19,8 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import io.lettuce.core.RedisException;
|
||||
@@ -30,17 +30,20 @@ import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicAccountsDynamoDbMigrationConfiguration;
|
||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
||||
import org.whispersystems.textsecuregcm.entities.AccountAttributes;
|
||||
import org.whispersystems.textsecuregcm.entities.SignedPreKey;
|
||||
import org.whispersystems.textsecuregcm.experiment.ExperimentEnrollmentManager;
|
||||
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster;
|
||||
import org.whispersystems.textsecuregcm.securebackup.SecureBackupClient;
|
||||
import org.whispersystems.textsecuregcm.securestorage.SecureStorageClient;
|
||||
import org.whispersystems.textsecuregcm.sqs.DirectoryQueue;
|
||||
@@ -49,21 +52,28 @@ import org.whispersystems.textsecuregcm.storage.Accounts;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsDynamoDb;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.ContestedOptimisticLockException;
|
||||
import org.whispersystems.textsecuregcm.storage.DeletedAccounts;
|
||||
import org.whispersystems.textsecuregcm.storage.DeletedAccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
import org.whispersystems.textsecuregcm.storage.Device.DeviceCapabilities;
|
||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
||||
import org.whispersystems.textsecuregcm.storage.KeysDynamoDb;
|
||||
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
||||
import org.whispersystems.textsecuregcm.storage.ProfilesManager;
|
||||
import org.whispersystems.textsecuregcm.storage.StoredVerificationCodeManager;
|
||||
import org.whispersystems.textsecuregcm.storage.UsernamesManager;
|
||||
import org.whispersystems.textsecuregcm.tests.util.JsonHelpers;
|
||||
import org.whispersystems.textsecuregcm.tests.util.RedisClusterHelper;
|
||||
|
||||
class AccountsManagerTest {
|
||||
|
||||
private DynamicConfigurationManager dynamicConfigurationManager = mock(DynamicConfigurationManager.class);
|
||||
private ExperimentEnrollmentManager experimentEnrollmentManager = mock(ExperimentEnrollmentManager.class);
|
||||
private Accounts accounts;
|
||||
private AccountsDynamoDb accountsDynamoDb;
|
||||
private DirectoryQueue directoryQueue;
|
||||
private DynamicConfigurationManager dynamicConfigurationManager;
|
||||
private ExperimentEnrollmentManager experimentEnrollmentManager;
|
||||
|
||||
private RedisAdvancedClusterCommands<String, String> commands;
|
||||
private AccountsManager accountsManager;
|
||||
|
||||
private static final Answer<?> ACCOUNT_UPDATE_ANSWER = (answer) -> {
|
||||
// it is implicit in the update() contract is that a successful call will
|
||||
@@ -75,49 +85,57 @@ class AccountsManagerTest {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
accounts = mock(Accounts.class);
|
||||
accountsDynamoDb = mock(AccountsDynamoDb.class);
|
||||
directoryQueue = mock(DirectoryQueue.class);
|
||||
dynamicConfigurationManager = mock(DynamicConfigurationManager.class);
|
||||
experimentEnrollmentManager = mock(ExperimentEnrollmentManager.class);
|
||||
|
||||
DynamicConfiguration dynamicConfiguration = new DynamicConfiguration();
|
||||
//noinspection unchecked
|
||||
commands = mock(RedisAdvancedClusterCommands.class);
|
||||
|
||||
final DynamicConfiguration dynamicConfiguration = new DynamicConfiguration();
|
||||
when(dynamicConfigurationManager.getConfiguration()).thenReturn(dynamicConfiguration);
|
||||
|
||||
accountsManager = new AccountsManager(
|
||||
accounts,
|
||||
accountsDynamoDb,
|
||||
RedisClusterHelper.buildMockRedisCluster(commands),
|
||||
mock(DeletedAccountsManager.class),
|
||||
directoryQueue,
|
||||
mock(KeysDynamoDb.class),
|
||||
mock(MessagesManager.class),
|
||||
mock(UsernamesManager.class),
|
||||
mock(ProfilesManager.class),
|
||||
mock(StoredVerificationCodeManager.class),
|
||||
mock(SecureStorageClient.class),
|
||||
mock(SecureBackupClient.class),
|
||||
experimentEnrollmentManager,
|
||||
dynamicConfigurationManager);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
void testGetAccountByNumberInCache(final boolean dynamoEnabled) {
|
||||
RedisAdvancedClusterCommands<String, String> commands = mock(RedisAdvancedClusterCommands.class);
|
||||
FaultTolerantRedisCluster cacheCluster = RedisClusterHelper.buildMockRedisCluster(commands);
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
AccountsDynamoDb accountsDynamoDb = mock(AccountsDynamoDb.class);
|
||||
DeletedAccountsManager deletedAccounts = mock(DeletedAccountsManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
ProfilesManager profilesManager = mock(ProfilesManager.class);
|
||||
SecureBackupClient secureBackupClient = mock(SecureBackupClient.class);
|
||||
SecureStorageClient secureStorageClient = mock(SecureStorageClient.class);
|
||||
|
||||
UUID uuid = UUID.randomUUID();
|
||||
|
||||
enableDynamo(dynamoEnabled);
|
||||
|
||||
when(commands.get(eq("AccountMap::+14152222222"))).thenReturn(uuid.toString());
|
||||
when(commands.get(eq("Account3::" + uuid.toString()))).thenReturn("{\"number\": \"+14152222222\", \"name\": \"test\"}");
|
||||
when(commands.get(eq("Account3::" + uuid))).thenReturn("{\"number\": \"+14152222222\", \"name\": \"test\"}");
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, accountsDynamoDb, cacheCluster, deletedAccounts,
|
||||
directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager, secureStorageClient, secureBackupClient, experimentEnrollmentManager, dynamicConfigurationManager);
|
||||
Optional<Account> account = accountsManager.get("+14152222222");
|
||||
Optional<Account> account = accountsManager.get("+14152222222");
|
||||
|
||||
assertTrue(account.isPresent());
|
||||
assertEquals(account.get().getNumber(), "+14152222222");
|
||||
assertEquals(account.get().getProfileName(), "test");
|
||||
|
||||
verify(commands, times(1)).get(eq("AccountMap::+14152222222"));
|
||||
verify(commands, times(1)).get(eq("Account3::" + uuid.toString()));
|
||||
verify(commands, times(1)).get(eq("Account3::" + uuid));
|
||||
verifyNoMoreInteractions(commands);
|
||||
verifyNoMoreInteractions(accounts);
|
||||
|
||||
verifyZeroInteractions(accountsDynamoDb);
|
||||
verifyNoInteractions(accountsDynamoDb);
|
||||
}
|
||||
|
||||
private void enableDynamo(boolean dynamoEnabled) {
|
||||
@@ -136,75 +154,46 @@ class AccountsManagerTest {
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
void testGetAccountByUuidInCache(boolean dynamoEnabled) {
|
||||
RedisAdvancedClusterCommands<String, String> commands = mock(RedisAdvancedClusterCommands.class);
|
||||
FaultTolerantRedisCluster cacheCluster = RedisClusterHelper.buildMockRedisCluster(commands);
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
AccountsDynamoDb accountsDynamoDb = mock(AccountsDynamoDb.class);
|
||||
DeletedAccountsManager deletedAccounts = mock(DeletedAccountsManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
ProfilesManager profilesManager = mock(ProfilesManager.class);
|
||||
SecureBackupClient secureBackupClient = mock(SecureBackupClient.class);
|
||||
SecureStorageClient secureStorageClient = mock(SecureStorageClient.class);
|
||||
|
||||
UUID uuid = UUID.randomUUID();
|
||||
|
||||
enableDynamo(dynamoEnabled);
|
||||
|
||||
when(commands.get(eq("Account3::" + uuid.toString()))).thenReturn("{\"number\": \"+14152222222\", \"name\": \"test\"}");
|
||||
when(commands.get(eq("Account3::" + uuid))).thenReturn("{\"number\": \"+14152222222\", \"name\": \"test\"}");
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, accountsDynamoDb, cacheCluster, deletedAccounts,
|
||||
directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager, secureStorageClient, secureBackupClient, experimentEnrollmentManager, dynamicConfigurationManager);
|
||||
Optional<Account> account = accountsManager.get(uuid);
|
||||
Optional<Account> account = accountsManager.get(uuid);
|
||||
|
||||
assertTrue(account.isPresent());
|
||||
assertEquals(account.get().getNumber(), "+14152222222");
|
||||
assertEquals(account.get().getUuid(), uuid);
|
||||
assertEquals(account.get().getProfileName(), "test");
|
||||
|
||||
verify(commands, times(1)).get(eq("Account3::" + uuid.toString()));
|
||||
verify(commands, times(1)).get(eq("Account3::" + uuid));
|
||||
verifyNoMoreInteractions(commands);
|
||||
verifyNoMoreInteractions(accounts);
|
||||
|
||||
verifyZeroInteractions(accountsDynamoDb);
|
||||
verifyNoInteractions(accountsDynamoDb);
|
||||
}
|
||||
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
void testGetAccountByNumberNotInCache(boolean dynamoEnabled) {
|
||||
RedisAdvancedClusterCommands<String, String> commands = mock(RedisAdvancedClusterCommands.class);
|
||||
FaultTolerantRedisCluster cacheCluster = RedisClusterHelper.buildMockRedisCluster(commands);
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
AccountsDynamoDb accountsDynamoDb = mock(AccountsDynamoDb.class);
|
||||
DeletedAccountsManager deletedAccounts = mock(DeletedAccountsManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
ProfilesManager profilesManager = mock(ProfilesManager.class);
|
||||
SecureBackupClient secureBackupClient = mock(SecureBackupClient.class);
|
||||
SecureStorageClient secureStorageClient = mock(SecureStorageClient.class);
|
||||
UUID uuid = UUID.randomUUID();
|
||||
Account account = new Account("+14152222222", uuid, new HashSet<>(), new byte[16]);
|
||||
UUID uuid = UUID.randomUUID();
|
||||
Account account = new Account("+14152222222", uuid, new HashSet<>(), new byte[16]);
|
||||
|
||||
enableDynamo(dynamoEnabled);
|
||||
|
||||
when(commands.get(eq("AccountMap::+14152222222"))).thenReturn(null);
|
||||
when(accounts.get(eq("+14152222222"))).thenReturn(Optional.of(account));
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, accountsDynamoDb, cacheCluster, deletedAccounts,
|
||||
directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager, secureStorageClient, secureBackupClient, experimentEnrollmentManager, dynamicConfigurationManager);
|
||||
Optional<Account> retrieved = accountsManager.get("+14152222222");
|
||||
Optional<Account> retrieved = accountsManager.get("+14152222222");
|
||||
|
||||
assertTrue(retrieved.isPresent());
|
||||
assertSame(retrieved.get(), account);
|
||||
|
||||
verify(commands, times(1)).get(eq("AccountMap::+14152222222"));
|
||||
verify(commands, times(1)).set(eq("AccountMap::+14152222222"), eq(uuid.toString()));
|
||||
verify(commands, times(1)).set(eq("Account3::" + uuid.toString()), anyString());
|
||||
verify(commands, times(1)).set(eq("Account3::" + uuid), anyString());
|
||||
verifyNoMoreInteractions(commands);
|
||||
|
||||
verify(accounts, times(1)).get(eq("+14152222222"));
|
||||
@@ -218,36 +207,22 @@ class AccountsManagerTest {
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
void testGetAccountByUuidNotInCache(boolean dynamoEnabled) {
|
||||
RedisAdvancedClusterCommands<String, String> commands = mock(RedisAdvancedClusterCommands.class);
|
||||
FaultTolerantRedisCluster cacheCluster = RedisClusterHelper.buildMockRedisCluster(commands);
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
AccountsDynamoDb accountsDynamoDb = mock(AccountsDynamoDb.class);
|
||||
DeletedAccountsManager deletedAccounts = mock(DeletedAccountsManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
ProfilesManager profilesManager = mock(ProfilesManager.class);
|
||||
SecureBackupClient secureBackupClient = mock(SecureBackupClient.class);
|
||||
SecureStorageClient secureStorageClient = mock(SecureStorageClient.class);
|
||||
UUID uuid = UUID.randomUUID();
|
||||
Account account = new Account("+14152222222", uuid, new HashSet<>(), new byte[16]);
|
||||
UUID uuid = UUID.randomUUID();
|
||||
Account account = new Account("+14152222222", uuid, new HashSet<>(), new byte[16]);
|
||||
|
||||
enableDynamo(dynamoEnabled);
|
||||
|
||||
when(commands.get(eq("Account3::" + uuid))).thenReturn(null);
|
||||
when(accounts.get(eq(uuid))).thenReturn(Optional.of(account));
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, accountsDynamoDb, cacheCluster, deletedAccounts,
|
||||
directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager, secureStorageClient, secureBackupClient, experimentEnrollmentManager, dynamicConfigurationManager);
|
||||
Optional<Account> retrieved = accountsManager.get(uuid);
|
||||
Optional<Account> retrieved = accountsManager.get(uuid);
|
||||
|
||||
assertTrue(retrieved.isPresent());
|
||||
assertSame(retrieved.get(), account);
|
||||
|
||||
verify(commands, times(1)).get(eq("Account3::" + uuid));
|
||||
verify(commands, times(1)).set(eq("AccountMap::+14152222222"), eq(uuid.toString()));
|
||||
verify(commands, times(1)).set(eq("Account3::" + uuid.toString()), anyString());
|
||||
verify(commands, times(1)).set(eq("Account3::" + uuid), anyString());
|
||||
verifyNoMoreInteractions(commands);
|
||||
|
||||
verify(accounts, times(1)).get(eq(uuid));
|
||||
@@ -260,18 +235,6 @@ class AccountsManagerTest {
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
void testGetAccountByNumberBrokenCache(boolean dynamoEnabled) {
|
||||
RedisAdvancedClusterCommands<String, String> commands = mock(RedisAdvancedClusterCommands.class);
|
||||
FaultTolerantRedisCluster cacheCluster = RedisClusterHelper.buildMockRedisCluster(commands);
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
AccountsDynamoDb accountsDynamoDb = mock(AccountsDynamoDb.class);
|
||||
DeletedAccountsManager deletedAccounts = mock(DeletedAccountsManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
ProfilesManager profilesManager = mock(ProfilesManager.class);
|
||||
SecureBackupClient secureBackupClient = mock(SecureBackupClient.class);
|
||||
SecureStorageClient secureStorageClient = mock(SecureStorageClient.class);
|
||||
UUID uuid = UUID.randomUUID();
|
||||
Account account = new Account("+14152222222", uuid, new HashSet<>(), new byte[16]);
|
||||
|
||||
@@ -280,8 +243,6 @@ class AccountsManagerTest {
|
||||
when(commands.get(eq("AccountMap::+14152222222"))).thenThrow(new RedisException("Connection lost!"));
|
||||
when(accounts.get(eq("+14152222222"))).thenReturn(Optional.of(account));
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, accountsDynamoDb, cacheCluster, deletedAccounts,
|
||||
directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager, secureStorageClient, secureBackupClient, experimentEnrollmentManager, dynamicConfigurationManager);
|
||||
Optional<Account> retrieved = accountsManager.get("+14152222222");
|
||||
|
||||
assertTrue(retrieved.isPresent());
|
||||
@@ -289,7 +250,7 @@ class AccountsManagerTest {
|
||||
|
||||
verify(commands, times(1)).get(eq("AccountMap::+14152222222"));
|
||||
verify(commands, times(1)).set(eq("AccountMap::+14152222222"), eq(uuid.toString()));
|
||||
verify(commands, times(1)).set(eq("Account3::" + uuid.toString()), anyString());
|
||||
verify(commands, times(1)).set(eq("Account3::" + uuid), anyString());
|
||||
verifyNoMoreInteractions(commands);
|
||||
|
||||
verify(accounts, times(1)).get(eq("+14152222222"));
|
||||
@@ -302,18 +263,6 @@ class AccountsManagerTest {
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
void testGetAccountByUuidBrokenCache(boolean dynamoEnabled) {
|
||||
RedisAdvancedClusterCommands<String, String> commands = mock(RedisAdvancedClusterCommands.class);
|
||||
FaultTolerantRedisCluster cacheCluster = RedisClusterHelper.buildMockRedisCluster(commands);
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
AccountsDynamoDb accountsDynamoDb = mock(AccountsDynamoDb.class);
|
||||
DeletedAccountsManager deletedAccounts = mock(DeletedAccountsManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
ProfilesManager profilesManager = mock(ProfilesManager.class);
|
||||
SecureBackupClient secureBackupClient = mock(SecureBackupClient.class);
|
||||
SecureStorageClient secureStorageClient = mock(SecureStorageClient.class);
|
||||
UUID uuid = UUID.randomUUID();
|
||||
Account account = new Account("+14152222222", uuid, new HashSet<>(), new byte[16]);
|
||||
|
||||
@@ -322,8 +271,6 @@ class AccountsManagerTest {
|
||||
when(commands.get(eq("Account3::" + uuid))).thenThrow(new RedisException("Connection lost!"));
|
||||
when(accounts.get(eq(uuid))).thenReturn(Optional.of(account));
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, accountsDynamoDb, cacheCluster, deletedAccounts,
|
||||
directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager, secureStorageClient, secureBackupClient, experimentEnrollmentManager, dynamicConfigurationManager);
|
||||
Optional<Account> retrieved = accountsManager.get(uuid);
|
||||
|
||||
assertTrue(retrieved.isPresent());
|
||||
@@ -331,7 +278,7 @@ class AccountsManagerTest {
|
||||
|
||||
verify(commands, times(1)).get(eq("Account3::" + uuid));
|
||||
verify(commands, times(1)).set(eq("AccountMap::+14152222222"), eq(uuid.toString()));
|
||||
verify(commands, times(1)).set(eq("Account3::" + uuid.toString()), anyString());
|
||||
verify(commands, times(1)).set(eq("Account3::" + uuid), anyString());
|
||||
verifyNoMoreInteractions(commands);
|
||||
|
||||
verify(accounts, times(1)).get(eq(uuid));
|
||||
@@ -344,18 +291,6 @@ class AccountsManagerTest {
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
void testUpdate_dynamoDbMigration(boolean dynamoEnabled) throws IOException {
|
||||
RedisAdvancedClusterCommands<String, String> commands = mock(RedisAdvancedClusterCommands.class);
|
||||
FaultTolerantRedisCluster cacheCluster = RedisClusterHelper.buildMockRedisCluster(commands);
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
AccountsDynamoDb accountsDynamoDb = mock(AccountsDynamoDb.class);
|
||||
DeletedAccountsManager deletedAccountsManager = mock(DeletedAccountsManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
ProfilesManager profilesManager = mock(ProfilesManager.class);
|
||||
SecureBackupClient secureBackupClient = mock(SecureBackupClient.class);
|
||||
SecureStorageClient secureStorageClient = mock(SecureStorageClient.class);
|
||||
UUID uuid = UUID.randomUUID();
|
||||
Account account = new Account("+14152222222", uuid, new HashSet<>(), new byte[16]);
|
||||
|
||||
@@ -367,9 +302,6 @@ class AccountsManagerTest {
|
||||
when(accountsDynamoDb.get(uuid)).thenReturn(Optional.of(new Account("+14152222222", uuid, new HashSet<>(), new byte[16])));
|
||||
doAnswer(ACCOUNT_UPDATE_ANSWER).when(accounts).update(any(Account.class));
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, accountsDynamoDb, cacheCluster, deletedAccountsManager,
|
||||
directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager, secureStorageClient, secureBackupClient, experimentEnrollmentManager, dynamicConfigurationManager);
|
||||
|
||||
Account updatedAccount = accountsManager.update(account, a -> a.setProfileName("name"));
|
||||
|
||||
assertThrows(AssertionError.class, account::getProfileName, "Account passed to update() should be stale");
|
||||
@@ -405,18 +337,6 @@ class AccountsManagerTest {
|
||||
|
||||
@Test
|
||||
void testUpdate_dynamoMissing() {
|
||||
RedisAdvancedClusterCommands<String, String> commands = mock(RedisAdvancedClusterCommands.class);
|
||||
FaultTolerantRedisCluster cacheCluster = RedisClusterHelper.buildMockRedisCluster(commands);
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
AccountsDynamoDb accountsDynamoDb = mock(AccountsDynamoDb.class);
|
||||
DeletedAccountsManager deletedAccounts = mock(DeletedAccountsManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
ProfilesManager profilesManager = mock(ProfilesManager.class);
|
||||
SecureBackupClient secureBackupClient = mock(SecureBackupClient.class);
|
||||
SecureStorageClient secureStorageClient = mock(SecureStorageClient.class);
|
||||
UUID uuid = UUID.randomUUID();
|
||||
Account account = new Account("+14152222222", uuid, new HashSet<>(), new byte[16]);
|
||||
|
||||
@@ -427,9 +347,6 @@ class AccountsManagerTest {
|
||||
doAnswer(ACCOUNT_UPDATE_ANSWER).when(accounts).update(any());
|
||||
doAnswer(ACCOUNT_UPDATE_ANSWER).when(accountsDynamoDb).update(any());
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, accountsDynamoDb, cacheCluster, deletedAccounts,
|
||||
directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager, secureStorageClient, secureBackupClient, experimentEnrollmentManager, dynamicConfigurationManager);
|
||||
|
||||
Account updatedAccount = accountsManager.update(account, a -> {});
|
||||
|
||||
verify(accounts, times(1)).update(account);
|
||||
@@ -444,18 +361,6 @@ class AccountsManagerTest {
|
||||
|
||||
@Test
|
||||
void testUpdate_optimisticLockingFailure() {
|
||||
RedisAdvancedClusterCommands<String, String> commands = mock(RedisAdvancedClusterCommands.class);
|
||||
FaultTolerantRedisCluster cacheCluster = RedisClusterHelper.buildMockRedisCluster(commands);
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
AccountsDynamoDb accountsDynamoDb = mock(AccountsDynamoDb.class);
|
||||
DeletedAccountsManager deletedAccounts = mock(DeletedAccountsManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
ProfilesManager profilesManager = mock(ProfilesManager.class);
|
||||
SecureBackupClient secureBackupClient = mock(SecureBackupClient.class);
|
||||
SecureStorageClient secureStorageClient = mock(SecureStorageClient.class);
|
||||
UUID uuid = UUID.randomUUID();
|
||||
Account account = new Account("+14152222222", uuid, new HashSet<>(), new byte[16]);
|
||||
|
||||
@@ -473,8 +378,6 @@ class AccountsManagerTest {
|
||||
.doAnswer(ACCOUNT_UPDATE_ANSWER)
|
||||
.when(accountsDynamoDb).update(any());
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, accountsDynamoDb, cacheCluster, deletedAccounts, directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager, secureStorageClient, secureBackupClient, experimentEnrollmentManager, dynamicConfigurationManager);
|
||||
|
||||
account = accountsManager.update(account, a -> a.setProfileName("name"));
|
||||
|
||||
assertEquals(1, account.getVersion());
|
||||
@@ -492,18 +395,6 @@ class AccountsManagerTest {
|
||||
|
||||
@Test
|
||||
void testUpdate_dynamoOptimisticLockingFailureDuringCreate() {
|
||||
RedisAdvancedClusterCommands<String, String> commands = mock(RedisAdvancedClusterCommands.class);
|
||||
FaultTolerantRedisCluster cacheCluster = RedisClusterHelper.buildMockRedisCluster(commands);
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
AccountsDynamoDb accountsDynamoDb = mock(AccountsDynamoDb.class);
|
||||
DeletedAccountsManager deletedAccountsManager = mock(DeletedAccountsManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
ProfilesManager profilesManager = mock(ProfilesManager.class);
|
||||
SecureBackupClient secureBackupClient = mock(SecureBackupClient.class);
|
||||
SecureStorageClient secureStorageClient = mock(SecureStorageClient.class);
|
||||
UUID uuid = UUID.randomUUID();
|
||||
Account account = new Account("+14152222222", uuid, new HashSet<>(), new byte[16]);
|
||||
|
||||
@@ -514,8 +405,6 @@ class AccountsManagerTest {
|
||||
.thenReturn(Optional.of(account));
|
||||
when(accountsDynamoDb.create(any())).thenThrow(ContestedOptimisticLockException.class);
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, accountsDynamoDb, cacheCluster, deletedAccountsManager, directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager, secureStorageClient, secureBackupClient, experimentEnrollmentManager, dynamicConfigurationManager);
|
||||
|
||||
accountsManager.update(account, a -> {});
|
||||
|
||||
verify(accounts, times(1)).update(account);
|
||||
@@ -526,22 +415,7 @@ class AccountsManagerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateDevice() throws Exception {
|
||||
RedisAdvancedClusterCommands<String, String> commands = mock(RedisAdvancedClusterCommands.class);
|
||||
FaultTolerantRedisCluster cacheCluster = RedisClusterHelper.buildMockRedisCluster(commands);
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
AccountsDynamoDb accountsDynamoDb = mock(AccountsDynamoDb.class);
|
||||
DeletedAccountsManager deletedAccountsManager = mock(DeletedAccountsManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
ProfilesManager profilesManager = mock(ProfilesManager.class);
|
||||
SecureBackupClient secureBackupClient = mock(SecureBackupClient.class);
|
||||
SecureStorageClient secureStorageClient = mock(SecureStorageClient.class);
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, accountsDynamoDb, cacheCluster, deletedAccountsManager, directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager, secureStorageClient, secureBackupClient, experimentEnrollmentManager, dynamicConfigurationManager);
|
||||
|
||||
void testUpdateDevice() {
|
||||
assertEquals(Optional.empty(), accountsManager.compareAccounts(Optional.empty(), Optional.empty()));
|
||||
|
||||
final UUID uuid = UUID.randomUUID();
|
||||
@@ -565,7 +439,7 @@ class AccountsManagerTest {
|
||||
account = accountsManager.updateDevice(account, deviceId, deviceUpdater);
|
||||
account = accountsManager.updateDevice(account, deviceId, d -> d.setName("deviceName"));
|
||||
|
||||
assertEquals("deviceName", account.getDevice(deviceId).get().getName());
|
||||
assertEquals("deviceName", account.getDevice(deviceId).orElseThrow().getName());
|
||||
|
||||
verify(deviceUpdater, times(1)).accept(any(Device.class));
|
||||
|
||||
@@ -574,25 +448,8 @@ class AccountsManagerTest {
|
||||
verify(unknownDeviceUpdater, never()).accept(any(Device.class));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testCompareAccounts() throws Exception {
|
||||
RedisAdvancedClusterCommands<String, String> commands = mock(RedisAdvancedClusterCommands.class);
|
||||
FaultTolerantRedisCluster cacheCluster = RedisClusterHelper.buildMockRedisCluster(commands);
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
AccountsDynamoDb accountsDynamoDb = mock(AccountsDynamoDb.class);
|
||||
DeletedAccountsManager deletedAccounts = mock(DeletedAccountsManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
ProfilesManager profilesManager = mock(ProfilesManager.class);
|
||||
SecureBackupClient secureBackupClient = mock(SecureBackupClient.class);
|
||||
SecureStorageClient secureStorageClient = mock(SecureStorageClient.class);
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, accountsDynamoDb, cacheCluster, deletedAccounts,
|
||||
directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager, secureStorageClient, secureBackupClient, experimentEnrollmentManager, dynamicConfigurationManager);
|
||||
|
||||
assertEquals(Optional.empty(), accountsManager.compareAccounts(Optional.empty(), Optional.empty()));
|
||||
|
||||
final UUID uuidA = UUID.randomUUID();
|
||||
@@ -663,4 +520,50 @@ class AccountsManagerTest {
|
||||
|
||||
assertEquals(Optional.of("profileName"), accountsManager.compareAccounts(Optional.of(a1), Optional.of(a2)));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
void testCreateWithDiscoverability(final boolean discoverable) {
|
||||
final AccountAttributes attributes = new AccountAttributes(false, 0, null, null, null, discoverable, null);
|
||||
final Account account = accountsManager.create("+18005550123", "password", null, attributes);
|
||||
|
||||
assertEquals(discoverable, account.isDiscoverableByPhoneNumber());
|
||||
|
||||
if (!discoverable) {
|
||||
verify(directoryQueue).deleteAccount(account);
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
void testCreateWithStorageCapability(final boolean hasStorage) {
|
||||
final AccountAttributes attributes = new AccountAttributes(false, 0, null, null, null, true,
|
||||
new DeviceCapabilities(false, false, false, hasStorage, false, false, false, false));
|
||||
|
||||
final Account account = accountsManager.create("+18005550123", "password", null, attributes);
|
||||
|
||||
assertEquals(hasStorage, account.isStorageSupported());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void testUpdateDirectoryQueue(final boolean discoverableBeforeUpdate, final boolean discoverableAfterUpdate, final boolean expectRefresh) {
|
||||
final Account account = new Account("+14152222222", UUID.randomUUID(), new HashSet<>(), new byte[16]);
|
||||
|
||||
when(directoryQueue.isDiscoverable(any()))
|
||||
.thenReturn(discoverableBeforeUpdate)
|
||||
.thenReturn(discoverableAfterUpdate);
|
||||
|
||||
final Account updatedAccount = accountsManager.update(account, a -> a.setProfileName("Hello I am a unit test"));
|
||||
|
||||
verify(directoryQueue, times(expectRefresh ? 1 : 0)).refreshAccount(updatedAccount);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> testUpdateDirectoryQueue() {
|
||||
return Stream.of(
|
||||
Arguments.of(false, false, false),
|
||||
Arguments.of(true, true, false),
|
||||
Arguments.of(false, true, true),
|
||||
Arguments.of(true, false, true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.whispersystems.textsecuregcm.tests.storage;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyBoolean;
|
||||
import static org.mockito.Mockito.eq;
|
||||
@@ -13,7 +12,7 @@ import static org.mockito.Mockito.isNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.whispersystems.textsecuregcm.tests.util.AccountsHelper.eqUuid;
|
||||
|
||||
@@ -23,11 +22,8 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.whispersystems.textsecuregcm.sqs.DirectoryQueue;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountDatabaseCrawlerRestartException;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
@@ -39,7 +35,6 @@ import org.whispersystems.textsecuregcm.util.Util;
|
||||
class PushFeedbackProcessorTest {
|
||||
|
||||
private AccountsManager accountsManager = mock(AccountsManager.class);
|
||||
private DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
|
||||
private Account uninstalledAccount = mock(Account.class);
|
||||
private Account mixedAccount = mock(Account.class);
|
||||
@@ -105,16 +100,15 @@ class PushFeedbackProcessorTest {
|
||||
|
||||
@Test
|
||||
void testEmpty() throws AccountDatabaseCrawlerRestartException {
|
||||
PushFeedbackProcessor processor = new PushFeedbackProcessor(accountsManager, directoryQueue);
|
||||
PushFeedbackProcessor processor = new PushFeedbackProcessor(accountsManager);
|
||||
processor.timeAndProcessCrawlChunk(Optional.of(UUID.randomUUID()), Collections.emptyList());
|
||||
|
||||
verifyZeroInteractions(accountsManager);
|
||||
verifyZeroInteractions(directoryQueue);
|
||||
verifyNoInteractions(accountsManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdate() throws AccountDatabaseCrawlerRestartException {
|
||||
PushFeedbackProcessor processor = new PushFeedbackProcessor(accountsManager, directoryQueue);
|
||||
PushFeedbackProcessor processor = new PushFeedbackProcessor(accountsManager);
|
||||
processor.timeAndProcessCrawlChunk(Optional.of(UUID.randomUUID()), List.of(uninstalledAccount, mixedAccount, stillActiveAccount, freshAccount, cleanAccount, undiscoverableAccount));
|
||||
|
||||
verify(uninstalledDevice).setApnId(isNull());
|
||||
@@ -151,15 +145,6 @@ class PushFeedbackProcessorTest {
|
||||
verify(stillActiveDevice, never()).setFetchesMessages(anyBoolean());
|
||||
|
||||
verify(accountsManager).update(eqUuid(stillActiveAccount), any());
|
||||
|
||||
final ArgumentCaptor<List<Account>> refreshedAccountArgumentCaptor = ArgumentCaptor.forClass(List.class);
|
||||
verify(directoryQueue).refreshRegisteredUsers(refreshedAccountArgumentCaptor.capture());
|
||||
|
||||
final List<UUID> refreshedUuids = refreshedAccountArgumentCaptor.getValue().stream()
|
||||
.map(Account::getUuid)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertTrue(refreshedUuids.containsAll(List.of(undiscoverableAccount.getUuid(), uninstalledAccount.getUuid())));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user