diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml new file mode 100644 index 0000000..071eb6a --- /dev/null +++ b/.github/workflows/unit_tests.yml @@ -0,0 +1,30 @@ +name: Unit Tests + +on: + pull_request: + branches: [ main ] + +jobs: + unit-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Run Unit Tests + run: ./gradlew test + + - name: Upload Test Results + uses: actions/upload-artifact@v3 + if: failure() + with: + name: unit-test-results + path: app/build/reports/tests/ \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2e700a1..9a36bb6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -62,14 +62,15 @@ dependencies { implementation(libs.androidx.material3) implementation(libs.androidx.ui.text.google.fonts) testImplementation(libs.junit) + testImplementation(libs.truth) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) androidTestImplementation(platform(libs.androidx.compose.bom)) androidTestImplementation(libs.androidx.ui.test.junit4) debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.test.manifest) - implementation("com.google.dagger:hilt-android:2.44") - kapt("com.google.dagger:hilt-android-compiler:2.44") + implementation(libs.hilt.android) + kapt(libs.hilt.android.compiler) } kapt { diff --git a/app/src/androidTest/java/com/mnbpdx/gardenbook/DetailScreenTest.kt b/app/src/androidTest/java/com/mnbpdx/gardenbook/DetailScreenTest.kt new file mode 100644 index 0000000..830c11b --- /dev/null +++ b/app/src/androidTest/java/com/mnbpdx/gardenbook/DetailScreenTest.kt @@ -0,0 +1,58 @@ +package com.mnbpdx.gardenbook + +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.ui.test.* +import androidx.compose.ui.test.junit4.createComposeRule +import com.mnbpdx.gardenbook.ui.detail.DetailScreenContent +import com.mnbpdx.gardenbook.ui.theme.GardenBookTheme +import org.junit.Before +import org.junit.Rule +import org.junit.Test + +@ExperimentalMaterial3Api +@ExperimentalFoundationApi +class DetailScreenTest { + + @get:Rule + val composeTestRule = createComposeRule() + + private var backPressed = false + private val testPlantName = "Test Plant" + + @Before + fun setUp() { + backPressed = false + composeTestRule.setContent { + GardenBookTheme { + DetailScreenContent( + plantName = testPlantName, + onArrowBackPress = { backPressed = true } + ) + } + } + } + + @Test + fun detailScreen_displaysPlantName() { + composeTestRule.onNodeWithText(testPlantName).assertIsDisplayed() + } + + @Test + fun detailScreen_displaysImageCarousel() { + composeTestRule.onNodeWithContentDescription("Carousel image 0").assertIsDisplayed() + } + + @Test + fun detailScreen_displaysThreeImagesInCarousel() { + repeat(3) { index -> + composeTestRule.onNodeWithContentDescription("Carousel image $index") + } + } + + @Test + fun detailScreen_backPress_triggersCallback() { + composeTestRule.onNodeWithContentDescription("up icon").performClick() + assert(backPressed) + } +} diff --git a/app/src/test/java/com/mnbpdx/gardenbook/ui/NavigationViewModelTest.kt b/app/src/test/java/com/mnbpdx/gardenbook/ui/NavigationViewModelTest.kt new file mode 100644 index 0000000..13c390b --- /dev/null +++ b/app/src/test/java/com/mnbpdx/gardenbook/ui/NavigationViewModelTest.kt @@ -0,0 +1,21 @@ +package com.mnbpdx.gardenbook.ui + +import com.google.common.truth.Truth.assertThat +import org.junit.Test + +class NavigationViewModelTest { + + private val viewModel = NavigationViewModel() + + @Test + fun `WHEN navigateToHomeScreen is called THEN destination set to home screen`() { + viewModel.navigateToHomeScreen() + assertThat(viewModel.destination.value).isEqualTo(Destination.HomeScreen) + } + + @Test + fun `WHEN navigateToDetailScreen is called THEN destination set to detail screen`() { + viewModel.navigateToDetailScreen("test plant name") + assertThat(viewModel.destination.value).isEqualTo(Destination.DetailScreen("test plant name")) + } +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 704fe78..69ef472 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,6 @@ [versions] agp = "8.5.0" +hiltAndroid = "2.44" kotlin = "1.9.0" coreKtx = "1.10.1" junit = "4.13.2" @@ -8,10 +9,13 @@ espressoCore = "3.5.1" lifecycleRuntimeKtx = "2.6.1" activityCompose = "1.8.0" composeBom = "2024.04.01" +truth = "1.4.3" uiTextGoogleFonts = "1.6.8" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hiltAndroid" } +hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hiltAndroid" } junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } @@ -26,6 +30,7 @@ androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-man androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } androidx-material3 = { group = "androidx.compose.material3", name = "material3" } androidx-ui-text-google-fonts = { group = "androidx.compose.ui", name = "ui-text-google-fonts", version.ref = "uiTextGoogleFonts" } +truth = { module = "com.google.truth:truth", version.ref = "truth" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" }