Don't send group update messages when member labels are changed.

This commit is contained in:
jeffrey-signal
2026-02-03 12:20:33 -05:00
committed by GitHub
parent 0cd93986bd
commit ff726ec4d2
8 changed files with 189 additions and 148 deletions

View File

@@ -3,15 +3,20 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
@file:JvmName("DecryptedGroupExtensions")
package org.whispersystems.signalservice.api.groupsv2
import org.signal.core.models.ServiceId
import org.signal.core.models.ServiceId.ACI
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.DecryptedPendingMember
import org.signal.storageservice.storage.protos.groups.local.DecryptedRequestingMember
import org.signal.storageservice.storage.protos.groups.local.EnabledState
import java.util.Optional
fun Collection<DecryptedMember>.toAciListWithUnknowns(): List<ACI> {
@@ -54,3 +59,78 @@ fun DecryptedGroup.Builder.setModifyMemberLabelActions(
members = updatedMembers
}
/**
* Returns the group change fields that contain actual changes (value is not empty or default).
*/
fun DecryptedGroupChange.getChangedFields(): Set<GroupChangeField> {
return buildSet {
if (newIsAnnouncementGroup != EnabledState.UNKNOWN) add(GroupChangeField.ANNOUNCEMENT_GROUP)
if (newAttributeAccess != AccessControl.AccessRequired.UNKNOWN) add(GroupChangeField.ATTRIBUTE_ACCESS)
if (newAvatar != null) add(GroupChangeField.AVATAR)
if (deleteBannedMembers.isNotEmpty()) add(GroupChangeField.BANNED_MEMBER_REMOVALS)
if (newBannedMembers.isNotEmpty()) add(GroupChangeField.BANNED_MEMBERS)
if (newDescription != null) add(GroupChangeField.DESCRIPTION)
if (newInviteLinkAccess != AccessControl.AccessRequired.UNKNOWN) add(GroupChangeField.INVITE_LINK_ACCESS)
if (newInviteLinkPassword.size != 0) add(GroupChangeField.INVITE_LINK_PASSWORD)
if (newMemberAccess != AccessControl.AccessRequired.UNKNOWN) add(GroupChangeField.MEMBER_ACCESS)
if (modifyMemberLabels.isNotEmpty()) add(GroupChangeField.MEMBER_LABELS)
if (deleteMembers.isNotEmpty()) add(GroupChangeField.MEMBER_REMOVALS)
if (modifyMemberRoles.isNotEmpty()) add(GroupChangeField.MEMBER_ROLES)
if (newMembers.isNotEmpty()) add(GroupChangeField.MEMBERS)
if (promotePendingMembers.isNotEmpty()) add(GroupChangeField.PENDING_MEMBER_PROMOTIONS)
if (deletePendingMembers.isNotEmpty()) add(GroupChangeField.PENDING_MEMBER_REMOVALS)
if (newPendingMembers.isNotEmpty()) add(GroupChangeField.PENDING_MEMBERS)
if (promotePendingPniAciMembers.isNotEmpty()) add(GroupChangeField.PNI_ACI_PROMOTIONS)
if (modifiedProfileKeys.isNotEmpty()) add(GroupChangeField.PROFILE_KEYS)
if (promoteRequestingMembers.isNotEmpty()) add(GroupChangeField.REQUESTING_MEMBER_APPROVALS)
if (deleteRequestingMembers.isNotEmpty()) add(GroupChangeField.REQUESTING_MEMBER_REMOVALS)
if (newRequestingMembers.isNotEmpty()) add(GroupChangeField.REQUESTING_MEMBERS)
if (newTimer != null) add(GroupChangeField.TIMER)
if (newTitle != null) add(GroupChangeField.TITLE)
}
}
/**
* Returns true if the group change should not be announced to the group members.
*/
@JvmOverloads
fun DecryptedGroupChange.isSilent(
changedFields: Set<GroupChangeField> = getChangedFields()
): Boolean {
return GroupChangeField.silentChanges.containsAll(changedFields)
}
/**
* Fields representing possible changes to a group state.
* To add a new field, update the enum and add corresponding checks in getChangedFields().
*/
enum class GroupChangeField(val changeSilently: Boolean = false) {
ANNOUNCEMENT_GROUP,
ATTRIBUTE_ACCESS,
AVATAR,
BANNED_MEMBER_REMOVALS,
BANNED_MEMBERS(changeSilently = true),
DESCRIPTION,
INVITE_LINK_ACCESS,
INVITE_LINK_PASSWORD,
MEMBER_ACCESS,
MEMBER_LABELS(changeSilently = true),
MEMBER_REMOVALS,
MEMBER_ROLES,
MEMBERS,
PENDING_MEMBER_PROMOTIONS,
PENDING_MEMBER_REMOVALS,
PENDING_MEMBERS,
PNI_ACI_PROMOTIONS,
PROFILE_KEYS(changeSilently = true),
REQUESTING_MEMBER_APPROVALS,
REQUESTING_MEMBER_REMOVALS,
REQUESTING_MEMBERS,
TIMER,
TITLE;
companion object {
val silentChanges = GroupChangeField.entries.filter { it.changeSilently }
}
}

View File

@@ -8,7 +8,6 @@ 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;
@@ -338,7 +337,7 @@ public final class DecryptedGroupUtil {
applyPromotePendingPniAciMemberActions(builder, change.promotePendingPniAciMembers);
DecryptedGroupExtensionsKt.setModifyMemberLabelActions(builder, change.modifyMemberLabels);
DecryptedGroupExtensions.setModifyMemberLabelActions(builder, change.modifyMemberLabels);
return builder.build();
}
@@ -722,73 +721,4 @@ public final class DecryptedGroupUtil {
}
return -1;
}
public static boolean changeIsEmpty(DecryptedGroupChange change) {
return change.modifiedProfileKeys.size() == 0 && // field 6
changeIsEmptyExceptForProfileKeyChanges(change);
}
/*
* When updating this, update {@link #changeIsEmptyExceptForBanChangesAndOptionalProfileKeyChanges(DecryptedGroupChange)}
*/
public static boolean changeIsEmptyExceptForProfileKeyChanges(DecryptedGroupChange change) {
return change.newMembers.size() == 0 && // field 3
change.deleteMembers.size() == 0 && // field 4
change.modifyMemberRoles.size() == 0 && // field 5
change.newPendingMembers.size() == 0 && // field 7
change.deletePendingMembers.size() == 0 && // field 8
change.promotePendingMembers.size() == 0 && // field 9
change.newTitle == null && // field 10
change.newAvatar == null && // field 11
change.newTimer == null && // field 12
isEmpty(change.newAttributeAccess) && // field 13
isEmpty(change.newMemberAccess) && // field 14
isEmpty(change.newInviteLinkAccess) && // field 15
change.newRequestingMembers.size() == 0 && // field 16
change.deleteRequestingMembers.size() == 0 && // field 17
change.promoteRequestingMembers.size() == 0 && // field 18
change.newInviteLinkPassword.size() == 0 && // field 19
change.newDescription == null && // field 20
isEmpty(change.newIsAnnouncementGroup) && // field 21
change.newBannedMembers.size() == 0 && // field 22
change.deleteBannedMembers.size() == 0 && // field 23
change.promotePendingPniAciMembers.size() == 0 && // field 24
change.modifyMemberLabels.isEmpty(); // field 26
}
public static boolean changeIsEmptyExceptForBanChangesAndOptionalProfileKeyChanges(DecryptedGroupChange change) {
return (change.newBannedMembers.size() != 0 || change.deleteBannedMembers.size() != 0) &&
change.newMembers.size() == 0 && // field 3
change.deleteMembers.size() == 0 && // field 4
change.modifyMemberRoles.size() == 0 && // field 5
change.newPendingMembers.size() == 0 && // field 7
change.deletePendingMembers.size() == 0 && // field 8
change.promotePendingMembers.size() == 0 && // field 9
change.newTitle == null && // field 10
change.newAvatar == null && // field 11
change.newTimer == null && // field 12
isEmpty(change.newAttributeAccess) && // field 13
isEmpty(change.newMemberAccess) && // field 14
isEmpty(change.newInviteLinkAccess) && // field 15
change.newRequestingMembers.size() == 0 && // field 16
change.deleteRequestingMembers.size() == 0 && // field 17
change.promoteRequestingMembers.size() == 0 && // field 18
change.newInviteLinkPassword.size() == 0 && // field 19
change.newDescription == null && // field 20
isEmpty(change.newIsAnnouncementGroup) && // field 21
change.promotePendingPniAciMembers.size() == 0 && // field 24
change.modifyMemberLabels.isEmpty(); // field 26
}
static boolean isEmpty(AccessControl.AccessRequired newAttributeAccess) {
return newAttributeAccess == AccessControl.AccessRequired.UNKNOWN;
}
static boolean isEmpty(EnabledState enabledState) {
return enabledState == EnabledState.UNKNOWN;
}
public static boolean changeIsSilent(DecryptedGroupChange plainGroupChange) {
return changeIsEmptyExceptForProfileKeyChanges(plainGroupChange) || changeIsEmptyExceptForBanChangesAndOptionalProfileKeyChanges(plainGroupChange);
}
}

View File

@@ -31,21 +31,22 @@ import static org.whispersystems.signalservice.api.groupsv2.ProtobufTestUtils.ge
@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.
* Ensures that {@link GroupChangeField} enum covers all fields of {@link DecryptedGroupChange}.
* <p>
* If we didn't, newly added fields would easily affect {@link DecryptedGroupUtil}'s ability to detect non-empty change states.
* If this test fails after a proto update, add the new field to {@link GroupChangeField}
* and update {{@link DecryptedGroupExtensions#getChangedFields(DecryptedGroupChange)}}.
*/
@Test
public void ensure_DecryptedGroupUtil_knows_about_all_fields_of_DecryptedGroupChange() {
public void ensure_GroupChangeField_knows_about_all_fields_of_DecryptedGroupChange() {
int maxFieldFound = getMaxDeclaredFieldNumber(DecryptedGroupChange.class);
assertEquals("DecryptedGroupUtil and its tests need updating to account for new fields on " + DecryptedGroupChange.class.getName(),
assertEquals("GroupChangeField and getChangedFields() need updating to account for new fields on " + DecryptedGroupChange.class.getName(),
26, maxFieldFound);
}
@Test
public void empty_change_set() {
assertTrue(DecryptedGroupUtil.changeIsEmpty(new DecryptedGroupChange.Builder().build()));
assertTrue(DecryptedGroupExtensions.getChangedFields(new DecryptedGroupChange.Builder().build()).isEmpty());
}
@Test
@@ -54,8 +55,8 @@ public final class DecryptedGroupUtil_empty_Test {
.newMembers(List.of(member(UUID.randomUUID())))
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -64,8 +65,8 @@ public final class DecryptedGroupUtil_empty_Test {
.deleteMembers(List.of(UuidUtil.toByteString(UUID.randomUUID())))
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -74,8 +75,8 @@ public final class DecryptedGroupUtil_empty_Test {
.modifyMemberRoles(List.of(promoteAdmin(UUID.randomUUID())))
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -84,8 +85,8 @@ public final class DecryptedGroupUtil_empty_Test {
.modifiedProfileKeys(List.of(member(UUID.randomUUID(), randomProfileKey())))
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertTrue(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertTrue(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -94,8 +95,8 @@ public final class DecryptedGroupUtil_empty_Test {
.newPendingMembers(List.of(pendingMember(UUID.randomUUID())))
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -104,8 +105,8 @@ public final class DecryptedGroupUtil_empty_Test {
.deletePendingMembers(List.of(pendingMemberRemoval(UUID.randomUUID())))
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -114,8 +115,8 @@ public final class DecryptedGroupUtil_empty_Test {
.promotePendingMembers(List.of(member(UUID.randomUUID())))
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -124,8 +125,8 @@ public final class DecryptedGroupUtil_empty_Test {
.newTitle(new DecryptedString.Builder().value_("New title").build())
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -134,8 +135,8 @@ public final class DecryptedGroupUtil_empty_Test {
.newAvatar(new DecryptedString.Builder().value_("New Avatar").build())
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -144,8 +145,8 @@ public final class DecryptedGroupUtil_empty_Test {
.newTimer(new DecryptedTimer.Builder().duration(60).build())
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -154,8 +155,8 @@ public final class DecryptedGroupUtil_empty_Test {
.newAttributeAccess(AccessControl.AccessRequired.ADMINISTRATOR)
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -164,8 +165,8 @@ public final class DecryptedGroupUtil_empty_Test {
.newMemberAccess(AccessControl.AccessRequired.MEMBER)
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -174,8 +175,8 @@ public final class DecryptedGroupUtil_empty_Test {
.newInviteLinkAccess(AccessControl.AccessRequired.ADMINISTRATOR)
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -184,8 +185,8 @@ public final class DecryptedGroupUtil_empty_Test {
.newRequestingMembers(List.of(new DecryptedRequestingMember()))
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -194,8 +195,8 @@ public final class DecryptedGroupUtil_empty_Test {
.deleteRequestingMembers(List.of(ByteString.of(new byte[16])))
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -204,8 +205,8 @@ public final class DecryptedGroupUtil_empty_Test {
.promoteRequestingMembers(List.of(new DecryptedApproveMember()))
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -214,8 +215,8 @@ public final class DecryptedGroupUtil_empty_Test {
.newInviteLinkPassword(ByteString.of(new byte[16]))
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -224,8 +225,8 @@ public final class DecryptedGroupUtil_empty_Test {
.newDescription(new DecryptedString.Builder().value_("New description").build())
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -234,8 +235,8 @@ public final class DecryptedGroupUtil_empty_Test {
.newIsAnnouncementGroup(EnabledState.ENABLED)
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -244,8 +245,8 @@ public final class DecryptedGroupUtil_empty_Test {
.newBannedMembers(List.of(new DecryptedBannedMember()))
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertTrue(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -254,8 +255,8 @@ public final class DecryptedGroupUtil_empty_Test {
.deleteBannedMembers(List.of(new DecryptedBannedMember()))
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
@@ -264,12 +265,12 @@ public final class DecryptedGroupUtil_empty_Test {
.promotePendingPniAciMembers(List.of(pendingPniAciMember(UUID.randomUUID(), UUID.randomUUID(), randomProfileKey())))
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
@Test
public void not_empty_with_modify_member_label_field_26() {
public void silent_with_modify_member_label_field_26() {
DecryptedModifyMemberLabel modifyLabelAction = new DecryptedModifyMemberLabel.Builder()
.aciBytes(UuidUtil.toByteString(UUID.randomUUID()))
.labelEmoji("🔥")
@@ -280,8 +281,29 @@ public final class DecryptedGroupUtil_empty_Test {
.modifyMemberLabels(List.of(modifyLabelAction))
.build();
assertFalse(DecryptedGroupUtil.changeIsEmpty(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForProfileKeyChanges(change));
assertFalse(DecryptedGroupUtil.changeIsEmptyExceptForBanChangesAndOptionalProfileKeyChanges(change));
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertTrue(DecryptedGroupExtensions.isSilent(change));
}
@Test
public void silent_with_profile_keys_and_banned_members() {
DecryptedGroupChange change = new DecryptedGroupChange.Builder()
.modifiedProfileKeys(List.of(member(UUID.randomUUID(), randomProfileKey())))
.newBannedMembers(List.of(new DecryptedBannedMember()))
.build();
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertTrue(DecryptedGroupExtensions.isSilent(change));
}
@Test
public void not_silent_with_profile_keys_and_new_members() {
DecryptedGroupChange change = new DecryptedGroupChange.Builder()
.modifiedProfileKeys(List.of(member(UUID.randomUUID(), randomProfileKey())))
.newMembers(List.of(member(UUID.randomUUID())))
.build();
assertFalse(DecryptedGroupExtensions.getChangedFields(change).isEmpty());
assertFalse(DecryptedGroupExtensions.isSilent(change));
}
}

View File

@@ -300,7 +300,7 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
DecryptedGroupChange resolvedChanges = GroupChangeUtil.resolveConflict(groupState, decryptedChange).build();
assertTrue(DecryptedGroupUtil.changeIsEmpty(resolvedChanges));
assertTrue(DecryptedGroupExtensions.getChangedFields(resolvedChanges).isEmpty());
}
@Test
@@ -328,7 +328,7 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
DecryptedGroupChange resolvedChanges = GroupChangeUtil.resolveConflict(groupState, decryptedChange).build();
assertTrue(DecryptedGroupUtil.changeIsEmpty(resolvedChanges));
assertTrue(DecryptedGroupExtensions.getChangedFields(resolvedChanges).isEmpty());
}
@Test
@@ -356,7 +356,7 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
DecryptedGroupChange resolvedChanges = GroupChangeUtil.resolveConflict(groupState, decryptedChange).build();
assertTrue(DecryptedGroupUtil.changeIsEmpty(resolvedChanges));
assertTrue(DecryptedGroupExtensions.getChangedFields(resolvedChanges).isEmpty());
}
@Test
@@ -384,7 +384,7 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
DecryptedGroupChange resolvedChanges = GroupChangeUtil.resolveConflict(groupState, decryptedChange).build();
assertTrue(DecryptedGroupUtil.changeIsEmpty(resolvedChanges));
assertTrue(DecryptedGroupExtensions.getChangedFields(resolvedChanges).isEmpty());
}
@Test
@@ -412,7 +412,7 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
DecryptedGroupChange resolvedChanges = GroupChangeUtil.resolveConflict(groupState, decryptedChange).build();
assertTrue(DecryptedGroupUtil.changeIsEmpty(resolvedChanges));
assertTrue(DecryptedGroupExtensions.getChangedFields(resolvedChanges).isEmpty());
}
@Test
@@ -426,7 +426,7 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
DecryptedGroupChange resolvedChanges = GroupChangeUtil.resolveConflict(groupState, decryptedChange).build();
assertTrue(DecryptedGroupUtil.changeIsEmpty(resolvedChanges));
assertTrue(DecryptedGroupExtensions.getChangedFields(resolvedChanges).isEmpty());
}
@Test
@@ -572,7 +572,7 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
DecryptedGroupChange resolvedChanges = GroupChangeUtil.resolveConflict(groupState, decryptedChange).build();
assertTrue(DecryptedGroupUtil.changeIsEmpty(resolvedChanges));
assertTrue(DecryptedGroupExtensions.getChangedFields(resolvedChanges).isEmpty());
}
@Test
@@ -602,7 +602,7 @@ public final class GroupChangeUtil_resolveConflict_decryptedOnly_Test {
DecryptedGroupChange resolvedChanges = GroupChangeUtil.resolveConflict(groupState, decryptedChange).build();
assertTrue(DecryptedGroupUtil.changeIsEmpty(resolvedChanges));
assertTrue(DecryptedGroupExtensions.getChangedFields(resolvedChanges).isEmpty());
}
@Test