mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-20 00:29:11 +01:00
Add send and receive support for group member labels.
This commit is contained in:
committed by
Greyson Parrelli
parent
ce46c44b5d
commit
0a572153f0
@@ -1,6 +1,7 @@
|
||||
package org.whispersystems.signalservice.api.groupsv2;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.signal.core.util.UuidUtil;
|
||||
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
|
||||
import org.signal.storageservice.storage.protos.groups.AccessControl;
|
||||
import org.signal.storageservice.storage.protos.groups.Member;
|
||||
@@ -9,6 +10,7 @@ import org.signal.storageservice.storage.protos.groups.local.DecryptedBannedMemb
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberLabel;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberRole;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMember;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMemberRemoval;
|
||||
@@ -16,7 +18,6 @@ import org.signal.storageservice.storage.protos.groups.local.DecryptedRequesting
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedString;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedTimer;
|
||||
import org.signal.storageservice.storage.protos.groups.local.EnabledState;
|
||||
import org.signal.core.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.util.Util;
|
||||
|
||||
import java.util.List;
|
||||
@@ -38,8 +39,8 @@ import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.reque
|
||||
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.withProfileKey;
|
||||
import static org.whispersystems.signalservice.api.groupsv2.ProtobufTestUtils.getMaxDeclaredFieldNumber;
|
||||
|
||||
@SuppressWarnings("NewClassNamingConvention")
|
||||
public final class DecryptedGroupUtil_apply_Test {
|
||||
|
||||
/**
|
||||
* Reflects over the generated protobuf class and ensures that no new fields have been added since we wrote this.
|
||||
* <p>
|
||||
@@ -50,7 +51,7 @@ public final class DecryptedGroupUtil_apply_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroupChange.class);
|
||||
|
||||
assertEquals("DecryptedGroupUtil and its tests need updating to account for new fields on " + DecryptedGroupChange.class.getName(),
|
||||
24, maxFieldFound);
|
||||
26, maxFieldFound);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -956,4 +957,99 @@ public final class DecryptedGroupUtil_apply_Test {
|
||||
.build(),
|
||||
newGroup);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void apply_modify_member_label() throws NotAbleToApplyGroupV2ChangeException {
|
||||
UUID memberUuid = UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001");
|
||||
DecryptedMember existingMember = member(memberUuid);
|
||||
|
||||
DecryptedModifyMemberLabel modifyLabelAction = new DecryptedModifyMemberLabel.Builder()
|
||||
.aciBytes(UuidUtil.toByteString(memberUuid))
|
||||
.labelEmoji("🎉")
|
||||
.labelString("Test Label")
|
||||
.build();
|
||||
|
||||
DecryptedGroup actualResult = DecryptedGroupUtil.apply(
|
||||
new DecryptedGroup.Builder()
|
||||
.revision(10)
|
||||
.members(List.of(existingMember))
|
||||
.build(),
|
||||
|
||||
new DecryptedGroupChange.Builder()
|
||||
.revision(11)
|
||||
.modifyMemberLabel(List.of(modifyLabelAction))
|
||||
.build()
|
||||
);
|
||||
|
||||
List<DecryptedMember> expectedMembers = List.of(
|
||||
existingMember.newBuilder()
|
||||
.labelEmoji("🎉")
|
||||
.labelString("Test Label")
|
||||
.build()
|
||||
);
|
||||
|
||||
DecryptedGroup expectedResult = new DecryptedGroup.Builder()
|
||||
.revision(11)
|
||||
.members(expectedMembers)
|
||||
.build();
|
||||
|
||||
assertEquals(expectedResult, actualResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void apply_modify_member_label_clear() throws NotAbleToApplyGroupV2ChangeException {
|
||||
UUID memberUuid = UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001");
|
||||
DecryptedMember member = member(memberUuid)
|
||||
.newBuilder()
|
||||
.labelEmoji("🎉")
|
||||
.labelString("Test Label")
|
||||
.build();
|
||||
|
||||
DecryptedModifyMemberLabel modifyLabelAction = new DecryptedModifyMemberLabel.Builder()
|
||||
.aciBytes(UuidUtil.toByteString(memberUuid))
|
||||
.labelEmoji("")
|
||||
.labelString("")
|
||||
.build();
|
||||
|
||||
DecryptedGroup actualResult = DecryptedGroupUtil.apply(
|
||||
new DecryptedGroup.Builder()
|
||||
.revision(10)
|
||||
.members(List.of(member))
|
||||
.build(),
|
||||
|
||||
new DecryptedGroupChange.Builder()
|
||||
.revision(11)
|
||||
.modifyMemberLabel(List.of(modifyLabelAction))
|
||||
.build());
|
||||
|
||||
DecryptedGroup expectedResult = new DecryptedGroup.Builder()
|
||||
.revision(11)
|
||||
.members(List.of(member(memberUuid)))
|
||||
.build();
|
||||
|
||||
assertEquals(expectedResult, actualResult);
|
||||
}
|
||||
|
||||
@Test(expected = NotAbleToApplyGroupV2ChangeException.class)
|
||||
public void apply_modify_member_label_for_non_member() throws NotAbleToApplyGroupV2ChangeException {
|
||||
UUID memberUuid = UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001");
|
||||
UUID nonMemberUuid = UUID.fromString("d2d2d2d2-0000-4000-8000-000000000002");
|
||||
DecryptedMember member1 = member(memberUuid);
|
||||
|
||||
DecryptedModifyMemberLabel modifyLabelAction = new DecryptedModifyMemberLabel.Builder()
|
||||
.aciBytes(UuidUtil.toByteString(nonMemberUuid))
|
||||
.labelEmoji("🎉")
|
||||
.labelString("Test Label")
|
||||
.build();
|
||||
|
||||
DecryptedGroupUtil.apply(
|
||||
new DecryptedGroup.Builder()
|
||||
.revision(10)
|
||||
.members(List.of(member1))
|
||||
.build(),
|
||||
new DecryptedGroupChange.Builder()
|
||||
.revision(11)
|
||||
.modifyMemberLabel(List.of(modifyLabelAction))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
package org.whispersystems.signalservice.api.groupsv2;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.signal.core.util.UuidUtil;
|
||||
import org.signal.storageservice.storage.protos.groups.AccessControl;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedApproveMember;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedBannedMember;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberLabel;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedRequestingMember;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedString;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedTimer;
|
||||
import org.signal.storageservice.storage.protos.groups.local.EnabledState;
|
||||
import org.signal.core.util.UuidUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@@ -27,8 +28,8 @@ import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.promo
|
||||
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.randomProfileKey;
|
||||
import static org.whispersystems.signalservice.api.groupsv2.ProtobufTestUtils.getMaxDeclaredFieldNumber;
|
||||
|
||||
@SuppressWarnings("NewClassNamingConvention")
|
||||
public final class DecryptedGroupUtil_empty_Test {
|
||||
|
||||
/**
|
||||
* Reflects over the generated protobuf class and ensures that no new fields have been added since we wrote this.
|
||||
* <p>
|
||||
@@ -39,7 +40,7 @@ public final class DecryptedGroupUtil_empty_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroupChange.class);
|
||||
|
||||
assertEquals("DecryptedGroupUtil and its tests need updating to account for new fields on " + DecryptedGroupChange.class.getName(),
|
||||
24, maxFieldFound);
|
||||
26, maxFieldFound);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -266,4 +267,21 @@ public final class DecryptedGroupUtil_empty_Test {
|
||||
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
|
||||
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void not_empty_with_modify_member_label_field_26() {
|
||||
DecryptedModifyMemberLabel modifyLabelAction = new DecryptedModifyMemberLabel.Builder()
|
||||
.aciBytes(UuidUtil.toByteString(UUID.randomUUID()))
|
||||
.labelEmoji("🔥")
|
||||
.labelString("Test")
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange change = new DecryptedGroupChange.Builder()
|
||||
.modifyMemberLabel(List.of(modifyLabelAction))
|
||||
.build();
|
||||
|
||||
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
|
||||
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
|
||||
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForBanChangesAndOptionalProfileKeyChanges(change));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
package org.whispersystems.signalservice.api.groupsv2;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.signal.core.util.UuidUtil;
|
||||
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
|
||||
import org.signal.storageservice.storage.protos.groups.AccessControl;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedString;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedTimer;
|
||||
import org.signal.storageservice.storage.protos.groups.local.EnabledState;
|
||||
import org.signal.core.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.util.Util;
|
||||
|
||||
import java.util.List;
|
||||
@@ -408,4 +409,57 @@ public final class GroupChangeReconstructTest {
|
||||
|
||||
assertEquals(new DecryptedGroupChange.Builder().deleteBannedMembers(List.of(bannedMember(uuidOld))).build(), decryptedGroupChange);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void member_label_change() {
|
||||
UUID memberUuid = UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001");
|
||||
|
||||
DecryptedMember existingMember = member(memberUuid);
|
||||
DecryptedMember updatedMember = member(memberUuid)
|
||||
.newBuilder()
|
||||
.labelEmoji("🎉")
|
||||
.labelString("New Label")
|
||||
.build();
|
||||
|
||||
DecryptedGroup from = new DecryptedGroup.Builder()
|
||||
.members(List.of(existingMember))
|
||||
.build();
|
||||
|
||||
DecryptedGroup to = new DecryptedGroup.Builder()
|
||||
.members(List.of(updatedMember))
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange change = GroupChangeReconstruct.reconstructGroupChange(from, to);
|
||||
|
||||
assertEquals(1, change.modifyMemberLabel.size());
|
||||
assertEquals(UuidUtil.toByteString(memberUuid), change.modifyMemberLabel.get(0).aciBytes);
|
||||
assertEquals("🎉", change.modifyMemberLabel.get(0).labelEmoji);
|
||||
assertEquals("New Label", change.modifyMemberLabel.get(0).labelString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void member_label_clear() {
|
||||
UUID memberUuid = UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001");
|
||||
|
||||
DecryptedMember memberWithLabel = member(memberUuid)
|
||||
.newBuilder()
|
||||
.labelEmoji("🎉")
|
||||
.labelString("existing label")
|
||||
.build();
|
||||
|
||||
DecryptedGroup from = new DecryptedGroup.Builder()
|
||||
.members(List.of(memberWithLabel))
|
||||
.build();
|
||||
|
||||
DecryptedGroup to = new DecryptedGroup.Builder()
|
||||
.members(List.of(member(memberUuid)))
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange change = GroupChangeReconstruct.reconstructGroupChange(from, to);
|
||||
|
||||
assertEquals(1, change.modifyMemberLabel.size());
|
||||
assertEquals(UuidUtil.toByteString(memberUuid), change.modifyMemberLabel.get(0).aciBytes);
|
||||
assertEquals("", change.modifyMemberLabel.get(0).labelEmoji);
|
||||
assertEquals("", change.modifyMemberLabel.get(0).labelString);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.whispersystems.signalservice.api.groupsv2.ProtobufTestUtils.getMaxDeclaredFieldNumber;
|
||||
|
||||
@SuppressWarnings("NewClassNamingConvention")
|
||||
public final class GroupChangeUtil_changeIsEmpty_Test {
|
||||
|
||||
/**
|
||||
* Reflects over the generated protobuf class and ensures that no new fields have been added since we wrote this.
|
||||
* <p>
|
||||
@@ -22,7 +22,7 @@ public final class GroupChangeUtil_changeIsEmpty_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(GroupChange.Actions.class);
|
||||
|
||||
assertEquals("GroupChangeUtil and its tests need updating to account for new fields on " + GroupChange.Actions.class.getName(),
|
||||
25, maxFieldFound);
|
||||
26, maxFieldFound);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -227,4 +227,13 @@ public final class GroupChangeUtil_changeIsEmpty_Test {
|
||||
|
||||
assertFalse(GroupChangeUtil.changeIsEmpty(actions));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void not_empty_with_modify_member_label_field_26() {
|
||||
GroupChange.Actions actions = new GroupChange.Actions.Builder()
|
||||
.modifyMemberLabel(List.of(new GroupChange.Actions.ModifyMemberLabelAction()))
|
||||
.build();
|
||||
|
||||
assertFalse(GroupChangeUtil.changeIsEmpty(actions));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
package org.whispersystems.signalservice.api.groupsv2;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.signal.core.util.UuidUtil;
|
||||
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
|
||||
import org.signal.storageservice.storage.protos.groups.AccessControl;
|
||||
import org.signal.storageservice.storage.protos.groups.MemberBanned;
|
||||
import org.signal.storageservice.storage.protos.groups.GroupChange;
|
||||
import org.signal.storageservice.storage.protos.groups.Member;
|
||||
import org.signal.storageservice.storage.protos.groups.MemberBanned;
|
||||
import org.signal.storageservice.storage.protos.groups.MemberPendingProfileKey;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberLabel;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedString;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedTimer;
|
||||
import org.signal.storageservice.storage.protos.groups.local.EnabledState;
|
||||
import org.signal.core.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.util.Util;
|
||||
|
||||
import java.util.List;
|
||||
@@ -40,8 +41,8 @@ import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.rando
|
||||
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.requestingMember;
|
||||
import static org.whispersystems.signalservice.api.groupsv2.ProtobufTestUtils.getMaxDeclaredFieldNumber;
|
||||
|
||||
@SuppressWarnings("NewClassNamingConvention")
|
||||
public final class GroupChangeUtil_resolveConflict_Test {
|
||||
|
||||
/**
|
||||
* Reflects over the generated protobuf class and ensures that no new fields have been added since we wrote this.
|
||||
* <p>
|
||||
@@ -52,7 +53,7 @@ public final class GroupChangeUtil_resolveConflict_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroupChange.class);
|
||||
|
||||
assertEquals("GroupChangeUtil#resolveConflict and its tests need updating to account for new fields on " + DecryptedGroupChange.class.getName(),
|
||||
24, maxFieldFound);
|
||||
26, maxFieldFound);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +66,7 @@ public final class GroupChangeUtil_resolveConflict_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroupChange.class);
|
||||
|
||||
assertEquals("GroupChangeUtil#resolveConflict and its tests need updating to account for new fields on " + GroupChange.class.getName(),
|
||||
24, maxFieldFound);
|
||||
26, maxFieldFound);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -854,4 +855,57 @@ public final class GroupChangeUtil_resolveConflict_Test {
|
||||
.build();
|
||||
assertEquals(expected, resolvedActions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_26__modify_member_label__remove_if_label_already_matches() {
|
||||
UUID memberUuid = UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001");
|
||||
|
||||
DecryptedMember existingMember = member(memberUuid)
|
||||
.newBuilder()
|
||||
.labelEmoji("🔥")
|
||||
.labelString("matching label")
|
||||
.build();
|
||||
|
||||
DecryptedGroup existingGroup = new DecryptedGroup.Builder()
|
||||
.revision(10)
|
||||
.members(List.of(existingMember))
|
||||
.build();
|
||||
|
||||
DecryptedModifyMemberLabel modifyLabelAction = new DecryptedModifyMemberLabel.Builder()
|
||||
.aciBytes(UuidUtil.toByteString(memberUuid))
|
||||
.labelEmoji("🔥")
|
||||
.labelString("matching label")
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange conflictingChange = new DecryptedGroupChange.Builder()
|
||||
.modifyMemberLabel(List.of(modifyLabelAction))
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange.Builder resolvedActions = GroupChangeUtil.resolveConflict(existingGroup, conflictingChange);
|
||||
assertTrue(resolvedActions.build().modifyMemberLabel.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_26__modify_member_label__remove_if_member_not_in_group() {
|
||||
UUID memberUuuid = UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001");
|
||||
UUID nonMemberUuid = UUID.fromString("d2d2d2d2-0000-4000-8000-000000000002");
|
||||
|
||||
DecryptedGroup existingGroup = new DecryptedGroup.Builder()
|
||||
.revision(10)
|
||||
.members(List.of(member(memberUuuid)))
|
||||
.build();
|
||||
|
||||
DecryptedModifyMemberLabel modifyLabelAction = new org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberLabel.Builder()
|
||||
.aciBytes(UuidUtil.toByteString(nonMemberUuid))
|
||||
.labelEmoji("🔥")
|
||||
.labelString("foo bar")
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange conflictingChange = new DecryptedGroupChange.Builder()
|
||||
.modifyMemberLabel(List.of(modifyLabelAction))
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange.Builder resolved = GroupChangeUtil.resolveConflict(existingGroup, conflictingChange);
|
||||
assertTrue(resolved.build().modifyMemberLabel.isEmpty());
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,16 @@
|
||||
package org.whispersystems.signalservice.api.groupsv2;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.signal.core.util.UuidUtil;
|
||||
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
|
||||
import org.signal.storageservice.storage.protos.groups.AccessControl;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberLabel;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedString;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedTimer;
|
||||
import org.signal.storageservice.storage.protos.groups.local.EnabledState;
|
||||
import org.signal.core.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.util.Util;
|
||||
|
||||
import java.util.List;
|
||||
@@ -32,8 +33,8 @@ import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.rando
|
||||
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.requestingMember;
|
||||
import static org.whispersystems.signalservice.api.groupsv2.ProtobufTestUtils.getMaxDeclaredFieldNumber;
|
||||
|
||||
@SuppressWarnings("NewClassNamingConvention")
|
||||
public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
|
||||
|
||||
/**
|
||||
* Reflects over the generated protobuf class and ensures that no new fields have been added since we wrote this.
|
||||
* <p>
|
||||
@@ -44,7 +45,7 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroupChange.class);
|
||||
|
||||
assertEquals("GroupChangeUtil#resolveConflict and its tests need updating to account for new fields on " + DecryptedGroupChange.class.getName(),
|
||||
24, maxFieldFound);
|
||||
26, maxFieldFound);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -673,4 +674,57 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
|
||||
|
||||
assertEquals(expected, resolvedChanges);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_26__modify_member_label__remove_if_label_already_matches() {
|
||||
UUID memberUuid = UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001");
|
||||
|
||||
DecryptedMember existingMember = member(memberUuid)
|
||||
.newBuilder()
|
||||
.labelEmoji("🔥")
|
||||
.labelString("Already Set")
|
||||
.build();
|
||||
|
||||
DecryptedModifyMemberLabel modifyLabelAction = new DecryptedModifyMemberLabel.Builder()
|
||||
.aciBytes(UuidUtil.toByteString(memberUuid))
|
||||
.labelEmoji("🔥")
|
||||
.labelString("Already Set")
|
||||
.build();
|
||||
|
||||
DecryptedGroup existingGroup = new DecryptedGroup.Builder()
|
||||
.revision(10)
|
||||
.members(List.of(existingMember))
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange conflictingChange = new DecryptedGroupChange.Builder()
|
||||
.modifyMemberLabel(List.of(modifyLabelAction))
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange.Builder resolved = GroupChangeUtil.resolveConflict(existingGroup, conflictingChange);
|
||||
assertTrue(resolved.build().modifyMemberLabel.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_26__modify_member_label__remove_if_member_not_in_group() {
|
||||
UUID memberUuid = UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001");
|
||||
UUID notInGroupUuid = UUID.fromString("d2d2d2d2-0000-4000-8000-000000000002");
|
||||
|
||||
DecryptedGroup existingGroup = new DecryptedGroup.Builder()
|
||||
.revision(10)
|
||||
.members(List.of(member(memberUuid)))
|
||||
.build();
|
||||
|
||||
DecryptedModifyMemberLabel modifyLabelAction = new DecryptedModifyMemberLabel.Builder()
|
||||
.aciBytes(UuidUtil.toByteString(notInGroupUuid))
|
||||
.labelEmoji("🔥")
|
||||
.labelString("Test")
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange conflictingChange = new DecryptedGroupChange.Builder()
|
||||
.modifyMemberLabel(List.of(modifyLabelAction))
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange.Builder resolved = GroupChangeUtil.resolveConflict(existingGroup, conflictingChange);
|
||||
assertTrue(resolved.build().modifyMemberLabel.isEmpty());
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,9 @@ package org.whispersystems.signalservice.api.groupsv2;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.signal.core.models.ServiceId.ACI;
|
||||
import org.signal.core.models.ServiceId.PNI;
|
||||
import org.signal.core.util.UuidUtil;
|
||||
import org.signal.libsignal.zkgroup.InvalidInputException;
|
||||
import org.signal.libsignal.zkgroup.VerificationFailedException;
|
||||
import org.signal.libsignal.zkgroup.groups.ClientZkGroupCipher;
|
||||
@@ -23,6 +26,7 @@ import org.signal.storageservice.storage.protos.groups.local.DecryptedApproveMem
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedBannedMember;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberLabel;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberRole;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMember;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMemberRemoval;
|
||||
@@ -30,9 +34,6 @@ import org.signal.storageservice.storage.protos.groups.local.DecryptedRequesting
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedString;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedTimer;
|
||||
import org.signal.storageservice.storage.protos.groups.local.EnabledState;
|
||||
import org.signal.core.models.ServiceId.ACI;
|
||||
import org.signal.core.models.ServiceId.PNI;
|
||||
import org.signal.core.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.util.Util;
|
||||
import org.whispersystems.signalservice.testutil.LibSignalLibraryUtil;
|
||||
|
||||
@@ -50,8 +51,8 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.whispersystems.signalservice.api.groupsv2.ProtobufTestUtils.getMaxDeclaredFieldNumber;
|
||||
|
||||
@SuppressWarnings("NewClassNamingConvention")
|
||||
public final class GroupsV2Operations_decrypt_change_Test {
|
||||
|
||||
private GroupSecretParams groupSecretParams;
|
||||
private GroupsV2Operations.GroupOperations groupOperations;
|
||||
private ClientZkOperations clientZkOperations;
|
||||
@@ -72,7 +73,7 @@ public final class GroupsV2Operations_decrypt_change_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroupChange.class);
|
||||
|
||||
assertEquals("GroupV2Operations#decryptChange and its tests need updating to account for new fields on " + DecryptedGroupChange.class.getName(),
|
||||
24,
|
||||
26,
|
||||
maxFieldFound);
|
||||
}
|
||||
|
||||
@@ -459,6 +460,22 @@ public final class GroupsV2Operations_decrypt_change_Test {
|
||||
.build())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void can_decrypt_modify_member_label_field26() {
|
||||
ACI aci = ACI.from(UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001"));
|
||||
|
||||
DecryptedModifyMemberLabel modifyLabelAction = new DecryptedModifyMemberLabel.Builder()
|
||||
.aciBytes(aci.toByteString())
|
||||
.labelString("Label Text")
|
||||
.labelEmoji("🔥")
|
||||
.build();
|
||||
|
||||
assertDecryption(
|
||||
groupOperations.createChangeMemberLabel(aci, "Label Text", "🔥"),
|
||||
new DecryptedGroupChange.Builder().modifyMemberLabel(List.of(modifyLabelAction))
|
||||
);
|
||||
}
|
||||
|
||||
private static ProfileKey newProfileKey() {
|
||||
try {
|
||||
return new ProfileKey(Util.getSecretBytes(32));
|
||||
|
||||
Reference in New Issue
Block a user