1 /* 2 * Copyright 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.education.data.repository 18 19 import android.content.Context 20 import androidx.test.ext.junit.runners.AndroidJUnit4 21 import androidx.test.filters.SmallTest 22 import com.android.systemui.SysuiTestCase 23 import com.android.systemui.SysuiTestableContext 24 import com.android.systemui.contextualeducation.GestureType.BACK 25 import com.android.systemui.coroutines.collectLastValue 26 import com.android.systemui.education.data.model.EduDeviceConnectionTime 27 import com.android.systemui.education.data.model.GestureEduModel 28 import com.android.systemui.education.domain.interactor.mockEduInputManager 29 import com.android.systemui.kosmos.Kosmos 30 import com.android.systemui.kosmos.testDispatcher 31 import com.android.systemui.kosmos.testScope 32 import com.google.common.truth.Truth.assertThat 33 import java.io.File 34 import javax.inject.Provider 35 import kotlinx.coroutines.CoroutineScope 36 import kotlinx.coroutines.test.TestScope 37 import kotlinx.coroutines.test.runTest 38 import org.junit.Before 39 import org.junit.Rule 40 import org.junit.Test 41 import org.junit.rules.TemporaryFolder 42 import org.junit.runner.RunWith 43 44 @SmallTest 45 @RunWith(AndroidJUnit4::class) 46 class ContextualEducationRepositoryTest : SysuiTestCase() { 47 48 private lateinit var underTest: UserContextualEducationRepository 49 private val kosmos = Kosmos() 50 private val testScope = kosmos.testScope <lambda>null51 private val dsScopeProvider: Provider<CoroutineScope> = Provider { 52 TestScope(kosmos.testDispatcher).backgroundScope 53 } 54 55 private val testUserId = 1111 56 private val secondTestUserId = 1112 57 58 // For deleting any test files created after the test 59 @get:Rule val tmpFolder: TemporaryFolder = TemporaryFolder.builder().assureDeletion().build() 60 61 @Before setUpnull62 fun setUp() { 63 // Create TestContext here because TemporaryFolder.create() is called in @Before. It is 64 // needed before calling TemporaryFolder.newFolder(). 65 val testContext = TestContext(context, tmpFolder.newFolder()) 66 underTest = 67 UserContextualEducationRepository( 68 testContext, 69 dsScopeProvider, 70 kosmos.mockEduInputManager, 71 kosmos.testDispatcher 72 ) 73 underTest.setUser(testUserId) 74 } 75 76 @Test changeRetrievedValueForNewUsernull77 fun changeRetrievedValueForNewUser() = 78 testScope.runTest { 79 // Update data for old user. 80 underTest.updateGestureEduModel(BACK) { it.copy(signalCount = 1) } 81 val model by collectLastValue(underTest.readGestureEduModelFlow(BACK)) 82 assertThat(model?.signalCount).isEqualTo(1) 83 84 // User is changed. 85 underTest.setUser(secondTestUserId) 86 // Assert count is 0 after user is changed. 87 assertThat(model?.signalCount).isEqualTo(0) 88 } 89 90 @Test changeUserIdForNewUsernull91 fun changeUserIdForNewUser() = 92 testScope.runTest { 93 val model by collectLastValue(underTest.readGestureEduModelFlow(BACK)) 94 assertThat(model?.userId).isEqualTo(testUserId) 95 underTest.setUser(secondTestUserId) 96 assertThat(model?.userId).isEqualTo(secondTestUserId) 97 } 98 99 @Test dataChangedOnUpdatenull100 fun dataChangedOnUpdate() = 101 testScope.runTest { 102 val newModel = 103 GestureEduModel( 104 signalCount = 2, 105 educationShownCount = 1, 106 lastShortcutTriggeredTime = kosmos.fakeEduClock.instant(), 107 lastEducationTime = kosmos.fakeEduClock.instant(), 108 usageSessionStartTime = kosmos.fakeEduClock.instant(), 109 userId = testUserId, 110 gestureType = BACK 111 ) 112 underTest.updateGestureEduModel(BACK) { newModel } 113 val model by collectLastValue(underTest.readGestureEduModelFlow(BACK)) 114 assertThat(model).isEqualTo(newModel) 115 } 116 117 @Test eduDeviceConnectionTimeDataChangedOnUpdatenull118 fun eduDeviceConnectionTimeDataChangedOnUpdate() = 119 testScope.runTest { 120 val newModel = 121 EduDeviceConnectionTime( 122 keyboardFirstConnectionTime = kosmos.fakeEduClock.instant(), 123 touchpadFirstConnectionTime = kosmos.fakeEduClock.instant(), 124 ) 125 underTest.updateEduDeviceConnectionTime { newModel } 126 val model by collectLastValue(underTest.readEduDeviceConnectionTime()) 127 assertThat(model).isEqualTo(newModel) 128 } 129 130 /** Test context which allows overriding getFilesDir path */ 131 private class TestContext(context: Context, private val folder: File) : 132 SysuiTestableContext(context) { getFilesDirnull133 override fun getFilesDir(): File { 134 return folder 135 } 136 } 137 } 138