public CompletableFuture<Pair<Account, Device>> addDevice(final Account account, final DeviceSpec deviceSpec) {
    return accountLockManager.withLockAsync(List.of(account.getNumber()),
        () -> addDevice(account.getIdentifier(IdentityType.ACI), deviceSpec, MAX_UPDATE_ATTEMPTS),
        accountLockExecutor);
  }
@Test
  void testAddDevice() {
    final String phoneNumber =
        PhoneNumberUtil.getInstance().format(PhoneNumberUtil.getInstance().getExampleNumber("US"),
            PhoneNumberUtil.PhoneNumberFormat.E164);

    final Account account = AccountsHelper.generateTestAccount(phoneNumber, List.of(generateTestDevice(clock.millis())));
    final UUID aci = account.getIdentifier(IdentityType.ACI);
    final UUID pni = account.getIdentifier(IdentityType.PNI);

    final byte nextDeviceId = account.getNextDeviceId();

    final ECKeyPair aciKeyPair = Curve.generateKeyPair();
    final ECKeyPair pniKeyPair = Curve.generateKeyPair();

    final byte[] deviceNameCiphertext = "device-name".getBytes(StandardCharsets.UTF_8);
    final String password = "password";
    final String signalAgent = "OWT";
    final DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, true, false, false);
    final int aciRegistrationId = 17;
    final int pniRegistrationId = 19;
    final ECSignedPreKey aciSignedPreKey = KeysHelper.signedECPreKey(1, aciKeyPair);
    final ECSignedPreKey pniSignedPreKey = KeysHelper.signedECPreKey(2, pniKeyPair);
    final KEMSignedPreKey aciPqLastResortPreKey = KeysHelper.signedKEMPreKey(3, aciKeyPair);
    final KEMSignedPreKey pniPqLastResortPreKey = KeysHelper.signedKEMPreKey(4, pniKeyPair);

    when(keysManager.deleteSingleUsePreKeys(any(), anyByte())).thenReturn(CompletableFuture.completedFuture(null));
    when(messagesManager.clear(any(), anyByte())).thenReturn(CompletableFuture.completedFuture(null));
    when(accounts.getByAccountIdentifierAsync(aci)).thenReturn(CompletableFuture.completedFuture(Optional.of(account)));
    when(accounts.updateTransactionallyAsync(any(), any())).thenReturn(CompletableFuture.completedFuture(null));

    clock.pin(clock.instant().plusSeconds(60));

    final Pair<Account, Device> updatedAccountAndDevice = accountsManager.addDevice(account, new DeviceSpec(
            deviceNameCiphertext,
            password,
            signalAgent,
            deviceCapabilities,
            aciRegistrationId,
            pniRegistrationId,
            true,
            Optional.empty(),
            Optional.empty(),
            aciSignedPreKey,
            pniSignedPreKey,
            aciPqLastResortPreKey,
            pniPqLastResortPreKey))
        .join();

    verify(keysManager).deleteSingleUsePreKeys(aci, nextDeviceId);
    verify(keysManager).deleteSingleUsePreKeys(pni, nextDeviceId);
    verify(messagesManager).clear(aci, nextDeviceId);

    verify(keysManager).buildWriteItemsForNewDevice(
        aci,
        pni,
        nextDeviceId,
        aciSignedPreKey,
        pniSignedPreKey,
        aciPqLastResortPreKey,
        pniPqLastResortPreKey);

    final Device device = updatedAccountAndDevice.second();

    assertEquals(deviceNameCiphertext, device.getName());
    assertTrue(device.getAuthTokenHash().verify(password));
    assertEquals(signalAgent, device.getUserAgent());
    assertEquals(deviceCapabilities, device.getCapabilities());
    assertEquals(aciRegistrationId, device.getRegistrationId());
    assertEquals(pniRegistrationId, device.getPhoneNumberIdentityRegistrationId().getAsInt());
    assertTrue(device.getFetchesMessages());
    assertNull(device.getApnId());
    assertNull(device.getVoipApnId());
    assertNull(device.getGcmId());
  }