Skip to content

Commit

Permalink
fix: navigation not working (#133)
Browse files Browse the repository at this point in the history
Rename MusikusScreen/MusikusApp to MainScreen to ensure consistency with other screens.

Fix navigation issue by handling navigation between tabs exclusively through the NavHost.
Move navigation bar from the home screen into the main screen.

Migrate to type-safe navigation, including type -safe deep links.
Fix pause and resume actions from notification.

Add navigation tests:
- MusikusNavHostTest.kt
- MusikusBottomBarTest.kt
  • Loading branch information
matthiasemde authored Nov 19, 2024
1 parent ea89f17 commit d368607
Show file tree
Hide file tree
Showing 32 changed files with 1,176 additions and 701 deletions.
8 changes: 7 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ plugins {
alias(libs.plugins.compose.compiler)
alias(libs.plugins.hilt)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.ksp)
alias(libs.plugins.license.report)
alias(libs.plugins.detekt)
Expand Down Expand Up @@ -261,9 +262,13 @@ dependencies {

implementation(libs.androidx.activity.ktx)

implementation(libs.androidx.navigation.runtime.ktx)
implementation(libs.androidx.legacy.support.v4)

// Navigation
implementation(libs.androidx.navigation.runtime.ktx)
implementation(libs.androidx.navigation.compose)
implementation(libs.kotlinx.serialization.json)

// Compose
// Animation
implementation(libs.androidx.compose.animation)
Expand Down Expand Up @@ -354,4 +359,5 @@ dependencies {
androidTestImplementation(libs.androidx.test.runner)
androidTestImplementation(libs.google.truth)
androidTestImplementation(libs.android.arch.persistence.room.testing)
androidTestImplementation(libs.androidx.test.navigation)
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ import app.musikus.activesession.domain.usecase.DeleteSectionUseCase
import app.musikus.activesession.domain.usecase.GetCompletedSectionsUseCase
import app.musikus.activesession.domain.usecase.GetFinalizedSessionUseCase
import app.musikus.activesession.domain.usecase.GetOngoingPauseDurationUseCase
import app.musikus.activesession.domain.usecase.GetPausedStateUseCase
import app.musikus.activesession.domain.usecase.GetRunningItemDurationUseCase
import app.musikus.activesession.domain.usecase.GetRunningItemUseCase
import app.musikus.activesession.domain.usecase.GetSessionStatusUseCase
import app.musikus.activesession.domain.usecase.GetStartTimeUseCase
import app.musikus.activesession.domain.usecase.GetTotalPracticeDurationUseCase
import app.musikus.activesession.domain.usecase.IsSessionPausedUseCase
import app.musikus.activesession.domain.usecase.IsSessionRunningUseCase
import app.musikus.activesession.domain.usecase.PauseActiveSessionUseCase
import app.musikus.activesession.domain.usecase.ResetSessionUseCase
Expand Down Expand Up @@ -82,7 +82,7 @@ object TestActiveSessionUseCasesModule {
getRunningItemDuration = getRunningItemDurationUseCase,
getCompletedSections = GetCompletedSectionsUseCase(activeSessionRepository),
getOngoingPauseDuration = GetOngoingPauseDurationUseCase(activeSessionRepository, timeProvider),
getPausedState = GetPausedStateUseCase(activeSessionRepository),
isSessionPaused = IsSessionPausedUseCase(activeSessionRepository),
getFinalizedSession = GetFinalizedSessionUseCase(
activeSessionRepository = activeSessionRepository,
getRunningItemDurationUseCase = getRunningItemDurationUseCase,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2024 Matthias Emde
*/

package app.musikus.core.presentation

import androidx.activity.compose.setContent
import androidx.compose.runtime.getValue
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavHostController
import app.musikus.core.domain.FakeTimeProvider
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import io.mockk.mockk
import io.mockk.verify
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import javax.inject.Inject

@HiltAndroidTest
class MusikusBottomBarTest {

@Inject lateinit var fakeTimeProvider: FakeTimeProvider

@get:Rule(order = 0)
val hiltRule = HiltAndroidRule(this)

@get:Rule(order = 1)
val composeRule = createAndroidComposeRule<MainActivity>()

lateinit var navController: NavHostController

@Before
fun setUp() {
hiltRule.inject()
composeRule.activity.setContent {

val mainViewModel: MainViewModel = hiltViewModel()

val mainUiState by mainViewModel.uiState.collectAsStateWithLifecycle()
val eventHandler = mainViewModel::onUiEvent

navController = mockk<NavHostController>(relaxed = true)

MusikusBottomBar(
mainUiState = mainUiState,
mainEventHandler = eventHandler,
currentTab = HomeTab.Sessions,
onTabSelected = { selectedTab ->
navController.navigate(Screen.Home(selectedTab))
},
)
}
}

@Test
fun navigateToSessions() = runTest {
composeRule.onNodeWithText("Sessions").performClick()

// Since we are already on the sessions tab, we should not navigate
verify(exactly = 0) {
navController.navigate<Any>(any())
}
}

@Test
fun navigateToGoals() = runTest {
composeRule.onNodeWithText("Goals").performClick()

verify(exactly = 1) {
navController.navigate(Screen.Home(HomeTab.Goals))
}
}

@Test
fun navigateToStatistics() = runTest {
composeRule.onNodeWithText("Statistics").performClick()

verify(exactly = 1) {
navController.navigate(Screen.Home(HomeTab.Statistics))
}
}

@Test
fun navigateToLibrary() = runTest {
composeRule.onNodeWithText("Library").performClick()

verify(exactly = 1) {
navController.navigate(Screen.Home(HomeTab.Library))
}
}
}
Loading

0 comments on commit d368607

Please sign in to comment.