Improve GV2 Invitation revoke experience.
This commit is contained in:
parent
c8ed0b19f0
commit
810ccf8e94
9 changed files with 241 additions and 25 deletions
|
@ -297,7 +297,13 @@ final class GroupsV2UpdateMessageProducer {
|
||||||
boolean newMemberIsYou = invitee.getUuid().equals(selfUuidBytes);
|
boolean newMemberIsYou = invitee.getUuid().equals(selfUuidBytes);
|
||||||
|
|
||||||
if (newMemberIsYou) {
|
if (newMemberIsYou) {
|
||||||
|
UUID uuid = UuidUtil.fromByteStringOrUnknown(invitee.getAddedByUuid());
|
||||||
|
|
||||||
|
if (UuidUtil.UNKNOWN_UUID.equals(uuid)) {
|
||||||
updates.add(updateDescription(context.getString(R.string.MessageRecord_you_were_invited_to_the_group)));
|
updates.add(updateDescription(context.getString(R.string.MessageRecord_you_were_invited_to_the_group)));
|
||||||
|
} else {
|
||||||
|
updates.add(updateDescription(invitee.getAddedByUuid(), editor -> context.getString(R.string.MessageRecord_s_invited_you_to_the_group, editor)));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
notYouInviteCount++;
|
notYouInviteCount++;
|
||||||
}
|
}
|
||||||
|
@ -320,6 +326,8 @@ final class GroupsV2UpdateMessageProducer {
|
||||||
} else {
|
} else {
|
||||||
updates.add(updateDescription(context.getString(R.string.MessageRecord_someone_declined_an_invitation_to_the_group)));
|
updates.add(updateDescription(context.getString(R.string.MessageRecord_someone_declined_an_invitation_to_the_group)));
|
||||||
}
|
}
|
||||||
|
} else if (invitee.getUuid().equals(selfUuidBytes)) {
|
||||||
|
updates.add(updateDescription(change.getEditor(), editor -> context.getString(R.string.MessageRecord_s_revoked_your_invitation_to_the_group, editor)));
|
||||||
} else {
|
} else {
|
||||||
notDeclineCount++;
|
notDeclineCount++;
|
||||||
}
|
}
|
||||||
|
@ -342,7 +350,7 @@ final class GroupsV2UpdateMessageProducer {
|
||||||
boolean inviteeWasYou = invitee.getUuid().equals(selfUuidBytes);
|
boolean inviteeWasYou = invitee.getUuid().equals(selfUuidBytes);
|
||||||
|
|
||||||
if (inviteeWasYou) {
|
if (inviteeWasYou) {
|
||||||
updates.add(updateDescription(context.getString(R.string.MessageRecord_your_invitation_to_the_group_was_revoked)));
|
updates.add(updateDescription(context.getString(R.string.MessageRecord_an_admin_revoked_your_invitation_to_the_group)));
|
||||||
} else {
|
} else {
|
||||||
notDeclineCount++;
|
notDeclineCount++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.messagerequests;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.WorkerThread;
|
||||||
import androidx.core.util.Consumer;
|
import androidx.core.util.Consumer;
|
||||||
|
|
||||||
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
||||||
|
@ -67,15 +68,29 @@ final class MessageRequestRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
void getMessageRequestState(@NonNull Recipient recipient, long threadId, @NonNull Consumer<MessageRequestState> state) {
|
void getMessageRequestState(@NonNull Recipient recipient, long threadId, @NonNull Consumer<MessageRequestState> state) {
|
||||||
executor.execute(() -> {
|
executor.execute(() -> state.accept(findMessageRequestState(recipient, threadId)));
|
||||||
if (!RecipientUtil.isMessageRequestAccepted(context, threadId)) {
|
}
|
||||||
state.accept(MessageRequestState.UNACCEPTED);
|
|
||||||
} else if (RecipientUtil.isPreMessageRequestThread(context, threadId) && !RecipientUtil.isLegacyProfileSharingAccepted(recipient)) {
|
@WorkerThread
|
||||||
state.accept(MessageRequestState.LEGACY);
|
private MessageRequestState findMessageRequestState(@NonNull Recipient recipient, long threadId) {
|
||||||
} else {
|
if (!RecipientUtil.isMessageRequestAccepted(context, threadId)) {
|
||||||
state.accept(MessageRequestState.ACCEPTED);
|
if (recipient.isGroup()) {
|
||||||
|
GroupDatabase.MemberLevel memberLevel = DatabaseFactory.getGroupDatabase(context)
|
||||||
|
.getGroup(recipient.getId())
|
||||||
|
.transform(g -> g.memberLevel(Recipient.self()))
|
||||||
|
.or(GroupDatabase.MemberLevel.NOT_A_MEMBER);
|
||||||
|
|
||||||
|
if (memberLevel == GroupDatabase.MemberLevel.NOT_A_MEMBER) {
|
||||||
|
return MessageRequestState.NOT_REQUIRED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return MessageRequestState.REQUIRED;
|
||||||
|
} else if (RecipientUtil.isPreMessageRequestThread(context, threadId) && !RecipientUtil.isLegacyProfileSharingAccepted(recipient)) {
|
||||||
|
return MessageRequestState.LEGACY;
|
||||||
|
} else {
|
||||||
|
return MessageRequestState.NOT_REQUIRED;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void acceptMessageRequest(@NonNull LiveRecipient liveRecipient,
|
void acceptMessageRequest(@NonNull LiveRecipient liveRecipient,
|
||||||
|
@ -218,6 +233,19 @@ final class MessageRequestRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MessageRequestState {
|
enum MessageRequestState {
|
||||||
ACCEPTED, UNACCEPTED, LEGACY
|
/**
|
||||||
|
* Message request permission does not need to be gained at this time.
|
||||||
|
* <p>
|
||||||
|
* Either:
|
||||||
|
* - Explicit message request has been accepted, or;
|
||||||
|
* - Did not need to be shown because they are a contact etc, or;
|
||||||
|
* - It's a group that they are no longer in or invited to.
|
||||||
|
*/
|
||||||
|
NOT_REQUIRED,
|
||||||
|
|
||||||
|
/** Explicit message request permission is required. */
|
||||||
|
REQUIRED,
|
||||||
|
|
||||||
|
LEGACY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,10 +161,10 @@ public class MessageRequestViewModel extends ViewModel {
|
||||||
|
|
||||||
repository.getMessageRequestState(recipient, threadId, accepted -> {
|
repository.getMessageRequestState(recipient, threadId, accepted -> {
|
||||||
switch (accepted) {
|
switch (accepted) {
|
||||||
case ACCEPTED:
|
case NOT_REQUIRED:
|
||||||
displayState.postValue(DisplayState.DISPLAY_NONE);
|
displayState.postValue(DisplayState.DISPLAY_NONE);
|
||||||
break;
|
break;
|
||||||
case UNACCEPTED:
|
case REQUIRED:
|
||||||
displayState.postValue(DisplayState.DISPLAY_MESSAGE_REQUEST);
|
displayState.postValue(DisplayState.DISPLAY_MESSAGE_REQUEST);
|
||||||
break;
|
break;
|
||||||
case LEGACY:
|
case LEGACY:
|
||||||
|
|
|
@ -168,6 +168,7 @@ public final class MessageGroupContext {
|
||||||
memberUuids.addAll(DecryptedGroupUtil.membersToUuidList(decryptedGroupV2Context.getGroupState().getMembersList()));
|
memberUuids.addAll(DecryptedGroupUtil.membersToUuidList(decryptedGroupV2Context.getGroupState().getMembersList()));
|
||||||
memberUuids.addAll(DecryptedGroupUtil.pendingToUuidList(decryptedGroupV2Context.getGroupState().getPendingMembersList()));
|
memberUuids.addAll(DecryptedGroupUtil.pendingToUuidList(decryptedGroupV2Context.getGroupState().getPendingMembersList()));
|
||||||
memberUuids.addAll(DecryptedGroupUtil.removedMembersUuidList(decryptedGroupV2Context.getChange()));
|
memberUuids.addAll(DecryptedGroupUtil.removedMembersUuidList(decryptedGroupV2Context.getChange()));
|
||||||
|
memberUuids.addAll(DecryptedGroupUtil.removedPendingMembersUuidList(decryptedGroupV2Context.getChange()));
|
||||||
|
|
||||||
return UuidUtil.filterKnown(memberUuids);
|
return UuidUtil.filterKnown(memberUuids);
|
||||||
}
|
}
|
||||||
|
|
|
@ -865,7 +865,8 @@
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="MessageRecord_someone_declined_an_invitation_to_the_group">Someone declined an invitation to the group.</string>
|
<string name="MessageRecord_someone_declined_an_invitation_to_the_group">Someone declined an invitation to the group.</string>
|
||||||
<string name="MessageRecord_you_declined_the_invitation_to_the_group">You declined the invitation to the group.</string>
|
<string name="MessageRecord_you_declined_the_invitation_to_the_group">You declined the invitation to the group.</string>
|
||||||
<string name="MessageRecord_your_invitation_to_the_group_was_revoked">Your invitation to the group was revoked.</string>
|
<string name="MessageRecord_s_revoked_your_invitation_to_the_group">%1$s revoked your invitation to the group.</string>
|
||||||
|
<string name="MessageRecord_an_admin_revoked_your_invitation_to_the_group">An admin revoked your invitation to the group.</string>
|
||||||
<plurals name="MessageRecord_d_invitations_were_revoked">
|
<plurals name="MessageRecord_d_invitations_were_revoked">
|
||||||
<item quantity="one">An invitation to the group was revoked.</item>
|
<item quantity="one">An invitation to the group was revoked.</item>
|
||||||
<item quantity="other">%1$d invitations to the group were revoked.</item>
|
<item quantity="other">%1$d invitations to the group were revoked.</item>
|
||||||
|
|
|
@ -391,7 +391,16 @@ public final class GroupsV2UpdateMessageProducerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void unknown_invited_you() {
|
public void unknown_editor_but_known_invitee_invited_you() {
|
||||||
|
DecryptedGroupChange change = changeByUnknown()
|
||||||
|
.inviteBy(you, alice)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat(describeChange(change), is(singletonList("Alice invited you to the group.")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unknown_editor_and_unknown_inviter_invited_you() {
|
||||||
DecryptedGroupChange change = changeByUnknown()
|
DecryptedGroupChange change = changeByUnknown()
|
||||||
.invite(you)
|
.invite(you)
|
||||||
.build();
|
.build();
|
||||||
|
@ -430,6 +439,18 @@ public final class GroupsV2UpdateMessageProducerTest {
|
||||||
assertThat(describeChange(change), is(Arrays.asList("You were invited to the group.", "3 people were invited to the group.")));
|
assertThat(describeChange(change), is(Arrays.asList("You were invited to the group.", "3 people were invited to the group.")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unknown_editor_invited_3_persons_and_you_inviter_known() {
|
||||||
|
DecryptedGroupChange change = changeByUnknown()
|
||||||
|
.invite(alice)
|
||||||
|
.inviteBy(you, bob)
|
||||||
|
.invite(UUID.randomUUID())
|
||||||
|
.invite(UUID.randomUUID())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat(describeChange(change), is(Arrays.asList("Bob invited you to the group.", "3 people were invited to the group.")));
|
||||||
|
}
|
||||||
|
|
||||||
// Member invitation revocation
|
// Member invitation revocation
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -494,7 +515,7 @@ public final class GroupsV2UpdateMessageProducerTest {
|
||||||
.uninvite(you)
|
.uninvite(you)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
assertThat(describeChange(change), is(singletonList("Your invitation to the group was revoked.")));
|
assertThat(describeChange(change), is(singletonList("An admin revoked your invitation to the group.")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -525,7 +546,16 @@ public final class GroupsV2UpdateMessageProducerTest {
|
||||||
.uninvite(UUID.randomUUID())
|
.uninvite(UUID.randomUUID())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
assertThat(describeChange(change), is(Arrays.asList("Your invitation to the group was revoked.", "3 invitations to the group were revoked.")));
|
assertThat(describeChange(change), is(Arrays.asList("An admin revoked your invitation to the group.", "3 invitations to the group were revoked.")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void your_invite_was_revoked_by_known_member() {
|
||||||
|
DecryptedGroupChange change = changeBy(bob)
|
||||||
|
.uninvite(you)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat(describeChange(change), is(singletonList("Bob revoked your invitation to the group.")));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Promote pending members
|
// Promote pending members
|
||||||
|
|
|
@ -72,8 +72,13 @@ public final class ChangeBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChangeBuilder invite(@NonNull UUID potentialMember) {
|
public ChangeBuilder invite(@NonNull UUID potentialMember) {
|
||||||
|
return inviteBy(potentialMember, UuidUtil.UNKNOWN_UUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChangeBuilder inviteBy(@NonNull UUID potentialMember, @NonNull UUID inviter) {
|
||||||
builder.addNewPendingMembers(DecryptedPendingMember.newBuilder()
|
builder.addNewPendingMembers(DecryptedPendingMember.newBuilder()
|
||||||
.setUuid(UuidUtil.toByteString(potentialMember)));
|
.setUuid(UuidUtil.toByteString(potentialMember))
|
||||||
|
.setAddedByUuid(UuidUtil.toByteString(inviter)));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ import org.signal.storageservice.protos.groups.local.DecryptedMember;
|
||||||
import org.signal.storageservice.protos.groups.local.DecryptedModifyMemberRole;
|
import org.signal.storageservice.protos.groups.local.DecryptedModifyMemberRole;
|
||||||
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
|
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
|
||||||
import org.signal.storageservice.protos.groups.local.DecryptedPendingMemberRemoval;
|
import org.signal.storageservice.protos.groups.local.DecryptedPendingMemberRemoval;
|
||||||
import org.signal.zkgroup.util.UUIDUtil;
|
|
||||||
import org.whispersystems.libsignal.logging.Log;
|
import org.whispersystems.libsignal.logging.Log;
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||||
|
@ -43,7 +42,11 @@ public final class DecryptedGroupUtil {
|
||||||
ArrayList<UUID> uuidList = new ArrayList<>(membersList.size());
|
ArrayList<UUID> uuidList = new ArrayList<>(membersList.size());
|
||||||
|
|
||||||
for (DecryptedMember member : membersList) {
|
for (DecryptedMember member : membersList) {
|
||||||
uuidList.add(toUuid(member));
|
UUID uuid = toUuid(member);
|
||||||
|
|
||||||
|
if (!UuidUtil.UNKNOWN_UUID.equals(uuid)) {
|
||||||
|
uuidList.add(uuid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return uuidList;
|
return uuidList;
|
||||||
|
@ -59,6 +62,9 @@ public final class DecryptedGroupUtil {
|
||||||
return uuidList;
|
return uuidList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can return non-decryptable member UUIDs as {@link UuidUtil#UNKNOWN_UUID}.
|
||||||
|
*/
|
||||||
public static ArrayList<UUID> pendingToUuidList(Collection<DecryptedPendingMember> membersList) {
|
public static ArrayList<UUID> pendingToUuidList(Collection<DecryptedPendingMember> membersList) {
|
||||||
ArrayList<UUID> uuidList = new ArrayList<>(membersList.size());
|
ArrayList<UUID> uuidList = new ArrayList<>(membersList.size());
|
||||||
|
|
||||||
|
@ -69,11 +75,37 @@ public final class DecryptedGroupUtil {
|
||||||
return uuidList;
|
return uuidList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will not return any non-decryptable member UUIDs.
|
||||||
|
*/
|
||||||
public static ArrayList<UUID> removedMembersUuidList(DecryptedGroupChange groupChange) {
|
public static ArrayList<UUID> removedMembersUuidList(DecryptedGroupChange groupChange) {
|
||||||
ArrayList<UUID> uuidList = new ArrayList<>(groupChange.getDeleteMembersCount());
|
List<ByteString> deletedMembers = groupChange.getDeleteMembersList();
|
||||||
|
ArrayList<UUID> uuidList = new ArrayList<>(deletedMembers.size());
|
||||||
|
|
||||||
for (ByteString member : groupChange.getDeleteMembersList()) {
|
for (ByteString member : deletedMembers) {
|
||||||
uuidList.add(toUuid(member));
|
UUID uuid = toUuid(member);
|
||||||
|
|
||||||
|
if (!UuidUtil.UNKNOWN_UUID.equals(uuid)) {
|
||||||
|
uuidList.add(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return uuidList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will not return any non-decryptable member UUIDs.
|
||||||
|
*/
|
||||||
|
public static ArrayList<UUID> removedPendingMembersUuidList(DecryptedGroupChange groupChange) {
|
||||||
|
List<DecryptedPendingMemberRemoval> deletedPendingMembers = groupChange.getDeletePendingMembersList();
|
||||||
|
ArrayList<UUID> uuidList = new ArrayList<>(deletedPendingMembers.size());
|
||||||
|
|
||||||
|
for (DecryptedPendingMemberRemoval member : deletedPendingMembers) {
|
||||||
|
UUID uuid = toUuid(member.getUuid());
|
||||||
|
|
||||||
|
if(!UuidUtil.UNKNOWN_UUID.equals(uuid)) {
|
||||||
|
uuidList.add(uuid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return uuidList;
|
return uuidList;
|
||||||
|
@ -87,8 +119,8 @@ public final class DecryptedGroupUtil {
|
||||||
return toUuid(member.getUuid());
|
return toUuid(member.getUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static UUID toUuid(ByteString member) {
|
private static UUID toUuid(ByteString memberUuid) {
|
||||||
return UUIDUtil.deserialize(member.toByteArray());
|
return UuidUtil.fromByteStringOrUnknown(memberUuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,12 +5,25 @@ import com.google.protobuf.ByteString;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
|
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
|
||||||
import org.signal.storageservice.protos.groups.local.DecryptedMember;
|
import org.signal.storageservice.protos.groups.local.DecryptedMember;
|
||||||
|
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
|
||||||
|
import org.signal.storageservice.protos.groups.local.DecryptedPendingMemberRemoval;
|
||||||
import org.signal.zkgroup.util.UUIDUtil;
|
import org.signal.zkgroup.util.UUIDUtil;
|
||||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||||
|
import org.whispersystems.signalservice.internal.util.Util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import static java.util.Collections.emptyList;
|
||||||
|
import static java.util.Collections.singleton;
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
public final class DecryptedGroupUtilTest {
|
public final class DecryptedGroupUtilTest {
|
||||||
|
|
||||||
|
@ -26,6 +39,17 @@ public final class DecryptedGroupUtilTest {
|
||||||
assertEquals(uuid, parsed);
|
assertEquals(uuid, parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void can_extract_uuid_from_bad_decrypted_member() {
|
||||||
|
DecryptedMember decryptedMember = DecryptedMember.newBuilder()
|
||||||
|
.setUuid(ByteString.copyFrom(new byte[0]))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
UUID parsed = DecryptedGroupUtil.toUuid(decryptedMember);
|
||||||
|
|
||||||
|
assertEquals(UuidUtil.UNKNOWN_UUID, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void can_extract_editor_uuid_from_decrypted_group_change() {
|
public void can_extract_editor_uuid_from_decrypted_group_change() {
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
|
@ -39,4 +63,91 @@ public final class DecryptedGroupUtilTest {
|
||||||
assertEquals(uuid, parsed);
|
assertEquals(uuid, parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void can_extract_uuid_from_decrypted_pending_member() {
|
||||||
|
UUID uuid = UUID.randomUUID();
|
||||||
|
DecryptedPendingMember decryptedMember = DecryptedPendingMember.newBuilder()
|
||||||
|
.setUuid(UuidUtil.toByteString(uuid))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
UUID parsed = DecryptedGroupUtil.toUuid(decryptedMember);
|
||||||
|
|
||||||
|
assertEquals(uuid, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void can_extract_uuid_from_bad_decrypted_pending_member() {
|
||||||
|
DecryptedPendingMember decryptedMember = DecryptedPendingMember.newBuilder()
|
||||||
|
.setUuid(ByteString.copyFrom(Util.getSecretBytes(17)))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
UUID parsed = DecryptedGroupUtil.toUuid(decryptedMember);
|
||||||
|
|
||||||
|
assertEquals(UuidUtil.UNKNOWN_UUID, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void can_extract_uuids_for_all_pending_including_bad_entries() {
|
||||||
|
UUID uuid1 = UUID.randomUUID();
|
||||||
|
UUID uuid2 = UUID.randomUUID();
|
||||||
|
DecryptedPendingMember decryptedMember1 = DecryptedPendingMember.newBuilder()
|
||||||
|
.setUuid(UuidUtil.toByteString(uuid1))
|
||||||
|
.build();
|
||||||
|
DecryptedPendingMember decryptedMember2 = DecryptedPendingMember.newBuilder()
|
||||||
|
.setUuid(UuidUtil.toByteString(uuid2))
|
||||||
|
.build();
|
||||||
|
DecryptedPendingMember decryptedMember3 = DecryptedPendingMember.newBuilder()
|
||||||
|
.setUuid(ByteString.copyFrom(Util.getSecretBytes(17)))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
DecryptedGroupChange groupChange = DecryptedGroupChange.newBuilder()
|
||||||
|
.addNewPendingMembers(decryptedMember1)
|
||||||
|
.addNewPendingMembers(decryptedMember2)
|
||||||
|
.addNewPendingMembers(decryptedMember3)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
List<UUID> pendingUuids = DecryptedGroupUtil.pendingToUuidList(groupChange.getNewPendingMembersList());
|
||||||
|
|
||||||
|
assertThat(pendingUuids, is(asList(uuid1, uuid2, UuidUtil.UNKNOWN_UUID)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void can_extract_uuids_for_all_deleted_pending_excluding_bad_entries() {
|
||||||
|
UUID uuid1 = UUID.randomUUID();
|
||||||
|
UUID uuid2 = UUID.randomUUID();
|
||||||
|
DecryptedPendingMemberRemoval decryptedMember1 = DecryptedPendingMemberRemoval.newBuilder()
|
||||||
|
.setUuid(UuidUtil.toByteString(uuid1))
|
||||||
|
.build();
|
||||||
|
DecryptedPendingMemberRemoval decryptedMember2 = DecryptedPendingMemberRemoval.newBuilder()
|
||||||
|
.setUuid(UuidUtil.toByteString(uuid2))
|
||||||
|
.build();
|
||||||
|
DecryptedPendingMemberRemoval decryptedMember3 = DecryptedPendingMemberRemoval.newBuilder()
|
||||||
|
.setUuid(ByteString.copyFrom(Util.getSecretBytes(17)))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
DecryptedGroupChange groupChange = DecryptedGroupChange.newBuilder()
|
||||||
|
.addDeletePendingMembers(decryptedMember1)
|
||||||
|
.addDeletePendingMembers(decryptedMember2)
|
||||||
|
.addDeletePendingMembers(decryptedMember3)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
List<UUID> removedUuids = DecryptedGroupUtil.removedPendingMembersUuidList(groupChange);
|
||||||
|
|
||||||
|
assertThat(removedUuids, is(asList(uuid1, uuid2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void can_extract_uuids_for_all_deleted_members_excluding_bad_entries() {
|
||||||
|
UUID uuid1 = UUID.randomUUID();
|
||||||
|
UUID uuid2 = UUID.randomUUID();
|
||||||
|
DecryptedGroupChange groupChange = DecryptedGroupChange.newBuilder()
|
||||||
|
.addDeleteMembers(UuidUtil.toByteString(uuid1))
|
||||||
|
.addDeleteMembers(UuidUtil.toByteString(uuid2))
|
||||||
|
.addDeleteMembers(ByteString.copyFrom(Util.getSecretBytes(17)))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
List<UUID> removedUuids = DecryptedGroupUtil.removedMembersUuidList(groupChange);
|
||||||
|
|
||||||
|
assertThat(removedUuids, is(asList(uuid1, uuid2)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue