11package com.clevertap.android.hms
22
3+ import com.clevertap.android.hms.HmsConstants.APP_ID_KEY
4+ import com.clevertap.android.hms.HmsConstants.HCM_SCOPE
35import com.clevertap.android.shared.test.BaseTestCase
46import com.clevertap.android.shared.test.TestApplication
7+ import com.huawei.agconnect.AGConnectInstance
58import com.huawei.agconnect.AGConnectOptions
69import com.huawei.agconnect.AGConnectOptionsBuilder
710import com.huawei.hms.aaid.HmsInstanceId
811import com.huawei.hms.api.HuaweiApiAvailability
912import io.mockk.every
1013import io.mockk.mockk
14+ import io.mockk.mockkConstructor
1115import io.mockk.mockkStatic
1216import io.mockk.spyk
17+ import io.mockk.verify
1318import org.junit.Assert
1419import org.junit.Before
1520import org.junit.Test
1621import org.junit.runner.RunWith
1722import org.robolectric.RobolectricTestRunner
1823import org.robolectric.annotation.Config
24+ import kotlin.test.assertEquals
25+ import kotlin.test.assertFalse
26+ import kotlin.test.assertNull
27+ import kotlin.test.assertTrue
1928
2029@RunWith(RobolectricTestRunner ::class )
2130@Config(sdk = [28 ], application = TestApplication ::class )
@@ -38,27 +47,27 @@ class HmsHandlerTest : BaseTestCase() {
3847
3948 @Test
4049 fun testAppId_Invalid () {
41- every { agConnectOptionsSpy.getString(HmsConstants . APP_ID_KEY ) } throws RuntimeException (" Something went wrong" )
50+ every { agConnectOptionsSpy.getString(APP_ID_KEY ) } throws RuntimeException (" Something went wrong" )
4251 val appId = sdkHandler.appId()
4352 Assert .assertNull(appId)
4453 }
4554
4655 @Test
4756 fun testAppId_Valid () {
48- every { agConnectOptionsSpy.getString(HmsConstants . APP_ID_KEY ) } returns HmsTestConstants .HMS_APP_ID
57+ every { agConnectOptionsSpy.getString(APP_ID_KEY ) } returns HmsTestConstants .HMS_APP_ID
4958 val appId = sdkHandler.appId()
5059 Assert .assertNotNull(appId)
5160 }
5261
5362 @Test
5463 fun testIsAvailable_Returns_False () {
55- every { agConnectOptionsSpy.getString(HmsConstants . APP_ID_KEY ) } throws RuntimeException (" Something Went Wrong" )
64+ every { agConnectOptionsSpy.getString(APP_ID_KEY ) } throws RuntimeException (" Something Went Wrong" )
5665 Assert .assertFalse(sdkHandler.isAvailable)
5766 }
5867
5968 @Test
6069 fun testIsAvailable_Returns_True () {
61- every { agConnectOptionsSpy.getString(HmsConstants . APP_ID_KEY ) } returns HmsTestConstants .HMS_APP_ID
70+ every { agConnectOptionsSpy.getString(APP_ID_KEY ) } returns HmsTestConstants .HMS_APP_ID
6271 Assert .assertTrue(sdkHandler.isAvailable)
6372 }
6473
@@ -93,8 +102,8 @@ class HmsHandlerTest : BaseTestCase() {
93102
94103 @Test
95104 fun testNewToken_Exception () {
96- every { agConnectOptionsSpy.getString(HmsConstants . APP_ID_KEY ) } returns HmsTestConstants .HMS_APP_ID
97- every { instance.getToken(HmsTestConstants .HMS_APP_ID , HmsConstants . HCM_SCOPE ) } throws
105+ every { agConnectOptionsSpy.getString(APP_ID_KEY ) } returns HmsTestConstants .HMS_APP_ID
106+ every { instance.getToken(HmsTestConstants .HMS_APP_ID , HCM_SCOPE ) } throws
98107 RuntimeException (" Something went wrong" )
99108 mockkStatic(HmsInstanceId ::class ) {
100109 every { HmsInstanceId .getInstance(application) } returns instance
@@ -103,20 +112,201 @@ class HmsHandlerTest : BaseTestCase() {
103112 }
104113 }
105114
115+ // Add these test cases to your existing HmsHandlerTest.kt file
116+
117+ @Test
118+ fun `appId should initialize options when options is null and return app id from existing AGConnect instance` () {
119+ // Arrange
120+ val mockOptions = mockk<AGConnectOptions >()
121+ val mockInstance = mockk<AGConnectInstance >()
122+
123+ mockkStatic(AGConnectInstance ::class )
124+ every { AGConnectInstance .getInstance() } returns mockInstance
125+ every { mockInstance.options } returns mockOptions
126+ every { mockOptions.getString(APP_ID_KEY ) } returns " test-app-id"
127+
128+ val handler = HmsSdkHandler (application, cleverTapInstanceConfig)
129+
130+ // Act
131+ val result = handler.appId()
132+
133+ // Assert
134+ assertEquals(" test-app-id" , result)
135+ verify { AGConnectInstance .getInstance() }
136+ verify { mockInstance.options }
137+ }
138+
139+ @Test
140+ fun `appId should fallback to AGConnectOptionsBuilder when existing instance is null` () {
141+ // Arrange
142+ val mockOptions = mockk<AGConnectOptions >()
143+
144+ mockkStatic(AGConnectInstance ::class )
145+ mockkConstructor(AGConnectOptionsBuilder ::class )
146+
147+ every { AGConnectInstance .getInstance() } returns null
148+ every { anyConstructed<AGConnectOptionsBuilder >().build(application) } returns mockOptions
149+ every { mockOptions.getString(APP_ID_KEY ) } returns " fallback-app-id"
150+
151+ val handler = HmsSdkHandler (application, cleverTapInstanceConfig)
152+
153+ // Act
154+ val result = handler.appId()
155+
156+ // Assert
157+ assertEquals(" fallback-app-id" , result)
158+ verify { AGConnectInstance .getInstance() }
159+ verify { anyConstructed<AGConnectOptionsBuilder >().build(application) }
160+ }
161+
162+ @Test
163+ fun `appId should fallback to AGConnectOptionsBuilder when existing instance options is null` () {
164+ // Arrange
165+ val mockOptions = mockk<AGConnectOptions >()
166+ val mockInstance = mockk<AGConnectInstance >()
167+
168+ mockkStatic(AGConnectInstance ::class )
169+ mockkConstructor(AGConnectOptionsBuilder ::class )
170+
171+ every { AGConnectInstance .getInstance() } returns mockInstance
172+ every { mockInstance.options } returns null
173+ every { anyConstructed<AGConnectOptionsBuilder >().build(application) } returns mockOptions
174+ every { mockOptions.getString(APP_ID_KEY ) } returns " builder-app-id"
175+
176+ val handler = HmsSdkHandler (application, cleverTapInstanceConfig)
177+
178+ // Act
179+ val result = handler.appId()
180+
181+ // Assert
182+ assertEquals(" builder-app-id" , result)
183+ verify { AGConnectInstance .getInstance() }
184+ verify { mockInstance.options }
185+ verify { anyConstructed<AGConnectOptionsBuilder >().build(application) }
186+ }
187+
188+ @Test
189+ fun `appId should handle exception during AGConnect instance retrieval and fallback to builder` () {
190+ // Arrange
191+ val mockOptions = mockk<AGConnectOptions >()
192+
193+ mockkStatic(AGConnectInstance ::class )
194+ mockkConstructor(AGConnectOptionsBuilder ::class )
195+
196+ every { AGConnectInstance .getInstance() } throws RuntimeException (" AGConnect not initialized" )
197+ every { anyConstructed<AGConnectOptionsBuilder >().build(application) } returns mockOptions
198+ every { mockOptions.getString(APP_ID_KEY ) } returns " exception-recovery-app-id"
199+
200+ val handler = HmsSdkHandler (application, cleverTapInstanceConfig)
201+
202+ // Act
203+ val result = handler.appId()
204+
205+ // Assert
206+ assertEquals(" exception-recovery-app-id" , result)
207+ }
208+
209+ @Test
210+ fun `appId should handle exception during AGConnectOptionsBuilder` () {
211+ // Arrange
212+ mockkStatic(AGConnectInstance ::class )
213+ mockkConstructor(AGConnectOptionsBuilder ::class )
214+
215+ every { AGConnectInstance .getInstance() } returns null
216+ every { anyConstructed<AGConnectOptionsBuilder >().build(application) } throws RuntimeException (" Build failed" )
217+
218+ val handler = HmsSdkHandler (application, cleverTapInstanceConfig)
219+
220+ // Act
221+ val result = handler.appId()
222+
223+ // Assert
224+ assertNull(result)
225+ }
226+
227+ @Test
228+ fun `isAvailable should trigger options initialization and return true when app id exists` () {
229+ // Arrange
230+ val mockOptions = mockk<AGConnectOptions >()
231+ val mockInstance = mockk<AGConnectInstance >()
232+
233+ mockkStatic(AGConnectInstance ::class )
234+ every { AGConnectInstance .getInstance() } returns mockInstance
235+ every { mockInstance.options } returns mockOptions
236+ every { mockOptions.getString(APP_ID_KEY ) } returns " test-app-id"
237+
238+ val handler = HmsSdkHandler (application, cleverTapInstanceConfig)
239+
240+ // Act
241+ val result = handler.isAvailable()
242+
243+ // Assert
244+ assertTrue(result)
245+ verify { AGConnectInstance .getInstance() } // Confirms initialization was triggered
246+ }
247+
248+ @Test
249+ fun `isAvailable should trigger options initialization and return false when app id is empty` () {
250+ // Arrange
251+ val mockOptions = mockk<AGConnectOptions >()
252+ val mockInstance = mockk<AGConnectInstance >()
253+
254+ mockkStatic(AGConnectInstance ::class )
255+ every { AGConnectInstance .getInstance() } returns mockInstance
256+ every { mockInstance.options } returns mockOptions
257+ every { mockOptions.getString(APP_ID_KEY ) } returns " "
258+
259+ val handler = HmsSdkHandler (application, cleverTapInstanceConfig)
260+
261+ // Act
262+ val result = handler.isAvailable()
263+
264+ // Assert
265+ assertFalse(result)
266+ verify { AGConnectInstance .getInstance() } // Confirms initialization was triggered
267+ }
268+
269+ @Test
270+ fun `onNewToken should trigger options initialization and use app id for token retrieval` () {
271+ // Arrange
272+ val mockOptions = mockk<AGConnectOptions >()
273+ val mockInstance = mockk<AGConnectInstance >()
274+ val mockHmsInstanceId = mockk<HmsInstanceId >()
275+
276+ mockkStatic(AGConnectInstance ::class )
277+ mockkStatic(HmsInstanceId ::class )
278+
279+ every { AGConnectInstance .getInstance() } returns mockInstance
280+ every { mockInstance.options } returns mockOptions
281+ every { mockOptions.getString(APP_ID_KEY ) } returns " token-app-id"
282+ every { HmsInstanceId .getInstance(application) } returns mockHmsInstanceId
283+ every { mockHmsInstanceId.getToken(" token-app-id" , HCM_SCOPE ) } returns " test-token"
284+
285+ val handler = HmsSdkHandler (application, cleverTapInstanceConfig)
286+
287+ // Act
288+ val result = handler.onNewToken()
289+
290+ // Assert
291+ assertEquals(" test-token" , result)
292+ verify { AGConnectInstance .getInstance() } // Confirms initialization was triggered
293+ verify { mockHmsInstanceId.getToken(" token-app-id" , HCM_SCOPE ) }
294+ }
295+
106296 @Test
107297 fun testNewToken_Invalid_AppId () {
108- every { agConnectOptionsSpy.getString(HmsConstants . APP_ID_KEY ) } returns null
298+ every { agConnectOptionsSpy.getString(APP_ID_KEY ) } returns null
109299 val token = sdkHandler.onNewToken()
110300 Assert .assertNull(token)
111301 }
112302
113303 @Test
114304 fun testNewToken_Success () {
115- every { agConnectOptionsSpy.getString(HmsConstants . APP_ID_KEY ) } returns HmsTestConstants .HMS_APP_ID
305+ every { agConnectOptionsSpy.getString(APP_ID_KEY ) } returns HmsTestConstants .HMS_APP_ID
116306 every {
117307 instance.getToken(
118308 HmsTestConstants .HMS_APP_ID ,
119- HmsConstants . HCM_SCOPE
309+ HCM_SCOPE
120310 )
121311 } returns HmsTestConstants .HMS_TOKEN
122312 mockkStatic(HmsInstanceId ::class ) {
0 commit comments