mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-21 12:08:03 +01:00
Prepare to read profile data stored as byte arrays
This commit is contained in:
@@ -12,6 +12,9 @@ import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.signal.libsignal.protocol.ServiceId;
|
||||
import org.signal.libsignal.zkgroup.InvalidInputException;
|
||||
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
|
||||
import org.whispersystems.textsecuregcm.util.AttributeValues;
|
||||
import org.whispersystems.textsecuregcm.storage.DynamoDbExtensionSchema.Tables;
|
||||
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
|
||||
@@ -19,78 +22,85 @@ import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Timeout(value = 10, threadMode = Timeout.ThreadMode.SEPARATE_THREAD)
|
||||
public class ProfilesTest {
|
||||
|
||||
private static final UUID ACI = UUID.randomUUID();
|
||||
@RegisterExtension
|
||||
static final DynamoDbExtension DYNAMO_DB_EXTENSION = new DynamoDbExtension(Tables.PROFILES);
|
||||
|
||||
private Profiles profiles;
|
||||
private VersionedProfile validProfile;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
void setUp() throws InvalidInputException {
|
||||
profiles = new Profiles(DYNAMO_DB_EXTENSION.getDynamoDbClient(),
|
||||
DYNAMO_DB_EXTENSION.getDynamoDbAsyncClient(),
|
||||
Tables.PROFILES.tableName());
|
||||
final byte[] commitment = new ProfileKey(new byte[32]).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||
final String version = "someVersion";
|
||||
final String name = generateRandomBase64FromByteArray(81);
|
||||
final String validAboutEmoji = generateRandomBase64FromByteArray(60);
|
||||
final String validAbout = generateRandomBase64FromByteArray(156);
|
||||
final String avatar = "profiles/" + generateRandomBase64FromByteArray(16);
|
||||
|
||||
validProfile = new VersionedProfile(version, name, avatar, validAboutEmoji, validAbout, null, commitment);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetGet() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
VersionedProfile profile = new VersionedProfile("123", "foo", "avatarLocation", "emoji",
|
||||
"the very model of a modern major general",
|
||||
null, "acommitment".getBytes());
|
||||
profiles.set(uuid, profile);
|
||||
profiles.set(ACI, validProfile);
|
||||
|
||||
Optional<VersionedProfile> retrieved = profiles.get(uuid, "123");
|
||||
Optional<VersionedProfile> retrieved = profiles.get(ACI, validProfile.getVersion());
|
||||
|
||||
assertThat(retrieved.isPresent()).isTrue();
|
||||
assertThat(retrieved.get().getName()).isEqualTo(profile.getName());
|
||||
assertThat(retrieved.get().getAvatar()).isEqualTo(profile.getAvatar());
|
||||
assertThat(retrieved.get().getCommitment()).isEqualTo(profile.getCommitment());
|
||||
assertThat(retrieved.get().getAbout()).isEqualTo(profile.getAbout());
|
||||
assertThat(retrieved.get().getAboutEmoji()).isEqualTo(profile.getAboutEmoji());
|
||||
assertThat(retrieved.get().getName()).isEqualTo(validProfile.getName());
|
||||
assertThat(retrieved.get().getAvatar()).isEqualTo(validProfile.getAvatar());
|
||||
assertThat(retrieved.get().getCommitment()).isEqualTo(validProfile.getCommitment());
|
||||
assertThat(retrieved.get().getAbout()).isEqualTo(validProfile.getAbout());
|
||||
assertThat(retrieved.get().getAboutEmoji()).isEqualTo(validProfile.getAboutEmoji());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetGetAsync() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
VersionedProfile profile = new VersionedProfile("123", "foo", "avatarLocation", "emoji",
|
||||
"the very model of a modern major general",
|
||||
null, "acommitment".getBytes());
|
||||
profiles.setAsync(uuid, profile).join();
|
||||
profiles.setAsync(ACI, validProfile).join();
|
||||
|
||||
Optional<VersionedProfile> retrieved = profiles.getAsync(uuid, "123").join();
|
||||
Optional<VersionedProfile> retrieved = profiles.getAsync(ACI, validProfile.getVersion()).join();
|
||||
|
||||
assertThat(retrieved.isPresent()).isTrue();
|
||||
assertThat(retrieved.get().getName()).isEqualTo(profile.getName());
|
||||
assertThat(retrieved.get().getAvatar()).isEqualTo(profile.getAvatar());
|
||||
assertThat(retrieved.get().getCommitment()).isEqualTo(profile.getCommitment());
|
||||
assertThat(retrieved.get().getAbout()).isEqualTo(profile.getAbout());
|
||||
assertThat(retrieved.get().getAboutEmoji()).isEqualTo(profile.getAboutEmoji());
|
||||
assertThat(retrieved.get().getName()).isEqualTo(validProfile.getName());
|
||||
assertThat(retrieved.get().getAvatar()).isEqualTo(validProfile.getAvatar());
|
||||
assertThat(retrieved.get().getCommitment()).isEqualTo(validProfile.getCommitment());
|
||||
assertThat(retrieved.get().getAbout()).isEqualTo(validProfile.getAbout());
|
||||
assertThat(retrieved.get().getAboutEmoji()).isEqualTo(validProfile.getAboutEmoji());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeleteReset() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
profiles.set(uuid, new VersionedProfile("123", "foo", "avatarLocation", "emoji",
|
||||
"the very model of a modern major general",
|
||||
null, "acommitment".getBytes()));
|
||||
void testDeleteReset() throws InvalidInputException {
|
||||
profiles.set(ACI, validProfile);
|
||||
|
||||
profiles.deleteAll(uuid);
|
||||
profiles.deleteAll(ACI);
|
||||
|
||||
VersionedProfile updatedProfile = new VersionedProfile("123", "name", "differentAvatarLocation",
|
||||
"differentEmoji", "changed text", "paymentAddress", "differentcommitment".getBytes(StandardCharsets.UTF_8));
|
||||
final String version = "someVersion";
|
||||
final String name = generateRandomBase64FromByteArray(81);
|
||||
final String differentAvatar = "profiles/" + generateRandomBase64FromByteArray(16);
|
||||
final String differentEmoji = generateRandomBase64FromByteArray(60);
|
||||
final String differentAbout = generateRandomBase64FromByteArray(156);
|
||||
final String paymentAddress = generateRandomBase64FromByteArray(582);
|
||||
final byte[] commitment = new ProfileKey(generateRandomByteArray(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||
|
||||
profiles.set(uuid, updatedProfile);
|
||||
VersionedProfile updatedProfile = new VersionedProfile(version, name, differentAvatar,
|
||||
differentEmoji, differentAbout, paymentAddress, commitment);
|
||||
|
||||
Optional<VersionedProfile> retrieved = profiles.get(uuid, "123");
|
||||
profiles.set(ACI, updatedProfile);
|
||||
|
||||
Optional<VersionedProfile> retrieved = profiles.get(ACI, version);
|
||||
|
||||
assertThat(retrieved.isPresent()).isTrue();
|
||||
assertThat(retrieved.get().getName()).isEqualTo(updatedProfile.getName());
|
||||
@@ -101,13 +111,16 @@ public class ProfilesTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetGetNullOptionalFields() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
VersionedProfile profile = new VersionedProfile("123", "foo", null, null, null, null,
|
||||
"acommitment".getBytes());
|
||||
profiles.set(uuid, profile);
|
||||
void testSetGetNullOptionalFields() throws InvalidInputException {
|
||||
final String version = "someVersion";
|
||||
final String name = generateRandomBase64FromByteArray(81);
|
||||
final byte[] commitment = new ProfileKey(generateRandomByteArray(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||
|
||||
Optional<VersionedProfile> retrieved = profiles.get(uuid, "123");
|
||||
VersionedProfile profile = new VersionedProfile(version, name, null, null, null, null,
|
||||
commitment);
|
||||
profiles.set(ACI, profile);
|
||||
|
||||
Optional<VersionedProfile> retrieved = profiles.get(ACI, version);
|
||||
|
||||
assertThat(retrieved.isPresent()).isTrue();
|
||||
assertThat(retrieved.get().getName()).isEqualTo(profile.getName());
|
||||
@@ -118,26 +131,30 @@ public class ProfilesTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetReplace() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
VersionedProfile profile = new VersionedProfile("123", "foo", "avatarLocation", null, null,
|
||||
"paymentAddress", "acommitment".getBytes());
|
||||
profiles.set(uuid, profile);
|
||||
void testSetReplace() throws InvalidInputException {
|
||||
profiles.set(ACI, validProfile);
|
||||
|
||||
Optional<VersionedProfile> retrieved = profiles.get(uuid, "123");
|
||||
Optional<VersionedProfile> retrieved = profiles.get(ACI, validProfile.getVersion());
|
||||
|
||||
assertThat(retrieved.isPresent()).isTrue();
|
||||
assertThat(retrieved.get().getName()).isEqualTo(profile.getName());
|
||||
assertThat(retrieved.get().getAvatar()).isEqualTo(profile.getAvatar());
|
||||
assertThat(retrieved.get().getCommitment()).isEqualTo(profile.getCommitment());
|
||||
assertThat(retrieved.get().getAbout()).isNull();
|
||||
assertThat(retrieved.get().getAboutEmoji()).isNull();
|
||||
assertThat(retrieved.get().getName()).isEqualTo(validProfile.getName());
|
||||
assertThat(retrieved.get().getAvatar()).isEqualTo(validProfile.getAvatar());
|
||||
assertThat(retrieved.get().getCommitment()).isEqualTo(validProfile.getCommitment());
|
||||
assertThat(retrieved.get().getAbout()).isEqualTo(validProfile.getAbout());
|
||||
assertThat(retrieved.get().getAboutEmoji()).isEqualTo(validProfile.getAboutEmoji());
|
||||
assertThat(retrieved.get().getPaymentAddress()).isNull();
|
||||
|
||||
VersionedProfile updated = new VersionedProfile("123", "bar", "baz", "emoji", "bio", null,
|
||||
"boof".getBytes());
|
||||
profiles.set(uuid, updated);
|
||||
final String differentName = generateRandomBase64FromByteArray(81);
|
||||
final String differentEmoji = generateRandomBase64FromByteArray(60);
|
||||
final String differentAbout = generateRandomBase64FromByteArray(156);
|
||||
final String differentAvatar = "profiles/" + generateRandomBase64FromByteArray(16);
|
||||
final byte[] differentCommitment = new ProfileKey(generateRandomByteArray(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||
|
||||
retrieved = profiles.get(uuid, "123");
|
||||
VersionedProfile updated = new VersionedProfile(validProfile.getVersion(), differentName, differentAvatar, differentEmoji, differentAbout, null,
|
||||
differentCommitment);
|
||||
profiles.set(ACI, updated);
|
||||
|
||||
retrieved = profiles.get(ACI, updated.getVersion());
|
||||
|
||||
assertThat(retrieved.isPresent()).isTrue();
|
||||
assertThat(retrieved.get().getName()).isEqualTo(updated.getName());
|
||||
@@ -146,22 +163,34 @@ public class ProfilesTest {
|
||||
assertThat(retrieved.get().getAvatar()).isEqualTo(updated.getAvatar());
|
||||
|
||||
// Commitment should be unchanged after an overwrite
|
||||
assertThat(retrieved.get().getCommitment()).isEqualTo(profile.getCommitment());
|
||||
assertThat(retrieved.get().getCommitment()).isEqualTo(validProfile.getCommitment());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMultipleVersions() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
VersionedProfile profileOne = new VersionedProfile("123", "foo", "avatarLocation", null, null,
|
||||
null, "acommitmnet".getBytes());
|
||||
VersionedProfile profileTwo = new VersionedProfile("345", "bar", "baz", "emoji",
|
||||
"i keep typing emoju for some reason",
|
||||
null, "boof".getBytes());
|
||||
void testMultipleVersions() throws InvalidInputException {
|
||||
final String versionOne = "versionOne";
|
||||
final String versionTwo = "versionTwo";
|
||||
|
||||
profiles.set(uuid, profileOne);
|
||||
profiles.set(uuid, profileTwo);
|
||||
final String nameOne = generateRandomBase64FromByteArray(81);
|
||||
final String nameTwo = generateRandomBase64FromByteArray(81);
|
||||
|
||||
Optional<VersionedProfile> retrieved = profiles.get(uuid, "123");
|
||||
final String avatarOne = "profiles/" + generateRandomBase64FromByteArray(16);
|
||||
final String avatarTwo = "profiles/" + generateRandomBase64FromByteArray(16);
|
||||
|
||||
final String aboutEmoji = generateRandomBase64FromByteArray(60);
|
||||
final String about = generateRandomBase64FromByteArray(156);
|
||||
|
||||
final byte[] commitmentOne = new ProfileKey(generateRandomByteArray(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||
final byte[] commitmentTwo = new ProfileKey(generateRandomByteArray(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||
|
||||
VersionedProfile profileOne = new VersionedProfile(versionOne, nameOne, avatarOne, null, null,
|
||||
null, commitmentOne);
|
||||
VersionedProfile profileTwo = new VersionedProfile(versionTwo, nameTwo, avatarTwo, aboutEmoji, about, null, commitmentTwo);
|
||||
|
||||
profiles.set(ACI, profileOne);
|
||||
profiles.set(ACI, profileTwo);
|
||||
|
||||
Optional<VersionedProfile> retrieved = profiles.get(ACI, versionOne);
|
||||
|
||||
assertThat(retrieved.isPresent()).isTrue();
|
||||
assertThat(retrieved.get().getName()).isEqualTo(profileOne.getName());
|
||||
@@ -170,7 +199,7 @@ public class ProfilesTest {
|
||||
assertThat(retrieved.get().getAbout()).isEqualTo(profileOne.getAbout());
|
||||
assertThat(retrieved.get().getAboutEmoji()).isEqualTo(profileOne.getAboutEmoji());
|
||||
|
||||
retrieved = profiles.get(uuid, "345");
|
||||
retrieved = profiles.get(ACI, versionTwo);
|
||||
|
||||
assertThat(retrieved.isPresent()).isTrue();
|
||||
assertThat(retrieved.get().getName()).isEqualTo(profileTwo.getName());
|
||||
@@ -182,33 +211,45 @@ public class ProfilesTest {
|
||||
|
||||
@Test
|
||||
void testMissing() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
VersionedProfile profile = new VersionedProfile("123", "foo", "avatarLocation", null, null,
|
||||
null, "aDigest".getBytes());
|
||||
profiles.set(uuid, profile);
|
||||
profiles.set(ACI, validProfile);
|
||||
final String missingVersion = "missingVersion";
|
||||
|
||||
Optional<VersionedProfile> retrieved = profiles.get(uuid, "888");
|
||||
Optional<VersionedProfile> retrieved = profiles.get(ACI, missingVersion);
|
||||
assertThat(retrieved.isPresent()).isFalse();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testDelete() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
VersionedProfile profileOne = new VersionedProfile("123", "foo", "avatarLocation", null, null,
|
||||
null, "aDigest".getBytes());
|
||||
VersionedProfile profileTwo = new VersionedProfile("345", "bar", "baz", null, null, null, "boof".getBytes());
|
||||
void testDelete() throws InvalidInputException {
|
||||
final String versionOne = "versionOne";
|
||||
final String versionTwo = "versionTwo";
|
||||
|
||||
profiles.set(uuid, profileOne);
|
||||
profiles.set(uuid, profileTwo);
|
||||
final String nameOne = generateRandomBase64FromByteArray(81);
|
||||
final String nameTwo = generateRandomBase64FromByteArray(81);
|
||||
|
||||
profiles.deleteAll(uuid);
|
||||
final String aboutEmoji = generateRandomBase64FromByteArray(60);
|
||||
final String about = generateRandomBase64FromByteArray(156);
|
||||
|
||||
Optional<VersionedProfile> retrieved = profiles.get(uuid, "123");
|
||||
final String avatarOne = "profiles/" + generateRandomBase64FromByteArray(16);
|
||||
final String avatarTwo = "profiles/" + generateRandomBase64FromByteArray(16);
|
||||
|
||||
final byte[] commitmentOne = new ProfileKey(generateRandomByteArray(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||
final byte[] commitmentTwo = new ProfileKey(generateRandomByteArray(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||
|
||||
VersionedProfile profileOne = new VersionedProfile(versionOne, nameOne, avatarOne, null, null,
|
||||
null, commitmentOne);
|
||||
VersionedProfile profileTwo = new VersionedProfile(versionTwo, nameTwo, avatarTwo, aboutEmoji, about, null, commitmentTwo);
|
||||
|
||||
profiles.set(ACI, profileOne);
|
||||
profiles.set(ACI, profileTwo);
|
||||
|
||||
profiles.deleteAll(ACI);
|
||||
|
||||
Optional<VersionedProfile> retrieved = profiles.get(ACI, versionOne);
|
||||
|
||||
assertThat(retrieved.isPresent()).isFalse();
|
||||
|
||||
retrieved = profiles.get(uuid, "345");
|
||||
retrieved = profiles.get(ACI, versionTwo);
|
||||
|
||||
assertThat(retrieved.isPresent()).isFalse();
|
||||
}
|
||||
@@ -219,32 +260,38 @@ public class ProfilesTest {
|
||||
assertEquals(expectedUpdateExpression, Profiles.buildUpdateExpression(profile));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> buildUpdateExpression() {
|
||||
final byte[] commitment = "commitment".getBytes(StandardCharsets.UTF_8);
|
||||
private static Stream<Arguments> buildUpdateExpression() throws InvalidInputException {
|
||||
final String version = "someVersion";
|
||||
final String name = generateRandomBase64FromByteArray(81);
|
||||
final String avatar = "profiles/" + generateRandomBase64FromByteArray(16);;
|
||||
final String emoji = generateRandomBase64FromByteArray(60);
|
||||
final String about = generateRandomBase64FromByteArray(156);
|
||||
final String paymentAddress = generateRandomBase64FromByteArray(582);
|
||||
final byte[] commitment = new ProfileKey(generateRandomByteArray(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(
|
||||
new VersionedProfile("version", "name", "avatar", "emoji", "about", "paymentAddress", commitment),
|
||||
new VersionedProfile(version, name, avatar, emoji, about, paymentAddress, commitment),
|
||||
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar, #about = :about, #aboutEmoji = :aboutEmoji, #paymentAddress = :paymentAddress"),
|
||||
|
||||
Arguments.of(
|
||||
new VersionedProfile("version", "name", "avatar", "emoji", "about", null, commitment),
|
||||
new VersionedProfile(version, name, avatar, emoji, about, null, commitment),
|
||||
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar, #about = :about, #aboutEmoji = :aboutEmoji REMOVE #paymentAddress"),
|
||||
|
||||
Arguments.of(
|
||||
new VersionedProfile("version", "name", "avatar", "emoji", null, null, commitment),
|
||||
new VersionedProfile(version, name, avatar, emoji, null, null, commitment),
|
||||
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar, #aboutEmoji = :aboutEmoji REMOVE #about, #paymentAddress"),
|
||||
|
||||
Arguments.of(
|
||||
new VersionedProfile("version", "name", "avatar", null, null, null, commitment),
|
||||
new VersionedProfile(version, name, avatar, null, null, null, commitment),
|
||||
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar REMOVE #about, #aboutEmoji, #paymentAddress"),
|
||||
|
||||
Arguments.of(
|
||||
new VersionedProfile("version", "name", null, null, null, null, commitment),
|
||||
new VersionedProfile(version, name, null, null, null, null, commitment),
|
||||
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name REMOVE #avatar, #about, #aboutEmoji, #paymentAddress"),
|
||||
|
||||
Arguments.of(
|
||||
new VersionedProfile("version", null, null, null, null, null, commitment),
|
||||
new VersionedProfile(version, null, null, null, null, null, commitment),
|
||||
"SET #commitment = if_not_exists(#commitment, :commitment) REMOVE #name, #avatar, #about, #aboutEmoji, #paymentAddress")
|
||||
);
|
||||
}
|
||||
@@ -255,53 +302,69 @@ public class ProfilesTest {
|
||||
assertEquals(expectedAttributeValues, Profiles.buildUpdateExpressionAttributeValues(profile));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> buildUpdateExpressionAttributeValues() {
|
||||
final byte[] commitment = "commitment".getBytes(StandardCharsets.UTF_8);
|
||||
private static Stream<Arguments> buildUpdateExpressionAttributeValues() throws InvalidInputException {
|
||||
final String version = "someVersion";
|
||||
final String name = generateRandomBase64FromByteArray(81);
|
||||
final String avatar = "profiles/" + generateRandomBase64FromByteArray(16);;
|
||||
final String emoji = generateRandomBase64FromByteArray(60);
|
||||
final String about = generateRandomBase64FromByteArray(156);
|
||||
final String paymentAddress = generateRandomBase64FromByteArray(582);
|
||||
final byte[] commitment = new ProfileKey(generateRandomByteArray(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(
|
||||
new VersionedProfile("version", "name", "avatar", "emoji", "about", "paymentAddress", commitment),
|
||||
new VersionedProfile(version, name, avatar, emoji, about, paymentAddress, commitment),
|
||||
Map.of(
|
||||
":commitment", AttributeValues.fromByteArray(commitment),
|
||||
":name", AttributeValues.fromString("name"),
|
||||
":avatar", AttributeValues.fromString("avatar"),
|
||||
":aboutEmoji", AttributeValues.fromString("emoji"),
|
||||
":about", AttributeValues.fromString("about"),
|
||||
":paymentAddress", AttributeValues.fromString("paymentAddress"))),
|
||||
":name", AttributeValues.fromString(name),
|
||||
":avatar", AttributeValues.fromString(avatar),
|
||||
":aboutEmoji", AttributeValues.fromString(emoji),
|
||||
":about", AttributeValues.fromString(about),
|
||||
":paymentAddress", AttributeValues.fromString(paymentAddress))),
|
||||
|
||||
Arguments.of(
|
||||
new VersionedProfile("version", "name", "avatar", "emoji", "about", null, commitment),
|
||||
new VersionedProfile(version, name, avatar, emoji, about, null, commitment),
|
||||
Map.of(
|
||||
":commitment", AttributeValues.fromByteArray(commitment),
|
||||
":name", AttributeValues.fromString("name"),
|
||||
":avatar", AttributeValues.fromString("avatar"),
|
||||
":aboutEmoji", AttributeValues.fromString("emoji"),
|
||||
":about", AttributeValues.fromString("about"))),
|
||||
":name", AttributeValues.fromString(name),
|
||||
":avatar", AttributeValues.fromString(avatar),
|
||||
":aboutEmoji", AttributeValues.fromString(emoji),
|
||||
":about", AttributeValues.fromString(about))),
|
||||
|
||||
Arguments.of(
|
||||
new VersionedProfile("version", "name", "avatar", "emoji", null, null, commitment),
|
||||
new VersionedProfile(version, name, avatar, emoji, null, null, commitment),
|
||||
Map.of(
|
||||
":commitment", AttributeValues.fromByteArray(commitment),
|
||||
":name", AttributeValues.fromString("name"),
|
||||
":avatar", AttributeValues.fromString("avatar"),
|
||||
":aboutEmoji", AttributeValues.fromString("emoji"))),
|
||||
":name", AttributeValues.fromString(name),
|
||||
":avatar", AttributeValues.fromString(avatar),
|
||||
":aboutEmoji", AttributeValues.fromString(emoji))),
|
||||
|
||||
Arguments.of(
|
||||
new VersionedProfile("version", "name", "avatar", null, null, null, commitment),
|
||||
new VersionedProfile(version, name, avatar, null, null, null, commitment),
|
||||
Map.of(
|
||||
":commitment", AttributeValues.fromByteArray(commitment),
|
||||
":name", AttributeValues.fromString("name"),
|
||||
":avatar", AttributeValues.fromString("avatar"))),
|
||||
":name", AttributeValues.fromString(name),
|
||||
":avatar", AttributeValues.fromString(avatar))),
|
||||
|
||||
Arguments.of(
|
||||
new VersionedProfile("version", "name", null, null, null, null, commitment),
|
||||
new VersionedProfile(version, name, null, null, null, null, commitment),
|
||||
Map.of(
|
||||
":commitment", AttributeValues.fromByteArray(commitment),
|
||||
":name", AttributeValues.fromString("name"))),
|
||||
":name", AttributeValues.fromString(name))),
|
||||
|
||||
Arguments.of(
|
||||
new VersionedProfile("version", null, null, null, null, null, commitment),
|
||||
new VersionedProfile(version, null, null, null, null, null, commitment),
|
||||
Map.of(":commitment", AttributeValues.fromByteArray(commitment)))
|
||||
);
|
||||
}
|
||||
|
||||
private static String generateRandomBase64FromByteArray(final int byteArrayLength) {
|
||||
return Base64.getEncoder().encodeToString(generateRandomByteArray(byteArrayLength));
|
||||
}
|
||||
|
||||
private static byte[] generateRandomByteArray(final int length) {
|
||||
byte[] byteArray = new byte[length];
|
||||
new Random().nextBytes(byteArray);
|
||||
return byteArray;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,34 +122,4 @@ abstract class SingleUsePreKeyStoreTest<K extends PreKey<?>> {
|
||||
assertEquals(0, preKeyStore.getCount(accountIdentifier, deviceId).join());
|
||||
assertEquals(0, preKeyStore.getCount(accountIdentifier, deviceId + 1).join());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void extractByteArray(final AttributeValue attributeValue, final byte[] expectedByteArray) {
|
||||
assertArrayEquals(expectedByteArray, getPreKeyStore().extractByteArray(attributeValue));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> extractByteArray() {
|
||||
final byte[] key = Base64.getDecoder().decode("c+k+8zv8WaFdDjR9IOvCk6BcY5OI7rge/YUDkaDGyRc=");
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(AttributeValue.fromB(SdkBytes.fromByteArray(key)), key),
|
||||
Arguments.of(AttributeValue.fromS(Base64.getEncoder().encodeToString(key)), key),
|
||||
Arguments.of(AttributeValue.fromS(Base64.getEncoder().withoutPadding().encodeToString(key)), key)
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void extractByteArrayIllegalArgument(final AttributeValue attributeValue) {
|
||||
assertThrows(IllegalArgumentException.class, () -> getPreKeyStore().extractByteArray(attributeValue));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> extractByteArrayIllegalArgument() {
|
||||
return Stream.of(
|
||||
Arguments.of(AttributeValue.fromN("12")),
|
||||
Arguments.of(AttributeValue.fromS("")),
|
||||
Arguments.of(AttributeValue.fromS("Definitely not legitimate base64 👎"))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,16 @@
|
||||
package org.whispersystems.textsecuregcm.util;
|
||||
|
||||
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 software.amazon.awssdk.core.SdkBytes;
|
||||
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Base64;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@@ -63,4 +69,34 @@ public class AttributeValuesTest {
|
||||
final Map<String, AttributeValue> item = Map.of("key", AttributeValue.builder().nul(true).build());
|
||||
assertNull(AttributeValues.getUUID(item, "key", null));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void extractByteArray(final AttributeValue attributeValue, final byte[] expectedByteArray) {
|
||||
assertArrayEquals(expectedByteArray, AttributeValues.extractByteArray(attributeValue, "counter"));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> extractByteArray() {
|
||||
final byte[] key = Base64.getDecoder().decode("c+k+8zv8WaFdDjR9IOvCk6BcY5OI7rge/YUDkaDGyRc=");
|
||||
|
||||
return Stream.of(
|
||||
Arguments.of(AttributeValue.fromB(SdkBytes.fromByteArray(key)), key),
|
||||
Arguments.of(AttributeValue.fromS(Base64.getEncoder().encodeToString(key)), key),
|
||||
Arguments.of(AttributeValue.fromS(Base64.getEncoder().withoutPadding().encodeToString(key)), key)
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void extractByteArrayIllegalArgument(final AttributeValue attributeValue) {
|
||||
assertThrows(IllegalArgumentException.class, () -> AttributeValues.extractByteArray(attributeValue, "counter"));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> extractByteArrayIllegalArgument() {
|
||||
return Stream.of(
|
||||
Arguments.of(AttributeValue.fromN("12")),
|
||||
Arguments.of(AttributeValue.fromS("")),
|
||||
Arguments.of(AttributeValue.fromS("Definitely not legitimate base64 👎"))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user