Convert more tests to kotlin.

Resolves #13829
This commit is contained in:
Jameson Williams
2024-12-06 23:45:13 -06:00
committed by Greyson Parrelli
parent 574d6c51ab
commit c2aceb2bd1
12 changed files with 965 additions and 1038 deletions

View File

@@ -1,184 +0,0 @@
package org.thoughtcrime.securesms.components.webrtc;
import androidx.annotation.NonNull;
import com.annimon.stream.Stream;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.thoughtcrime.securesms.events.CallParticipant;
import org.thoughtcrime.securesms.events.CallParticipantId;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientCreator;
import org.thoughtcrime.securesms.recipients.RecipientId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
public class CallParticipantListUpdateTest {
@Test
public void givenEmptySets_thenExpectNoChanges() {
// GIVEN
Set<CallParticipantListUpdate.Wrapper> added = Collections.emptySet();
Set<CallParticipantListUpdate.Wrapper> removed = Collections.emptySet();
CallParticipantListUpdate update = new CallParticipantListUpdate(added, removed);
// THEN
assertTrue(update.hasNoChanges());
assertFalse(update.hasSingleChange());
}
@Test
public void givenOneEmptySet_thenExpectMultipleChanges() {
// GIVEN
Set<CallParticipantListUpdate.Wrapper> added = new HashSet<>(Arrays.asList(createWrappers(1, 2, 3)));
Set<CallParticipantListUpdate.Wrapper> removed = Collections.emptySet();
CallParticipantListUpdate update = new CallParticipantListUpdate(added, removed);
// THEN
assertFalse(update.hasNoChanges());
assertFalse(update.hasSingleChange());
}
@Test
public void givenNoEmptySets_thenExpectMultipleChanges() {
// GIVEN
Set<CallParticipantListUpdate.Wrapper> added = new HashSet<>(Arrays.asList(createWrappers(1, 2, 3)));
Set<CallParticipantListUpdate.Wrapper> removed = new HashSet<>(Arrays.asList(createWrappers(4, 5, 6)));
CallParticipantListUpdate update = new CallParticipantListUpdate(added, removed);
// THEN
assertFalse(update.hasNoChanges());
assertFalse(update.hasSingleChange());
}
@Test
public void givenOneSetWithSingleItemAndAnEmptySet_thenExpectSingleChange() {
// GIVEN
Set<CallParticipantListUpdate.Wrapper> added = new HashSet<>(Arrays.asList(createWrappers(1)));
Set<CallParticipantListUpdate.Wrapper> removed = Collections.emptySet();
CallParticipantListUpdate update = new CallParticipantListUpdate(added, removed);
// THEN
assertFalse(update.hasNoChanges());
assertTrue(update.hasSingleChange());
}
@Test
public void whenFirstListIsAdded_thenIExpectAnUpdateWithAllItemsFromListAdded() {
// GIVEN
List<CallParticipant> newList = createParticipants(1, 2, 3, 4, 5);
// WHEN
CallParticipantListUpdate update = CallParticipantListUpdate.computeDeltaUpdate(Collections.emptyList(), newList);
// THEN
assertFalse(update.hasNoChanges());
assertTrue(update.getRemoved().isEmpty());
assertThat(update.getAdded(), Matchers.containsInAnyOrder(createWrappers(1, 2, 3, 4, 5)));
}
@Test
public void whenSameListIsAddedTwiceInARowWithinTimeout_thenIExpectAnEmptyUpdate() {
// GIVEN
List<CallParticipant> newList = createParticipants(1, 2, 3, 4, 5);
// WHEN
CallParticipantListUpdate update = CallParticipantListUpdate.computeDeltaUpdate(newList, newList);
// THEN
assertTrue(update.hasNoChanges());
}
@Test
public void whenPlaceholdersAreUsed_thenIExpectAnEmptyUpdate() {
// GIVEN
List<CallParticipant> newList = createPlaceholderParticipants(1, 2, 3, 4, 5);
// WHEN
CallParticipantListUpdate update = CallParticipantListUpdate.computeDeltaUpdate(Collections.emptyList(), newList);
// THEN
assertTrue(update.hasNoChanges());
}
@Test
public void whenNewListIsAdded_thenIExpectAReducedUpdate() {
// GIVEN
List<CallParticipant> list1 = createParticipants(1, 2, 3, 4, 5);
List<CallParticipant> list2 = createParticipants(2, 3, 4, 5, 6);
// WHEN
CallParticipantListUpdate update = CallParticipantListUpdate.computeDeltaUpdate(list1, list2);
// THEN
assertFalse(update.hasNoChanges());
assertThat(update.getAdded(), Matchers.containsInAnyOrder(createWrappers(6)));
assertThat(update.getRemoved(), Matchers.containsInAnyOrder(createWrappers(1)));
}
@Test
public void whenRecipientExistsMultipleTimes_thenIExpectOneInstancePrimaryAndOthersSecondary() {
// GIVEN
List<CallParticipant> list = createParticipants(new long[]{1, 1, 1}, new long[]{1, 2, 3});
// WHEN
CallParticipantListUpdate update = CallParticipantListUpdate.computeDeltaUpdate(Collections.emptyList(), list);
// THEN
List<Boolean> isPrimaryList = Stream.of(update.getAdded()).map(wrapper -> wrapper.getCallParticipant().isPrimary()).toList();
assertThat(isPrimaryList, Matchers.containsInAnyOrder(true, false, false));
}
static CallParticipantListUpdate.Wrapper[] createWrappers(long ... recipientIds) {
CallParticipantListUpdate.Wrapper[] ids = new CallParticipantListUpdate.Wrapper[recipientIds.length];
Set<Long> primaries = new HashSet<>();
for (int i = 0; i < recipientIds.length; i++) {
CallParticipant participant = createParticipant(recipientIds[i], recipientIds[i], primaries.contains(recipientIds[i]) ? CallParticipant.DeviceOrdinal.SECONDARY : CallParticipant.DeviceOrdinal.PRIMARY);
ids[i] = CallParticipantListUpdate.createWrapper(participant);
}
return ids;
}
private static List<CallParticipant> createPlaceholderParticipants(long ... recipientIds) {
long[] deMuxIds = new long[recipientIds.length];
Arrays.fill(deMuxIds, -1);
return createParticipants(recipientIds, deMuxIds);
}
private static List<CallParticipant> createParticipants(long ... recipientIds) {
return createParticipants(recipientIds, recipientIds);
}
private static List<CallParticipant> createParticipants(long[] recipientIds, long[] placeholderIds) {
List<CallParticipant> participants = new ArrayList<>(recipientIds.length);
Set<Long> primaries = new HashSet<>();
for (int i = 0; i < recipientIds.length; i++) {
participants.add(createParticipant(recipientIds[i], placeholderIds[i], primaries.contains(recipientIds[i]) ? CallParticipant.DeviceOrdinal.SECONDARY : CallParticipant.DeviceOrdinal.PRIMARY));
primaries.add(recipientIds[i]);
}
return participants;
}
private static CallParticipant createParticipant(long recipientId, long deMuxId, @NonNull CallParticipant.DeviceOrdinal deviceOrdinal) {
Recipient recipient = RecipientCreator.forId(RecipientId.from(recipientId), true);
return CallParticipant.createRemote(new CallParticipantId(deMuxId, recipient.getId()), recipient, null, new BroadcastVideoSink(), false, false, false, CallParticipant.HAND_LOWERED, -1, false, 0, false, deviceOrdinal);
}
}

View File

@@ -0,0 +1,186 @@
package org.thoughtcrime.securesms.components.webrtc
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.containsInAnyOrder
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import org.thoughtcrime.securesms.events.CallParticipant
import org.thoughtcrime.securesms.events.CallParticipant.Companion.createRemote
import org.thoughtcrime.securesms.events.CallParticipant.DeviceOrdinal
import org.thoughtcrime.securesms.events.CallParticipantId
import org.thoughtcrime.securesms.recipients.RecipientCreator.forId
import org.thoughtcrime.securesms.recipients.RecipientId
class CallParticipantListUpdateTest {
@Test
fun givenEmptySets_thenExpectNoChanges() {
// GIVEN
val added = emptySet<CallParticipantListUpdate.Wrapper>()
val removed = emptySet<CallParticipantListUpdate.Wrapper>()
val update = CallParticipantListUpdate(added, removed)
// THEN
assertTrue(update.hasNoChanges())
assertFalse(update.hasSingleChange())
}
@Test
fun givenOneEmptySet_thenExpectMultipleChanges() {
// GIVEN
val added = createWrappers(1, 2, 3).toSet()
val removed = emptySet<CallParticipantListUpdate.Wrapper>()
val update = CallParticipantListUpdate(added, removed)
// THEN
assertFalse(update.hasNoChanges())
assertFalse(update.hasSingleChange())
}
@Test
fun givenNoEmptySets_thenExpectMultipleChanges() {
// GIVEN
val added = createWrappers(1, 2, 3).toSet()
val removed = createWrappers(4, 5, 6).toSet()
val update = CallParticipantListUpdate(added, removed)
// THEN
assertFalse(update.hasNoChanges())
assertFalse(update.hasSingleChange())
}
@Test
fun givenOneSetWithSingleItemAndAnEmptySet_thenExpectSingleChange() {
// GIVEN
val added = createWrappers(1).toSet()
val removed = emptySet<CallParticipantListUpdate.Wrapper>()
val update = CallParticipantListUpdate(added, removed)
// THEN
assertFalse(update.hasNoChanges())
assertTrue(update.hasSingleChange())
}
@Test
fun whenFirstListIsAdded_thenIExpectAnUpdateWithAllItemsFromListAdded() {
// GIVEN
val newList = createParticipants(1, 2, 3, 4, 5)
// WHEN
val update = CallParticipantListUpdate.computeDeltaUpdate(emptyList(), newList)
// THEN
assertFalse(update.hasNoChanges())
assertTrue(update.removed.isEmpty())
assertThat(update.added, containsInAnyOrder(*createWrappers(1, 2, 3, 4, 5)))
}
@Test
fun whenSameListIsAddedTwiceInARowWithinTimeout_thenIExpectAnEmptyUpdate() {
// GIVEN
val newList = createParticipants(1, 2, 3, 4, 5)
// WHEN
val update = CallParticipantListUpdate.computeDeltaUpdate(newList, newList)
// THEN
assertTrue(update.hasNoChanges())
}
@Test
fun whenPlaceholdersAreUsed_thenIExpectAnEmptyUpdate() {
// GIVEN
val newList = createPlaceholderParticipants(1, 2, 3, 4, 5)
// WHEN
val update = CallParticipantListUpdate.computeDeltaUpdate(emptyList(), newList)
// THEN
assertTrue(update.hasNoChanges())
}
@Test
fun whenNewListIsAdded_thenIExpectAReducedUpdate() {
// GIVEN
val list1 = createParticipants(1, 2, 3, 4, 5)
val list2 = createParticipants(2, 3, 4, 5, 6)
// WHEN
val update = CallParticipantListUpdate.computeDeltaUpdate(list1, list2)
// THEN
assertFalse(update.hasNoChanges())
assertThat(update.added, containsInAnyOrder(*createWrappers(6)))
assertThat(update.removed, containsInAnyOrder(*createWrappers(1)))
}
@Test
fun whenRecipientExistsMultipleTimes_thenIExpectOneInstancePrimaryAndOthersSecondary() {
// GIVEN
val list = createParticipants(longArrayOf(1, 1, 1), longArrayOf(1, 2, 3))
// WHEN
val update = CallParticipantListUpdate.computeDeltaUpdate(emptyList(), list)
// THEN
val isPrimaryList = update.added.map { it.callParticipant.isPrimary }.toList()
assertThat(isPrimaryList, containsInAnyOrder(true, false, false))
}
companion object {
internal fun createWrappers(vararg recipientIds: Long): Array<CallParticipantListUpdate.Wrapper?> {
val ids = arrayOfNulls<CallParticipantListUpdate.Wrapper>(recipientIds.size)
for (i in recipientIds.indices) {
val participant = createParticipant(recipientIds[i], recipientIds[i], DeviceOrdinal.PRIMARY)
ids[i] = CallParticipantListUpdate.createWrapper(participant)
}
return ids
}
private fun createPlaceholderParticipants(
@Suppress("SameParameterValue") vararg recipientIds: Long
): List<CallParticipant> {
val deMuxIds = LongArray(recipientIds.size) { -1 }
return createParticipants(recipientIds, deMuxIds)
}
private fun createParticipants(vararg recipientIds: Long): List<CallParticipant> {
return createParticipants(recipientIds, recipientIds)
}
private fun createParticipants(recipientIds: LongArray, placeholderIds: LongArray): List<CallParticipant> {
val participants = mutableListOf<CallParticipant>()
val primaries = mutableSetOf<Long>()
for (i in recipientIds.indices) {
participants.add(createParticipant(recipientIds[i], placeholderIds[i], if (primaries.contains(recipientIds[i])) DeviceOrdinal.SECONDARY else DeviceOrdinal.PRIMARY))
primaries.add(recipientIds[i])
}
return participants
}
private fun createParticipant(recipientId: Long, deMuxId: Long, deviceOrdinal: DeviceOrdinal): CallParticipant {
val recipient = forId(RecipientId.from(recipientId), true)
return createRemote(
callParticipantId = CallParticipantId(deMuxId, recipient.id),
recipient = recipient,
identityKey = null,
renderer = BroadcastVideoSink(),
isForwardingVideo = false,
audioEnabled = false,
videoEnabled = false,
handRaisedTimestamp = CallParticipant.HAND_LOWERED,
lastSpoke = -1,
mediaKeysReceived = false,
addedToCallTime = 0,
isScreenSharing = false,
deviceOrdinal = deviceOrdinal
)
}
}
}