Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be84c6c9 authored by Dave Mankoff's avatar Dave Mankoff Committed by Gerrit Code Review
Browse files

Merge "Change coroutine testing for kotlinx.coroutines 1.9" into main

parents b6a0612f 38305b7d
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -32,7 +32,8 @@ import java.util.Optional
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.runBlockingTest
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -125,14 +126,11 @@ class HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest : SysuiTes
            )

        underTest =
            HomeControlsKeyguardQuickAffordanceConfig(
                context = context,
                component = component,
            )
            HomeControlsKeyguardQuickAffordanceConfig(context = context, component = component)
    }

    @Test
    fun state() = runBlockingTest {
    fun state() = runTest(UnconfinedTestDispatcher()) {
        whenever(component.isEnabled()).thenReturn(isFeatureEnabled)
        whenever(controlsController.getFavorites())
            .thenReturn(
+21 −21
Original line number Diff line number Diff line
@@ -19,19 +19,20 @@ package com.android.systemui.keyguard.data.quickaffordance

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Expandable
import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.controls.dagger.ControlsComponent
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnTriggeredResult
import com.android.systemui.res.R
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import java.util.Optional
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.runBlockingTest
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -54,14 +55,11 @@ class HomeControlsKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
        whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(true))

        underTest =
            HomeControlsKeyguardQuickAffordanceConfig(
                context = context,
                component = component,
            )
            HomeControlsKeyguardQuickAffordanceConfig(context = context, component = component)
    }

    @Test
    fun state_whenCannotShowWhileLocked_returnsHidden() = runBlockingTest {
    fun state_whenCannotShowWhileLocked_returnsHidden() = runTest(UnconfinedTestDispatcher()) {
        whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(false))
        whenever(component.isEnabled()).thenReturn(true)
        whenever(component.getTileImageId()).thenReturn(R.drawable.controls_icon)
@@ -81,7 +79,7 @@ class HomeControlsKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
    }

    @Test
    fun state_whenListingControllerIsMissing_returnsHidden() = runBlockingTest {
    fun state_whenListingControllerIsMissing_returnsHidden() = runTest(UnconfinedTestDispatcher()) {
        whenever(component.isEnabled()).thenReturn(true)
        whenever(component.getTileImageId()).thenReturn(R.drawable.controls_icon)
        whenever(component.getTileTitleId()).thenReturn(R.string.quick_controls_title)
@@ -100,7 +98,8 @@ class HomeControlsKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
    }

    @Test
    fun onQuickAffordanceTriggered_canShowWhileLockedSettingIsTrue() = runBlockingTest {
    fun onQuickAffordanceTriggered_canShowWhileLockedSettingIsTrue() =
        runTest(UnconfinedTestDispatcher()) {
            whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(true))

            val onClickedResult = underTest.onTriggered(expandable)
@@ -110,7 +109,8 @@ class HomeControlsKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
        }

    @Test
    fun onQuickAffordanceTriggered_canShowWhileLockedSettingIsFalse() = runBlockingTest {
    fun onQuickAffordanceTriggered_canShowWhileLockedSettingIsFalse() =
        runTest(UnconfinedTestDispatcher()) {
            whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(false))

            val onClickedResult = underTest.onTriggered(expandable)
+61 −59
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.runBlockingTest
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -56,7 +56,8 @@ class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
    }

    @Test
    fun affordance_setsUpRegistrationAndDeliversInitialModel() = runBlockingTest {
    fun affordance_setsUpRegistrationAndDeliversInitialModel() =
        runTest(UnconfinedTestDispatcher()) {
            whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
            var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null

@@ -67,7 +68,7 @@ class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
            verify(controller)
                .registerQRCodeScannerChangeObservers(
                    QRCodeScannerController.DEFAULT_QR_CODE_SCANNER_CHANGE,
                QRCodeScannerController.QR_CODE_SCANNER_PREFERENCE_CHANGE
                    QRCodeScannerController.QR_CODE_SCANNER_PREFERENCE_CHANGE,
                )
            assertVisibleState(latest)

@@ -76,7 +77,8 @@ class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
        }

    @Test
    fun affordance_scannerActivityChanged_deliversModelWithUpdatedIntent() = runBlockingTest {
        fun affordance_scannerActivityChanged_deliversModelWithUpdatedIntent() =
            runTest(UnconfinedTestDispatcher()) {
            whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
            var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
            val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
@@ -93,7 +95,8 @@ class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
        }

    @Test
    fun affordance_scannerPreferenceChanged_deliversVisibleModel() = runBlockingTest {
    fun affordance_scannerPreferenceChanged_deliversVisibleModel() =
        runTest(UnconfinedTestDispatcher()) {
            var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
            val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
            val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
@@ -109,7 +112,7 @@ class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
        }

    @Test
    fun affordance_scannerPreferenceChanged_deliversNone() = runBlockingTest {
    fun affordance_scannerPreferenceChanged_deliversNone() = runTest(UnconfinedTestDispatcher()) {
        var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
        val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
        val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
@@ -128,15 +131,13 @@ class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
    fun onQuickAffordanceTriggered() {
        assertThat(underTest.onTriggered(mock()))
            .isEqualTo(
                OnTriggeredResult.StartActivity(
                    intent = INTENT_1,
                    canShowWhileLocked = true,
                )
                OnTriggeredResult.StartActivity(intent = INTENT_1, canShowWhileLocked = true)
            )
    }

    @Test
    fun getPickerScreenState_enabledIfConfiguredOnDevice_isEnabledForPickerState() = runTest {
    fun getPickerScreenState_enabledIfConfiguredOnDevice_isEnabledForPickerState() =
        runTest(UnconfinedTestDispatcher()) {
            whenever(controller.isAllowedOnLockScreen).thenReturn(true)
            whenever(controller.isAbleToLaunchScannerActivity).thenReturn(true)

@@ -145,7 +146,8 @@ class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
        }

    @Test
    fun getPickerScreenState_disabledIfConfiguredOnDevice_isDisabledForPickerState() = runTest {
    fun getPickerScreenState_disabledIfConfiguredOnDevice_isDisabledForPickerState() =
        runTest(UnconfinedTestDispatcher()) {
            whenever(controller.isAllowedOnLockScreen).thenReturn(true)
            whenever(controller.isAbleToLaunchScannerActivity).thenReturn(false)

+114 −83
Original line number Diff line number Diff line
@@ -24,9 +24,9 @@ import android.os.Handler
import android.os.Looper
import android.os.PatternMatcher
import android.os.UserHandle
import androidx.test.filters.SmallTest
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
import com.android.systemui.dump.DumpManager
@@ -40,8 +40,9 @@ import java.util.concurrent.Executor
import junit.framework.Assert.assertSame
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runBlockingTest
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -68,39 +69,28 @@ class BroadcastDispatcherTest : SysuiTestCase() {
        val DEFAULT_PERMISSION: String? = null

        fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()

        const val TEST_ACTION = "TEST_ACTION"
        const val TEST_SCHEME = "TEST_SCHEME"
        const val TEST_PATH = "TEST_PATH"
        const val TEST_TYPE = "test/type"
    }

    @Mock
    private lateinit var mockContext: Context
    @Mock
    private lateinit var mockUBRUser0: UserBroadcastDispatcher
    @Mock
    private lateinit var mockUBRUser1: UserBroadcastDispatcher
    @Mock
    private lateinit var broadcastReceiver: BroadcastReceiver
    @Mock
    private lateinit var broadcastReceiverOther: BroadcastReceiver
    @Mock
    private lateinit var intentFilter: IntentFilter
    @Mock
    private lateinit var intentFilterOther: IntentFilter
    @Mock
    private lateinit var mockHandler: Handler
    @Mock
    private lateinit var logger: BroadcastDispatcherLogger
    @Mock
    private lateinit var userTracker: UserTracker
    @Mock
    private lateinit var removalPendingStore: PendingRemovalStore
    @Mock private lateinit var mockContext: Context
    @Mock private lateinit var mockUBRUser0: UserBroadcastDispatcher
    @Mock private lateinit var mockUBRUser1: UserBroadcastDispatcher
    @Mock private lateinit var broadcastReceiver: BroadcastReceiver
    @Mock private lateinit var broadcastReceiverOther: BroadcastReceiver
    @Mock private lateinit var intentFilter: IntentFilter
    @Mock private lateinit var intentFilterOther: IntentFilter
    @Mock private lateinit var mockHandler: Handler
    @Mock private lateinit var logger: BroadcastDispatcherLogger
    @Mock private lateinit var userTracker: UserTracker
    @Mock private lateinit var removalPendingStore: PendingRemovalStore

    private lateinit var mainExecutor: Executor

    @Captor
    private lateinit var argumentCaptor: ArgumentCaptor<ReceiverData>
    @Captor private lateinit var argumentCaptor: ArgumentCaptor<ReceiverData>

    private lateinit var testableLooper: TestableLooper
    private lateinit var broadcastDispatcher: BroadcastDispatcher
@@ -112,7 +102,8 @@ class BroadcastDispatcherTest : SysuiTestCase() {
        mainExecutor = FakeExecutor(FakeSystemClock())
        `when`(mockContext.mainExecutor).thenReturn(mainExecutor)

        broadcastDispatcher = TestBroadcastDispatcher(
        broadcastDispatcher =
            TestBroadcastDispatcher(
                mockContext,
                mainExecutor,
                testableLooper.looper,
@@ -121,7 +112,8 @@ class BroadcastDispatcherTest : SysuiTestCase() {
                logger,
                userTracker,
                removalPendingStore,
                mapOf(0 to mockUBRUser0, 1 to mockUBRUser1))
                mapOf(0 to mockUBRUser0, 1 to mockUBRUser1),
            )

        // These should be valid filters
        `when`(intentFilter.countActions()).thenReturn(1)
@@ -131,10 +123,18 @@ class BroadcastDispatcherTest : SysuiTestCase() {

    @Test
    fun testAddingReceiverToCorrectUBR() {
        broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
                mockHandler, user0)
        broadcastDispatcher.registerReceiverWithHandler(
                broadcastReceiverOther, intentFilterOther, mockHandler, user1)
            broadcastReceiver,
            intentFilter,
            mockHandler,
            user0,
        )
        broadcastDispatcher.registerReceiverWithHandler(
            broadcastReceiverOther,
            intentFilterOther,
            mockHandler,
            user1,
        )

        testableLooper.processAllMessages()

@@ -152,7 +152,11 @@ class BroadcastDispatcherTest : SysuiTestCase() {
    fun testAddingReceiverToCorrectUBR_executor() {
        broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, mainExecutor, user0)
        broadcastDispatcher.registerReceiver(
                broadcastReceiverOther, intentFilterOther, mainExecutor, user1)
            broadcastReceiverOther,
            intentFilterOther,
            mainExecutor,
            user1,
        )

        testableLooper.processAllMessages()

@@ -169,7 +173,10 @@ class BroadcastDispatcherTest : SysuiTestCase() {
    @Test
    fun testAddReceiverDefaultFlag_handler() {
        broadcastDispatcher.registerReceiverWithHandler(
                broadcastReceiver, intentFilter, mockHandler)
            broadcastReceiver,
            intentFilter,
            mockHandler,
        )
        testableLooper.processAllMessages()

        verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG))
@@ -183,7 +190,11 @@ class BroadcastDispatcherTest : SysuiTestCase() {
        val flag = 3

        broadcastDispatcher.registerReceiverWithHandler(
                broadcastReceiver, intentFilter, mockHandler, flags = flag)
            broadcastReceiver,
            intentFilter,
            mockHandler,
            flags = flag,
        )
        testableLooper.processAllMessages()

        verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(flag))
@@ -212,7 +223,7 @@ class BroadcastDispatcherTest : SysuiTestCase() {
            broadcastReceiver,
            intentFilter,
            flags = flag,
            permission = permission
            permission = permission,
        )
        testableLooper.processAllMessages()

@@ -250,10 +261,18 @@ class BroadcastDispatcherTest : SysuiTestCase() {

    @Test
    fun testRemovingReceiversRemovesFromAllUBR() {
        broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
                mockHandler, user0)
        broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
                mockHandler, user1)
        broadcastDispatcher.registerReceiverWithHandler(
            broadcastReceiver,
            intentFilter,
            mockHandler,
            user0,
        )
        broadcastDispatcher.registerReceiverWithHandler(
            broadcastReceiver,
            intentFilter,
            mockHandler,
            user1,
        )

        broadcastDispatcher.unregisterReceiver(broadcastReceiver)

@@ -265,10 +284,18 @@ class BroadcastDispatcherTest : SysuiTestCase() {

    @Test
    fun testRemoveReceiverFromUser() {
        broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
                mockHandler, user0)
        broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
                mockHandler, user1)
        broadcastDispatcher.registerReceiverWithHandler(
            broadcastReceiver,
            intentFilter,
            mockHandler,
            user0,
        )
        broadcastDispatcher.registerReceiverWithHandler(
            broadcastReceiver,
            intentFilter,
            mockHandler,
            user1,
        )

        broadcastDispatcher.unregisterReceiverForUser(broadcastReceiver, user0)

@@ -282,13 +309,17 @@ class BroadcastDispatcherTest : SysuiTestCase() {
    fun testRegisterCurrentAsActualUser() {
        `when`(userTracker.userId).thenReturn(user1.identifier)

        broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
                mockHandler, UserHandle.CURRENT)
        broadcastDispatcher.registerReceiverWithHandler(
            broadcastReceiver,
            intentFilter,
            mockHandler,
            UserHandle.CURRENT,
        )

        testableLooper.processAllMessages()

        verify(mockUBRUser1).registerReceiver(
                capture(argumentCaptor), eq(Context.RECEIVER_EXPORTED))
        verify(mockUBRUser1)
            .registerReceiver(capture(argumentCaptor), eq(Context.RECEIVER_EXPORTED))
        assertSame(broadcastReceiver, argumentCaptor.value.receiver)
    }

@@ -300,15 +331,14 @@ class BroadcastDispatcherTest : SysuiTestCase() {

    @Test(expected = IllegalArgumentException::class)
    fun testFilterMustNotContainDataScheme() {
        val testFilter = IntentFilter(TEST_ACTION).apply {
            addDataScheme(TEST_SCHEME)
        }
        val testFilter = IntentFilter(TEST_ACTION).apply { addDataScheme(TEST_SCHEME) }
        broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
    }

    @Test(expected = IllegalArgumentException::class)
    fun testFilterMustNotContainDataAuthority() {
        val testFilter = IntentFilter(TEST_ACTION).apply {
        val testFilter =
            IntentFilter(TEST_ACTION).apply {
                addDataAuthority(mock(IntentFilter.AuthorityEntry::class.java))
            }
        broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
@@ -316,7 +346,8 @@ class BroadcastDispatcherTest : SysuiTestCase() {

    @Test(expected = IllegalArgumentException::class)
    fun testFilterMustNotContainDataPath() {
        val testFilter = IntentFilter(TEST_ACTION).apply {
        val testFilter =
            IntentFilter(TEST_ACTION).apply {
                addDataPath(TEST_PATH, PatternMatcher.PATTERN_LITERAL)
            }
        broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
@@ -324,17 +355,14 @@ class BroadcastDispatcherTest : SysuiTestCase() {

    @Test(expected = IllegalArgumentException::class)
    fun testFilterMustNotContainDataType() {
        val testFilter = IntentFilter(TEST_ACTION).apply {
            addDataType(TEST_TYPE)
        }
        val testFilter = IntentFilter(TEST_ACTION).apply { addDataType(TEST_TYPE) }
        broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
    }

    @Test(expected = IllegalArgumentException::class)
    fun testFilterMustNotSetPriority() {
        val testFilter = IntentFilter(TEST_ACTION).apply {
            priority = IntentFilter.SYSTEM_HIGH_PRIORITY
        }
        val testFilter =
            IntentFilter(TEST_ACTION).apply { priority = IntentFilter.SYSTEM_HIGH_PRIORITY }
        broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
    }

@@ -366,12 +394,14 @@ class BroadcastDispatcherTest : SysuiTestCase() {

        val inOrderUser0 = inOrder(mockUBRUser0, removalPendingStore)
        inOrderUser0.verify(mockUBRUser0).unregisterReceiver(broadcastReceiver)
        inOrderUser0.verify(removalPendingStore)
        inOrderUser0
            .verify(removalPendingStore)
            .clearPendingRemoval(broadcastReceiver, UserHandle.USER_ALL)

        val inOrderUser1 = inOrder(mockUBRUser1, removalPendingStore)
        inOrderUser1.verify(mockUBRUser1).unregisterReceiver(broadcastReceiver)
        inOrderUser1.verify(removalPendingStore)
        inOrderUser1
            .verify(removalPendingStore)
            .clearPendingRemoval(broadcastReceiver, UserHandle.USER_ALL)
    }

@@ -385,21 +415,21 @@ class BroadcastDispatcherTest : SysuiTestCase() {

        val inOrderUser1 = inOrder(mockUBRUser1, removalPendingStore)
        inOrderUser1.verify(mockUBRUser1).unregisterReceiver(broadcastReceiver)
        inOrderUser1.verify(removalPendingStore)
        inOrderUser1
            .verify(removalPendingStore)
            .clearPendingRemoval(broadcastReceiver, user1.identifier)
    }

    @Test
    fun testBroadcastFlow() = runBlockingTest {
        val flow = broadcastDispatcher.broadcastFlow(intentFilter, user1) { intent, receiver ->
    fun testBroadcastFlow() = runTest(UnconfinedTestDispatcher()) {
        val flow =
            broadcastDispatcher.broadcastFlow(intentFilter, user1) { intent, receiver ->
                intent to receiver
            }

        // Collect the values into collectedValues.
        val collectedValues = mutableListOf<Pair<Intent, BroadcastReceiver>>()
        val job = launch {
            flow.collect { collectedValues.add(it) }
        }
        val job = launch { flow.collect { collectedValues.add(it) } }

        testableLooper.processAllMessages()
        verify(mockUBRUser1).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG))
@@ -436,8 +466,9 @@ class BroadcastDispatcherTest : SysuiTestCase() {
        logger: BroadcastDispatcherLogger,
        userTracker: UserTracker,
        removalPendingStore: PendingRemovalStore,
        var mockUBRMap: Map<Int, UserBroadcastDispatcher>
    ) : BroadcastDispatcher(
        var mockUBRMap: Map<Int, UserBroadcastDispatcher>,
    ) :
        BroadcastDispatcher(
            context,
            mainExecutor,
            backgroundRunningLooper,
@@ -445,7 +476,7 @@ class BroadcastDispatcherTest : SysuiTestCase() {
            dumpManager,
            logger,
            userTracker,
        removalPendingStore
            removalPendingStore,
        ) {
        override fun createUBRForUser(userId: Int): UserBroadcastDispatcher {
            return mockUBRMap.getOrDefault(userId, mock(UserBroadcastDispatcher::class.java))
+12 −43
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.TestCoroutineScope
import kotlinx.coroutines.test.TestScope
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -125,11 +125,7 @@ class UserRepositoryImplTest : SysuiTestCase() {
        whenever(mainUser.identifier).thenReturn(mainUserId)

        underTest = create(this)
        val initialExpectedValue =
            setUpUsers(
                count = 3,
                selectedIndex = 0,
            )
        val initialExpectedValue = setUpUsers(count = 3, selectedIndex = 0)
        var userInfos: List<UserInfo>? = null
        var selectedUserInfo: UserInfo? = null
        underTest.userInfos.onEach { userInfos = it }.launchIn(this)
@@ -140,23 +136,14 @@ class UserRepositoryImplTest : SysuiTestCase() {
        assertThat(selectedUserInfo).isEqualTo(initialExpectedValue[0])
        assertThat(underTest.lastSelectedNonGuestUserId).isEqualTo(selectedUserInfo?.id)

        val secondExpectedValue =
            setUpUsers(
                count = 4,
                selectedIndex = 1,
            )
        val secondExpectedValue = setUpUsers(count = 4, selectedIndex = 1)
        underTest.refreshUsers()
        assertThat(userInfos).isEqualTo(secondExpectedValue)
        assertThat(selectedUserInfo).isEqualTo(secondExpectedValue[1])
        assertThat(underTest.lastSelectedNonGuestUserId).isEqualTo(selectedUserInfo?.id)

        val selectedNonGuestUserId = selectedUserInfo?.id
        val thirdExpectedValue =
            setUpUsers(
                count = 2,
                isLastGuestUser = true,
                selectedIndex = 1,
            )
        val thirdExpectedValue = setUpUsers(count = 2, isLastGuestUser = true, selectedIndex = 1)
        underTest.refreshUsers()
        assertThat(userInfos).isEqualTo(thirdExpectedValue)
        assertThat(selectedUserInfo).isEqualTo(thirdExpectedValue[1])
@@ -168,12 +155,7 @@ class UserRepositoryImplTest : SysuiTestCase() {
    @Test
    fun refreshUsers_sortsByCreationTime_guestUserLast() = runSelfCancelingTest {
        underTest = create(this)
        val unsortedUsers =
            setUpUsers(
                count = 3,
                selectedIndex = 0,
                isLastGuestUser = true,
            )
        val unsortedUsers = setUpUsers(count = 3, selectedIndex = 0, isLastGuestUser = true)
        unsortedUsers[0].creationTime = 999
        unsortedUsers[1].creationTime = 900
        unsortedUsers[2].creationTime = 950
@@ -197,30 +179,22 @@ class UserRepositoryImplTest : SysuiTestCase() {
    ): List<UserInfo> {
        val userInfos =
            (0 until count).map { index ->
                createUserInfo(
                    index,
                    isGuest = isLastGuestUser && index == count - 1,
                )
                createUserInfo(index, isGuest = isLastGuestUser && index == count - 1)
            }
        whenever(manager.aliveUsers).thenReturn(userInfos)
        tracker.set(userInfos, selectedIndex)
        return userInfos
    }

    @Test
    fun userTrackerCallback_updatesSelectedUserInfo() = runSelfCancelingTest {
        underTest = create(this)
        var selectedUserInfo: UserInfo? = null
        underTest.selectedUserInfo.onEach { selectedUserInfo = it }.launchIn(this)
        setUpUsers(
            count = 2,
            selectedIndex = 0,
        )
        setUpUsers(count = 2, selectedIndex = 0)
        tracker.onProfileChanged()
        assertThat(selectedUserInfo?.id).isEqualTo(0)
        setUpUsers(
            count = 2,
            selectedIndex = 1,
        )
        setUpUsers(count = 2, selectedIndex = 1)
        tracker.onProfileChanged()
        assertThat(selectedUserInfo?.id).isEqualTo(1)
    }
@@ -259,10 +233,7 @@ class UserRepositoryImplTest : SysuiTestCase() {
        assertThat(selectedUser!!.selectionStatus).isEqualTo(SelectionStatus.SELECTION_IN_PROGRESS)
    }

    private fun createUserInfo(
        id: Int,
        isGuest: Boolean,
    ): UserInfo {
    private fun createUserInfo(id: Int, isGuest: Boolean): UserInfo {
        val flags = 0
        return UserInfo(
            id,
@@ -312,16 +283,14 @@ class UserRepositoryImplTest : SysuiTestCase() {
     * Executes the given block of execution within the scope of a dedicated [CoroutineScope] which
     * is then automatically canceled and cleaned-up.
     */
    private fun runSelfCancelingTest(
        block: suspend CoroutineScope.() -> Unit,
    ) =
    private fun runSelfCancelingTest(block: suspend CoroutineScope.() -> Unit) =
        runBlocking(Dispatchers.Main.immediate) {
            val scope = CoroutineScope(coroutineContext + Job())
            block(scope)
            scope.cancel()
        }

    private fun create(scope: CoroutineScope = TestCoroutineScope()): UserRepositoryImpl {
    private fun create(scope: CoroutineScope = TestScope()): UserRepositoryImpl {
        return UserRepositoryImpl(
            appContext = context,
            manager = manager,
Loading