Skip to content

Commit 997ba6c

Browse files
committed
Add API level checks
1 parent 55a520f commit 997ba6c

File tree

1 file changed

+46
-4
lines changed

1 file changed

+46
-4
lines changed

firebase-ai/src/test/java/com/google/firebase/ai/type/LiveSessionTest.kt

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,21 @@ package com.google.firebase.ai.type
1919
import android.Manifest
2020
import android.content.Context
2121
import android.content.pm.PackageManager
22+
import android.os.Build
2223
import com.google.firebase.ai.common.PermissionMissingException
2324
import io.ktor.client.plugins.websocket.ClientWebSocketSession
2425
import kotlin.coroutines.CoroutineContext
2526
import kotlinx.coroutines.ExperimentalCoroutinesApi
2627
import kotlinx.coroutines.test.UnconfinedTestDispatcher
2728
import kotlinx.coroutines.test.runTest
29+
import org.junit.After
2830
import org.junit.Assert.assertEquals
2931
import org.junit.Assert.assertThrows
3032
import org.junit.Before
3133
import org.junit.Test
3234
import org.junit.runner.RunWith
3335
import org.mockito.Mock
36+
import org.mockito.MockedStatic
3437
import org.mockito.Mockito.mockStatic
3538
import org.mockito.Mockito.`when`
3639
import org.mockito.junit.MockitoJUnitRunner
@@ -44,25 +47,39 @@ class LiveSessionTest {
4447
@Mock private lateinit var mockSession: ClientWebSocketSession
4548
@Mock private lateinit var mockAudioHelper: AudioHelper
4649

50+
private lateinit var mockedBuildVersion: MockedStatic<Build.VERSION>
4751
private lateinit var testDispatcher: CoroutineContext
4852
private lateinit var liveSession: LiveSession
4953

5054
@Before
5155
fun setUp() {
5256
testDispatcher = UnconfinedTestDispatcher()
5357
`when`(mockContext.packageManager).thenReturn(mockPackageManager)
58+
mockedBuildVersion = mockStatic(Build.VERSION::class.java)
5459

5560
// Mock AudioHelper.build() to return our mockAudioHelper
5661
// Need to use mockStatic for static methods
57-
mockStatic(AudioHelper::class.java).use { mockedAudioHelper ->
58-
mockedAudioHelper.`when`<AudioHelper> { AudioHelper.build() }.thenReturn(mockAudioHelper)
62+
// Note: It's generally better to manage static mocks with try-with-resources or @ExtendWith if
63+
// the runner supports it well, but for this structure, @Before/@After is common.
64+
// AudioHelper static mock is managed with try-with-resources where it's used for instance
65+
// creation.
66+
mockStatic(AudioHelper::class.java).use { mockedAudioHelperStatic ->
67+
mockedAudioHelperStatic
68+
.`when`<AudioHelper> { AudioHelper.build() }
69+
.thenReturn(mockAudioHelper)
5970
liveSession = LiveSession(mockContext, mockSession, testDispatcher, null)
6071
}
6172
}
6273

74+
@After
75+
fun tearDown() {
76+
mockedBuildVersion.close()
77+
}
78+
6379
@Test
64-
fun `startAudioConversation with RECORD_AUDIO permission proceeds normally`() = runTest {
80+
fun `startAudioConversation on API M+ with permission proceeds normally`() = runTest {
6581
// Arrange
82+
mockedBuildVersion.`when` { Build.VERSION.SDK_INT }.thenReturn(Build.VERSION_CODES.M)
6683
`when`(mockContext.checkSelfPermission(Manifest.permission.RECORD_AUDIO))
6784
.thenReturn(PackageManager.PERMISSION_GRANTED)
6885

@@ -72,9 +89,10 @@ class LiveSessionTest {
7289
}
7390

7491
@Test
75-
fun `startAudioConversation without RECORD_AUDIO permission throws PermissionMissingException`() =
92+
fun `startAudioConversation on API M+ without permission throws PermissionMissingException`() =
7693
runTest {
7794
// Arrange
95+
mockedBuildVersion.`when` { Build.VERSION.SDK_INT }.thenReturn(Build.VERSION_CODES.M)
7896
`when`(mockContext.checkSelfPermission(Manifest.permission.RECORD_AUDIO))
7997
.thenReturn(PackageManager.PERMISSION_DENIED)
8098

@@ -85,4 +103,28 @@ class LiveSessionTest {
85103
}
86104
assertEquals("Missing RECORD_AUDIO", exception.message)
87105
}
106+
107+
@Test
108+
fun `startAudioConversation on API Pre-M with denied permission proceeds normally`() = runTest {
109+
// Arrange
110+
mockedBuildVersion.`when` { Build.VERSION.SDK_INT }.thenReturn(Build.VERSION_CODES.LOLLIPOP)
111+
`when`(mockContext.checkSelfPermission(Manifest.permission.RECORD_AUDIO))
112+
.thenReturn(PackageManager.PERMISSION_DENIED) // This shouldn't be checked
113+
114+
// Act & Assert
115+
// No exception should be thrown
116+
liveSession.startAudioConversation()
117+
}
118+
119+
@Test
120+
fun `startAudioConversation on API Pre-M with granted permission proceeds normally`() = runTest {
121+
// Arrange
122+
mockedBuildVersion.`when` { Build.VERSION.SDK_INT }.thenReturn(Build.VERSION_CODES.LOLLIPOP)
123+
`when`(mockContext.checkSelfPermission(Manifest.permission.RECORD_AUDIO))
124+
.thenReturn(PackageManager.PERMISSION_GRANTED) // This shouldn't be checked
125+
126+
// Act & Assert
127+
// No exception should be thrown
128+
liveSession.startAudioConversation()
129+
}
88130
}

0 commit comments

Comments
 (0)