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 package com.android.bedstead.testapps
17 
18 import android.app.AppOpsManager
19 import android.content.pm.PackageManager
20 import com.android.bedstead.harrier.BedsteadJUnit4
21 import com.android.bedstead.harrier.DeviceState
22 import com.android.bedstead.harrier.UserType
23 import com.android.bedstead.harrier.annotations.EnsureInstrumented
24 import com.android.bedstead.harrier.annotations.EnsureTestAppDoesNotHavePermission
25 import com.android.bedstead.harrier.annotations.EnsureTestAppHasAppOp
26 import com.android.bedstead.harrier.annotations.EnsureTestAppHasPermission
27 import com.android.bedstead.harrier.annotations.EnsureTestAppInstalled
28 import com.android.bedstead.harrier.annotations.InstrumentationComponent
29 import com.android.bedstead.multiuser.annotations.EnsureHasSecondaryUser
30 import com.android.bedstead.multiuser.secondaryUser
31 import com.android.bedstead.nene.TestApis.packages
32 import com.android.bedstead.nene.appops.AppOpsMode
33 import com.android.bedstead.nene.exceptions.NeneException
34 import com.android.bedstead.permissions.CommonPermissions
35 import com.android.bedstead.testapp.NotFoundException
36 import com.android.bedstead.testapp.TestApp
37 import com.android.queryable.annotations.Query
38 import com.android.queryable.annotations.StringQuery
39 import com.google.common.truth.Truth.assertThat
40 import org.junit.Assert.assertThrows
41 import org.junit.ClassRule
42 import org.junit.Rule
43 import org.junit.Test
44 import org.junit.runner.RunWith
45 
46 @RunWith(BedsteadJUnit4::class)
47 class TestAppsAnnotationExecutorTest {
48 
49     // We run this test twice to ensure that teardown doesn't change behaviour
50     @Test
testApps_testAppsAreAvailableToMultipleTests_1null51     fun testApps_testAppsAreAvailableToMultipleTests_1() {
52         assertThat(
53             deviceState.testApps().query()
54                 .wherePackageName().isEqualTo(TEST_APP_PACKAGE_NAME).get()
55         ).isNotNull()
56     }
57 
58     @Test
testApps_testAppsAreAvailableToMultipleTests_2null59     fun testApps_testAppsAreAvailableToMultipleTests_2() {
60         assertThat(
61             deviceState.testApps().query()
62                 .wherePackageName().isEqualTo(TEST_APP_PACKAGE_NAME).get()
63         ).isNotNull()
64     }
65 
66     // We run this test twice to ensure that teardown doesn't change behaviour
67     @Test
testApps_staticTestAppsAreNotReleased_1null68     fun testApps_staticTestAppsAreNotReleased_1() {
69         assertThrows(NotFoundException::class.java) {
70             deviceState.testApps()
71                 .query()
72                 .wherePackageName()
73                 .isEqualTo(TEST_APP_USED_IN_FIELD_NAME)
74                 .get()
75         }
76     }
77 
78     @Test
testApps_staticTestAppsAreNotReleased_2null79     fun testApps_staticTestAppsAreNotReleased_2() {
80         assertThrows(NotFoundException::class.java) {
81             deviceState.testApps()
82                 .query()
83                 .wherePackageName()
84                 .isEqualTo(TEST_APP_USED_IN_FIELD_NAME)
85                 .get()
86         }
87     }
88 
89     @EnsureTestAppInstalled(
90         query = Query(packageName = StringQuery(isEqualTo = TEST_APP_PACKAGE_NAME))
91     )
92     @Test
ensureTestAppInstalledAnnotation_testAppIsInstallednull93     fun ensureTestAppInstalledAnnotation_testAppIsInstalled() {
94         assertThat(packages().find(TEST_APP_PACKAGE_NAME).installedOnUser()).isTrue()
95     }
96 
97     @EnsureHasSecondaryUser
98     @EnsureTestAppInstalled(
99         query = Query(packageName = StringQuery(isEqualTo = TEST_APP_PACKAGE_NAME)),
100         onUser = UserType.SECONDARY_USER
101     )
102     @Test
ensureTestAppInstalledAnnotation_testAppIsInstalledOnCorrectUsernull103     fun ensureTestAppInstalledAnnotation_testAppIsInstalledOnCorrectUser() {
104         assertThat(
105             packages()
106                 .find(TEST_APP_PACKAGE_NAME)
107                 .installedOnUser(deviceState.secondaryUser())
108         ).isTrue()
109     }
110 
111     @EnsureTestAppInstalled(
112         query = Query(packageName = StringQuery(isEqualTo = TEST_APP_PACKAGE_NAME))
113     )
114     @Test
testApp_returnsTestAppnull115     fun testApp_returnsTestApp() {
116         assertThat(deviceState.testApp().packageName()).isEqualTo(TEST_APP_PACKAGE_NAME)
117     }
118 
119     @Test
testApp_noHarrierManagedTestApp_throwsExceptionnull120     fun testApp_noHarrierManagedTestApp_throwsException() {
121         deviceState.testApps().any().install().use {
122             assertThrows(NeneException::class.java) {
123                 deviceState.testApp()
124             }
125         }
126     }
127 
128     @EnsureTestAppInstalled(
129         key = "testApp1",
130         query = Query(packageName = StringQuery(isEqualTo = TEST_APP_PACKAGE_NAME))
131     )
132     @EnsureTestAppInstalled(
133         key = "testApp2",
134         query = Query(packageName = StringQuery(isEqualTo = TEST_APP_PACKAGE_NAME2))
135     )
136     @Test
testApp_withKey_returnsCorrectTestAppnull137     fun testApp_withKey_returnsCorrectTestApp() {
138         assertThat(
139             deviceState.testApp("testApp1").packageName()
140         ).isEqualTo(TEST_APP_PACKAGE_NAME)
141         assertThat(
142             deviceState.testApp("testApp2").packageName()
143         ).isEqualTo(TEST_APP_PACKAGE_NAME2)
144     }
145 
146     @EnsureTestAppInstalled(
147         query = Query(packageName = StringQuery(isEqualTo = TEST_APP_PACKAGE_NAME))
148     )
149     @EnsureTestAppHasPermission(CommonPermissions.READ_CONTACTS)
150     @Test
ensureTestAppHasPermissionAnnotation_testAppHasPermissionnull151     fun ensureTestAppHasPermissionAnnotation_testAppHasPermission() {
152         assertThat(
153             deviceState.testApp()
154                 .context()
155                 .checkSelfPermission(CommonPermissions.READ_CONTACTS)
156         ).isEqualTo(PackageManager.PERMISSION_GRANTED)
157     }
158 
159     @EnsureTestAppInstalled(
160         query = Query(packageName = StringQuery(isEqualTo = TEST_APP_PACKAGE_NAME))
161     )
162     @EnsureTestAppDoesNotHavePermission(CommonPermissions.READ_CONTACTS)
163     @Test
ensureTestAppDoesNotHavePermissionAnnotation_testAppDoesNotHavePermissionnull164     fun ensureTestAppDoesNotHavePermissionAnnotation_testAppDoesNotHavePermission() {
165         assertThat(
166             deviceState.testApp()
167                 .context()
168                 .checkSelfPermission(CommonPermissions.READ_CONTACTS)
169         ).isNotEqualTo(PackageManager.PERMISSION_GRANTED)
170     }
171 
172     @EnsureTestAppInstalled(
173         query = Query(packageName = StringQuery(isEqualTo = TEST_APP_PACKAGE_NAME))
174     )
175     @EnsureTestAppHasAppOp(AppOpsManager.OPSTR_START_FOREGROUND)
176     @Test
ensureTestAppHasAppOpAnnotation_testAppHasAppOpnull177     fun ensureTestAppHasAppOpAnnotation_testAppHasAppOp() {
178         assertThat(
179             deviceState.testApp().testApp().pkg().appOps()[AppOpsManager.OPSTR_START_FOREGROUND]
180         ).isEqualTo(AppOpsMode.ALLOWED)
181     }
182 
183     @Test
184     @EnsureTestAppInstalled(
185         query = Query(packageName = StringQuery(isEqualTo = TEST_APP_PACKAGE_NAME))
186     )
187     @EnsureInstrumented(
188         [InstrumentationComponent(
189             packageName = TEST_APP_PACKAGE_NAME,
190             runnerClass = "androidx.test.runner.AndroidJUnitRunner"
191         )]
192     )
ensureTestAppInstrumented_testAppIsInstrumentednull193     fun ensureTestAppInstrumented_testAppIsInstrumented() {
194         // This test does not assert anything. But will run successfully only when the test app
195         // given by [TEST_APP_PACKAGE_NAME] is successfully instrumented.
196     }
197 
198     companion object {
199         @JvmField
200         @ClassRule
201         @Rule
202         val deviceState = DeviceState()
203 
204         // Expects that this package name matches an actual test app
205         private const val TEST_APP_PACKAGE_NAME: String = "com.android.bedstead.testapp.LockTaskApp"
206         private const val TEST_APP_PACKAGE_NAME2: String = "com.android.bedstead.testapp.SmsApp"
207         private const val TEST_APP_USED_IN_FIELD_NAME: String =
208             "com.android.bedstead.testapp.NotEmptyTestApp"
209 
210         // This is not used but is depended on by testApps_staticTestAppsAreNotReleased_1 and
211         // testApps_staticTestAppsAreNotReleased_2 which test that this testapp isn't released
212         private val sTestApp: TestApp = deviceState.testApps().query()
213             .wherePackageName().isEqualTo(TEST_APP_USED_IN_FIELD_NAME).get()
214     }
215 }
216