Add GV2 copy for the unknown editor.

master
Alan Evans 2020-06-30 14:46:10 -03:00 committed by GitHub
parent a01bec3a11
commit eafccc5721
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 436 additions and 17 deletions

View File

@ -78,20 +78,39 @@ final class GroupsV2UpdateMessageProducer {
List<String> describeChange(@NonNull DecryptedGroupChange change) {
List<String> updates = new LinkedList<>();
describeMemberAdditions(change, updates);
describeMemberRemovals(change, updates);
describeModifyMemberRoles(change, updates);
describeInvitations(change, updates);
describeRevokedInvitations(change, updates);
describePromotePending(change, updates);
describeNewTitle(change, updates);
describeNewAvatar(change, updates);
describeNewTimer(change, updates);
describeNewAttributeAccess(change, updates);
describeNewMembershipAccess(change, updates);
if (change.getEditor().isEmpty() || UuidUtil.UNKNOWN_UUID.equals(UuidUtil.fromByteString(change.getEditor()))) {
describeUnknownEditorMemberAdditions(change, updates);
describeUnknownEditorMemberRemovals(change, updates);
describeUnknownEditorModifyMemberRoles(change, updates);
describeUnknownEditorInvitations(change, updates);
describeUnknownEditorRevokedInvitations(change, updates);
describeUnknownEditorPromotePending(change, updates);
describeUnknownEditorNewTitle(change, updates);
describeUnknownEditorNewAvatar(change, updates);
describeUnknownEditorNewTimer(change, updates);
describeUnknownEditorNewAttributeAccess(change, updates);
describeUnknownEditorNewMembershipAccess(change, updates);
if (updates.isEmpty()) {
describeUnknownChange(change, updates);
if (updates.isEmpty()) {
describeUnknownEditorUnknownChange(updates);
}
} else {
describeMemberAdditions(change, updates);
describeMemberRemovals(change, updates);
describeModifyMemberRoles(change, updates);
describeInvitations(change, updates);
describeRevokedInvitations(change, updates);
describePromotePending(change, updates);
describeNewTitle(change, updates);
describeNewAvatar(change, updates);
describeNewTimer(change, updates);
describeNewAttributeAccess(change, updates);
describeNewMembershipAccess(change, updates);
if (updates.isEmpty()) {
describeUnknownChange(change, updates);
}
}
return updates;
@ -110,6 +129,10 @@ final class GroupsV2UpdateMessageProducer {
}
}
private void describeUnknownEditorUnknownChange(@NonNull List<String> updates) {
updates.add(context.getString(R.string.MessageRecord_the_group_was_updated));
}
private void describeMemberAdditions(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
boolean editorIsYou = change.getEditor().equals(selfUuidBytes);
@ -136,6 +159,18 @@ final class GroupsV2UpdateMessageProducer {
}
}
private void describeUnknownEditorMemberAdditions(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
for (DecryptedMember member : change.getNewMembersList()) {
boolean newMemberIsYou = member.getUuid().equals(selfUuidBytes);
if (newMemberIsYou) {
updates.add(context.getString(R.string.MessageRecord_you_joined_the_group));
} else {
updates.add(context.getString(R.string.MessageRecord_s_joined_the_group, describe(member.getUuid())));
}
}
}
private void describeMemberRemovals(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
boolean editorIsYou = change.getEditor().equals(selfUuidBytes);
@ -162,16 +197,28 @@ final class GroupsV2UpdateMessageProducer {
}
}
private void describeUnknownEditorMemberRemovals(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
for (ByteString member : change.getDeleteMembersList()) {
boolean removedMemberIsYou = member.equals(selfUuidBytes);
if (removedMemberIsYou) {
updates.add(context.getString(R.string.MessageRecord_you_are_no_longer_in_the_group));
} else {
updates.add(context.getString(R.string.MessageRecord_s_is_no_longer_in_the_group, describe(member)));
}
}
}
private void describeModifyMemberRoles(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
boolean editorIsYou = change.getEditor().equals(selfUuidBytes);
for (DecryptedModifyMemberRole roleChange : change.getModifyMemberRolesList()) {
boolean changedMemberIsYou = roleChange.getUuid().equals(selfUuidBytes);
if (roleChange.getRole() == Member.Role.ADMINISTRATOR) {
boolean newMemberIsYou = roleChange.getUuid().equals(selfUuidBytes);
if (editorIsYou) {
updates.add(context.getString(R.string.MessageRecord_you_made_s_an_admin, describe(roleChange.getUuid())));
} else {
if (newMemberIsYou) {
if (changedMemberIsYou) {
updates.add(context.getString(R.string.MessageRecord_s_made_you_an_admin, describe(change.getEditor())));
} else {
updates.add(context.getString(R.string.MessageRecord_s_made_s_an_admin, describe(change.getEditor()), describe(roleChange.getUuid())));
@ -179,11 +226,10 @@ final class GroupsV2UpdateMessageProducer {
}
}
} else {
boolean newMemberIsYou = roleChange.getUuid().equals(selfUuidBytes);
if (editorIsYou) {
updates.add(context.getString(R.string.MessageRecord_you_revoked_admin_privileges_from_s, describe(roleChange.getUuid())));
} else {
if (newMemberIsYou) {
if (changedMemberIsYou) {
updates.add(context.getString(R.string.MessageRecord_s_revoked_your_admin_privileges, describe(change.getEditor())));
} else {
updates.add(context.getString(R.string.MessageRecord_s_revoked_admin_privileges_from_s, describe(change.getEditor()), describe(roleChange.getUuid())));
@ -193,6 +239,26 @@ final class GroupsV2UpdateMessageProducer {
}
}
private void describeUnknownEditorModifyMemberRoles(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
for (DecryptedModifyMemberRole roleChange : change.getModifyMemberRolesList()) {
boolean changedMemberIsYou = roleChange.getUuid().equals(selfUuidBytes);
if (roleChange.getRole() == Member.Role.ADMINISTRATOR) {
if (changedMemberIsYou) {
updates.add(context.getString(R.string.MessageRecord_you_are_now_an_admin));
} else {
updates.add(context.getString(R.string.MessageRecord_s_is_now_an_admin, describe(roleChange.getUuid())));
}
} else {
if (changedMemberIsYou) {
updates.add(context.getString(R.string.MessageRecord_you_are_no_longer_an_admin));
} else {
updates.add(context.getString(R.string.MessageRecord_s_is_no_longer_an_admin, describe(roleChange.getUuid())));
}
}
}
}
private void describeInvitations(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
boolean editorIsYou = change.getEditor().equals(selfUuidBytes);
int notYouInviteCount = 0;
@ -216,6 +282,24 @@ final class GroupsV2UpdateMessageProducer {
}
}
private void describeUnknownEditorInvitations(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
int notYouInviteCount = 0;
for (DecryptedPendingMember invitee : change.getNewPendingMembersList()) {
boolean newMemberIsYou = invitee.getUuid().equals(selfUuidBytes);
if (newMemberIsYou) {
updates.add(context.getString(R.string.MessageRecord_you_were_invited_to_the_group));
} else {
notYouInviteCount++;
}
}
if (notYouInviteCount > 0) {
updates.add(context.getResources().getQuantityString(R.plurals.MessageRecord_d_people_were_invited_to_the_group, notYouInviteCount, notYouInviteCount));
}
}
private void describeRevokedInvitations(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
boolean editorIsYou = change.getEditor().equals(selfUuidBytes);
int notDeclineCount = 0;
@ -242,6 +326,24 @@ final class GroupsV2UpdateMessageProducer {
}
}
private void describeUnknownEditorRevokedInvitations(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
int notDeclineCount = 0;
for (DecryptedPendingMemberRemoval invitee : change.getDeletePendingMembersList()) {
boolean inviteeWasYou = invitee.getUuid().equals(selfUuidBytes);
if (inviteeWasYou) {
updates.add(context.getString(R.string.MessageRecord_your_invitation_to_the_group_was_revoked));
} else {
notDeclineCount++;
}
}
if (notDeclineCount > 0) {
updates.add(context.getResources().getQuantityString(R.plurals.MessageRecord_d_invitations_were_revoked, notDeclineCount, notDeclineCount));
}
}
private void describePromotePending(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
boolean editorIsYou = change.getEditor().equals(selfUuidBytes);
@ -269,6 +371,19 @@ final class GroupsV2UpdateMessageProducer {
}
}
private void describeUnknownEditorPromotePending(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
for (DecryptedMember newMember : change.getPromotePendingMembersList()) {
ByteString uuid = newMember.getUuid();
boolean newMemberIsYou = uuid.equals(selfUuidBytes);
if (newMemberIsYou) {
updates.add(context.getString(R.string.MessageRecord_you_joined_the_group));
} else {
updates.add(context.getString(R.string.MessageRecord_s_joined_the_group, describe(uuid)));
}
}
}
private void describeNewTitle(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
boolean editorIsYou = change.getEditor().equals(selfUuidBytes);
@ -281,6 +396,12 @@ final class GroupsV2UpdateMessageProducer {
}
}
private void describeUnknownEditorNewTitle(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
if (change.hasNewTitle()) {
updates.add(context.getString(R.string.MessageRecord_the_group_name_has_changed_to_s, change.getNewTitle().getValue()));
}
}
private void describeNewAvatar(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
boolean editorIsYou = change.getEditor().equals(selfUuidBytes);
@ -293,6 +414,12 @@ final class GroupsV2UpdateMessageProducer {
}
}
private void describeUnknownEditorNewAvatar(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
if (change.hasNewAvatar()) {
updates.add(context.getString(R.string.MessageRecord_the_group_group_avatar_has_been_changed));
}
}
private void describeNewTimer(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
boolean editorIsYou = change.getEditor().equals(selfUuidBytes);
@ -306,6 +433,13 @@ final class GroupsV2UpdateMessageProducer {
}
}
private void describeUnknownEditorNewTimer(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
if (change.hasNewTimer()) {
String time = ExpirationUtil.getExpirationDisplayValue(context, change.getNewTimer().getDuration());
updates.add(context.getString(R.string.MessageRecord_disappearing_message_time_set_to_s, time));
}
}
private void describeNewAttributeAccess(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
boolean editorIsYou = change.getEditor().equals(selfUuidBytes);
@ -319,6 +453,13 @@ final class GroupsV2UpdateMessageProducer {
}
}
private void describeUnknownEditorNewAttributeAccess(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
if (change.getNewAttributeAccess() != AccessControl.AccessRequired.UNKNOWN) {
String accessLevel = GV2AccessLevelUtil.toString(context, change.getNewAttributeAccess());
updates.add(context.getString(R.string.MessageRecord_who_can_edit_group_info_has_been_changed_to_s, accessLevel));
}
}
private void describeNewMembershipAccess(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
boolean editorIsYou = change.getEditor().equals(selfUuidBytes);
@ -332,6 +473,13 @@ final class GroupsV2UpdateMessageProducer {
}
}
private void describeUnknownEditorNewMembershipAccess(@NonNull DecryptedGroupChange change, @NonNull List<String> updates) {
if (change.getNewMemberAccess() != AccessControl.AccessRequired.UNKNOWN) {
String accessLevel = GV2AccessLevelUtil.toString(context, change.getNewMemberAccess());
updates.add(context.getString(R.string.MessageRecord_who_can_edit_group_membership_has_been_changed_to_s, accessLevel));
}
}
private @NonNull String describe(@NonNull ByteString uuid) {
return descriptionStrategy.describe(UuidUtil.fromByteString(uuid));
}

View File

@ -740,6 +740,7 @@
<string name="MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported">Received a message encrypted using an old version of Signal that is no longer supported. Please ask the sender to update to the most recent version and resend the message.</string>
<string name="MessageRecord_left_group">You have left the group.</string>
<string name="MessageRecord_you_updated_group">You updated the group.</string>
<string name="MessageRecord_the_group_was_updated">The group was updated.</string>
<string name="MessageRecord_you_called">You called</string>
<string name="MessageRecord_called_you">Contact called</string>
<string name="MessageRecord_missed_call">Missed call</string>
@ -752,6 +753,7 @@
<string name="MessageRecord_s_disabled_disappearing_messages">%1$s disabled disappearing messages.</string>
<string name="MessageRecord_you_set_disappearing_message_time_to_s">You set the disappearing message timer to %1$s.</string>
<string name="MessageRecord_s_set_disappearing_message_time_to_s">%1$s set the disappearing message timer to %2$s.</string>
<string name="MessageRecord_disappearing_message_time_set_to_s">The disappearing message timer has been set to %1$s.</string>
<!-- GV2 specific -->
<string name="MessageRecord_you_created_the_group">You created the group.</string>
@ -770,6 +772,8 @@
<string name="MessageRecord_s_removed_you_from_the_group">%1$s removed you from the group.</string>
<string name="MessageRecord_you_left_the_group">You left the group.</string>
<string name="MessageRecord_s_left_the_group">%1$s left the group.</string>
<string name="MessageRecord_you_are_no_longer_in_the_group">You are no longer in the group.</string>
<string name="MessageRecord_s_is_no_longer_in_the_group">%1$s is no longer in the group.</string>
<!-- GV2 role change -->
<string name="MessageRecord_you_made_s_an_admin">You made %1$s an admin.</string>
@ -778,6 +782,10 @@
<string name="MessageRecord_you_revoked_admin_privileges_from_s">You revoked admin privileges from %1$s.</string>
<string name="MessageRecord_s_revoked_your_admin_privileges">%1$s revoked your admin privileges."</string>
<string name="MessageRecord_s_revoked_admin_privileges_from_s">%1$s revoked admin privileges from %2$s.</string>
<string name="MessageRecord_s_is_now_an_admin">%1$s is now an admin.</string>
<string name="MessageRecord_you_are_now_an_admin">You are now an admin.</string>
<string name="MessageRecord_s_is_no_longer_an_admin">%1$s is no longer an admin.</string>
<string name="MessageRecord_you_are_no_longer_an_admin">You are no longer an admin.</string>
<!-- GV2 invitations -->
<string name="MessageRecord_you_invited_s_to_the_group">You invited %1$s to the group.</string>
@ -786,6 +794,11 @@
<item quantity="one">%1$s invited 1 person to the group.</item>
<item quantity="other">%1$s invited %2$d people to the group.</item>
</plurals>
<string name="MessageRecord_you_were_invited_to_the_group">You were invited to the group.</string>
<plurals name="MessageRecord_d_people_were_invited_to_the_group">
<item quantity="one">1 person was invited to the group.</item>
<item quantity="other">%1$d people were invited to the group.</item>
</plurals>
<!-- GV2 invitation revokes -->
<plurals name="MessageRecord_you_revoked_invites">
@ -798,6 +811,11 @@
</plurals>
<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_your_invitation_to_the_group_was_revoked">Your invitation to the group was revoked.</string>
<plurals name="MessageRecord_d_invitations_were_revoked">
<item quantity="one">An invitation to the group was revoked.</item>
<item quantity="other">%1$d invitations to the group were revoked.</item>
</plurals>
<!-- GV2 invitation acceptance -->
<string name="MessageRecord_you_accepted_invite">You accepted the invitation to the group.</string>
@ -808,18 +826,22 @@
<!-- GV2 title change -->
<string name="MessageRecord_you_changed_the_group_name_to_s">You changed the group name to \"%1$s\".</string>
<string name="MessageRecord_s_changed_the_group_name_to_s">%1$s changed the group name to \"%2$s\".</string>
<string name="MessageRecord_the_group_name_has_changed_to_s">The group name has changed to \"%1$s\".</string>
<!-- GV2 avatar change -->
<string name="MessageRecord_you_changed_the_group_avatar">You changed the group avatar.</string>
<string name="MessageRecord_s_changed_the_group_avatar">%1$s changed the group avatar.</string>
<string name="MessageRecord_the_group_group_avatar_has_been_changed">The group avatar has been changed.</string>
<!-- GV2 attribute access level change -->
<string name="MessageRecord_you_changed_who_can_edit_group_info_to_s">You changed who can edit group info to \"%1$s\".</string>
<string name="MessageRecord_s_changed_who_can_edit_group_info_to_s">%1$s changed who can edit group info to \"%2$s\".</string>
<string name="MessageRecord_who_can_edit_group_info_has_been_changed_to_s">Who can edit group info has been changed to \"%1$s\".</string>
<!-- GV2 membership access level change -->
<string name="MessageRecord_you_changed_who_can_edit_group_membership_to_s">You changed who can edit group membership to \"%1$s\".</string>
<string name="MessageRecord_s_changed_who_can_edit_group_membership_to_s">%1$s changed who can edit group membership to \"%2$s\".</string>
<string name="MessageRecord_who_can_edit_group_membership_has_been_changed_to_s">Who can edit group membership has been changed to \"%1$s\".</string>
<!-- End of GV2 specific update messages -->

View File

@ -68,6 +68,14 @@ public final class GroupsV2UpdateMessageProducerTest {
assertThat(producer.describeChange(change), is(singletonList("You updated the group.")));
}
@Test
public void empty_change_by_unknown() {
DecryptedGroupChange change = changeByUnknown()
.build();
assertThat(producer.describeChange(change), is(singletonList("The group was updated.")));
}
// Member additions
@Test
@ -115,6 +123,24 @@ public final class GroupsV2UpdateMessageProducerTest {
assertThat(producer.describeChange(change), is(singletonList("Bob joined the group.")));
}
@Test
public void unknown_added_you() {
DecryptedGroupChange change = changeByUnknown()
.addMember(you)
.build();
assertThat(producer.describeChange(change), is(singletonList("You joined the group.")));
}
@Test
public void unknown_added_member() {
DecryptedGroupChange change = changeByUnknown()
.addMember(bob)
.build();
assertThat(producer.describeChange(change), is(singletonList("Bob joined the group.")));
}
// Member removals
@Test
@ -162,6 +188,24 @@ public final class GroupsV2UpdateMessageProducerTest {
assertThat(producer.describeChange(change), is(singletonList("Bob left the group.")));
}
@Test
public void unknown_removed_member() {
DecryptedGroupChange change = changeByUnknown()
.deleteMember(alice)
.build();
assertThat(producer.describeChange(change), is(singletonList("Alice is no longer in the group.")));
}
@Test
public void unknown_removed_you() {
DecryptedGroupChange change = changeByUnknown()
.deleteMember(you)
.build();
assertThat(producer.describeChange(change), is(singletonList("You are no longer in the group.")));
}
// Member role modifications
@Test
@ -218,6 +262,42 @@ public final class GroupsV2UpdateMessageProducerTest {
assertThat(producer.describeChange(change), is(singletonList("Alice revoked your admin privileges.")));
}
@Test
public void unknown_makes_member_admin() {
DecryptedGroupChange change = changeByUnknown()
.promoteToAdmin(alice)
.build();
assertThat(producer.describeChange(change), is(singletonList("Alice is now an admin.")));
}
@Test
public void unknown_makes_you_admin() {
DecryptedGroupChange change = changeByUnknown()
.promoteToAdmin(you)
.build();
assertThat(producer.describeChange(change), is(singletonList("You are now an admin.")));
}
@Test
public void unknown_revokes_member_admin() {
DecryptedGroupChange change = changeByUnknown()
.demoteToMember(alice)
.build();
assertThat(producer.describeChange(change), is(singletonList("Alice is no longer an admin.")));
}
@Test
public void unknown_revokes_your_admin() {
DecryptedGroupChange change = changeByUnknown()
.demoteToMember(you)
.build();
assertThat(producer.describeChange(change), is(singletonList("You are no longer an admin.")));
}
// Member invitation
@Test
@ -269,6 +349,46 @@ public final class GroupsV2UpdateMessageProducerTest {
assertThat(producer.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(producer.describeChange(change), is(singletonList("You were invited to the group.")));
}
@Test
public void unknown_invited_1_person() {
DecryptedGroupChange change = changeByUnknown()
.invite(alice)
.build();
assertThat(producer.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(producer.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(producer.describeChange(change), is(Arrays.asList("You were invited to the group.", "3 people were invited to the group.")));
}
// Member invitation revocation
@Test
@ -327,6 +447,46 @@ public final class GroupsV2UpdateMessageProducerTest {
assertThat(producer.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(producer.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(producer.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(producer.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(producer.describeChange(change), is(Arrays.asList("Your invitation to the group was revoked.", "3 invitations to the group were revoked.")));
}
// Promote pending members
@Test
@ -374,6 +534,24 @@ public final class GroupsV2UpdateMessageProducerTest {
assertThat(producer.describeChange(change), is(singletonList("Bob added you to the group.")));
}
@Test
public void unknown_added_by_invite() {
DecryptedGroupChange change = changeByUnknown()
.promote(you)
.build();
assertThat(producer.describeChange(change), is(singletonList("You joined the group.")));
}
@Test
public void unknown_promotes_pending_member() {
DecryptedGroupChange change = changeByUnknown()
.promote(alice)
.build();
assertThat(producer.describeChange(change), is(singletonList("Alice joined the group.")));
}
// Title change
@Test
@ -393,6 +571,15 @@ public final class GroupsV2UpdateMessageProducerTest {
assertThat(producer.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(producer.describeChange(change), is(singletonList("The group name has changed to \"Title 3\".")));
}
// Avatar change
@ -414,6 +601,15 @@ public final class GroupsV2UpdateMessageProducerTest {
assertThat(producer.describeChange(change), is(singletonList("You changed the group avatar.")));
}
@Test
public void unknown_changed_avatar() {
DecryptedGroupChange change = changeByUnknown()
.avatar("Avatar3")
.build();
assertThat(producer.describeChange(change), is(singletonList("The group avatar has been changed.")));
}
// Timer change
@Test
@ -434,6 +630,15 @@ public final class GroupsV2UpdateMessageProducerTest {
assertThat(producer.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(producer.describeChange(change), is(singletonList("The disappearing message timer has been set to 2 minutes.")));
}
// Attribute access change
@Test
@ -454,6 +659,15 @@ public final class GroupsV2UpdateMessageProducerTest {
assertThat(producer.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(producer.describeChange(change), is(singletonList("Who can edit group info has been changed to \"Only admins\".")));
}
// Membership access change
@Test
@ -474,6 +688,15 @@ public final class GroupsV2UpdateMessageProducerTest {
assertThat(producer.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(producer.describeChange(change), is(singletonList("Who can edit group membership has been changed to \"Only admins\".")));
}
// Multiple changes
@Test
@ -492,6 +715,24 @@ public final class GroupsV2UpdateMessageProducerTest {
"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(producer.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
@ -579,6 +820,10 @@ public final class GroupsV2UpdateMessageProducerTest {
.setEditor(UuidUtil.toByteString(editor));
}
ChangeBuilder() {
builder = DecryptedGroupChange.newBuilder();
}
ChangeBuilder addMember(@NonNull UUID newMember) {
builder.addNewMembers(DecryptedMember.newBuilder()
.setUuid(UuidUtil.toByteString(newMember)));
@ -658,6 +903,10 @@ public final class GroupsV2UpdateMessageProducerTest {
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);