diff --git a/lib_utils/src/androidTest/java/no/nordicsemi/android/utils/ExampleInstrumentedTest.kt b/lib_utils/src/androidTest/java/no/nordicsemi/android/utils/ExampleInstrumentedTest.kt deleted file mode 100644 index f9a859af..00000000 --- a/lib_utils/src/androidTest/java/no/nordicsemi/android/utils/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -package no.nordicsemi.android.utils - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import org.junit.Assert.* -import org.junit.Test -import org.junit.runner.RunWith - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("no.nordicsemi.android.utils.test", appContext.packageName) - } -} \ No newline at end of file diff --git a/lib_utils/src/test/java/no/nordicsemi/android/utils/ExampleUnitTest.kt b/lib_utils/src/test/java/no/nordicsemi/android/utils/ExampleUnitTest.kt deleted file mode 100644 index 3468a2d2..00000000 --- a/lib_utils/src/test/java/no/nordicsemi/android/utils/ExampleUnitTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package no.nordicsemi.android.utils - -import org.junit.Assert.* -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file diff --git a/profile_bps/build.gradle b/profile_bps/build.gradle index 972f2937..c0a5b435 100644 --- a/profile_bps/build.gradle +++ b/profile_bps/build.gradle @@ -20,9 +20,5 @@ dependencies { implementation libs.compose.lifecycle implementation libs.compose.activity - testImplementation libs.test.junit - androidTestImplementation libs.android.test.junit - androidTestImplementation libs.android.test.espresso - androidTestImplementation libs.android.test.compose.ui - debugImplementation libs.android.test.compose.tooling + testImplementation libs.bundles.test } diff --git a/profile_bps/src/androidTest/java/no/nordicsemi/android/bps/ExampleInstrumentedTest.kt b/profile_bps/src/androidTest/java/no/nordicsemi/android/bps/ExampleInstrumentedTest.kt deleted file mode 100644 index 1d17d36c..00000000 --- a/profile_bps/src/androidTest/java/no/nordicsemi/android/bps/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -package no.nordicsemi.android.bps - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("no.nordicsemi.android.bps.test", appContext.packageName) - } -} \ No newline at end of file diff --git a/profile_bps/src/main/java/no/nordicsemi/android/bps/viewmodel/BPSViewModel.kt b/profile_bps/src/main/java/no/nordicsemi/android/bps/viewmodel/BPSViewModel.kt index 9dc9b2c5..dc5dbfbb 100644 --- a/profile_bps/src/main/java/no/nordicsemi/android/bps/viewmodel/BPSViewModel.kt +++ b/profile_bps/src/main/java/no/nordicsemi/android/bps/viewmodel/BPSViewModel.kt @@ -90,8 +90,11 @@ internal class BPSViewModel @Inject constructor( } private fun onDisconnectButtonClick() { - bpsManager.disconnect().enqueue() - repository.clear() + if (bpsManager.isConnected) { + bpsManager.disconnect().enqueue() + } else { + repository.setNewStatus(BleManagerStatus.DISCONNECTED) + } } override fun onCleared() { diff --git a/profile_bps/src/test/java/no/nordicsemi/android/bps/BPSViewModelTest.kt b/profile_bps/src/test/java/no/nordicsemi/android/bps/BPSViewModelTest.kt new file mode 100644 index 00000000..9d84cf8c --- /dev/null +++ b/profile_bps/src/test/java/no/nordicsemi/android/bps/BPSViewModelTest.kt @@ -0,0 +1,82 @@ +package no.nordicsemi.android.bps + +import io.mockk.every +import io.mockk.justRun +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.setMain +import no.nordicsemi.android.bps.data.BPSRepository +import no.nordicsemi.android.bps.repository.BPSManager +import no.nordicsemi.android.bps.view.DisconnectEvent +import no.nordicsemi.android.bps.viewmodel.BPSViewModel +import no.nordicsemi.android.navigation.NavigationManager +import no.nordicsemi.android.service.BleManagerStatus +import org.junit.After +import org.junit.Before +import org.junit.Test + +class BPSViewModelTest { + + val dispatcher = UnconfinedTestDispatcher() + + @Before + fun setup() { + Dispatchers.setMain(dispatcher) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + @Test + fun `check if navigation up called after disconnect event returns success`() { + val repository = BPSRepository() + val manager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + every { manager.isConnected } returns true + justRun { manager.setConnectionObserver(any()) } + justRun { manager.disconnect().enqueue() } + + val viewModel = BPSViewModel(manager, repository, navigationManager) + + viewModel.onEvent(DisconnectEvent) + + //Invoke by manager + repository.setNewStatus(BleManagerStatus.DISCONNECTED) + + verify { navigationManager.navigateUp() } + } + + @Test + fun `check if navigation up called after disconnect if manager not connected event returns success`() { + val repository = BPSRepository() + val manager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + every { manager.isConnected } returns false + justRun { manager.setConnectionObserver(any()) } + + val viewModel = BPSViewModel(manager, repository, navigationManager) + + viewModel.onEvent(DisconnectEvent) + + verify { navigationManager.navigateUp() } + } +} diff --git a/profile_bps/src/test/java/no/nordicsemi/android/bps/ExampleUnitTest.kt b/profile_bps/src/test/java/no/nordicsemi/android/bps/ExampleUnitTest.kt deleted file mode 100644 index 0d32bb2e..00000000 --- a/profile_bps/src/test/java/no/nordicsemi/android/bps/ExampleUnitTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package no.nordicsemi.android.bps - -import org.junit.Assert.assertEquals -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file diff --git a/profile_cgms/build.gradle b/profile_cgms/build.gradle index 7cc4f99e..ee04804e 100644 --- a/profile_cgms/build.gradle +++ b/profile_cgms/build.gradle @@ -21,9 +21,5 @@ dependencies { implementation libs.compose.lifecycle implementation libs.compose.activity - testImplementation libs.test.junit - androidTestImplementation libs.android.test.junit - androidTestImplementation libs.android.test.espresso - androidTestImplementation libs.android.test.compose.ui - debugImplementation libs.android.test.compose.tooling + testImplementation libs.bundles.test } diff --git a/profile_cgms/src/androidTest/java/no/nordicsemi/android/cgms/ExampleInstrumentedTest.kt b/profile_cgms/src/androidTest/java/no/nordicsemi/android/cgms/ExampleInstrumentedTest.kt deleted file mode 100644 index c66608ba..00000000 --- a/profile_cgms/src/androidTest/java/no/nordicsemi/android/cgms/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -package no.nordicsemi.android.cgms - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("no.nordicsemi.android.cgms.test", appContext.packageName) - } -} \ No newline at end of file diff --git a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/data/CGMRepository.kt b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/data/CGMRepository.kt index 3cf0cd2d..303f6645 100644 --- a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/data/CGMRepository.kt +++ b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/data/CGMRepository.kt @@ -1,11 +1,7 @@ package no.nordicsemi.android.cgms.data import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asSharedFlow -import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.* import no.nordicsemi.android.service.BleManagerStatus import javax.inject.Inject import javax.inject.Singleton @@ -35,7 +31,11 @@ internal class CGMRepository @Inject constructor() { } fun sendNewServiceCommand(workingMode: CGMServiceCommand) { - _command.tryEmit(workingMode) + if (_command.subscriptionCount.value > 0) { + _command.tryEmit(workingMode) + } else { + _status.tryEmit(BleManagerStatus.DISCONNECTED) + } } fun setNewStatus(status: BleManagerStatus) { diff --git a/profile_cgms/src/test/java/no/nordicsemi/android/cgms/CGMSViewModelTest.kt b/profile_cgms/src/test/java/no/nordicsemi/android/cgms/CGMSViewModelTest.kt new file mode 100644 index 00000000..4afa6cf4 --- /dev/null +++ b/profile_cgms/src/test/java/no/nordicsemi/android/cgms/CGMSViewModelTest.kt @@ -0,0 +1,77 @@ +package no.nordicsemi.android.cgms + +import io.mockk.every +import io.mockk.justRun +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.setMain +import no.nordicsemi.android.cgms.data.CGMRepository +import no.nordicsemi.android.cgms.view.DisconnectEvent +import no.nordicsemi.android.cgms.viewmodel.CGMScreenViewModel +import no.nordicsemi.android.navigation.NavigationManager +import no.nordicsemi.android.service.BleManagerStatus +import no.nordicsemi.android.service.ServiceManager +import org.junit.After +import org.junit.Before +import org.junit.Test + +class CGMSViewModelTest { + + val dispatcher = UnconfinedTestDispatcher() + + @Before + fun setup() { + Dispatchers.setMain(dispatcher) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + @Test + fun `check if navigation up called after disconnect event returns success`() { + val repository = CGMRepository() + val serviceManager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + + val viewModel = CGMScreenViewModel(repository, serviceManager, navigationManager) + + viewModel.onEvent(DisconnectEvent) + + //Invoke by remote service + repository.setNewStatus(BleManagerStatus.DISCONNECTED) + + verify { navigationManager.navigateUp() } + } + + @Test + fun `check if navigation up called after disconnect if no service started event returns success`() { + val repository = CGMRepository() + val serviceManager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + + val viewModel = CGMScreenViewModel(repository, serviceManager, navigationManager) + + viewModel.onEvent(DisconnectEvent) + + verify { navigationManager.navigateUp() } + } +} diff --git a/profile_cgms/src/test/java/no/nordicsemi/android/cgms/ExampleUnitTest.kt b/profile_cgms/src/test/java/no/nordicsemi/android/cgms/ExampleUnitTest.kt deleted file mode 100644 index 78c91bd8..00000000 --- a/profile_cgms/src/test/java/no/nordicsemi/android/cgms/ExampleUnitTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package no.nordicsemi.android.cgms - -import org.junit.Assert.assertEquals -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file diff --git a/profile_csc/build.gradle b/profile_csc/build.gradle index 286b2e1c..21f90c18 100644 --- a/profile_csc/build.gradle +++ b/profile_csc/build.gradle @@ -21,9 +21,5 @@ dependencies { implementation libs.compose.lifecycle implementation libs.compose.activity - testImplementation libs.test.junit - androidTestImplementation libs.android.test.junit - androidTestImplementation libs.android.test.espresso - androidTestImplementation libs.android.test.compose.ui - debugImplementation libs.android.test.compose.tooling + testImplementation libs.bundles.test } diff --git a/profile_csc/src/androidTest/java/no/nordicsemi/android/csc/ExampleInstrumentedTest.kt b/profile_csc/src/androidTest/java/no/nordicsemi/android/csc/ExampleInstrumentedTest.kt deleted file mode 100644 index 5795b0fb..00000000 --- a/profile_csc/src/androidTest/java/no/nordicsemi/android/csc/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -package no.nordicsemi.android.csc - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("no.nordicsemi.android.csc.test", appContext.packageName) - } -} \ No newline at end of file diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCRepository.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCRepository.kt index 446ef6f3..c451cd5f 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCRepository.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCRepository.kt @@ -50,7 +50,11 @@ internal class CSCRepository @Inject constructor() { } fun sendNewServiceCommand(workingMode: CSCServiceCommand) { - _command.tryEmit(workingMode) + if (_command.subscriptionCount.value > 0) { + _command.tryEmit(workingMode) + } else { + _status.tryEmit(BleManagerStatus.DISCONNECTED) + } } fun setNewStatus(status: BleManagerStatus) { diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/viewmodel/CSCViewModel.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/viewmodel/CSCViewModel.kt index 7f434e5d..ea15901e 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/viewmodel/CSCViewModel.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/viewmodel/CSCViewModel.kt @@ -74,7 +74,6 @@ internal class CSCViewModel @Inject constructor( private fun onDisconnectButtonClick() { repository.sendNewServiceCommand(DisconnectCommand) - repository.setNewStatus(BleManagerStatus.DISCONNECTED) repository.clear() } diff --git a/profile_csc/src/test/java/no/nordicsemi/android/csc/CSCViewModelTest.kt b/profile_csc/src/test/java/no/nordicsemi/android/csc/CSCViewModelTest.kt new file mode 100644 index 00000000..3b75f2ca --- /dev/null +++ b/profile_csc/src/test/java/no/nordicsemi/android/csc/CSCViewModelTest.kt @@ -0,0 +1,77 @@ +package no.nordicsemi.android.csc + +import io.mockk.every +import io.mockk.justRun +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.setMain +import no.nordicsemi.android.csc.data.CSCRepository +import no.nordicsemi.android.csc.view.OnDisconnectButtonClick +import no.nordicsemi.android.csc.viewmodel.CSCViewModel +import no.nordicsemi.android.navigation.NavigationManager +import no.nordicsemi.android.service.BleManagerStatus +import no.nordicsemi.android.service.ServiceManager +import org.junit.After +import org.junit.Before +import org.junit.Test + +class CSCViewModelTest { + + val dispatcher = UnconfinedTestDispatcher() + + @Before + fun setup() { + Dispatchers.setMain(dispatcher) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + @Test + fun `check if navigation up called after disconnect event returns success`() { + val repository = CSCRepository() + val serviceManager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + + val viewModel = CSCViewModel(repository, serviceManager, navigationManager) + + viewModel.onEvent(OnDisconnectButtonClick) + + //Invoke by remote service + repository.setNewStatus(BleManagerStatus.DISCONNECTED) + + verify { navigationManager.navigateUp() } + } + + @Test + fun `check if navigation up called after disconnect if no service started event returns success`() { + val repository = CSCRepository() + val serviceManager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + + val viewModel = CSCViewModel(repository, serviceManager, navigationManager) + + viewModel.onEvent(OnDisconnectButtonClick) + + verify { navigationManager.navigateUp() } + } +} diff --git a/profile_csc/src/test/java/no/nordicsemi/android/csc/ExampleUnitTest.kt b/profile_csc/src/test/java/no/nordicsemi/android/csc/ExampleUnitTest.kt deleted file mode 100644 index f140885a..00000000 --- a/profile_csc/src/test/java/no/nordicsemi/android/csc/ExampleUnitTest.kt +++ /dev/null @@ -1,23 +0,0 @@ -package no.nordicsemi.android.csc - -import androidx.annotation.FloatRange -import org.junit.Assert.assertEquals -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - - println("red: ${colorToHex(0f)}") - println("green: ${colorToHex(169f)}") - println("blue: ${colorToHex(206f)}") - assertEquals(4, 2 + 2) - } - - private fun colorToHex(@FloatRange(from = 0.0, to = 1.0) value: Float) = Integer.toHexString((0xFF * value).toInt()) -} \ No newline at end of file diff --git a/profile_gls/build.gradle b/profile_gls/build.gradle index 8be488cc..31c9dccd 100644 --- a/profile_gls/build.gradle +++ b/profile_gls/build.gradle @@ -23,9 +23,5 @@ dependencies { implementation libs.compose.lifecycle implementation libs.compose.activity - testImplementation libs.test.junit - androidTestImplementation libs.android.test.junit - androidTestImplementation libs.android.test.espresso - androidTestImplementation libs.android.test.compose.ui - debugImplementation libs.android.test.compose.tooling + testImplementation libs.bundles.test } diff --git a/profile_gls/src/androidTest/java/no/nordicsemi/android/gls/ExampleInstrumentedTest.kt b/profile_gls/src/androidTest/java/no/nordicsemi/android/gls/ExampleInstrumentedTest.kt deleted file mode 100644 index 0514c1e8..00000000 --- a/profile_gls/src/androidTest/java/no/nordicsemi/android/gls/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -package no.nordicsemi.android.gls - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("no.nordicsemi.android.gls.test", appContext.packageName) - } -} \ No newline at end of file diff --git a/profile_gls/src/main/java/no/nordicsemi/android/gls/main/viewmodel/GLSViewModel.kt b/profile_gls/src/main/java/no/nordicsemi/android/gls/main/viewmodel/GLSViewModel.kt index baada734..cf7f4ff0 100644 --- a/profile_gls/src/main/java/no/nordicsemi/android/gls/main/viewmodel/GLSViewModel.kt +++ b/profile_gls/src/main/java/no/nordicsemi/android/gls/main/viewmodel/GLSViewModel.kt @@ -99,7 +99,11 @@ internal class GLSViewModel @Inject constructor( } private fun disconnect() { - glsManager.disconnect().enqueue() + if (glsManager.isConnected) { + glsManager.disconnect().enqueue() + } else { + repository.setNewStatus(BleManagerStatus.DISCONNECTED) + } } override fun onCleared() { diff --git a/profile_gls/src/test/java/no/nordicsemi/android/gls/ExampleUnitTest.kt b/profile_gls/src/test/java/no/nordicsemi/android/gls/ExampleUnitTest.kt deleted file mode 100644 index a1f4e631..00000000 --- a/profile_gls/src/test/java/no/nordicsemi/android/gls/ExampleUnitTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package no.nordicsemi.android.gls - -import org.junit.Assert.assertEquals -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file diff --git a/profile_gls/src/test/java/no/nordicsemi/android/gls/GLSViewModelTest.kt b/profile_gls/src/test/java/no/nordicsemi/android/gls/GLSViewModelTest.kt new file mode 100644 index 00000000..34be5f2e --- /dev/null +++ b/profile_gls/src/test/java/no/nordicsemi/android/gls/GLSViewModelTest.kt @@ -0,0 +1,82 @@ +package no.nordicsemi.android.gls + +import io.mockk.every +import io.mockk.justRun +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.setMain +import no.nordicsemi.android.gls.data.GLSRepository +import no.nordicsemi.android.gls.main.view.DisconnectEvent +import no.nordicsemi.android.gls.main.viewmodel.GLSViewModel +import no.nordicsemi.android.gls.repository.GLSManager +import no.nordicsemi.android.navigation.NavigationManager +import no.nordicsemi.android.service.BleManagerStatus +import org.junit.After +import org.junit.Before +import org.junit.Test + +class GLSViewModelTest { + + val dispatcher = UnconfinedTestDispatcher() + + @Before + fun setup() { + Dispatchers.setMain(dispatcher) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + @Test + fun `check if navigation up called after disconnect event returns success`() { + val repository = GLSRepository() + val manager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + every { manager.isConnected } returns true + justRun { manager.setConnectionObserver(any()) } + justRun { manager.disconnect().enqueue() } + + val viewModel = GLSViewModel(manager, repository, navigationManager) + + viewModel.onEvent(DisconnectEvent) + + //Invoke by manager + repository.setNewStatus(BleManagerStatus.DISCONNECTED) + + verify { navigationManager.navigateUp() } + } + + @Test + fun `check if navigation up called after disconnect if manager not connected event returns success`() { + val repository = GLSRepository() + val manager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + every { manager.isConnected } returns false + justRun { manager.setConnectionObserver(any()) } + + val viewModel = GLSViewModel(manager, repository, navigationManager) + + viewModel.onEvent(DisconnectEvent) + + verify { navigationManager.navigateUp() } + } +} diff --git a/profile_hrs/build.gradle b/profile_hrs/build.gradle index 8d0cc6e7..c7950cf7 100644 --- a/profile_hrs/build.gradle +++ b/profile_hrs/build.gradle @@ -21,10 +21,7 @@ dependencies { implementation libs.lifecycle.service implementation libs.compose.lifecycle implementation libs.compose.activity + implementation libs.kotlin.coroutines - testImplementation libs.test.junit - androidTestImplementation libs.android.test.junit - androidTestImplementation libs.android.test.espresso - androidTestImplementation libs.android.test.compose.ui - debugImplementation libs.android.test.compose.tooling + testImplementation libs.bundles.test } diff --git a/profile_hrs/src/androidTest/java/no/nordicsemi/android/hrs/ExampleInstrumentedTest.kt b/profile_hrs/src/androidTest/java/no/nordicsemi/android/hrs/ExampleInstrumentedTest.kt deleted file mode 100644 index c51579ce..00000000 --- a/profile_hrs/src/androidTest/java/no/nordicsemi/android/hrs/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -package no.nordicsemi.android.hrs - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("no.nordicsemi.android.hrs.test", appContext.packageName) - } -} \ No newline at end of file diff --git a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/data/HRSRepository.kt b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/data/HRSRepository.kt index d0a9eee2..6f1c049c 100644 --- a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/data/HRSRepository.kt +++ b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/data/HRSRepository.kt @@ -1,11 +1,7 @@ package no.nordicsemi.android.hrs.data import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asSharedFlow -import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.* import no.nordicsemi.android.service.BleManagerStatus import javax.inject.Inject import javax.inject.Singleton @@ -38,7 +34,11 @@ internal class HRSRepository @Inject constructor() { } fun sendDisconnectCommand() { - _command.tryEmit(DisconnectCommand) + if (_command.subscriptionCount.value > 0) { + _command.tryEmit(DisconnectCommand) + } else { + _status.tryEmit(BleManagerStatus.DISCONNECTED) + } } fun setNewStatus(status: BleManagerStatus) { diff --git a/profile_hrs/src/test/java/no/nordicsemi/android/hrs/ExampleUnitTest.kt b/profile_hrs/src/test/java/no/nordicsemi/android/hrs/ExampleUnitTest.kt deleted file mode 100644 index c4a005a9..00000000 --- a/profile_hrs/src/test/java/no/nordicsemi/android/hrs/ExampleUnitTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package no.nordicsemi.android.hrs - -import org.junit.Assert.assertEquals -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file diff --git a/profile_hrs/src/test/java/no/nordicsemi/android/hrs/HRSViewModelTest.kt b/profile_hrs/src/test/java/no/nordicsemi/android/hrs/HRSViewModelTest.kt new file mode 100644 index 00000000..6fb516c0 --- /dev/null +++ b/profile_hrs/src/test/java/no/nordicsemi/android/hrs/HRSViewModelTest.kt @@ -0,0 +1,77 @@ +package no.nordicsemi.android.hrs + +import io.mockk.every +import io.mockk.justRun +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.setMain +import no.nordicsemi.android.hrs.data.HRSRepository +import no.nordicsemi.android.hrs.view.DisconnectEvent +import no.nordicsemi.android.hrs.viewmodel.HRSViewModel +import no.nordicsemi.android.navigation.NavigationManager +import no.nordicsemi.android.service.BleManagerStatus +import no.nordicsemi.android.service.ServiceManager +import org.junit.After +import org.junit.Before +import org.junit.Test + +class HRSViewModelTest { + + val dispatcher = UnconfinedTestDispatcher() + + @Before + fun setup() { + Dispatchers.setMain(dispatcher) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + @Test + fun `check if navigation up called after disconnect event returns success`() { + val repository = HRSRepository() + val serviceManager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + + val viewModel = HRSViewModel(repository, serviceManager, navigationManager) + + viewModel.onEvent(DisconnectEvent) + + //Invoke by remote service + repository.setNewStatus(BleManagerStatus.DISCONNECTED) + + verify { navigationManager.navigateUp() } + } + + @Test + fun `check if navigation up called after disconnect if no service started event returns success`() { + val repository = HRSRepository() + val serviceManager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + + val viewModel = HRSViewModel(repository, serviceManager, navigationManager) + + viewModel.onEvent(DisconnectEvent) + + verify { navigationManager.navigateUp() } + } +} \ No newline at end of file diff --git a/profile_hts/build.gradle b/profile_hts/build.gradle index 7cc4f99e..ee04804e 100644 --- a/profile_hts/build.gradle +++ b/profile_hts/build.gradle @@ -21,9 +21,5 @@ dependencies { implementation libs.compose.lifecycle implementation libs.compose.activity - testImplementation libs.test.junit - androidTestImplementation libs.android.test.junit - androidTestImplementation libs.android.test.espresso - androidTestImplementation libs.android.test.compose.ui - debugImplementation libs.android.test.compose.tooling + testImplementation libs.bundles.test } diff --git a/profile_hts/src/androidTest/java/no/nordicsemi/android/hts/ExampleInstrumentedTest.kt b/profile_hts/src/androidTest/java/no/nordicsemi/android/hts/ExampleInstrumentedTest.kt deleted file mode 100644 index 1b48241c..00000000 --- a/profile_hts/src/androidTest/java/no/nordicsemi/android/hts/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -package no.nordicsemi.android.hts - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("no.nordicsemi.android.hts.test", appContext.packageName) - } -} \ No newline at end of file diff --git a/profile_hts/src/main/java/no/nordicsemi/android/hts/data/HTSRepository.kt b/profile_hts/src/main/java/no/nordicsemi/android/hts/data/HTSRepository.kt index cb056da3..d5b726ee 100644 --- a/profile_hts/src/main/java/no/nordicsemi/android/hts/data/HTSRepository.kt +++ b/profile_hts/src/main/java/no/nordicsemi/android/hts/data/HTSRepository.kt @@ -1,11 +1,7 @@ package no.nordicsemi.android.hts.data import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asSharedFlow -import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.* import no.nordicsemi.android.service.BleManagerStatus import javax.inject.Inject import javax.inject.Singleton @@ -35,7 +31,11 @@ internal class HTSRepository @Inject constructor() { } fun sendDisconnectCommand() { - _command.tryEmit(DisconnectCommand) + if (_command.subscriptionCount.value > 0) { + _command.tryEmit(DisconnectCommand) + } else { + _status.tryEmit(BleManagerStatus.DISCONNECTED) + } } fun setNewStatus(status: BleManagerStatus) { diff --git a/profile_hts/src/test/java/no/nordicsemi/android/hts/ExampleUnitTest.kt b/profile_hts/src/test/java/no/nordicsemi/android/hts/ExampleUnitTest.kt deleted file mode 100644 index 5468079d..00000000 --- a/profile_hts/src/test/java/no/nordicsemi/android/hts/ExampleUnitTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package no.nordicsemi.android.hts - -import org.junit.Assert.assertEquals -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file diff --git a/profile_hts/src/test/java/no/nordicsemi/android/hts/HTSViewModelTest.kt b/profile_hts/src/test/java/no/nordicsemi/android/hts/HTSViewModelTest.kt new file mode 100644 index 00000000..782137a1 --- /dev/null +++ b/profile_hts/src/test/java/no/nordicsemi/android/hts/HTSViewModelTest.kt @@ -0,0 +1,77 @@ +package no.nordicsemi.android.hts + +import io.mockk.every +import io.mockk.justRun +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.setMain +import no.nordicsemi.android.hts.data.HTSRepository +import no.nordicsemi.android.hts.view.DisconnectEvent +import no.nordicsemi.android.hts.viewmodel.HTSViewModel +import no.nordicsemi.android.navigation.NavigationManager +import no.nordicsemi.android.service.BleManagerStatus +import no.nordicsemi.android.service.ServiceManager +import org.junit.After +import org.junit.Before +import org.junit.Test + +class HTSViewModelTest { + + val dispatcher = UnconfinedTestDispatcher() + + @Before + fun setup() { + Dispatchers.setMain(dispatcher) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + @Test + fun `check if navigation up called after disconnect event returns success`() { + val repository = HTSRepository() + val serviceManager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + + val viewModel = HTSViewModel(repository, serviceManager, navigationManager) + + viewModel.onEvent(DisconnectEvent) + + //Invoke by remote service + repository.setNewStatus(BleManagerStatus.DISCONNECTED) + + verify { navigationManager.navigateUp() } + } + + @Test + fun `check if navigation up called after disconnect if no service started event returns success`() { + val repository = HTSRepository() + val serviceManager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + + val viewModel = HTSViewModel(repository, serviceManager, navigationManager) + + viewModel.onEvent(DisconnectEvent) + + verify { navigationManager.navigateUp() } + } +} \ No newline at end of file diff --git a/profile_prx/build.gradle b/profile_prx/build.gradle index c8350305..4da933f5 100644 --- a/profile_prx/build.gradle +++ b/profile_prx/build.gradle @@ -20,9 +20,5 @@ dependencies { implementation libs.compose.lifecycle implementation libs.compose.activity - testImplementation libs.test.junit - androidTestImplementation libs.android.test.junit - androidTestImplementation libs.android.test.espresso - androidTestImplementation libs.android.test.compose.ui - debugImplementation libs.android.test.compose.tooling + testImplementation libs.bundles.test } diff --git a/profile_prx/src/androidTest/java/no/nordicsemi/android/prx/ExampleInstrumentedTest.kt b/profile_prx/src/androidTest/java/no/nordicsemi/android/prx/ExampleInstrumentedTest.kt deleted file mode 100644 index d446cd60..00000000 --- a/profile_prx/src/androidTest/java/no/nordicsemi/android/prx/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -package no.nordicsemi.android.prx - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("no.nordicsemi.android.prx.test", appContext.packageName) - } -} \ No newline at end of file diff --git a/profile_prx/src/main/AndroidManifest.xml b/profile_prx/src/main/AndroidManifest.xml index 26bf6b9c..257c562d 100644 --- a/profile_prx/src/main/AndroidManifest.xml +++ b/profile_prx/src/main/AndroidManifest.xml @@ -3,6 +3,6 @@ package="no.nordicsemi.android.prx"> - + diff --git a/profile_prx/src/main/java/no/nordicsemi/android/prx/data/PRXRepository.kt b/profile_prx/src/main/java/no/nordicsemi/android/prx/data/PRXRepository.kt index 8e28da2a..e4b3bff3 100644 --- a/profile_prx/src/main/java/no/nordicsemi/android/prx/data/PRXRepository.kt +++ b/profile_prx/src/main/java/no/nordicsemi/android/prx/data/PRXRepository.kt @@ -1,11 +1,7 @@ package no.nordicsemi.android.prx.data import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asSharedFlow -import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.* import no.nordicsemi.android.service.BleManagerStatus import javax.inject.Inject import javax.inject.Singleton @@ -36,7 +32,11 @@ internal class PRXRepository @Inject constructor() { } fun invokeCommand(command: PRXCommand) { - _command.tryEmit(command) + if (_command.subscriptionCount.value > 0) { + _command.tryEmit(command) + } else { + _status.tryEmit(BleManagerStatus.DISCONNECTED) + } } fun setNewStatus(status: BleManagerStatus) { diff --git a/profile_prx/src/main/java/no/nordicsemi/android/prx/service/AlarmHandler.kt b/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/AlarmHandler.kt similarity index 97% rename from profile_prx/src/main/java/no/nordicsemi/android/prx/service/AlarmHandler.kt rename to profile_prx/src/main/java/no/nordicsemi/android/prx/repository/AlarmHandler.kt index c1eac501..8a1aedb2 100644 --- a/profile_prx/src/main/java/no/nordicsemi/android/prx/service/AlarmHandler.kt +++ b/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/AlarmHandler.kt @@ -1,4 +1,4 @@ -package no.nordicsemi.android.prx.service +package no.nordicsemi.android.prx.repository import android.content.Context import android.media.AudioManager diff --git a/profile_prx/src/main/java/no/nordicsemi/android/prx/service/PRXManager.kt b/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/PRXManager.kt similarity index 99% rename from profile_prx/src/main/java/no/nordicsemi/android/prx/service/PRXManager.kt rename to profile_prx/src/main/java/no/nordicsemi/android/prx/repository/PRXManager.kt index f9c52a10..b9e8ed75 100644 --- a/profile_prx/src/main/java/no/nordicsemi/android/prx/service/PRXManager.kt +++ b/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/PRXManager.kt @@ -19,7 +19,7 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package no.nordicsemi.android.prx.service +package no.nordicsemi.android.prx.repository import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothGatt diff --git a/profile_prx/src/main/java/no/nordicsemi/android/prx/service/PRXService.kt b/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/PRXService.kt similarity index 97% rename from profile_prx/src/main/java/no/nordicsemi/android/prx/service/PRXService.kt rename to profile_prx/src/main/java/no/nordicsemi/android/prx/repository/PRXService.kt index e2bdb80f..9f50c1bb 100644 --- a/profile_prx/src/main/java/no/nordicsemi/android/prx/service/PRXService.kt +++ b/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/PRXService.kt @@ -1,4 +1,4 @@ -package no.nordicsemi.android.prx.service +package no.nordicsemi.android.prx.repository import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.launchIn diff --git a/profile_prx/src/main/java/no/nordicsemi/android/prx/service/ProximityServerManager.kt b/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/ProximityServerManager.kt similarity index 98% rename from profile_prx/src/main/java/no/nordicsemi/android/prx/service/ProximityServerManager.kt rename to profile_prx/src/main/java/no/nordicsemi/android/prx/repository/ProximityServerManager.kt index 9cf3bbda..756b6256 100644 --- a/profile_prx/src/main/java/no/nordicsemi/android/prx/service/ProximityServerManager.kt +++ b/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/ProximityServerManager.kt @@ -19,7 +19,7 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package no.nordicsemi.android.prx.service +package no.nordicsemi.android.prx.repository import android.bluetooth.BluetoothGattCharacteristic import android.bluetooth.BluetoothGattService diff --git a/profile_prx/src/main/java/no/nordicsemi/android/prx/viewmodel/PRXViewModel.kt b/profile_prx/src/main/java/no/nordicsemi/android/prx/viewmodel/PRXViewModel.kt index d93565d0..9b1c7b2a 100644 --- a/profile_prx/src/main/java/no/nordicsemi/android/prx/viewmodel/PRXViewModel.kt +++ b/profile_prx/src/main/java/no/nordicsemi/android/prx/viewmodel/PRXViewModel.kt @@ -9,8 +9,8 @@ import no.nordicsemi.android.prx.data.DisableAlarm import no.nordicsemi.android.prx.data.Disconnect import no.nordicsemi.android.prx.data.EnableAlarm import no.nordicsemi.android.prx.data.PRXRepository -import no.nordicsemi.android.prx.service.PRXService -import no.nordicsemi.android.prx.service.PRX_SERVICE_UUID +import no.nordicsemi.android.prx.repository.PRXService +import no.nordicsemi.android.prx.repository.PRX_SERVICE_UUID import no.nordicsemi.android.prx.view.* import no.nordicsemi.android.service.BleManagerStatus import no.nordicsemi.android.service.ServiceManager diff --git a/profile_prx/src/test/java/no/nordicsemi/android/prx/ExampleUnitTest.kt b/profile_prx/src/test/java/no/nordicsemi/android/prx/ExampleUnitTest.kt deleted file mode 100644 index 03ecdc2a..00000000 --- a/profile_prx/src/test/java/no/nordicsemi/android/prx/ExampleUnitTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package no.nordicsemi.android.prx - -import org.junit.Assert.assertEquals -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file diff --git a/profile_prx/src/test/java/no/nordicsemi/android/prx/PRXViewModelTest.kt b/profile_prx/src/test/java/no/nordicsemi/android/prx/PRXViewModelTest.kt new file mode 100644 index 00000000..7c01ce59 --- /dev/null +++ b/profile_prx/src/test/java/no/nordicsemi/android/prx/PRXViewModelTest.kt @@ -0,0 +1,77 @@ +package no.nordicsemi.android.prx + +import io.mockk.every +import io.mockk.justRun +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.setMain +import no.nordicsemi.android.navigation.NavigationManager +import no.nordicsemi.android.prx.data.PRXRepository +import no.nordicsemi.android.prx.view.DisconnectEvent +import no.nordicsemi.android.prx.viewmodel.PRXViewModel +import no.nordicsemi.android.service.BleManagerStatus +import no.nordicsemi.android.service.ServiceManager +import org.junit.After +import org.junit.Before +import org.junit.Test + +class PRXViewModelTest { + + val dispatcher = UnconfinedTestDispatcher() + + @Before + fun setup() { + Dispatchers.setMain(dispatcher) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + @Test + fun `check if navigation up called after disconnect event returns success`() { + val repository = PRXRepository() + val serviceManager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + + val viewModel = PRXViewModel(repository, serviceManager, navigationManager) + + viewModel.onEvent(DisconnectEvent) + + //Invoke by remote service + repository.setNewStatus(BleManagerStatus.DISCONNECTED) + + verify { navigationManager.navigateUp() } + } + + @Test + fun `check if navigation up called after disconnect if no service started event returns success`() { + val repository = PRXRepository() + val serviceManager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + + val viewModel = PRXViewModel(repository, serviceManager, navigationManager) + + viewModel.onEvent(DisconnectEvent) + + verify { navigationManager.navigateUp() } + } +} \ No newline at end of file diff --git a/profile_rscs/build.gradle b/profile_rscs/build.gradle index c8350305..4da933f5 100644 --- a/profile_rscs/build.gradle +++ b/profile_rscs/build.gradle @@ -20,9 +20,5 @@ dependencies { implementation libs.compose.lifecycle implementation libs.compose.activity - testImplementation libs.test.junit - androidTestImplementation libs.android.test.junit - androidTestImplementation libs.android.test.espresso - androidTestImplementation libs.android.test.compose.ui - debugImplementation libs.android.test.compose.tooling + testImplementation libs.bundles.test } diff --git a/profile_rscs/src/androidTest/java/no/nordicsemi/android/rscs/ExampleInstrumentedTest.kt b/profile_rscs/src/androidTest/java/no/nordicsemi/android/rscs/ExampleInstrumentedTest.kt deleted file mode 100644 index 169f65bb..00000000 --- a/profile_rscs/src/androidTest/java/no/nordicsemi/android/rscs/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -package no.nordicsemi.android.rscs - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("no.nordicsemi.android.rscs.test", appContext.packageName) - } -} \ No newline at end of file diff --git a/profile_rscs/src/main/AndroidManifest.xml b/profile_rscs/src/main/AndroidManifest.xml index 896ad954..8280717d 100644 --- a/profile_rscs/src/main/AndroidManifest.xml +++ b/profile_rscs/src/main/AndroidManifest.xml @@ -3,6 +3,6 @@ package="no.nordicsemi.android.rscs"> - + diff --git a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/data/RSCSRepository.kt b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/data/RSCSRepository.kt index 1e147ce1..4c3ff12e 100644 --- a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/data/RSCSRepository.kt +++ b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/data/RSCSRepository.kt @@ -1,11 +1,7 @@ package no.nordicsemi.android.rscs.data import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asSharedFlow -import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.* import no.nordicsemi.android.service.BleManagerStatus import javax.inject.Inject import javax.inject.Singleton @@ -47,7 +43,11 @@ internal class RSCSRepository @Inject constructor() { } fun sendDisconnectCommand() { - _command.tryEmit(DisconnectCommand) + if (_command.subscriptionCount.value > 0) { + _command.tryEmit(DisconnectCommand) + } else { + _status.tryEmit(BleManagerStatus.DISCONNECTED) + } } fun clear() { diff --git a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/service/RSCSManager.kt b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSManager.kt similarity index 98% rename from profile_rscs/src/main/java/no/nordicsemi/android/rscs/service/RSCSManager.kt rename to profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSManager.kt index a84847db..7195992f 100644 --- a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/service/RSCSManager.kt +++ b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSManager.kt @@ -19,7 +19,7 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package no.nordicsemi.android.rscs.service +package no.nordicsemi.android.rscs.repository import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothGatt diff --git a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/service/RSCSService.kt b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSService.kt similarity index 93% rename from profile_rscs/src/main/java/no/nordicsemi/android/rscs/service/RSCSService.kt rename to profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSService.kt index 800a493b..38a3223d 100644 --- a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/service/RSCSService.kt +++ b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSService.kt @@ -1,4 +1,4 @@ -package no.nordicsemi.android.rscs.service +package no.nordicsemi.android.rscs.repository import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.launchIn diff --git a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/viewmodel/RSCSViewModel.kt b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/viewmodel/RSCSViewModel.kt index 14f5f967..7a97e43a 100644 --- a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/viewmodel/RSCSViewModel.kt +++ b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/viewmodel/RSCSViewModel.kt @@ -6,8 +6,8 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.* import no.nordicsemi.android.navigation.* import no.nordicsemi.android.rscs.data.RSCSRepository -import no.nordicsemi.android.rscs.service.RSCSService -import no.nordicsemi.android.rscs.service.RSCS_SERVICE_UUID +import no.nordicsemi.android.rscs.repository.RSCSService +import no.nordicsemi.android.rscs.repository.RSCS_SERVICE_UUID import no.nordicsemi.android.rscs.view.DisconnectEvent import no.nordicsemi.android.rscs.view.DisplayDataState import no.nordicsemi.android.rscs.view.LoadingState diff --git a/profile_rscs/src/test/java/no/nordicsemi/android/rscs/ExampleUnitTest.kt b/profile_rscs/src/test/java/no/nordicsemi/android/rscs/ExampleUnitTest.kt deleted file mode 100644 index bf6cceb1..00000000 --- a/profile_rscs/src/test/java/no/nordicsemi/android/rscs/ExampleUnitTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package no.nordicsemi.android.rscs - -import org.junit.Assert.assertEquals -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file diff --git a/profile_rscs/src/test/java/no/nordicsemi/android/rscs/RSCSViewModelTest.kt b/profile_rscs/src/test/java/no/nordicsemi/android/rscs/RSCSViewModelTest.kt new file mode 100644 index 00000000..7ec24860 --- /dev/null +++ b/profile_rscs/src/test/java/no/nordicsemi/android/rscs/RSCSViewModelTest.kt @@ -0,0 +1,77 @@ +package no.nordicsemi.android.rscs + +import io.mockk.every +import io.mockk.justRun +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.setMain +import no.nordicsemi.android.navigation.NavigationManager +import no.nordicsemi.android.rscs.data.RSCSRepository +import no.nordicsemi.android.rscs.view.DisconnectEvent +import no.nordicsemi.android.rscs.viewmodel.RSCSViewModel +import no.nordicsemi.android.service.BleManagerStatus +import no.nordicsemi.android.service.ServiceManager +import org.junit.After +import org.junit.Before +import org.junit.Test + +class RSCSViewModelTest { + + val dispatcher = UnconfinedTestDispatcher() + + @Before + fun setup() { + Dispatchers.setMain(dispatcher) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + @Test + fun `check if navigation up called after disconnect event returns success`() { + val repository = RSCSRepository() + val serviceManager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + + val viewModel = RSCSViewModel(repository, serviceManager, navigationManager) + + viewModel.onEvent(DisconnectEvent) + + //Invoke by remote service + repository.setNewStatus(BleManagerStatus.DISCONNECTED) + + verify { navigationManager.navigateUp() } + } + + @Test + fun `check if navigation up called after disconnect if no service started event returns success`() { + val repository = RSCSRepository() + val serviceManager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + + val viewModel = RSCSViewModel(repository, serviceManager, navigationManager) + + viewModel.onEvent(DisconnectEvent) + + verify { navigationManager.navigateUp() } + } +} \ No newline at end of file diff --git a/profile_uart/build.gradle b/profile_uart/build.gradle index 18e90c33..ee04804e 100644 --- a/profile_uart/build.gradle +++ b/profile_uart/build.gradle @@ -20,4 +20,6 @@ dependencies { implementation libs.lifecycle.service implementation libs.compose.lifecycle implementation libs.compose.activity + + testImplementation libs.bundles.test } diff --git a/profile_uart/src/main/java/no/nordicsemi/android/uart/data/UARTRepository.kt b/profile_uart/src/main/java/no/nordicsemi/android/uart/data/UARTRepository.kt index 6713af34..a8b75b47 100644 --- a/profile_uart/src/main/java/no/nordicsemi/android/uart/data/UARTRepository.kt +++ b/profile_uart/src/main/java/no/nordicsemi/android/uart/data/UARTRepository.kt @@ -41,7 +41,11 @@ internal class UARTRepository @Inject constructor() { } fun sendNewCommand(command: UARTServiceCommand) { - _command.tryEmit(command) + if (_command.subscriptionCount.value > 0) { + _command.tryEmit(command) + } else { + _status.tryEmit(BleManagerStatus.DISCONNECTED) + } } fun setNewStatus(status: BleManagerStatus) { diff --git a/profile_uart/src/test/java/no/nordicsemi/android/gls/UARTViewModelTest.kt b/profile_uart/src/test/java/no/nordicsemi/android/gls/UARTViewModelTest.kt new file mode 100644 index 00000000..1d49f19a --- /dev/null +++ b/profile_uart/src/test/java/no/nordicsemi/android/gls/UARTViewModelTest.kt @@ -0,0 +1,77 @@ +package no.nordicsemi.android.gls + +import io.mockk.every +import io.mockk.justRun +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.setMain +import no.nordicsemi.android.navigation.NavigationManager +import no.nordicsemi.android.service.BleManagerStatus +import no.nordicsemi.android.service.ServiceManager +import no.nordicsemi.android.uart.data.UARTRepository +import no.nordicsemi.android.uart.view.OnDisconnectButtonClick +import no.nordicsemi.android.uart.viewmodel.UARTViewModel +import org.junit.After +import org.junit.Before +import org.junit.Test + +class UARTViewModelTest { + + val dispatcher = UnconfinedTestDispatcher() + + @Before + fun setup() { + Dispatchers.setMain(dispatcher) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + @Test + fun `check if navigation up called after disconnect event returns success`() { + val repository = UARTRepository() + val serviceManager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + + val viewModel = UARTViewModel(repository, serviceManager, navigationManager) + + viewModel.onEvent(OnDisconnectButtonClick) + + //Invoke by remote service + repository.setNewStatus(BleManagerStatus.DISCONNECTED) + + verify { navigationManager.navigateUp() } + } + + @Test + fun `check if navigation up called after disconnect if no service started event returns success`() { + val repository = UARTRepository() + val serviceManager = mockk() + val navigationManager = mockk() + + every { navigationManager.recentResult } returns MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + justRun { navigationManager.navigateTo(any(), any()) } + + val viewModel = UARTViewModel(repository, serviceManager, navigationManager) + + viewModel.onEvent(OnDisconnectButtonClick) + + verify { navigationManager.navigateUp() } + } +} diff --git a/settings.gradle b/settings.gradle index 680ce5b1..399ce200 100644 --- a/settings.gradle +++ b/settings.gradle @@ -60,6 +60,11 @@ dependencyResolutionManagement { alias('android-test-espresso').to('androidx.test.espresso:espresso-core:3.4.0') alias('android-test-compose-ui').to('androidx.compose.ui', 'ui-test-junit4').versionRef('compose') alias('android-test-compose-tooling').to('androidx.compose.ui', 'ui-tooling').versionRef('compose') + + alias('mockk-main').to('io.mockk:mockk:1.12.2') + alias('mockk-jvm').to('io.mockk:mockk-agent-jvm:1.12.2') + alias('test-coroutines').to('org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0') + bundle('test', ['test-junit', 'android-test-junit', 'mockk-main', 'mockk-jvm', 'test-coroutines']) } } }