1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.bouncer.ui.composable
18 
19 import android.app.AlertDialog
20 import android.platform.test.annotations.MotionTest
21 import androidx.compose.foundation.layout.fillMaxSize
22 import androidx.compose.runtime.Composable
23 import androidx.compose.ui.Modifier
24 import androidx.compose.ui.platform.testTag
25 import androidx.compose.ui.test.doubleClick
26 import androidx.compose.ui.test.hasTestTag
27 import androidx.compose.ui.test.performTouchInput
28 import androidx.test.ext.junit.runners.AndroidJUnit4
29 import androidx.test.filters.LargeTest
30 import com.android.compose.theme.PlatformTheme
31 import com.android.systemui.SysuiTestCase
32 import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
33 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
34 import com.android.systemui.bouncer.ui.BouncerDialogFactory
35 import com.android.systemui.bouncer.ui.helper.BouncerSceneLayout
36 import com.android.systemui.bouncer.ui.viewmodel.bouncerViewModel
37 import com.android.systemui.flags.Flags
38 import com.android.systemui.flags.fakeFeatureFlagsClassic
39 import com.android.systemui.motion.createSysUiComposeMotionTestRule
40 import com.android.systemui.scene.domain.interactor.sceneContainerStartable
41 import com.android.systemui.testKosmos
42 import org.junit.Before
43 import org.junit.Rule
44 import org.junit.Test
45 import org.junit.runner.RunWith
46 import platform.test.motion.compose.ComposeFeatureCaptures.alpha
47 import platform.test.motion.compose.ComposeFeatureCaptures.positionInRoot
48 import platform.test.motion.compose.ComposeRecordingSpec
49 import platform.test.motion.compose.MotionControl
50 import platform.test.motion.compose.feature
51 import platform.test.motion.compose.motionTestValueOfNode
52 import platform.test.motion.compose.recordMotion
53 import platform.test.motion.compose.runTest
54 import platform.test.screenshot.DeviceEmulationSpec
55 import platform.test.screenshot.Displays.FoldableInner
56 
57 @RunWith(AndroidJUnit4::class)
58 @LargeTest
59 @MotionTest
60 class BouncerContentTest : SysuiTestCase() {
61     private val deviceSpec = DeviceEmulationSpec(FoldableInner)
62     private val kosmos = testKosmos()
63 
64     @get:Rule val motionTestRule = createSysUiComposeMotionTestRule(kosmos, deviceSpec)
65 
66     private val bouncerDialogFactory =
67         object : BouncerDialogFactory {
invokenull68             override fun invoke(): AlertDialog {
69                 throw AssertionError()
70             }
71         }
72 
73     @Before
setUpnull74     fun setUp() {
75         kosmos.sceneContainerStartable.start()
76         kosmos.fakeFeatureFlagsClassic.set(Flags.FULL_SCREEN_USER_SWITCHER, true)
77         kosmos.fakeAuthenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
78     }
79 
80     @Composable
BouncerContentUnderTestnull81     private fun BouncerContentUnderTest() {
82         PlatformTheme {
83             BouncerContent(
84                 viewModel = kosmos.bouncerViewModel,
85                 layout = BouncerSceneLayout.BESIDE_USER_SWITCHER,
86                 modifier = Modifier.fillMaxSize().testTag("BouncerContent"),
87                 dialogFactory = bouncerDialogFactory
88             )
89         }
90     }
91 
92     @Test
doubleClick_swapSidenull93     fun doubleClick_swapSide() =
94         motionTestRule.runTest {
95             val motion =
96                 recordMotion(
97                     content = { BouncerContentUnderTest() },
98                     ComposeRecordingSpec(
99                         MotionControl {
100                             onNode(hasTestTag("BouncerContent")).performTouchInput {
101                                 doubleClick(position = centerLeft)
102                             }
103 
104                             awaitCondition {
105                                 motionTestValueOfNode(BouncerMotionTestKeys.swapAnimationEnd)
106                             }
107                         }
108                     ) {
109                         feature(hasTestTag("UserSwitcher"), positionInRoot, "userSwitcher_pos")
110                         feature(hasTestTag("UserSwitcher"), alpha, "userSwitcher_alpha")
111                         feature(hasTestTag("FoldAware"), positionInRoot, "foldAware_pos")
112                         feature(hasTestTag("FoldAware"), alpha, "foldAware_alpha")
113                     }
114                 )
115 
116             assertThat(motion).timeSeriesMatchesGolden()
117         }
118 }
119