Signal-Android/app/src/test/java/org/thoughtcrime/securesms/database/model/GroupsV2UpdateMessageProduc...

997 lines
34 KiB
Java

package org.thoughtcrime.securesms.database.model;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.test.core.app.ApplicationProvider;
import com.annimon.stream.Stream;
import com.google.common.collect.ImmutableMap;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.signal.storageservice.protos.groups.AccessControl;
import org.signal.storageservice.protos.groups.Member;
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
import org.signal.storageservice.protos.groups.local.DecryptedMember;
import org.signal.storageservice.protos.groups.local.DecryptedModifyMemberRole;
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
import org.signal.storageservice.protos.groups.local.DecryptedPendingMemberRemoval;
import org.signal.storageservice.protos.groups.local.DecryptedString;
import org.signal.storageservice.protos.groups.local.DecryptedTimer;
import org.thoughtcrime.securesms.testutil.MainThreadUtil;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.signalservice.api.util.UuidUtil;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE, application = Application.class)
@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*", "androidx.*" })
@PrepareForTest(Util.class)
public final class GroupsV2UpdateMessageProducerTest {
private UUID you;
private UUID alice;
private UUID bob;
private GroupsV2UpdateMessageProducer producer;
@Rule
public PowerMockRule powerMockRule = new PowerMockRule();
@Before
public void setup() {
you = UUID.randomUUID();
alice = UUID.randomUUID();
bob = UUID.randomUUID();
GroupsV2UpdateMessageProducer.DescribeMemberStrategy describeMember = createDescriber(ImmutableMap.of(alice, "Alice", bob, "Bob"));
producer = new GroupsV2UpdateMessageProducer(ApplicationProvider.getApplicationContext(), describeMember, you);
}
@Test
public void empty_change() {
DecryptedGroupChange change = changeBy(alice)
.build();
assertThat(describeChange(change), is(singletonList("Alice updated the group.")));
}
@Test
public void empty_change_by_you() {
DecryptedGroupChange change = changeBy(you)
.build();
assertThat(describeChange(change), is(singletonList("You updated the group.")));
}
@Test
public void empty_change_by_unknown() {
DecryptedGroupChange change = changeByUnknown()
.build();
assertThat(describeChange(change), is(singletonList("The group was updated.")));
}
// Member additions
@Test
public void member_added_member() {
DecryptedGroupChange change = changeBy(alice)
.addMember(bob)
.build();
assertThat(describeChange(change), is(singletonList("Alice added Bob.")));
}
@Test
public void member_added_member_mentions_both() {
DecryptedGroupChange change = changeBy(alice)
.addMember(bob)
.build();
assertSingleChangeMentioning(change, Arrays.asList(alice, bob));
}
@Test
public void you_added_member() {
DecryptedGroupChange change = changeBy(you)
.addMember(bob)
.build();
assertThat(describeChange(change), is(singletonList("You added Bob.")));
}
@Test
public void you_added_member_mentions_just_member() {
DecryptedGroupChange change = changeBy(you)
.addMember(bob)
.build();
assertSingleChangeMentioning(change, singletonList(bob));
}
@Test
public void member_added_you() {
DecryptedGroupChange change = changeBy(alice)
.addMember(you)
.build();
assertThat(describeChange(change), is(singletonList("Alice added you to the group.")));
}
@Test
public void you_added_you() {
DecryptedGroupChange change = changeBy(you)
.addMember(you)
.build();
assertThat(describeChange(change), is(singletonList("You joined the group.")));
}
@Test
public void member_added_themselves() {
DecryptedGroupChange change = changeBy(bob)
.addMember(bob)
.build();
assertThat(describeChange(change), is(singletonList("Bob joined the group.")));
}
@Test
public void member_added_themselves_mentions_just_member() {
DecryptedGroupChange change = changeBy(bob)
.addMember(bob)
.build();
assertSingleChangeMentioning(change, singletonList(bob));
}
@Test
public void unknown_added_you() {
DecryptedGroupChange change = changeByUnknown()
.addMember(you)
.build();
assertThat(describeChange(change), is(singletonList("You joined the group.")));
}
@Test
public void unknown_added_member() {
DecryptedGroupChange change = changeByUnknown()
.addMember(bob)
.build();
assertThat(describeChange(change), is(singletonList("Bob joined the group.")));
}
// Member removals
@Test
public void member_removed_member() {
DecryptedGroupChange change = changeBy(alice)
.deleteMember(bob)
.build();
assertThat(describeChange(change), is(singletonList("Alice removed Bob.")));
}
@Test
public void you_removed_member() {
DecryptedGroupChange change = changeBy(you)
.deleteMember(bob)
.build();
assertThat(describeChange(change), is(singletonList("You removed Bob.")));
}
@Test
public void member_removed_you() {
DecryptedGroupChange change = changeBy(alice)
.deleteMember(you)
.build();
assertThat(describeChange(change), is(singletonList("Alice removed you from the group.")));
}
@Test
public void you_removed_you() {
DecryptedGroupChange change = changeBy(you)
.deleteMember(you)
.build();
assertThat(describeChange(change), is(singletonList("You left the group.")));
}
@Test
public void member_removed_themselves() {
DecryptedGroupChange change = changeBy(bob)
.deleteMember(bob)
.build();
assertThat(describeChange(change), is(singletonList("Bob left the group.")));
}
@Test
public void unknown_removed_member() {
DecryptedGroupChange change = changeByUnknown()
.deleteMember(alice)
.build();
assertThat(describeChange(change), is(singletonList("Alice is no longer in the group.")));
}
@Test
public void unknown_removed_you() {
DecryptedGroupChange change = changeByUnknown()
.deleteMember(you)
.build();
assertThat(describeChange(change), is(singletonList("You are no longer in the group.")));
}
// Member role modifications
@Test
public void you_make_member_admin() {
DecryptedGroupChange change = changeBy(you)
.promoteToAdmin(alice)
.build();
assertThat(describeChange(change), is(singletonList("You made Alice an admin.")));
}
@Test
public void member_makes_member_admin() {
DecryptedGroupChange change = changeBy(bob)
.promoteToAdmin(alice)
.build();
assertThat(describeChange(change), is(singletonList("Bob made Alice an admin.")));
}
@Test
public void member_makes_you_admin() {
DecryptedGroupChange change = changeBy(alice)
.promoteToAdmin(you)
.build();
assertThat(describeChange(change), is(singletonList("Alice made you an admin.")));
}
@Test
public void you_revoked_member_admin() {
DecryptedGroupChange change = changeBy(you)
.demoteToMember(bob)
.build();
assertThat(describeChange(change), is(singletonList("You revoked admin privileges from Bob.")));
}
@Test
public void member_revokes_member_admin() {
DecryptedGroupChange change = changeBy(bob)
.demoteToMember(alice)
.build();
assertThat(describeChange(change), is(singletonList("Bob revoked admin privileges from Alice.")));
}
@Test
public void member_revokes_your_admin() {
DecryptedGroupChange change = changeBy(alice)
.demoteToMember(you)
.build();
assertThat(describeChange(change), is(singletonList("Alice revoked your admin privileges.")));
}
@Test
public void unknown_makes_member_admin() {
DecryptedGroupChange change = changeByUnknown()
.promoteToAdmin(alice)
.build();
assertThat(describeChange(change), is(singletonList("Alice is now an admin.")));
}
@Test
public void unknown_makes_you_admin() {
DecryptedGroupChange change = changeByUnknown()
.promoteToAdmin(you)
.build();
assertThat(describeChange(change), is(singletonList("You are now an admin.")));
}
@Test
public void unknown_revokes_member_admin() {
DecryptedGroupChange change = changeByUnknown()
.demoteToMember(alice)
.build();
assertThat(describeChange(change), is(singletonList("Alice is no longer an admin.")));
}
@Test
public void unknown_revokes_your_admin() {
DecryptedGroupChange change = changeByUnknown()
.demoteToMember(you)
.build();
assertThat(describeChange(change), is(singletonList("You are no longer an admin.")));
}
// Member invitation
@Test
public void you_invited_member() {
DecryptedGroupChange change = changeBy(you)
.invite(alice)
.build();
assertThat(describeChange(change), is(singletonList("You invited Alice to the group.")));
}
@Test
public void member_invited_you() {
DecryptedGroupChange change = changeBy(alice)
.invite(you)
.build();
assertThat(describeChange(change), is(singletonList("Alice invited you to the group.")));
}
@Test
public void member_invited_1_person() {
DecryptedGroupChange change = changeBy(alice)
.invite(bob)
.build();
assertThat(describeChange(change), is(singletonList("Alice invited 1 person to the group.")));
}
@Test
public void member_invited_2_persons() {
DecryptedGroupChange change = changeBy(alice)
.invite(bob)
.invite(UUID.randomUUID())
.build();
assertThat(describeChange(change), is(singletonList("Alice invited 2 people to the group.")));
}
@Test
public void member_invited_3_persons_and_you() {
DecryptedGroupChange change = changeBy(bob)
.invite(alice)
.invite(you)
.invite(UUID.randomUUID())
.invite(UUID.randomUUID())
.build();
assertThat(describeChange(change), is(Arrays.asList("Bob invited you to the group.", "Bob invited 3 people to the group.")));
}
@Test
public void unknown_invited_you() {
DecryptedGroupChange change = changeByUnknown()
.invite(you)
.build();
assertThat(describeChange(change), is(singletonList("You were invited to the group.")));
}
@Test
public void unknown_invited_1_person() {
DecryptedGroupChange change = changeByUnknown()
.invite(alice)
.build();
assertThat(describeChange(change), is(singletonList("1 person was invited to the group.")));
}
@Test
public void unknown_invited_2_persons() {
DecryptedGroupChange change = changeByUnknown()
.invite(alice)
.invite(bob)
.build();
assertThat(describeChange(change), is(singletonList("2 people were invited to the group.")));
}
@Test
public void unknown_invited_3_persons_and_you() {
DecryptedGroupChange change = changeByUnknown()
.invite(alice)
.invite(you)
.invite(UUID.randomUUID())
.invite(UUID.randomUUID())
.build();
assertThat(describeChange(change), is(Arrays.asList("You were invited to the group.", "3 people were invited to the group.")));
}
// Member invitation revocation
@Test
public void member_uninvited_1_person() {
DecryptedGroupChange change = changeBy(alice)
.uninvite(bob)
.build();
assertThat(describeChange(change), is(singletonList("Alice revoked an invitation to the group.")));
}
@Test
public void member_uninvited_2_people() {
DecryptedGroupChange change = changeBy(alice)
.uninvite(bob)
.uninvite(UUID.randomUUID())
.build();
assertThat(describeChange(change), is(singletonList("Alice revoked 2 invitations to the group.")));
}
@Test
public void you_uninvited_1_person() {
DecryptedGroupChange change = changeBy(you)
.uninvite(bob)
.build();
assertThat(describeChange(change), is(singletonList("You revoked an invitation to the group.")));
}
@Test
public void you_uninvited_2_people() {
DecryptedGroupChange change = changeBy(you)
.uninvite(bob)
.uninvite(UUID.randomUUID())
.build();
assertThat(describeChange(change), is(singletonList("You revoked 2 invitations to the group.")));
}
@Test
public void pending_member_declines_invite() {
DecryptedGroupChange change = changeBy(bob)
.uninvite(bob)
.build();
assertThat(describeChange(change), is(singletonList("Someone declined an invitation to the group.")));
}
@Test
public void you_decline_invite() {
DecryptedGroupChange change = changeBy(you)
.uninvite(you)
.build();
assertThat(describeChange(change), is(singletonList("You declined the invitation to the group.")));
}
@Test
public void unknown_revokes_your_invite() {
DecryptedGroupChange change = changeByUnknown()
.uninvite(you)
.build();
assertThat(describeChange(change), is(singletonList("Your invitation to the group was revoked.")));
}
@Test
public void unknown_revokes_1_invite() {
DecryptedGroupChange change = changeByUnknown()
.uninvite(bob)
.build();
assertThat(describeChange(change), is(singletonList("An invitation to the group was revoked.")));
}
@Test
public void unknown_revokes_2_invites() {
DecryptedGroupChange change = changeByUnknown()
.uninvite(bob)
.uninvite(UUID.randomUUID())
.build();
assertThat(describeChange(change), is(singletonList("2 invitations to the group were revoked.")));
}
@Test
public void unknown_revokes_yours_and_three_other_invites() {
DecryptedGroupChange change = changeByUnknown()
.uninvite(bob)
.uninvite(you)
.uninvite(UUID.randomUUID())
.uninvite(UUID.randomUUID())
.build();
assertThat(describeChange(change), is(Arrays.asList("Your invitation to the group was revoked.", "3 invitations to the group were revoked.")));
}
// Promote pending members
@Test
public void member_accepts_invite() {
DecryptedGroupChange change = changeBy(bob)
.promote(bob)
.build();
assertThat(describeChange(change), is(singletonList("Bob accepted an invitation to the group.")));
}
@Test
public void you_accept_invite() {
DecryptedGroupChange change = changeBy(you)
.promote(you)
.build();
assertThat(describeChange(change), is(singletonList("You accepted the invitation to the group.")));
}
@Test
public void member_promotes_pending_member() {
DecryptedGroupChange change = changeBy(bob)
.promote(alice)
.build();
assertThat(describeChange(change), is(singletonList("Bob added invited member Alice.")));
}
@Test
public void you_promote_pending_member() {
DecryptedGroupChange change = changeBy(you)
.promote(bob)
.build();
assertThat(describeChange(change), is(singletonList("You added invited member Bob.")));
}
@Test
public void member_promotes_you() {
DecryptedGroupChange change = changeBy(bob)
.promote(you)
.build();
assertThat(describeChange(change), is(singletonList("Bob added you to the group.")));
}
@Test
public void unknown_added_by_invite() {
DecryptedGroupChange change = changeByUnknown()
.promote(you)
.build();
assertThat(describeChange(change), is(singletonList("You joined the group.")));
}
@Test
public void unknown_promotes_pending_member() {
DecryptedGroupChange change = changeByUnknown()
.promote(alice)
.build();
assertThat(describeChange(change), is(singletonList("Alice joined the group.")));
}
// Title change
@Test
public void member_changes_title() {
DecryptedGroupChange change = changeBy(alice)
.title("New title")
.build();
assertThat(describeChange(change), is(singletonList("Alice changed the group name to \"New title\".")));
}
@Test
public void you_change_title() {
DecryptedGroupChange change = changeBy(you)
.title("Title 2")
.build();
assertThat(describeChange(change), is(singletonList("You changed the group name to \"Title 2\".")));
}
@Test
public void unknown_changed_title() {
DecryptedGroupChange change = changeByUnknown()
.title("Title 3")
.build();
assertThat(describeChange(change), is(singletonList("The group name has changed to \"Title 3\".")));
}
// Avatar change
@Test
public void member_changes_avatar() {
DecryptedGroupChange change = changeBy(alice)
.avatar("Avatar1")
.build();
assertThat(describeChange(change), is(singletonList("Alice changed the group avatar.")));
}
@Test
public void you_change_avatar() {
DecryptedGroupChange change = changeBy(you)
.avatar("Avatar2")
.build();
assertThat(describeChange(change), is(singletonList("You changed the group avatar.")));
}
@Test
public void unknown_changed_avatar() {
DecryptedGroupChange change = changeByUnknown()
.avatar("Avatar3")
.build();
assertThat(describeChange(change), is(singletonList("The group avatar has been changed.")));
}
// Timer change
@Test
public void member_changes_timer() {
DecryptedGroupChange change = changeBy(bob)
.timer(10)
.build();
assertThat(describeChange(change), is(singletonList("Bob set the disappearing message timer to 10 seconds.")));
}
@Test
public void you_change_timer() {
DecryptedGroupChange change = changeBy(you)
.timer(60)
.build();
assertThat(describeChange(change), is(singletonList("You set the disappearing message timer to 1 minute.")));
}
@Test
public void unknown_change_timer() {
DecryptedGroupChange change = changeByUnknown()
.timer(120)
.build();
assertThat(describeChange(change), is(singletonList("The disappearing message timer has been set to 2 minutes.")));
}
@Test
public void unknown_change_timer_mentions_no_one() {
DecryptedGroupChange change = changeByUnknown()
.timer(120)
.build();
assertSingleChangeMentioning(change, emptyList());
}
// Attribute access change
@Test
public void member_changes_attribute_access() {
DecryptedGroupChange change = changeBy(bob)
.attributeAccess(AccessControl.AccessRequired.MEMBER)
.build();
assertThat(describeChange(change), is(singletonList("Bob changed who can edit group info to \"All members\".")));
}
@Test
public void you_changed_attribute_access() {
DecryptedGroupChange change = changeBy(you)
.attributeAccess(AccessControl.AccessRequired.ADMINISTRATOR)
.build();
assertThat(describeChange(change), is(singletonList("You changed who can edit group info to \"Only admins\".")));
}
@Test
public void unknown_changed_attribute_access() {
DecryptedGroupChange change = changeByUnknown()
.attributeAccess(AccessControl.AccessRequired.ADMINISTRATOR)
.build();
assertThat(describeChange(change), is(singletonList("Who can edit group info has been changed to \"Only admins\".")));
}
// Membership access change
@Test
public void member_changes_membership_access() {
DecryptedGroupChange change = changeBy(alice)
.membershipAccess(AccessControl.AccessRequired.ADMINISTRATOR)
.build();
assertThat(describeChange(change), is(singletonList("Alice changed who can edit group membership to \"Only admins\".")));
}
@Test
public void you_changed_membership_access() {
DecryptedGroupChange change = changeBy(you)
.membershipAccess(AccessControl.AccessRequired.MEMBER)
.build();
assertThat(describeChange(change), is(singletonList("You changed who can edit group membership to \"All members\".")));
}
@Test
public void unknown_changed_membership_access() {
DecryptedGroupChange change = changeByUnknown()
.membershipAccess(AccessControl.AccessRequired.ADMINISTRATOR)
.build();
assertThat(describeChange(change), is(singletonList("Who can edit group membership has been changed to \"Only admins\".")));
}
// Multiple changes
@Test
public void multiple_changes() {
DecryptedGroupChange change = changeBy(alice)
.addMember(bob)
.membershipAccess(AccessControl.AccessRequired.MEMBER)
.title("Title")
.timer(300)
.build();
assertThat(describeChange(change), is(Arrays.asList(
"Alice added Bob.",
"Alice changed the group name to \"Title\".",
"Alice set the disappearing message timer to 5 minutes.",
"Alice changed who can edit group membership to \"All members\".")));
}
@Test
public void multiple_changes_by_unknown() {
DecryptedGroupChange change = changeByUnknown()
.addMember(bob)
.membershipAccess(AccessControl.AccessRequired.MEMBER)
.title("Title 2")
.avatar("Avatar 1")
.timer(600)
.build();
assertThat(describeChange(change), is(Arrays.asList(
"Bob joined the group.",
"The group name has changed to \"Title 2\".",
"The group avatar has been changed.",
"The disappearing message timer has been set to 10 minutes.",
"Who can edit group membership has been changed to \"All members\".")));
}
// Group state without a change record
@Test
public void you_created_a_group() {
DecryptedGroup group = newGroupBy(you, 0)
.build();
assertThat(describeNewGroup(group), is("You created the group."));
}
@Test
public void alice_created_a_group() {
DecryptedGroup group = newGroupBy(alice, 0)
.member(you)
.build();
assertThat(describeNewGroup(group), is("Alice added you to the group."));
}
@Test
public void alice_created_a_group_above_zero() {
DecryptedGroup group = newGroupBy(alice, 1)
.member(you)
.build();
assertThat(describeNewGroup(group), is("You joined the group."));
}
@Test
public void you_were_invited_to_a_group() {
DecryptedGroup group = newGroupBy(alice, 0)
.invite(bob, you)
.build();
assertThat(describeNewGroup(group), is("Bob invited you to the group."));
}
@Test
public void describe_a_group_you_are_not_in() {
DecryptedGroup group = newGroupBy(alice, 1)
.build();
assertThat(describeNewGroup(group), is("Group updated."));
}
private @NonNull List<String> describeChange(@NonNull DecryptedGroupChange change) {
MainThreadUtil.setMainThread(false);
return Stream.of(producer.describeChanges(change))
.map(UpdateDescription::getString)
.toList();
}
private @NonNull String describeNewGroup(@NonNull DecryptedGroup group) {
MainThreadUtil.setMainThread(false);
return producer.describeNewGroup(group).getString();
}
private static GroupStateBuilder newGroupBy(UUID foundingMember, int revision) {
return new GroupStateBuilder(foundingMember, revision);
}
private void assertSingleChangeMentioning(DecryptedGroupChange change, List<UUID> expectedMentions) {
List<UpdateDescription> changes = producer.describeChanges(change);
assertThat(changes.size(), is(1));
UpdateDescription description = changes.get(0);
assertThat(description.getMentioned(), is(expectedMentions));
if (expectedMentions.isEmpty()) {
assertTrue(description.isStringStatic());
} else {
assertFalse(description.isStringStatic());
}
}
private static class GroupStateBuilder {
private final DecryptedGroup.Builder builder;
GroupStateBuilder(@NonNull UUID foundingMember, int revision) {
builder = DecryptedGroup.newBuilder()
.setRevision(revision)
.addMembers(DecryptedMember.newBuilder()
.setUuid(UuidUtil.toByteString(foundingMember)));
}
GroupStateBuilder invite(@NonNull UUID inviter, @NonNull UUID invitee) {
builder.addPendingMembers(DecryptedPendingMember.newBuilder()
.setUuid(UuidUtil.toByteString(invitee))
.setAddedByUuid(UuidUtil.toByteString(inviter)));
return this;
}
GroupStateBuilder member(@NonNull UUID member) {
builder.addMembers(DecryptedMember.newBuilder()
.setUuid(UuidUtil.toByteString(member)));
return this;
}
public DecryptedGroup build() {
return builder.build();
}
}
private static class ChangeBuilder {
private final DecryptedGroupChange.Builder builder;
ChangeBuilder(@NonNull UUID editor) {
builder = DecryptedGroupChange.newBuilder()
.setEditor(UuidUtil.toByteString(editor));
}
ChangeBuilder() {
builder = DecryptedGroupChange.newBuilder();
}
ChangeBuilder addMember(@NonNull UUID newMember) {
builder.addNewMembers(DecryptedMember.newBuilder()
.setUuid(UuidUtil.toByteString(newMember)));
return this;
}
ChangeBuilder deleteMember(@NonNull UUID removedMember) {
builder.addDeleteMembers(UuidUtil.toByteString(removedMember));
return this;
}
ChangeBuilder promoteToAdmin(@NonNull UUID member) {
builder.addModifyMemberRoles(DecryptedModifyMemberRole.newBuilder()
.setRole(Member.Role.ADMINISTRATOR)
.setUuid(UuidUtil.toByteString(member)));
return this;
}
ChangeBuilder demoteToMember(@NonNull UUID member) {
builder.addModifyMemberRoles(DecryptedModifyMemberRole.newBuilder()
.setRole(Member.Role.DEFAULT)
.setUuid(UuidUtil.toByteString(member)));
return this;
}
ChangeBuilder invite(@NonNull UUID potentialMember) {
builder.addNewPendingMembers(DecryptedPendingMember.newBuilder()
.setUuid(UuidUtil.toByteString(potentialMember)));
return this;
}
ChangeBuilder uninvite(@NonNull UUID pendingMember) {
builder.addDeletePendingMembers(DecryptedPendingMemberRemoval.newBuilder()
.setUuid(UuidUtil.toByteString(pendingMember)));
return this;
}
ChangeBuilder promote(@NonNull UUID pendingMember) {
builder.addPromotePendingMembers(DecryptedMember.newBuilder().setUuid(UuidUtil.toByteString(pendingMember)));
return this;
}
ChangeBuilder title(@NonNull String newTitle) {
builder.setNewTitle(DecryptedString.newBuilder()
.setValue(newTitle));
return this;
}
ChangeBuilder avatar(@NonNull String newAvatar) {
builder.setNewAvatar(DecryptedString.newBuilder()
.setValue(newAvatar));
return this;
}
ChangeBuilder timer(int duration) {
builder.setNewTimer(DecryptedTimer.newBuilder()
.setDuration(duration));
return this;
}
ChangeBuilder attributeAccess(@NonNull AccessControl.AccessRequired accessRequired) {
builder.setNewAttributeAccess(accessRequired);
return this;
}
ChangeBuilder membershipAccess(@NonNull AccessControl.AccessRequired accessRequired) {
builder.setNewMemberAccess(accessRequired);
return this;
}
DecryptedGroupChange build() {
return builder.build();
}
}
private static ChangeBuilder changeBy(@NonNull UUID groupEditor) {
return new ChangeBuilder(groupEditor);
}
private static ChangeBuilder changeByUnknown() {
return new ChangeBuilder();
}
private static @NonNull GroupsV2UpdateMessageProducer.DescribeMemberStrategy createDescriber(@NonNull Map<UUID, String> map) {
return uuid -> {
String name = map.get(uuid);
assertNotNull(name);
return name;
};
}
}