mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-17 15:33:30 +01:00
Add group terminate support.
This commit is contained in:
@@ -50,4 +50,6 @@ public interface ChangeSetModifier {
|
||||
void removeModifyMemberLabels(int i);
|
||||
|
||||
void clearModifyMemberLabelAccess();
|
||||
|
||||
void clearTerminateGroup();
|
||||
}
|
||||
|
||||
@@ -118,6 +118,10 @@ internal class DecryptedGroupChangeActionsBuilderChangeSetModifier(private val r
|
||||
result.newMemberLabelAccess = AccessControl.AccessRequired.UNKNOWN
|
||||
}
|
||||
|
||||
override fun clearTerminateGroup() {
|
||||
result.terminateGroup = false
|
||||
}
|
||||
|
||||
private fun <T> List<T>.removeIndex(i: Int): List<T> {
|
||||
val modifiedList = this.toMutableList()
|
||||
modifiedList.removeAt(i)
|
||||
|
||||
@@ -89,6 +89,7 @@ fun DecryptedGroupChange.getChangedFields(): Set<GroupChangeField> {
|
||||
if (newRequestingMembers.isNotEmpty()) add(GroupChangeField.REQUESTING_MEMBERS)
|
||||
if (newTimer != null) add(GroupChangeField.TIMER)
|
||||
if (newTitle != null) add(GroupChangeField.TITLE)
|
||||
if (terminateGroup) add(GroupChangeField.TERMINATE_GROUP)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +130,7 @@ enum class GroupChangeField(val changeSilently: Boolean = false) {
|
||||
REQUESTING_MEMBER_APPROVALS,
|
||||
REQUESTING_MEMBER_REMOVALS,
|
||||
REQUESTING_MEMBERS,
|
||||
TERMINATE_GROUP,
|
||||
TIMER,
|
||||
TITLE;
|
||||
|
||||
|
||||
@@ -341,6 +341,8 @@ public final class DecryptedGroupUtil {
|
||||
|
||||
DecryptedGroupExtensions.setModifyMemberLabelActions(builder, change.modifyMemberLabels);
|
||||
|
||||
applyTerminateGroup(builder, change);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@@ -535,6 +537,12 @@ public final class DecryptedGroupUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyTerminateGroup(DecryptedGroup.Builder builder, DecryptedGroupChange change) {
|
||||
if (change.terminateGroup) {
|
||||
builder.terminated(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyAddRequestingMembers(DecryptedGroup.Builder builder, List<DecryptedRequestingMember> newRequestingMembers) {
|
||||
List<DecryptedRequestingMember> requestingMembers = new ArrayList<>(builder.requestingMembers);
|
||||
requestingMembers.addAll(newRequestingMembers);
|
||||
|
||||
@@ -109,6 +109,10 @@ internal class GroupChangeActionsBuilderChangeSetModifier(private val result: Gr
|
||||
result.modifyMemberLabelAccess = null
|
||||
}
|
||||
|
||||
override fun clearTerminateGroup() {
|
||||
result.terminate_group = null
|
||||
}
|
||||
|
||||
private fun <T> List<T>.removeIndex(i: Int): List<T> {
|
||||
val modifiedList = this.toMutableList()
|
||||
modifiedList.removeAt(i)
|
||||
|
||||
@@ -186,6 +186,10 @@ public final class GroupChangeReconstruct {
|
||||
})
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
if (!fromState.terminated && toState.terminated) {
|
||||
builder.terminateGroup(true);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@ public final class GroupChangeUtil {
|
||||
change.delete_members_banned.isEmpty() && // field 23
|
||||
change.promote_members_pending_pni_aci_profile_key.isEmpty() && // field 24
|
||||
change.modifyMemberLabels.isEmpty() && // field 26
|
||||
change.modifyMemberLabelAccess == null; // field 27
|
||||
change.modifyMemberLabelAccess == null && // field 27
|
||||
change.terminate_group == null; // field 28
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,6 +158,7 @@ public final class GroupChangeUtil {
|
||||
resolveField24PromotePendingPniAciMembers (conflictingChange, changeSetModifier, fullMembersByUuid);
|
||||
resolveField26ModifyMemberLabels (conflictingChange, changeSetModifier, fullMembersByUuid);
|
||||
resolveField27ModifyMemberLabelAccess (groupState, conflictingChange, changeSetModifier);
|
||||
resolveField28TerminateGroup (groupState, conflictingChange, changeSetModifier);
|
||||
}
|
||||
|
||||
private static void resolveField3AddMembers(DecryptedGroupChange conflictingChange, ChangeSetModifier result, HashMap<ByteString, DecryptedMember> fullMembersByUuid, HashMap<ByteString, DecryptedPendingMember> pendingMembersByServiceId) {
|
||||
@@ -403,4 +405,13 @@ public final class GroupChangeUtil {
|
||||
result.clearModifyMemberLabelAccess();
|
||||
}
|
||||
}
|
||||
|
||||
private static void resolveField28TerminateGroup(@Nonnull DecryptedGroup groupState,
|
||||
@Nonnull DecryptedGroupChange conflictingChange,
|
||||
@Nonnull ChangeSetModifier result)
|
||||
{
|
||||
if (groupState.terminated && conflictingChange.terminateGroup) {
|
||||
result.clearTerminateGroup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public final class GroupsV2Operations {
|
||||
public static final UUID UNKNOWN_UUID = UuidUtil.UNKNOWN_UUID;
|
||||
|
||||
/** Highest change epoch this class knows now to decrypt */
|
||||
public static final int HIGHEST_KNOWN_EPOCH = 6;
|
||||
public static final int HIGHEST_KNOWN_EPOCH = 7;
|
||||
|
||||
private final ServerPublicParams serverPublicParams;
|
||||
private final ClientZkProfileOperations clientZkProfileOperations;
|
||||
@@ -350,6 +350,12 @@ public final class GroupsV2Operations {
|
||||
);
|
||||
}
|
||||
|
||||
public GroupChange.Actions.Builder createTerminateGroup() {
|
||||
return new GroupChange.Actions.Builder().terminate_group(
|
||||
new GroupChange.Actions.TerminateGroupAction.Builder().build()
|
||||
);
|
||||
}
|
||||
|
||||
public GroupChange.Actions.Builder createAnnouncementGroupChange(boolean isAnnouncementGroup) {
|
||||
return new GroupChange.Actions.Builder().modify_announcements_only(
|
||||
new GroupChange.Actions.ModifyAnnouncementsOnlyAction.Builder().announcements_only(isAnnouncementGroup).build()
|
||||
@@ -493,6 +499,7 @@ public final class GroupsV2Operations {
|
||||
.disappearingMessagesTimer(new DecryptedTimer.Builder().duration(decryptDisappearingMessagesTimer(group.disappearingMessagesTimer)).build())
|
||||
.inviteLinkPassword(group.inviteLinkPassword)
|
||||
.bannedMembers(decryptedBannedMembers)
|
||||
.terminated(group.terminated)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -781,6 +788,11 @@ public final class GroupsV2Operations {
|
||||
builder.newMemberLabelAccess(actions.modifyMemberLabelAccess.memberLabelAccess);
|
||||
}
|
||||
|
||||
// Field 28
|
||||
if (actions.terminate_group != null) {
|
||||
builder.terminateGroup(true);
|
||||
}
|
||||
|
||||
if (editorServiceId instanceof ServiceId.PNI) {
|
||||
if (actions.addMembers.size() == 1 && builder.newMembers.size() == 1) {
|
||||
GroupChange.Actions.AddMemberAction addMemberAction = actions.addMembers.get(0);
|
||||
|
||||
@@ -79,6 +79,7 @@ message DecryptedGroup {
|
||||
string description = 11;
|
||||
EnabledState isAnnouncementGroup = 12;
|
||||
repeated DecryptedBannedMember bannedMembers = 13;
|
||||
bool terminated = 14;
|
||||
bool isPlaceholderGroup = 64;
|
||||
}
|
||||
|
||||
@@ -112,6 +113,7 @@ message DecryptedGroupChange {
|
||||
repeated DecryptedMember promotePendingPniAciMembers = 24;
|
||||
repeated DecryptedModifyMemberLabel modifyMemberLabels = 26;
|
||||
AccessControl.AccessRequired newMemberLabelAccess = 27;
|
||||
bool terminateGroup = 28;
|
||||
}
|
||||
|
||||
message DecryptedString {
|
||||
|
||||
@@ -88,7 +88,8 @@ message Group {
|
||||
bytes inviteLinkPassword = 10;
|
||||
bool announcements_only = 12;
|
||||
repeated MemberBanned members_banned = 13;
|
||||
// next: 14
|
||||
bool terminated = 14;
|
||||
// next: 15
|
||||
}
|
||||
|
||||
message GroupAttributeBlob {
|
||||
@@ -238,6 +239,8 @@ message GroupChange {
|
||||
bool announcements_only = 1;
|
||||
}
|
||||
|
||||
message TerminateGroupAction {}
|
||||
|
||||
bytes sourceUserId = 1;
|
||||
// clients should not provide this value; the server will provide it in the response buffer to ensure the signature is binding to a particular group
|
||||
// if clients set it during a request the server will respond with 400.
|
||||
@@ -268,7 +271,8 @@ message GroupChange {
|
||||
repeated PromoteMemberPendingPniAciProfileKeyAction promote_members_pending_pni_aci_profile_key = 24; // change epoch = 5
|
||||
repeated ModifyMemberLabelAction modifyMemberLabels = 26; // change epoch = 6;
|
||||
ModifyMemberLabelAccessControlAction modifyMemberLabelAccess = 27; // change epoch = 6
|
||||
// next: 28
|
||||
TerminateGroupAction terminate_group = 28; // change epoch = 7
|
||||
// next: 29
|
||||
}
|
||||
|
||||
bytes actions = 1;
|
||||
|
||||
@@ -51,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(),
|
||||
27, maxFieldFound);
|
||||
28, maxFieldFound);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1084,4 +1084,23 @@ public final class DecryptedGroupUtil_apply_Test {
|
||||
|
||||
assertEquals(expectedResult, DecryptedGroupUtil.apply(group, groupChange));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void apply_terminate_group() throws NotAbleToApplyGroupV2ChangeException {
|
||||
DecryptedGroup group = new DecryptedGroup.Builder()
|
||||
.revision(10)
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange groupChange = new DecryptedGroupChange.Builder()
|
||||
.revision(11)
|
||||
.terminateGroup(true)
|
||||
.build();
|
||||
|
||||
DecryptedGroup expectedResult = new DecryptedGroup.Builder()
|
||||
.revision(11)
|
||||
.terminated(true)
|
||||
.build();
|
||||
|
||||
assertEquals(expectedResult, DecryptedGroupUtil.apply(group, groupChange));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public final class DecryptedGroupUtil_empty_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroupChange.class);
|
||||
|
||||
assertEquals("GroupChangeField and getChangedFields() need updating to account for new fields on " + DecryptedGroupChange.class.getName(),
|
||||
27, maxFieldFound);
|
||||
28, maxFieldFound);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -295,6 +295,16 @@ public final class DecryptedGroupUtil_empty_Test {
|
||||
assertFalse(DecryptedGroupExtensions.isSilent(change));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void not_empty_with_terminate_group_field_28() {
|
||||
DecryptedGroupChange change = new DecryptedGroupChange.Builder()
|
||||
.terminateGroup(true)
|
||||
.build();
|
||||
|
||||
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
|
||||
assertFalse(DecryptedGroupExtensions.isSilent(change));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void silent_with_profile_keys_and_banned_members() {
|
||||
DecryptedGroupChange change = new DecryptedGroupChange.Builder()
|
||||
|
||||
@@ -45,7 +45,7 @@ public final class GroupChangeReconstructTest {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroup.class, ProtobufTestUtils.IGNORED_DECRYPTED_GROUP_TAGS);
|
||||
|
||||
assertEquals("GroupChangeReconstruct and its tests need updating to account for new fields on " + DecryptedGroup.class.getName(),
|
||||
13, maxFieldFound);
|
||||
14, maxFieldFound);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -487,4 +487,22 @@ public final class GroupChangeReconstructTest {
|
||||
.build(),
|
||||
decryptedGroupChange);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void terminate_group() {
|
||||
DecryptedGroup from = new DecryptedGroup.Builder()
|
||||
.build();
|
||||
|
||||
DecryptedGroup to = new DecryptedGroup.Builder()
|
||||
.terminated(true)
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange decryptedGroupChange = GroupChangeReconstruct.reconstructGroupChange(from, to);
|
||||
|
||||
assertEquals(
|
||||
new DecryptedGroupChange.Builder()
|
||||
.terminateGroup(true)
|
||||
.build(),
|
||||
decryptedGroupChange);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
27, maxFieldFound);
|
||||
28, maxFieldFound);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -245,4 +245,13 @@ public final class GroupChangeUtil_changeIsEmpty_Test {
|
||||
|
||||
assertFalse(GroupChangeUtil.changeIsEmpty(actions));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void not_empty_with_terminate_group_field_28() {
|
||||
GroupChange.Actions actions = new GroupChange.Actions.Builder()
|
||||
.terminate_group(new GroupChange.Actions.TerminateGroupAction())
|
||||
.build();
|
||||
|
||||
assertFalse(GroupChangeUtil.changeIsEmpty(actions));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,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(),
|
||||
27, maxFieldFound);
|
||||
28, maxFieldFound);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,7 +66,7 @@ public final class GroupChangeUtil_resolveConflict_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(GroupChange.Actions.class);
|
||||
|
||||
assertEquals("GroupChangeUtil#resolveConflict and its tests need updating to account for new fields on " + GroupChange.class.getName(),
|
||||
27, maxFieldFound);
|
||||
28, maxFieldFound);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,7 +79,7 @@ public final class GroupChangeUtil_resolveConflict_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroup.class, ProtobufTestUtils.IGNORED_DECRYPTED_GROUP_TAGS);
|
||||
|
||||
assertEquals("GroupChangeUtil#resolveConflict and its tests need updating to account for new fields on " + DecryptedGroup.class.getName(),
|
||||
13, maxFieldFound);
|
||||
14, maxFieldFound);
|
||||
}
|
||||
|
||||
|
||||
@@ -993,4 +993,53 @@ public final class GroupChangeUtil_resolveConflict_Test {
|
||||
GroupChange.Actions resolvedActions = GroupChangeUtil.resolveConflict(groupState, decryptedChange, change).build();
|
||||
assertTrue(GroupChangeUtil.changeIsEmpty(resolvedActions));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_28__terminate_group_preserved_when_group_not_terminated() {
|
||||
DecryptedGroup groupState = new DecryptedGroup.Builder()
|
||||
.revision(5)
|
||||
.terminated(false)
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange conflictingChange = new DecryptedGroupChange.Builder()
|
||||
.revision(6)
|
||||
.terminateGroup(true)
|
||||
.build();
|
||||
|
||||
GroupChange.Actions conflictingActions = new GroupChange.Actions.Builder()
|
||||
.version(6)
|
||||
.terminate_group(new GroupChange.Actions.TerminateGroupAction())
|
||||
.build();
|
||||
|
||||
GroupChange.Actions expectedResolvedActions = new GroupChange.Actions.Builder()
|
||||
.version(6)
|
||||
.terminate_group(new GroupChange.Actions.TerminateGroupAction())
|
||||
.build();
|
||||
|
||||
assertEquals(expectedResolvedActions, GroupChangeUtil.resolveConflict(groupState, conflictingChange, conflictingActions).build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_28__terminate_group_removed_when_group_already_terminated() {
|
||||
DecryptedGroup groupState = new DecryptedGroup.Builder()
|
||||
.revision(5)
|
||||
.terminated(true)
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange conflictingChange = new DecryptedGroupChange.Builder()
|
||||
.revision(6)
|
||||
.terminateGroup(true)
|
||||
.build();
|
||||
|
||||
GroupChange.Actions conflictingActions = new GroupChange.Actions.Builder()
|
||||
.version(6)
|
||||
.terminate_group(new GroupChange.Actions.TerminateGroupAction())
|
||||
.build();
|
||||
|
||||
GroupChange.Actions expectedResolvedActions = new GroupChange.Actions.Builder()
|
||||
.version(6)
|
||||
.build();
|
||||
|
||||
assertEquals(expectedResolvedActions, GroupChangeUtil.resolveConflict(groupState, conflictingChange, conflictingActions).build());
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,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(),
|
||||
27, maxFieldFound);
|
||||
28, maxFieldFound);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,7 +59,7 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroup.class, ProtobufTestUtils.IGNORED_DECRYPTED_GROUP_TAGS);
|
||||
|
||||
assertEquals("GroupChangeUtil#resolveConflict and its tests need updating to account for new fields on " + DecryptedGroup.class.getName(),
|
||||
13, maxFieldFound);
|
||||
14, maxFieldFound);
|
||||
}
|
||||
|
||||
|
||||
@@ -785,4 +785,43 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
|
||||
DecryptedGroupChange resolvedChanges = GroupChangeUtil.resolveConflict(groupState, decryptedChange).build();
|
||||
assertTrue(DecryptedGroupExtensions.getChangedFields(resolvedChanges).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_28__terminate_group_preserved_when_group_not_terminated() {
|
||||
DecryptedGroup groupState = new DecryptedGroup.Builder()
|
||||
.revision(5)
|
||||
.terminated(false)
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange conflictingChange = new DecryptedGroupChange.Builder()
|
||||
.revision(6)
|
||||
.terminateGroup(true)
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange expectedResolvedChange = new DecryptedGroupChange.Builder()
|
||||
.revision(6)
|
||||
.terminateGroup(true)
|
||||
.build();
|
||||
|
||||
assertEquals(expectedResolvedChange, GroupChangeUtil.resolveConflict(groupState, conflictingChange).build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void field_28__terminate_group_removed_when_group_already_terminated() {
|
||||
DecryptedGroup groupState = new DecryptedGroup.Builder()
|
||||
.revision(5)
|
||||
.terminated(true)
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange conflictingChange = new DecryptedGroupChange.Builder()
|
||||
.revision(6)
|
||||
.terminateGroup(true)
|
||||
.build();
|
||||
|
||||
DecryptedGroupChange expectedResolvedChange = new DecryptedGroupChange.Builder()
|
||||
.revision(6)
|
||||
.build();
|
||||
|
||||
assertEquals(expectedResolvedChange, GroupChangeUtil.resolveConflict(groupState, conflictingChange).build());
|
||||
}
|
||||
}
|
||||
@@ -73,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(),
|
||||
27,
|
||||
28,
|
||||
maxFieldFound);
|
||||
}
|
||||
|
||||
@@ -544,6 +544,16 @@ public final class GroupsV2Operations_decrypt_change_Test {
|
||||
assertDecryption(encryptedChange, expectedDecryptedChange);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void can_pass_through_terminate_group_field_28() {
|
||||
GroupChange.Actions.Builder encryptedChange = groupOperations.createTerminateGroup();
|
||||
|
||||
DecryptedGroupChange.Builder expectedDecryptedChange = new DecryptedGroupChange.Builder()
|
||||
.terminateGroup(true);
|
||||
|
||||
assertDecryption(encryptedChange, expectedDecryptedChange);
|
||||
}
|
||||
|
||||
private static ProfileKey newProfileKey() {
|
||||
try {
|
||||
return new ProfileKey(Util.getSecretBytes(32));
|
||||
|
||||
@@ -58,7 +58,7 @@ public final class GroupsV2Operations_decrypt_group_Test {
|
||||
int maxFieldFound = getMaxDeclaredFieldNumber(Group.class);
|
||||
|
||||
assertEquals("GroupOperations and its tests need updating to account for new fields on " + Group.class.getName(),
|
||||
13, maxFieldFound);
|
||||
14, maxFieldFound);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -310,6 +310,17 @@ public final class GroupsV2Operations_decrypt_group_Test {
|
||||
assertEquals(new DecryptedBannedMember.Builder().serviceIdBytes(member1.toByteString()).build(), decryptedGroup.bannedMembers.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pass_through_terminated_field_14() throws VerificationFailedException, InvalidGroupStateException {
|
||||
Group group = new Group.Builder()
|
||||
.terminated(true)
|
||||
.build();
|
||||
|
||||
DecryptedGroup decryptedGroup = groupOperations.decryptGroup(group);
|
||||
|
||||
assertEquals(true, decryptedGroup.terminated);
|
||||
}
|
||||
|
||||
private ByteString encryptProfileKey(ACI aci, ProfileKey profileKey) {
|
||||
return ByteString.of(new ClientZkGroupCipher(groupSecretParams).encryptProfileKey(profileKey, aci.getLibSignalAci()).serialize());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user