Skip to content

Commit 2b1b666

Browse files
committed
Add FileNavigatorTest
1 parent 8740d5f commit 2b1b666

File tree

8 files changed

+188
-81
lines changed

8 files changed

+188
-81
lines changed

.idea/androidTestResultsUserPreferences.xml

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/deploymentTargetSelector.xml

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/navigator/build.gradle.kts

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ android {
1111
isIncludeAndroidResources = true
1212
}
1313
}
14-
// defaultConfig {
15-
// testInstrumentationRunner = "com.w2sv.navigator.HiltTestRunner"
16-
// }
14+
defaultConfig {
15+
testInstrumentationRunner = "com.w2sv.navigator.HiltTestRunner"
16+
}
1717
}
1818

1919
dependencies {
@@ -29,26 +29,32 @@ dependencies {
2929
implementation(libs.slimber)
3030

3131
implementation(libs.google.guava)
32-
3332
implementation(libs.simplestorage)
33+
}
3434

35-
// ==============
36-
// Test
37-
// ==============
38-
35+
/**
36+
* Test dependencies.
37+
*/
38+
dependencies {
3939
testImplementation(projects.core.test)
40-
41-
// ==============
42-
// Android Test
43-
// ==============
44-
45-
// androidTestImplementation(libs.androidx.test.runner)
46-
// androidTestImplementation(libs.androidx.test.rules)
47-
// androidTestImplementation(libs.androidx.test.uiautomator)
48-
// androidTestImplementation(libs.androidx.test.ext.junit)
49-
//
50-
// androidTestImplementation(libs.google.hilt.android.testing)
51-
// androidTestImplementation(projects.core.database)
52-
// androidTestImplementation(projects.core.datastore)
53-
// kspAndroidTest(libs.google.hilt.compiler)
5440
}
41+
42+
/**
43+
* Android Test dependencies.
44+
*/
45+
dependencies {
46+
androidTestImplementation(libs.androidx.test.runner)
47+
androidTestImplementation(libs.androidx.test.rules)
48+
androidTestImplementation(libs.androidx.test.uiautomator)
49+
androidTestImplementation(libs.androidx.test.ext.junit.ktx)
50+
51+
androidTestImplementation(projects.core.database)
52+
androidTestImplementation(projects.core.datastore)
53+
54+
androidTestImplementation(libs.kotlinx.coroutines.test)
55+
androidTestImplementation(libs.turbine)
56+
57+
// Hilt
58+
androidTestImplementation(libs.google.hilt.android.testing)
59+
kspAndroidTest(libs.google.hilt.compiler)
60+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.w2sv.navigator
2+
3+
import android.content.Context
4+
import androidx.test.core.app.ApplicationProvider
5+
import androidx.test.ext.junit.rules.activityScenarioRule
6+
import app.cash.turbine.test
7+
import com.w2sv.androidutils.isServiceRunning
8+
import com.w2sv.navigator.moving.activity.QuickMoveDestinationPermissionQueryOverlayDialogActivity
9+
import dagger.hilt.android.testing.HiltAndroidRule
10+
import dagger.hilt.android.testing.HiltAndroidTest
11+
import kotlinx.coroutines.test.runTest
12+
import org.junit.Assert.assertFalse
13+
import org.junit.Assert.assertTrue
14+
import org.junit.Before
15+
import org.junit.Rule
16+
import org.junit.Test
17+
import javax.inject.Inject
18+
19+
@HiltAndroidTest
20+
class FileNavigatorTest {
21+
22+
@get:Rule(order = 0)
23+
val hiltRule = HiltAndroidRule(this)
24+
25+
/**
26+
* Random activity used for launching of foreground service.
27+
*/
28+
@get:Rule(order = 1)
29+
internal val activityScenario =
30+
activityScenarioRule<QuickMoveDestinationPermissionQueryOverlayDialogActivity>()
31+
32+
@Inject
33+
lateinit var fileNavigatorIsRunning: FileNavigator.IsRunning
34+
35+
@Before
36+
fun setUp() {
37+
hiltRule.inject()
38+
FileNavigator.stop(context)
39+
}
40+
41+
private val context: Context = ApplicationProvider.getApplicationContext()
42+
43+
@Test
44+
fun `start starts service and emits true on isRunning while stop stops service and emits false on isRunning`() = runTest {
45+
fileNavigatorIsRunning.test {
46+
assertFalse(awaitItem())
47+
48+
startFileNavigator()
49+
assertTrue(awaitItem())
50+
assertTrue(context.isServiceRunning<FileNavigator>())
51+
52+
FileNavigator.stop(context)
53+
assertFalse(awaitItem())
54+
assertFalse(context.isServiceRunning<FileNavigator>())
55+
}
56+
}
57+
58+
private fun startFileNavigator() {
59+
// Launching of foreground service requires app to be in the foreground in some way
60+
activityScenario.scenario.onActivity {
61+
FileNavigator.start(it.applicationContext)
62+
}
63+
}
64+
}
Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
//package com.w2sv.navigator
2-
//
3-
//import android.app.Application
4-
//import android.content.Context
5-
//import androidx.test.runner.AndroidJUnitRunner
6-
//import dagger.hilt.android.testing.HiltTestApplication
7-
//
8-
//internal class HiltTestRunner : AndroidJUnitRunner() {
9-
//
10-
// override fun newApplication(cl: ClassLoader?, name: String?, context: Context?): Application {
11-
// return super.newApplication(cl, HiltTestApplication::class.java.name, context)
12-
// }
13-
//}
1+
package com.w2sv.navigator
2+
3+
import android.app.Application
4+
import android.content.Context
5+
import androidx.test.runner.AndroidJUnitRunner
6+
import dagger.hilt.android.testing.HiltTestApplication
7+
import timber.log.Timber
8+
9+
internal class HiltTestRunner : AndroidJUnitRunner() {
10+
11+
override fun newApplication(cl: ClassLoader?, name: String?, context: Context?): Application {
12+
Timber.plant(Timber.DebugTree())
13+
return super.newApplication(cl, HiltTestApplication::class.java.name, context)
14+
}
15+
}

core/navigator/src/androidTest/kotlin/com/w2sv/navigator/quicktile/FileNavigatorTileServiceTest.kt

Lines changed: 38 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
//import androidx.test.uiautomator.UiObject
1111
//import androidx.test.uiautomator.UiSelector
1212
//import androidx.test.uiautomator.Until
13+
//import app.cash.turbine.test
1314
//import com.w2sv.navigator.FileNavigator
1415
//import dagger.hilt.android.testing.HiltAndroidRule
1516
//import dagger.hilt.android.testing.HiltAndroidTest
17+
//import kotlinx.coroutines.test.runTest
1618
//import org.junit.Assert.assertFalse
1719
//import org.junit.Assert.assertTrue
1820
//import org.junit.Before
@@ -21,70 +23,66 @@
2123
//import java.io.FileInputStream
2224
//import java.io.IOException
2325
//import javax.inject.Inject
26+
//import kotlin.time.Duration.Companion.seconds
2427
//
2528
//@HiltAndroidTest
26-
//internal class FileNavigatorTileServiceTest {
29+
//class FileNavigatorTileServiceTest {
2730
//
2831
// @get:Rule
29-
// var hiltRule = HiltAndroidRule(this)
32+
// val hiltRule = HiltAndroidRule(this)
3033
//
3134
// @Inject
3235
// lateinit var fileNavigatorIsRunning: FileNavigator.IsRunning
3336
//
3437
// private lateinit var device: UiDevice
35-
// private val context: Context = ApplicationProvider.getApplicationContext()
36-
//
37-
// private val tileLabel = context.getString(com.w2sv.core.common.R.string.app_name)
38-
//// private val tileService = FileNavigatorTileService()
3938
//
4039
// @Before
4140
// fun setUp() {
42-
// hiltRule.inject()
4341
// device = UiDevice.getInstance(getInstrumentation())
42+
// hiltRule.inject()
4443
// FileNavigator.stop(context)
4544
// }
4645
//
46+
// private val context: Context = ApplicationProvider.getApplicationContext()
47+
// private val tileLabel = context.getString(com.w2sv.core.common.R.string.app_name)
48+
//
4749
// @Test
48-
// fun testTileService() {
49-
// val tileService = FileNavigatorTileService()
50-
// println(tileService.scope.coroutineContext)
51-
// assertFalse(tileService.fileNavigatorIsRunning.value)
52-
// device.openQuickSettings()
53-
// device.waitForIdle()
50+
// fun testTileService() = runTest {
51+
// fileNavigatorIsRunning.test(timeout = 5.seconds) {
52+
// assertFalse(awaitItem())
53+
//
54+
// device.openQuickSettings()
55+
// device.wait(Until.hasObject(By.textContains(tileLabel)), 2_000)
5456
//
55-
// device.wait(Until.hasObject(By.textContains(tileLabel)), 10_000)
56-
// val tile = device.findObject(By.textContains(tileLabel).clickable(true))
57-
// assert(tile != null)
57+
// val tile = device.findObject(By.textContains(tileLabel))
58+
// requireNotNull(tile)
5859
//
59-
// tile.click()
60-
// device.wait({ false }, 5_000)
61-
// assertTrue(fileNavigatorIsRunning.value)
62-
//// assertNotNull(tileService.qsTile)
63-
//// assertEquals(Tile.STATE_ACTIVE, tileService.qsTile.state)
60+
// tile.click()
61+
// assertTrue(awaitItem())
6462
//
65-
// // Click the tile again to toggle its state
66-
// tile.click()
67-
// device.waitForIdle()
68-
// assertFalse(fileNavigatorIsRunning.value)
63+
// // Click the tile again to toggle its state
64+
// device.openQuickSettings()
65+
// device.wait(Until.hasObject(By.textContains(tileLabel)), 2_000)
6966
//
70-
// // Verify the tile state changed to inactive
71-
//// assertEquals(Tile.STATE_INACTIVE, tileService.qsTile.state)
67+
// tile.click()
68+
// assertFalse(awaitItem())
69+
// }
7270
// }
71+
//}
7372
//
74-
// private fun UiDevice.findObjects(selector: UiSelector): List<UiObject> {
75-
// val objects = mutableListOf<UiObject>()
76-
// var index = 0
77-
// while (true) {
78-
// val obj = findObject(selector.instance(index))
79-
// if (obj.exists()) {
80-
// objects.add(obj)
81-
// index++
82-
// } else {
83-
// break
84-
// }
73+
//private fun UiDevice.findObjects(selector: UiSelector): List<UiObject> {
74+
// val objects = mutableListOf<UiObject>()
75+
// var index = 0
76+
// while (true) {
77+
// val obj = findObject(selector.instance(index))
78+
// if (obj.exists()) {
79+
// objects.add(obj)
80+
// index++
81+
// } else {
82+
// break
8583
// }
86-
// return objects
8784
// }
85+
// return objects
8886
//}
8987
//
9088
///**
@@ -98,7 +96,7 @@
9896
// * @throws Exception
9997
// */
10098
//@Throws(IOException::class)
101-
//fun runShellCommand(instrumentation: Instrumentation, cmd: String?): String {
99+
//private fun runShellCommand(instrumentation: Instrumentation, cmd: String?): String {
102100
// val pfd = instrumentation.uiAutomation.executeShellCommand(cmd)
103101
// val buf = ByteArray(512)
104102
// var bytesRead: Int

core/navigator/src/main/kotlin/com/w2sv/navigator/FileNavigator.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@ class FileNavigator : UnboundService() {
6868
}
6969

7070
private fun start() {
71-
i { "Starting FileNavigator" }
72-
7371
startForeground(
7472
AppNotificationId.FileNavigatorIsRunning.id,
7573
isRunningNotificationManager.buildNotification(Unit)

gradle/libs.versions.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,21 @@ textflow = { module = "io.github.oleksandrbalan:textflow-material3", version = "
8989
junit = { module = "junit:junit", version.ref = "junit" }
9090
androidx-test-rules = "androidx.test:rules:1.6.1"
9191
androidx-test-runner = "androidx.test:runner:1.6.2"
92-
androidx-test-ext-junit = "androidx.test.ext:junit:1.2.1"
93-
#androidx-test-uiautomator = "androidx.test.uiautomator:uiautomator:2.3.0"
92+
androidx-test-ext-junit-ktx = "androidx.test.ext:junit-ktx:1.2.1"
93+
androidx-test-uiautomator = "androidx.test.uiautomator:uiautomator:2.3.0"
9494
roboelectric = "org.robolectric:robolectric:4.13"
9595
mockito-kotlin = "org.mockito.kotlin:mockito-kotlin:5.4.0"
9696
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinxCoroutines" }
97+
turbine = "app.cash.turbine:turbine:1.1.0"
9798

9899
# Plugins
99100
android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "agp" }
100101
kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
101102
ksp-gradlePlugin = { group = "com.google.devtools.ksp", name = "com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" }
102103

103104
[bundles]
104-
unitTest = ["junit", "androidx-test-ext-junit", "roboelectric", "mockito-kotlin", "kotlinx-coroutines-test"]
105-
instrumentationTest = ["androidx-test-rules", "androidx-test-runner", "androidx-test-ext-junit"]
105+
unitTest = ["junit", "androidx-test-ext-junit-ktx", "roboelectric", "mockito-kotlin", "kotlinx-coroutines-test"]
106+
instrumentationTest = ["androidx-test-rules", "androidx-test-runner", "androidx-test-ext-junit-ktx"]
106107

107108
[plugins]
108109
android-application = { id = "com.android.application", version.ref = "agp" }

0 commit comments

Comments
 (0)