Signal-Android/libsignal/service/src/test/java/org/whispersystems/signalservice/api/groupsv2/DecryptedGroupUtil_apply_Te...

767 lines
47 KiB
Java

package org.whispersystems.signalservice.api.groupsv2;
import com.google.protobuf.ByteString;
import org.junit.Test;
import org.signal.storageservice.protos.groups.AccessControl;
import org.signal.storageservice.protos.groups.Member;
import org.signal.storageservice.protos.groups.local.DecryptedApproveMember;
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.DecryptedRequestingMember;
import org.signal.storageservice.protos.groups.local.DecryptedString;
import org.signal.storageservice.protos.groups.local.DecryptedTimer;
import org.signal.zkgroup.profiles.ProfileKey;
import org.whispersystems.signalservice.api.util.UuidUtil;
import org.whispersystems.signalservice.internal.util.Util;
import java.util.UUID;
import static org.junit.Assert.assertEquals;
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.admin;
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.asAdmin;
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.asMember;
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.member;
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.newProfileKey;
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.pendingMember;
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.randomProfileKey;
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.requestingMember;
import static org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.withProfileKey;
import static org.whispersystems.signalservice.api.groupsv2.ProtobufTestUtils.getMaxDeclaredFieldNumber;
public final class DecryptedGroupUtil_apply_Test {
/**
* Reflects over the generated protobuf class and ensures that no new fields have been added since we wrote this.
* <p>
* If we didn't, newly added fields would not be applied by {@link DecryptedGroupUtil#apply}.
*/
@Test
public void ensure_DecryptedGroupUtil_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(),
19, maxFieldFound);
}
@Test
public void apply_revision() throws NotAbleToApplyGroupV2ChangeException {
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(9)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(10)
.build());
assertEquals(10, newGroup.getRevision());
}
@Test
public void apply_new_member() throws NotAbleToApplyGroupV2ChangeException {
DecryptedMember member1 = member(UUID.randomUUID());
DecryptedMember member2 = member(UUID.randomUUID());
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.addMembers(member1)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.addNewMembers(member2)
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.addMembers(member1)
.addMembers(member2)
.build(),
newGroup);
}
@Test
public void apply_remove_member() throws NotAbleToApplyGroupV2ChangeException {
DecryptedMember member1 = member(UUID.randomUUID());
DecryptedMember member2 = member(UUID.randomUUID());
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(13)
.addMembers(member1)
.addMembers(member2)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(14)
.addDeleteMembers(member1.getUuid())
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(14)
.addMembers(member2)
.build(),
newGroup);
}
@Test
public void apply_remove_members() throws NotAbleToApplyGroupV2ChangeException {
DecryptedMember member1 = member(UUID.randomUUID());
DecryptedMember member2 = member(UUID.randomUUID());
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(13)
.addMembers(member1)
.addMembers(member2)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(14)
.addDeleteMembers(member1.getUuid())
.addDeleteMembers(member2.getUuid())
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(14)
.build(),
newGroup);
}
@Test
public void apply_remove_members_not_found() throws NotAbleToApplyGroupV2ChangeException {
DecryptedMember member1 = member(UUID.randomUUID());
DecryptedMember member2 = member(UUID.randomUUID());
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(13)
.addMembers(member1)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(14)
.addDeleteMembers(member2.getUuid())
.build());
assertEquals(DecryptedGroup.newBuilder()
.addMembers(member1)
.setRevision(14)
.build(),
newGroup);
}
@Test
public void apply_modify_member_role() throws NotAbleToApplyGroupV2ChangeException {
DecryptedMember member1 = member(UUID.randomUUID());
DecryptedMember member2 = admin(UUID.randomUUID());
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(13)
.addMembers(member1)
.addMembers(member2)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(14)
.addModifyMemberRoles(DecryptedModifyMemberRole.newBuilder().setUuid(member1.getUuid()).setRole(Member.Role.ADMINISTRATOR))
.addModifyMemberRoles(DecryptedModifyMemberRole.newBuilder().setUuid(member2.getUuid()).setRole(Member.Role.DEFAULT))
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(14)
.addMembers(asAdmin(member1))
.addMembers(asMember(member2))
.build(),
newGroup);
}
@Test(expected = NotAbleToApplyGroupV2ChangeException.class)
public void not_able_to_apply_modify_member_role_for_non_member() throws NotAbleToApplyGroupV2ChangeException {
DecryptedMember member1 = member(UUID.randomUUID());
DecryptedMember member2 = member(UUID.randomUUID());
DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(13)
.addMembers(member1)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(14)
.addModifyMemberRoles(DecryptedModifyMemberRole.newBuilder()
.setRole(Member.Role.ADMINISTRATOR)
.setUuid(member2.getUuid())
.build())
.build());
}
@Test(expected = NotAbleToApplyGroupV2ChangeException.class)
public void not_able_to_apply_modify_member_role_for_no_role() throws NotAbleToApplyGroupV2ChangeException {
DecryptedMember member1 = member(UUID.randomUUID());
DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(13)
.addMembers(member1)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(14)
.addModifyMemberRoles(DecryptedModifyMemberRole.newBuilder()
.setUuid(member1.getUuid())
.build())
.build());
}
@Test
public void apply_modify_member_profile_keys() throws NotAbleToApplyGroupV2ChangeException {
ProfileKey profileKey1 = randomProfileKey();
ProfileKey profileKey2a = randomProfileKey();
ProfileKey profileKey2b = randomProfileKey();
DecryptedMember member1 = member(UUID.randomUUID(), profileKey1);
DecryptedMember member2a = member(UUID.randomUUID(), profileKey2a);
DecryptedMember member2b = withProfileKey(member2a, profileKey2b);
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(13)
.addMembers(member1)
.addMembers(member2a)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(14)
.addModifiedProfileKeys(member2b)
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(14)
.addMembers(member1)
.addMembers(member2b)
.build(),
newGroup);
}
@Test(expected = NotAbleToApplyGroupV2ChangeException.class)
public void cant_apply_modify_member_profile_keys_if_member_not_in_group() throws NotAbleToApplyGroupV2ChangeException {
ProfileKey profileKey1 = randomProfileKey();
ProfileKey profileKey2a = randomProfileKey();
ProfileKey profileKey2b = randomProfileKey();
DecryptedMember member1 = member(UUID.randomUUID(), profileKey1);
DecryptedMember member2a = member(UUID.randomUUID(), profileKey2a);
DecryptedMember member2b = member(UUID.randomUUID(), profileKey2b);
DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(13)
.addMembers(member1)
.addMembers(member2a)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(14)
.addModifiedProfileKeys(member2b)
.build());
}
@Test
public void apply_modify_admin_profile_keys() throws NotAbleToApplyGroupV2ChangeException {
UUID adminUuid = UUID.randomUUID();
ProfileKey profileKey1 = randomProfileKey();
ProfileKey profileKey2a = randomProfileKey();
ProfileKey profileKey2b = randomProfileKey();
DecryptedMember member1 = member(UUID.randomUUID(), profileKey1);
DecryptedMember admin2a = admin(adminUuid, profileKey2a);
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(13)
.addMembers(member1)
.addMembers(admin2a)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(14)
.addModifiedProfileKeys(DecryptedMember.newBuilder(DecryptedMember.newBuilder()
.setUuid(UuidUtil.toByteString(adminUuid))
.build())
.setProfileKey(ByteString.copyFrom(profileKey2b.serialize())))
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(14)
.addMembers(member1)
.addMembers(admin(adminUuid, profileKey2b))
.build(),
newGroup);
}
@Test
public void apply_new_pending_member() throws NotAbleToApplyGroupV2ChangeException {
DecryptedMember member1 = member(UUID.randomUUID());
DecryptedPendingMember pending = pendingMember(UUID.randomUUID());
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.addMembers(member1)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.addNewPendingMembers(pending)
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.addMembers(member1)
.addPendingMembers(pending)
.build(),
newGroup);
}
@Test
public void apply_new_pending_member_already_pending() throws NotAbleToApplyGroupV2ChangeException {
DecryptedMember member1 = member(UUID.randomUUID());
DecryptedPendingMember pending = pendingMember(UUID.randomUUID());
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.addMembers(member1)
.addPendingMembers(pending)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.addNewPendingMembers(pending)
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.addMembers(member1)
.addPendingMembers(pending)
.build(),
newGroup);
}
@Test(expected = NotAbleToApplyGroupV2ChangeException.class)
public void apply_new_pending_member_already_in_group() throws NotAbleToApplyGroupV2ChangeException {
DecryptedMember member1 = member(UUID.randomUUID());
UUID uuid2 = UUID.randomUUID();
DecryptedMember member2 = member(uuid2);
DecryptedPendingMember pending2 = pendingMember(uuid2);
DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.addMembers(member1)
.addMembers(member2)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.addNewPendingMembers(pending2)
.build());
}
@Test
public void remove_pending_member() throws NotAbleToApplyGroupV2ChangeException {
DecryptedMember member1 = member(UUID.randomUUID());
UUID pendingUuid = UUID.randomUUID();
DecryptedPendingMember pending = pendingMember(pendingUuid);
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.addMembers(member1)
.addPendingMembers(pending)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.addDeletePendingMembers(DecryptedPendingMemberRemoval.newBuilder()
.setUuidCipherText(ProtoTestUtils.encrypt(pendingUuid))
.build())
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.addMembers(member1)
.build(),
newGroup);
}
@Test
public void cannot_remove_pending_member_if_not_in_group() throws NotAbleToApplyGroupV2ChangeException {
DecryptedMember member1 = member(UUID.randomUUID());
UUID pendingUuid = UUID.randomUUID();
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.addMembers(member1)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.addDeletePendingMembers(DecryptedPendingMemberRemoval.newBuilder()
.setUuidCipherText(ProtoTestUtils.encrypt(pendingUuid))
.build())
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.addMembers(member1)
.build(),
newGroup);
}
@Test
public void promote_pending_member() throws NotAbleToApplyGroupV2ChangeException {
ProfileKey profileKey2 = randomProfileKey();
DecryptedMember member1 = member(UUID.randomUUID());
UUID pending2Uuid = UUID.randomUUID();
DecryptedPendingMember pending2 = pendingMember(pending2Uuid);
DecryptedMember member2 = member(pending2Uuid, profileKey2);
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.addMembers(member1)
.addPendingMembers(pending2)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.addPromotePendingMembers(member2)
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.addMembers(member1)
.addMembers(member2)
.build(),
newGroup);
}
@Test(expected = NotAbleToApplyGroupV2ChangeException.class)
public void cannot_promote_pending_member_if_not_in_group() throws NotAbleToApplyGroupV2ChangeException {
ProfileKey profileKey2 = randomProfileKey();
DecryptedMember member1 = member(UUID.randomUUID());
UUID pending2Uuid = UUID.randomUUID();
DecryptedMember member2 = withProfileKey(admin(pending2Uuid), profileKey2);
DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.addMembers(member1)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.addPromotePendingMembers(member2)
.build());
}
@Test
public void skip_promote_pending_member_by_direct_add() throws NotAbleToApplyGroupV2ChangeException {
ProfileKey profileKey2 = randomProfileKey();
ProfileKey profileKey3 = randomProfileKey();
DecryptedMember member1 = member(UUID.randomUUID());
UUID pending2Uuid = UUID.randomUUID();
UUID pending3Uuid = UUID.randomUUID();
UUID pending4Uuid = UUID.randomUUID();
DecryptedPendingMember pending2 = pendingMember(pending2Uuid);
DecryptedPendingMember pending3 = pendingMember(pending3Uuid);
DecryptedPendingMember pending4 = pendingMember(pending4Uuid);
DecryptedMember member2 = member(pending2Uuid, profileKey2);
DecryptedMember member3 = member(pending3Uuid, profileKey3);
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.addMembers(member1)
.addPendingMembers(pending2)
.addPendingMembers(pending3)
.addPendingMembers(pending4)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.addNewMembers(member2)
.addNewMembers(member3)
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.addMembers(member1)
.addMembers(member2)
.addMembers(member3)
.addPendingMembers(pending4)
.build(),
newGroup);
}
@Test
public void title() throws NotAbleToApplyGroupV2ChangeException {
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.setTitle("Old title")
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.setNewTitle(DecryptedString.newBuilder().setValue("New title").build())
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.setTitle("New title")
.build(),
newGroup);
}
@Test
public void avatar() throws NotAbleToApplyGroupV2ChangeException {
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.setAvatar("https://cnd/oldavatar")
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.setNewAvatar(DecryptedString.newBuilder().setValue("https://cnd/newavatar").build())
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.setAvatar("https://cnd/newavatar")
.build(),
newGroup);
}
@Test
public void timer() throws NotAbleToApplyGroupV2ChangeException {
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.setDisappearingMessagesTimer(DecryptedTimer.newBuilder().setDuration(100))
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.setNewTimer(DecryptedTimer.newBuilder().setDuration(2000))
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.setDisappearingMessagesTimer(DecryptedTimer.newBuilder().setDuration(2000))
.build(),
newGroup);
}
@Test
public void attribute_access() throws NotAbleToApplyGroupV2ChangeException {
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.setAccessControl(AccessControl.newBuilder()
.setAttributes(AccessControl.AccessRequired.ADMINISTRATOR)
.setMembers(AccessControl.AccessRequired.MEMBER)
.build())
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.setNewAttributeAccess(AccessControl.AccessRequired.MEMBER)
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.setAccessControl(AccessControl.newBuilder()
.setAttributes(AccessControl.AccessRequired.MEMBER)
.setMembers(AccessControl.AccessRequired.MEMBER)
.build())
.build(),
newGroup);
}
@Test
public void membership_access() throws NotAbleToApplyGroupV2ChangeException {
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.setAccessControl(AccessControl.newBuilder()
.setAttributes(AccessControl.AccessRequired.ADMINISTRATOR)
.setMembers(AccessControl.AccessRequired.MEMBER)
.build())
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.setNewMemberAccess(AccessControl.AccessRequired.ADMINISTRATOR)
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.setAccessControl(AccessControl.newBuilder()
.setAttributes(AccessControl.AccessRequired.ADMINISTRATOR)
.setMembers(AccessControl.AccessRequired.ADMINISTRATOR)
.build())
.build(),
newGroup);
}
@Test
public void change_both_access_levels() throws NotAbleToApplyGroupV2ChangeException {
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.setAccessControl(AccessControl.newBuilder()
.setAttributes(AccessControl.AccessRequired.ADMINISTRATOR)
.setMembers(AccessControl.AccessRequired.MEMBER)
.build())
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.setNewAttributeAccess(AccessControl.AccessRequired.MEMBER)
.setNewMemberAccess(AccessControl.AccessRequired.ADMINISTRATOR)
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.setAccessControl(AccessControl.newBuilder()
.setAttributes(AccessControl.AccessRequired.MEMBER)
.setMembers(AccessControl.AccessRequired.ADMINISTRATOR)
.build())
.build(),
newGroup);
}
@Test
public void invite_link_access() throws NotAbleToApplyGroupV2ChangeException {
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.setAccessControl(AccessControl.newBuilder()
.setAttributes(AccessControl.AccessRequired.MEMBER)
.setMembers(AccessControl.AccessRequired.MEMBER)
.setAddFromInviteLink(AccessControl.AccessRequired.UNSATISFIABLE)
.build())
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.setNewInviteLinkAccess(AccessControl.AccessRequired.ADMINISTRATOR)
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.setAccessControl(AccessControl.newBuilder()
.setAttributes(AccessControl.AccessRequired.MEMBER)
.setMembers(AccessControl.AccessRequired.MEMBER)
.setAddFromInviteLink(AccessControl.AccessRequired.ADMINISTRATOR)
.build())
.build(),
newGroup);
}
@Test
public void apply_new_requesting_member() throws NotAbleToApplyGroupV2ChangeException {
DecryptedRequestingMember member1 = requestingMember(UUID.randomUUID());
DecryptedRequestingMember member2 = requestingMember(UUID.randomUUID());
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.addRequestingMembers(member1)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.addNewRequestingMembers(member2)
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.addRequestingMembers(member1)
.addRequestingMembers(member2)
.build(),
newGroup);
}
@Test
public void apply_remove_requesting_member() throws NotAbleToApplyGroupV2ChangeException {
DecryptedRequestingMember member1 = requestingMember(UUID.randomUUID());
DecryptedRequestingMember member2 = requestingMember(UUID.randomUUID());
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(13)
.addRequestingMembers(member1)
.addRequestingMembers(member2)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(14)
.addDeleteRequestingMembers(member1.getUuid())
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(14)
.addRequestingMembers(member2)
.build(),
newGroup);
}
@Test
public void promote_requesting_member() throws NotAbleToApplyGroupV2ChangeException {
UUID uuid1 = UUID.randomUUID();
UUID uuid2 = UUID.randomUUID();
UUID uuid3 = UUID.randomUUID();
ProfileKey profileKey1 = newProfileKey();
ProfileKey profileKey2 = newProfileKey();
ProfileKey profileKey3 = newProfileKey();
DecryptedRequestingMember member1 = requestingMember(uuid1, profileKey1);
DecryptedRequestingMember member2 = requestingMember(uuid2, profileKey2);
DecryptedRequestingMember member3 = requestingMember(uuid3, profileKey3);
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(13)
.addRequestingMembers(member1)
.addRequestingMembers(member2)
.addRequestingMembers(member3)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(14)
.addPromoteRequestingMembers(DecryptedApproveMember.newBuilder()
.setRole(Member.Role.DEFAULT)
.setUuid(member1.getUuid()))
.addPromoteRequestingMembers(DecryptedApproveMember.newBuilder()
.setRole(Member.Role.ADMINISTRATOR)
.setUuid(member2.getUuid()))
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(14)
.addMembers(member(uuid1, profileKey1))
.addMembers(admin(uuid2, profileKey2))
.addRequestingMembers(member3)
.build(),
newGroup);
}
@Test(expected = NotAbleToApplyGroupV2ChangeException.class)
public void cannot_apply_promote_requesting_member_without_a_role() throws NotAbleToApplyGroupV2ChangeException {
UUID uuid = UUID.randomUUID();
DecryptedRequestingMember member = requestingMember(uuid);
DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(13)
.addRequestingMembers(member)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(14)
.addPromoteRequestingMembers(DecryptedApproveMember.newBuilder()
.setUuid(member.getUuid()))
.build());
}
@Test
public void invite_link_password() throws NotAbleToApplyGroupV2ChangeException {
ByteString password1 = ByteString.copyFrom(Util.getSecretBytes(16));
ByteString password2 = ByteString.copyFrom(Util.getSecretBytes(16));
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.setInviteLinkPassword(password1)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.setNewInviteLinkPassword(password2)
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.setInviteLinkPassword(password2)
.build(),
newGroup);
}
@Test
public void invite_link_password_not_changed() throws NotAbleToApplyGroupV2ChangeException {
ByteString password = ByteString.copyFrom(Util.getSecretBytes(16));
DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()
.setRevision(10)
.setInviteLinkPassword(password)
.build(),
DecryptedGroupChange.newBuilder()
.setRevision(11)
.build());
assertEquals(DecryptedGroup.newBuilder()
.setRevision(11)
.setInviteLinkPassword(password)
.build(),
newGroup);
}
}