Add numberless variants to username tests

This commit is contained in:
Ravi Khadiwala
2026-08-12 09:07:42 -04:00
committed by Jon Chambers
parent d99515e31e
commit 9d601047c8
2 changed files with 83 additions and 44 deletions
@@ -1262,9 +1262,10 @@ class AccountsManagerTest {
assertThrows(AssertionError.class, () -> accountsManager.update(uuid, a -> a.setNumber(targetNumber, UUID.randomUUID())));
}
@Test
void testReserveUsernameHash() throws UsernameHashNotAvailableException {
final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testReserveUsernameHash(boolean hasNumber) throws UsernameHashNotAvailableException {
final Account account = AccountsHelper.generateTestAccount(hasNumber ? "+18005551234" : null, new ArrayList<>());
when(accounts.getByAccountIdentifier(account.getAccountIdentifier())).thenReturn(Optional.of(account));
final List<byte[]> usernameHashes = List.of(TestRandomUtil.nextBytes(32), TestRandomUtil.nextBytes(32));
@@ -1316,9 +1317,10 @@ class AccountsManagerTest {
accountsManager.reserveUsernameHash(account.getIdentifier(IdentityType.ACI), List.of(USERNAME_HASH_1, USERNAME_HASH_2)));
}
@Test
void testConfirmReservedUsernameHash() throws UsernameHashNotAvailableException, UsernameReservationNotFoundException {
final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testConfirmReservedUsernameHash(final boolean hasNumber) throws UsernameHashNotAvailableException, UsernameReservationNotFoundException {
final Account account = AccountsHelper.generateTestAccount(hasNumber ? "+18005551234" : null, new ArrayList<>());
addRetrievableAccount(account);
setReservationHash(account, USERNAME_HASH_1);
@@ -1386,9 +1388,10 @@ class AccountsManagerTest {
verify(accounts, never()).confirmUsernameHash(any(), any(), any());
}
@Test
void testClearUsernameHash() {
final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testClearUsernameHash(final boolean hasNumber) {
final Account account = AccountsHelper.generateTestAccount(hasNumber ? "+18005551234" : null, new ArrayList<>());
addRetrievableAccount(account);
account.setUsernameHash(USERNAME_HASH_1);
@@ -1396,9 +1399,10 @@ class AccountsManagerTest {
verify(accounts).clearUsernameHash(eq(account));
}
@Test
void testSetUsernameViaUpdate() {
final Account account = AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), new ArrayList<>(), new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH]);
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testSetUsernameViaUpdate(final boolean hasNumber) {
final Account account = AccountsHelper.generateTestAccount(hasNumber ? "+18005551234" : null, new ArrayList<>());
addRetrievableAccount(account);
assertThrows(AssertionError.class, () ->
@@ -1349,10 +1349,10 @@ class AccountsTest {
assertPhoneNumberIdentifierConstraintExists(targetPni, firstAccountInstance.getAccountIdentifier());
}
@Test
void testSwitchUsernameHashes() throws UsernameHashNotAvailableException {
final Account account = generateAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID());
createAccount(account);
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testSwitchUsernameHashes(final boolean numberless) throws UsernameHashNotAvailableException {
final Account account = createAccount(numberless);
assertThat(accounts.getByUsernameHash(USERNAME_HASH_1).join()).isEmpty();
@@ -1362,10 +1362,12 @@ class AccountsTest {
{
final Optional<Account> maybeAccount = accounts.getByUsernameHash(USERNAME_HASH_1).join();
verifyStoredState(account.getNumber(), account.getAccountIdentifier(), account.getPhoneNumberIdentifier(), USERNAME_HASH_1, maybeAccount.orElseThrow(), account);
assertThat(maybeAccount.orElseThrow().getUsernameHash()).hasValue(USERNAME_HASH_1);
verifyAccountEquals(maybeAccount.orElseThrow(), account);
final Optional<Account> maybeAccount2 = accounts.getByUsernameLinkHandle(oldHandle).join();
verifyStoredState(account.getNumber(), account.getAccountIdentifier(), account.getPhoneNumberIdentifier(), USERNAME_HASH_1, maybeAccount2.orElseThrow(), account);
assertThat(maybeAccount2.orElseThrow().getUsernameHash()).hasValue(USERNAME_HASH_1);
verifyAccountEquals(maybeAccount2.orElseThrow(), account);
}
accounts.reserveUsernameHash(account, USERNAME_HASH_2, Duration.ofDays(1));
@@ -1386,11 +1388,11 @@ class AccountsTest {
final Optional<Account> maybeAccount = accounts.getByUsernameHash(USERNAME_HASH_2).join();
assertThat(maybeAccount).isPresent();
verifyStoredState(account.getNumber(), account.getAccountIdentifier(), account.getPhoneNumberIdentifier(),
USERNAME_HASH_2, maybeAccount.orElseThrow(), account);
assertThat(maybeAccount.orElseThrow().getUsernameHash()).hasValue(USERNAME_HASH_2);
verifyAccountEquals(maybeAccount.orElseThrow(), account);
final Optional<Account> maybeAccount2 = accounts.getByUsernameLinkHandle(newHandle).join();
verifyStoredState(account.getNumber(), account.getAccountIdentifier(), account.getPhoneNumberIdentifier(),
USERNAME_HASH_2, maybeAccount2.orElseThrow(), account);
assertThat(maybeAccount2.orElseThrow().getUsernameHash()).hasValue(USERNAME_HASH_2);
verifyAccountEquals(maybeAccount2.orElseThrow(), account);
}
}
@@ -1540,10 +1542,10 @@ class AccountsTest {
assertThat(account.getUsernameHash()).isEmpty();
}
@Test
void testClearUsername() throws UsernameHashNotAvailableException {
final Account account = generateAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID());
createAccount(account);
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testClearUsername(final boolean numberless) throws UsernameHashNotAvailableException {
final Account account = createAccount(numberless);
accounts.reserveUsernameHash(account, USERNAME_HASH_1, Duration.ofDays(1));
accounts.confirmUsernameHash(account, USERNAME_HASH_1, ENCRYPTED_USERNAME_1);
@@ -1639,12 +1641,11 @@ class AccountsTest {
);
}
@Test
void testReservedUsernameHash() throws UsernameHashNotAvailableException {
final Account account1 = generateAccount("+18005551111", UUID.randomUUID(), UUID.randomUUID());
createAccount(account1);
final Account account2 = generateAccount("+18005552222", UUID.randomUUID(), UUID.randomUUID());
createAccount(account2);
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testReservedUsernameHash(final boolean numberless) throws UsernameHashNotAvailableException {
final Account account1 = createAccount(numberless);
final Account account2 = createAccount(numberless);
accounts.reserveUsernameHash(account1, USERNAME_HASH_1, Duration.ofDays(1));
assertArrayEquals(USERNAME_HASH_1, account1.getReservedUsernameHash().orElseThrow());
@@ -1835,10 +1836,10 @@ class AccountsTest {
}
}
@Test
void testHoldUsername() throws UsernameHashNotAvailableException {
final Account account = generateAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID());
createAccount(account);
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testHoldUsername(final boolean numberless) throws UsernameHashNotAvailableException {
final Account account = createAccount(numberless);
accounts.reserveUsernameHash(account, USERNAME_HASH_1, Duration.ofDays(1));
accounts.confirmUsernameHash(account, USERNAME_HASH_1, ENCRYPTED_USERNAME_1);
@@ -1991,12 +1992,19 @@ class AccountsTest {
}
@Test
public void testIgnoredFieldsNotAddedToDataAttribute() throws Exception {
final Account account = generateAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID());
@ParameterizedTest
@ValueSource(booleans = {false, true})
public void testIgnoredFieldsNotAddedToDataAttribute(final boolean numberless) throws Exception {
final Account account = numberless
? generateNumberlessAccount(UUID.randomUUID())
: generateAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID());
account.setUsernameHash(TestRandomUtil.nextBytes(32));
account.setUsernameLinkDetails(UUID.randomUUID(), TestRandomUtil.nextBytes(32));
createAccount(account);
if (numberless) {
createNumberlessAccount(account, receiptPresentation(), TestRandomUtil.nextBytes(16));
} else {
createAccount(account);
}
final Map<String, AttributeValue> accountRecord = DYNAMO_DB_EXTENSION.getDynamoDbClient()
.getItem(GetItemRequest.builder()
.tableName(Tables.ACCOUNTS.tableName())
@@ -2009,12 +2017,12 @@ class AccountsTest {
.forEach(field -> assertFalse(dataMap.containsKey(field)));
}
@Test
void testGetByUsernameHashAsync() throws UsernameHashNotAvailableException {
@ParameterizedTest
@ValueSource(booleans = {false, true})
void testGetByUsernameHashAsync(final boolean numberless) throws UsernameHashNotAvailableException {
assertThat(accounts.getByUsernameHash(USERNAME_HASH_1).join()).isEmpty();
final Account account = generateAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID());
createAccount(account);
final Account account = createAccount(numberless);
assertThat(accounts.getByUsernameHash(USERNAME_HASH_1).join()).isEmpty();
@@ -2277,6 +2285,23 @@ class AccountsTest {
}
}
/// Generate a random account and create it
private Account createAccount(final boolean numberless) {
try {
final Account account;
if (numberless) {
account = generateNumberlessAccount(UUID.randomUUID());
createNumberlessAccount(account, receiptPresentation(), TestRandomUtil.nextBytes(16));
} else {
account = nextRandomAccount();
createAccount(account);
}
return account;
} catch (InvalidInputException | VerificationFailedException e) {
throw new AssertionError(e);
}
}
private static Account nextRandomAccount() {
final String nextNumber = "+1800%07d".formatted(ACCOUNT_COUNTER.getAndIncrement());
return generateAccount(nextNumber, UUID.randomUUID(), UUID.randomUUID());
@@ -2410,6 +2435,16 @@ class AccountsTest {
}
}
private void verifyAccountEquals(Account result, Account expecting) {
verifyStoredState(
expecting.getNumberOptional().orElse(null),
expecting.getAccountIdentifier(),
expecting.getPhoneNumberIdentifierOptional().orElse(null),
expecting.getUsernameHash().orElse(null),
result,
expecting);
}
private void verifyStoredState(String number, UUID uuid, UUID pni, byte[] usernameHash, Account result, Account expecting) {
assertThat(result.getNumberOptional()).isEqualTo(Optional.ofNullable(number));
assertThat(result.getPhoneNumberIdentifierOptional()).isEqualTo(Optional.ofNullable(pni));