diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 513d0f5..6aef53a 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -219,8 +219,8 @@ dependencies { testImplementation(libs.junit.jupiter.params) testImplementation(libs.junit.junit4) testRuntimeOnly(libs.junit.jupiter.vintageEngine) + androidTestImplementation(libs.androidJunit5.compose) androidTestImplementation(libs.junit.jupiter.api) - androidTestImplementation(libs.androidJunit5.core) androidTestRuntimeOnly(libs.androidJunit5.runner) testImplementation(libs.robolectric) @@ -244,6 +244,8 @@ dependencies { testImplementation(libs.mockk) testImplementation(libs.mockk.agentJvm) androidTestImplementation(libs.mockk.android) + + testImplementation(libs.turbine) } androidComponents { diff --git a/app/src/androidTest/kotlin/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPromptTest.kt b/app/src/androidTest/kotlin/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPromptTest.kt index 2aa137d..6d6051d 100644 --- a/app/src/androidTest/kotlin/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPromptTest.kt +++ b/app/src/androidTest/kotlin/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPromptTest.kt @@ -3,8 +3,8 @@ package dev.aungkyawpaing.ccdroidx.feature.notification.prompt import android.content.Context import android.content.Intent import android.provider.Settings +import androidx.compose.ui.test.ExperimentalTestApi import androidx.compose.ui.test.assertIsDisplayed -import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick @@ -13,93 +13,122 @@ import androidx.test.espresso.intent.Intents import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction import androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra import androidx.test.espresso.intent.matcher.IntentMatchers.hasFlag +import de.mannodermaus.junit5.compose.createComposeExtension import dev.aungkyawpaing.ccdroidx.R +import io.mockk.every import io.mockk.mockk import io.mockk.verify +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.test.runTest import org.hamcrest.CoreMatchers.allOf -import org.junit.Rule -import org.junit.Test +import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.RegisterExtension +@ExperimentalTestApi class NotificationPromptTest { - @get:Rule - val composeTestRule = createComposeRule() + @JvmField + @RegisterExtension + val extension = createComposeExtension() + + val notificationPromptViewModel: NotificationPromptViewModel = mockk(relaxed = true) private val notificationPromptText = ApplicationProvider.getApplicationContext() .getString(R.string.notification_prompt_body) @Test @DisplayName("does not render Notification Prompt Card when prompt should not be visible") - fun doesNotRenderNotificationPromptCardWhenPromptIsNotVisible() { - composeTestRule.setContent { - NotificationPrompt( - false, - {} - ) + fun doesNotRenderNotificationPromptCardWhenPromptIsNotVisible() = runTest { + every { + notificationPromptViewModel.promptIsVisible + } returns flowOf(false).stateIn(this) + + extension.use { + setContent { + NotificationPrompt( + notificationPromptViewModel + ) + } + + onNodeWithText(notificationPromptText).assertDoesNotExist() } - - composeTestRule.onNodeWithText(notificationPromptText).assertDoesNotExist() } - @Test - @DisplayName("render Notification Prompt Card when prompt should be visible") - fun renderNotificationCardWhenPromptIsVisible() { - composeTestRule.setContent { - NotificationPrompt( - true, - {} - ) - } - - composeTestRule.onNodeWithText(notificationPromptText).assertIsDisplayed() - composeTestRule.onNodeWithText("ENABLE NOTIFICATION").assertIsDisplayed() - } + @Nested + @DisplayName("When prompt should be visible") + internal inner class WhenPromptIsVisible { - @Test - @DisplayName("invoke onDismissClick on clicking dismiss") - fun invokeOnDismissClickOnClickingDismiss() { - val onDismissPrompt = mockk<() -> Unit>(relaxed = true) - composeTestRule.setContent { - NotificationPrompt( - true, - onDismissPrompt - ) + @BeforeEach + fun setUp() = runTest { + every { + notificationPromptViewModel.promptIsVisible + } returns flowOf(true).stateIn(this) } - val contentDescription = ApplicationProvider.getApplicationContext() - .getString(R.string.notification_prompt_close_content_description) - composeTestRule.onNodeWithContentDescription(contentDescription).assertIsDisplayed() - composeTestRule.onNodeWithContentDescription(contentDescription).performClick() - - verify(exactly = 1) { - onDismissPrompt() + @Test + @DisplayName("render Notification Prompt Card ") + fun renderNotificationCardWhenPromptIsVisible() { + extension.use { + setContent { + NotificationPrompt( + notificationPromptViewModel + ) + } + + onNodeWithText(notificationPromptText).assertIsDisplayed() + } } - } - @Test - @DisplayName("invoke onEnableNotification on clicking enable notification") - fun invokeOnEnableNotificationOnClickingEnableNotification() { - val context = ApplicationProvider.getApplicationContext() - Intents.init() - - composeTestRule.setContent { - NotificationPrompt( - true, - {} - ) + @Test + @DisplayName("invoke onDismissClick on clicking dismiss") + fun invokeOnDismissClickOnClickingDismiss() { + extension.use { + setContent { + NotificationPrompt( + notificationPromptViewModel + ) + } + + val contentDescription = ApplicationProvider.getApplicationContext() + .getString(R.string.notification_prompt_close_content_description) + onNodeWithContentDescription(contentDescription).assertIsDisplayed() + onNodeWithContentDescription(contentDescription).performClick() + } + + verify(exactly = 1) { + notificationPromptViewModel.onDismissClick() + } } - composeTestRule.onNodeWithText("ENABLE NOTIFICATION").performClick() - - Intents.intended( - allOf( - hasAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS), - hasExtra(Settings.EXTRA_APP_PACKAGE, context.packageName), - hasFlag(Intent.FLAG_ACTIVITY_NEW_TASK) + @Test + @DisplayName("open notification settings on clicking enable notification") + fun invokeOnEnableNotificationOnClickingEnableNotification() { + val context = ApplicationProvider.getApplicationContext() + Intents.init() + + extension.use { + setContent { + NotificationPrompt( + notificationPromptViewModel + ) + } + + onNodeWithText("ENABLE NOTIFICATION").performClick() + } + + Intents.intended( + allOf( + hasAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS), + hasExtra(Settings.EXTRA_APP_PACKAGE, context.packageName), + hasFlag(Intent.FLAG_ACTIVITY_NEW_TASK) + ) ) - ) - Intents.release() + Intents.release() + } } } \ No newline at end of file diff --git a/app/src/main/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPrompt.kt b/app/src/main/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPrompt.kt index e2a8e77..a1b3e74 100644 --- a/app/src/main/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPrompt.kt +++ b/app/src/main/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPrompt.kt @@ -22,9 +22,11 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Devices import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.constraintlayout.compose.ConstraintLayout @@ -33,7 +35,7 @@ import com.google.accompanist.themeadapter.material3.Mdc3Theme import dev.aungkyawpaing.ccdroidx.R @Composable -private fun NotificationPromptCard( +fun NotificationPromptContent( onDismissPrompt: () -> Unit, onEnableNotification: () -> Unit ) { @@ -100,15 +102,14 @@ private fun NotificationPromptCard( @Composable fun NotificationPrompt( - isNotificationPromptVisible: Boolean, - onDismissNotificationPrompt: () -> Unit, + notificationPromptViewModel: NotificationPromptViewModel, modifier: Modifier = Modifier, ) { val context = LocalContext.current Box(modifier = modifier) { AnimatedVisibility( - visible = isNotificationPromptVisible, + visible = notificationPromptViewModel.promptIsVisible.collectAsState(false).value, enter = fadeIn() + slideInVertically( initialOffsetY = { it / 2 @@ -120,22 +121,29 @@ fun NotificationPrompt( }, ) ) { - NotificationPromptCard(onDismissPrompt = onDismissNotificationPrompt, onEnableNotification = { - kotlin.runCatching { - val settingsIntent: Intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - .putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName) - context.startActivity(settingsIntent) - } - }) + NotificationPromptContent( + onDismissPrompt = notificationPromptViewModel::onDismissClick, + onEnableNotification = { + kotlin.runCatching { + val settingsIntent: Intent = + Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + .putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName) + context.startActivity(settingsIntent) + } + }) } } } -@Preview +@Preview( + name = "Phone", device = Devices.PHONE +) +@Preview( + name = "Tablet", device = Devices.TABLET +) @Composable fun NotificationPromptPreview() { Mdc3Theme { - NotificationPrompt(isNotificationPromptVisible = true, {}) + NotificationPromptContent({}, {}) } } \ No newline at end of file diff --git a/app/src/main/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPromptViewModel.kt b/app/src/main/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPromptViewModel.kt index d8923b5..08640cd 100644 --- a/app/src/main/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPromptViewModel.kt +++ b/app/src/main/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPromptViewModel.kt @@ -1,14 +1,15 @@ package dev.aungkyawpaing.ccdroidx.feature.notification.prompt -import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModel -import androidx.lifecycle.asLiveData import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dev.aungkyawpaing.ccdroidx.data.ProjectRepo import dev.aungkyawpaing.ccdroidx.feature.notification.prompt.permssionflow.NotificationPermissionFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import java.time.Clock import java.time.LocalDateTime @@ -22,7 +23,7 @@ class NotificationPromptViewModel @Inject constructor( private val clock: Clock ) : ViewModel() { - val promptIsVisibleLiveData: LiveData = combine( + val promptIsVisible: StateFlow = combine( projectRepo.getAll(), notificationDismissStore.getDismissTimeStamp(), notificationsPermissionFlow.getFlow(), @@ -35,7 +36,7 @@ class NotificationPromptViewModel @Inject constructor( .isAfter(dismissTimeStamp) return@map thereIsAtLeastOneProject && lastDismissTimeNotWithin14Days && !isPermissionGranted - }.asLiveData() + }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), false) fun onDismissClick() { viewModelScope.launch { diff --git a/app/src/main/java/dev/aungkyawpaing/ccdroidx/feature/projectlist/ProjectListPage.kt b/app/src/main/java/dev/aungkyawpaing/ccdroidx/feature/projectlist/ProjectListPage.kt index ea55f44..64e3f73 100644 --- a/app/src/main/java/dev/aungkyawpaing/ccdroidx/feature/projectlist/ProjectListPage.kt +++ b/app/src/main/java/dev/aungkyawpaing/ccdroidx/feature/projectlist/ProjectListPage.kt @@ -168,8 +168,7 @@ fun ProjectListPageContent( onPressSync: () -> Unit, clearOnProgressSyncedEvent: () -> Unit, onDeleteProject: (project: Project) -> Unit, - isNotificationPromptVisible: Boolean, - onDismissNotificationPrompt: () -> Unit, + notificationPromptViewModel: NotificationPromptViewModel, navigator: DestinationsNavigator, clock: Clock = Clock.systemDefaultZone() ) { @@ -225,8 +224,7 @@ fun ProjectListPageContent( ) NotificationPrompt( - isNotificationPromptVisible = isNotificationPromptVisible, - onDismissNotificationPrompt = onDismissNotificationPrompt, + notificationPromptViewModel = notificationPromptViewModel, modifier = Modifier.constrainAs(notificationPrompt) { end.linkTo(parent.end) start.linkTo(parent.start) @@ -278,10 +276,7 @@ fun ProjectListPage( clearOnProgressSyncedEvent = projectListViewModel::clearOnProgressSyncedEvent, onPressSync = projectListViewModel::onPressSync, onDeleteProject = projectListViewModel::onDeleteProject, - isNotificationPromptVisible = notificationPromptViewModel.promptIsVisibleLiveData.observeAsState( - initial = false - ).value, - onDismissNotificationPrompt = notificationPromptViewModel::onDismissClick, + notificationPromptViewModel = notificationPromptViewModel, navigator = navigator ) } \ No newline at end of file diff --git a/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/add/AddProjectViewModelTest.kt b/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/add/AddProjectViewModelTest.kt index 81019c6..c4202f6 100644 --- a/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/add/AddProjectViewModelTest.kt +++ b/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/add/AddProjectViewModelTest.kt @@ -14,7 +14,11 @@ import io.mockk.mockk import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.* +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.EnumSource @@ -23,7 +27,7 @@ import org.junit.jupiter.params.provider.EnumSource @ExtendWith(InstantTaskExecutorExtension::class) class AddProjectViewModelTest : CoroutineTest() { - private val projectRepo = mockk() + private val projectRepo = mockk(relaxed = true) private val mockValidator = mockk() private val viewModel = diff --git a/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPromptScreenshotTest.kt b/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPromptScreenshotTest.kt new file mode 100644 index 0000000..50a56a2 --- /dev/null +++ b/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPromptScreenshotTest.kt @@ -0,0 +1,48 @@ +package dev.aungkyawpaing.ccdroidx.feature.notification.prompt + +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onRoot +import com.github.takahirom.roborazzi.captureRoboImage +import com.google.accompanist.themeadapter.material3.Mdc3Theme +import dev.aungkyawpaing.ccdroidx._testhelper_.ScreenshotTest +import dev.aungkyawpaing.ccdroidx.testDevices +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.ParameterizedRobolectricTestRunner +import org.robolectric.ParameterizedRobolectricTestRunner.Parameters +import org.robolectric.RuntimeEnvironment +import org.robolectric.annotation.GraphicsMode + +@RunWith(ParameterizedRobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +class NotificationPromptScreenshotTest( + private val deviceName: String, + private val deviceQualifier: String, +) : ScreenshotTest() { + + companion object { + @JvmStatic + @Parameters(name = "Device: {0}") + fun testParamsProvider() = testDevices + } + + @get:Rule + val composeTestRule = createComposeRule() + + @Test + fun notificationPromptCard() { + RuntimeEnvironment.setQualifiers(deviceQualifier) + composeTestRule.setContent { + Mdc3Theme { + NotificationPromptContent( + onDismissPrompt = {}, + onEnableNotification = {} + ) + } + } + + composeTestRule.onRoot() + .captureRoboImage(getScreenshotPath("notificationPrompt_${deviceName}")) + } +} \ No newline at end of file diff --git a/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPromptViewModelTest.kt b/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPromptViewModelTest.kt index 93ebe29..c7bb076 100644 --- a/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPromptViewModelTest.kt +++ b/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/NotificationPromptViewModelTest.kt @@ -1,11 +1,11 @@ package dev.aungkyawpaing.ccdroidx.feature.notification.prompt +import app.cash.turbine.test import dev.aungkyawpaing.ccdroidx._testhelper_.CoroutineTest import dev.aungkyawpaing.ccdroidx._testhelper_.InstantTaskExecutorExtension import dev.aungkyawpaing.ccdroidx._testhelper_.ProjectBuilder import dev.aungkyawpaing.ccdroidx.data.ProjectRepo import dev.aungkyawpaing.ccdroidx.feature.notification.prompt.permssionflow.NotificationPermissionFlow -import dev.aungkyawpaing.ccdroidx.observeForTesting import io.mockk.coEvery import io.mockk.coVerify import io.mockk.every @@ -14,7 +14,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Nested @@ -70,9 +70,9 @@ class NotificationPromptViewModelTest : CoroutineTest() { val viewModel = createViewModel() - viewModel.promptIsVisibleLiveData.observeForTesting { - runCurrent() - Assertions.assertEquals(false, viewModel.promptIsVisibleLiveData.value) + viewModel.promptIsVisible.test { + assertEquals(false, awaitItem()) + cancelAndConsumeRemainingEvents() } } @@ -95,9 +95,10 @@ class NotificationPromptViewModelTest : CoroutineTest() { val viewModel = createViewModel(currentTimeClock) - viewModel.promptIsVisibleLiveData.observeForTesting { - runCurrent() - Assertions.assertEquals(true, viewModel.promptIsVisibleLiveData.value) + viewModel.promptIsVisible.test { + skipItems(1) + assertEquals(true, awaitItem()) + cancelAndConsumeRemainingEvents() } } @@ -109,9 +110,9 @@ class NotificationPromptViewModelTest : CoroutineTest() { val viewModel = createViewModel(currentTimeClock) - viewModel.promptIsVisibleLiveData.observeForTesting { - runCurrent() - Assertions.assertEquals(false, viewModel.promptIsVisibleLiveData.value) + viewModel.promptIsVisible.test { + assertEquals(false, awaitItem()) + cancelAndConsumeRemainingEvents() } } @@ -133,9 +134,9 @@ class NotificationPromptViewModelTest : CoroutineTest() { } returns flowOf(true) val viewModel = createViewModel(currentTimeClock) - viewModel.promptIsVisibleLiveData.observeForTesting { - runCurrent() - Assertions.assertEquals(false, viewModel.promptIsVisibleLiveData.value) + viewModel.promptIsVisible.test { + assertEquals(false, awaitItem()) + cancelAndConsumeRemainingEvents() } } @@ -146,12 +147,12 @@ class NotificationPromptViewModelTest : CoroutineTest() { } returns flowOf(false) val viewModel = createViewModel(currentTimeClock) - viewModel.promptIsVisibleLiveData.observeForTesting { - runCurrent() - Assertions.assertEquals(true, viewModel.promptIsVisibleLiveData.value) + viewModel.promptIsVisible.test { + skipItems(1) + assertEquals(true, awaitItem()) + cancelAndConsumeRemainingEvents() } } - } } } @@ -161,7 +162,6 @@ class NotificationPromptViewModelTest : CoroutineTest() { val viewModel = createViewModel() viewModel.onDismissClick() - runCurrent() coVerify(exactly = 1) { diff --git a/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/_screenshots/NotificationPromptScreenshotTest_notificationPrompt_Medium_Phone.png b/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/_screenshots/NotificationPromptScreenshotTest_notificationPrompt_Medium_Phone.png new file mode 100644 index 0000000..6670733 Binary files /dev/null and b/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/_screenshots/NotificationPromptScreenshotTest_notificationPrompt_Medium_Phone.png differ diff --git a/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/_screenshots/NotificationPromptScreenshotTest_notificationPrompt_Medium_Tablet.png b/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/_screenshots/NotificationPromptScreenshotTest_notificationPrompt_Medium_Tablet.png new file mode 100644 index 0000000..6734098 Binary files /dev/null and b/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/_screenshots/NotificationPromptScreenshotTest_notificationPrompt_Medium_Tablet.png differ diff --git a/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/_screenshots/NotificationPromptScreenshotTest_notificationPrompt_Small_Phone.png b/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/_screenshots/NotificationPromptScreenshotTest_notificationPrompt_Small_Phone.png new file mode 100644 index 0000000..6059613 Binary files /dev/null and b/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/notification/prompt/_screenshots/NotificationPromptScreenshotTest_notificationPrompt_Small_Phone.png differ diff --git a/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/projectlist/ProjectListScreenshotTest.kt b/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/projectlist/ProjectListScreenshotTest.kt index 8ffa1a9..7ab07e0 100644 --- a/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/projectlist/ProjectListScreenshotTest.kt +++ b/app/src/test/java/dev/aungkyawpaing/ccdroidx/feature/projectlist/ProjectListScreenshotTest.kt @@ -11,6 +11,7 @@ import dev.aungkyawpaing.ccdroidx.common.BuildStatus import dev.aungkyawpaing.ccdroidx.feature.sync.LastSyncedState import dev.aungkyawpaing.ccdroidx.feature.sync.LastSyncedStatus import dev.aungkyawpaing.ccdroidx.testDevices +import io.mockk.mockk import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -53,8 +54,7 @@ class ProjectListScreenshotTest( onPressSync = { }, clearOnProgressSyncedEvent = { }, onDeleteProject = { }, - isNotificationPromptVisible = false, - onDismissNotificationPrompt = { }, + notificationPromptViewModel = mockk(relaxed = true), navigator = EmptyDestinationsNavigator ) } @@ -102,8 +102,7 @@ class ProjectListScreenshotTest( onPressSync = { }, clearOnProgressSyncedEvent = { }, onDeleteProject = { }, - isNotificationPromptVisible = true, - onDismissNotificationPrompt = { }, + notificationPromptViewModel = mockk(relaxed = true), navigator = EmptyDestinationsNavigator, clock = Clock.fixed( currentDateTime.toInstant(), @@ -133,8 +132,7 @@ class ProjectListScreenshotTest( onPressSync = { }, clearOnProgressSyncedEvent = { }, onDeleteProject = { }, - isNotificationPromptVisible = false, - onDismissNotificationPrompt = { }, + notificationPromptViewModel = mockk(relaxed = true), navigator = EmptyDestinationsNavigator ) } @@ -159,8 +157,7 @@ class ProjectListScreenshotTest( onPressSync = { }, clearOnProgressSyncedEvent = { }, onDeleteProject = { }, - isNotificationPromptVisible = false, - onDismissNotificationPrompt = { }, + notificationPromptViewModel = mockk(relaxed = true), navigator = EmptyDestinationsNavigator, clock = Clock.fixed( currentDateTime.toInstant(), diff --git a/build.gradle.kts b/build.gradle.kts index 2dbe2d1..06b2906 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,6 @@ val versionNameConfig by extra { "$versionMajor.$versionMinor.$versionPatch" } val versionCodeConfig by extra { versionMajor * 1000000 + versionMinor * 10000 + versionPatch * 100 + versionBuild * 10 } val wearVersionCodeConfig by extra { versionMajor * 1000000 + versionMinor * 10000 + versionPatch * 100 + versionBuild * 10 + 1 } - plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.android.library) apply false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 625a308..f9c0747 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ androidx-fragment = "1.6.1" androidx-lifecycle = "2.6.1" androidx-test = "1.5.0" androidx-work = "2.8.1" -compose = "1.4.0" +compose = "1.5.3" compose-destinations = "1.8.42-beta" compose-wear = "1.1.2" dagger = "2.48" @@ -14,7 +14,7 @@ desugar-jdk-libs = "2.0.3" espresso = "3.4.0" firebase-crashlytics-gradle = "2.9.8" google-services = "4.3.15" -jupiter = "5.9.2" +jupiter = "5.9.3" kotlin = "1.8.10" kotlinx-coroutine = "1.6.4" mockk = "1.12.3" @@ -31,6 +31,7 @@ wire = "4.5.2" accompanist = { group = "com.google.accompanist", name = "accompanist-themeadapter-material3", version = "0.30.0" } androidJunit5-core = { group = "de.mannodermaus.junit5", name = "android-test-core", version.ref = "android-junit5" } androidJunit5-runner = { group = "de.mannodermaus.junit5", name = "android-test-runner", version.ref = "android-junit5" } +androidJunit5-compose = { group = "de.mannodermaus.junit5", name = "android-test-compose", version = "1.0.0-SNAPSHOT" } androidx-activity = { module = "androidx.activity:activity-ktx", version = "1.7.2" } androidx-appcompat = { module = "androidx.appcompat:appcompat", version = "1.6.1" } androidx-arch-testing = { module = "androidx.arch.core:core-testing", version = "2.2.0" } @@ -120,11 +121,12 @@ sqldelight-android = { group = "com.squareup.sqldelight", name = "android-driver sqldelight-coroutine = { group = "com.squareup.sqldelight", name = "coroutines-extensions", version.ref = "sqldelight" } sqldelight-jvm = { group = "com.squareup.sqldelight", name = "sqlite-driver", version.ref = "sqldelight" } timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" } +turbine = { module = "app.cash.turbine:turbine", version = "1.0.0" } wire = { group = "com.squareup.wire", name = "wire-runtime", version.ref = "wire" } [plugins] android-application = { id = "com.android.application", version.ref = "android-plugin" } -android-junit5 = { id = "de.mannodermaus.android-junit5", version = "1.8.2.1" } +android-junit5 = { id = "de.mannodermaus.android-junit5", version = "1.9.3.0" } android-library = { id = "com.android.library", version.ref = "android-plugin" } dagger-hilt = { id = "com.google.dagger.hilt.android", version.ref = "dagger" } firebase-crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "firebase-crashlytics-gradle" } diff --git a/settings.gradle.kts b/settings.gradle.kts index 748ebe4..09f72a9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -10,6 +10,7 @@ dependencyResolutionManagement { repositories { google() mavenCentral() + maven("https://oss.sonatype.org/content/repositories/snapshots") } }