@@ -9,6 +9,7 @@ import com.formbricks.android.logger.Logger
99import com.formbricks.android.manager.SurveyManager
1010import com.formbricks.android.manager.UserManager
1111import com.formbricks.android.model.user.AttributeValue
12+ import com.formbricks.android.network.queue.UpdateQueue
1213import org.junit.Assert.assertEquals
1314import org.junit.Assert.assertFalse
1415import org.junit.Assert.assertNotEquals
@@ -41,6 +42,7 @@ class FormbricksInstrumentedTest {
4142 Formbricks .isInitialized = false
4243 Formbricks .language = " default"
4344 UserManager .logout()
45+ UpdateQueue .reset()
4446 SurveyManager .environmentDataHolder = null
4547 SurveyManager .filteredSurveys.clear()
4648 FormbricksApi .service = MockFormbricksApiService ()
@@ -278,16 +280,87 @@ class FormbricksInstrumentedTest {
278280
279281 @Test
280282 fun testLogoutWithoutUserIdDoesNotError () {
281- val appContext = InstrumentationRegistry .getInstrumentation().targetContext
282- Formbricks .setup(appContext, FormbricksConfig .Builder (appUrl, environmentId).setLoggingEnabled(true ).build())
283- waitForSeconds(1 )
283+ // Mark SDK as initialized without triggering async operations
284+ Formbricks .isInitialized = true
284285
285286 // Logout without ever setting a userId — should not crash
286287 assertNull(UserManager .userId)
287288 Formbricks .logout()
288289 assertNull(UserManager .userId)
289290 }
290291
292+ @Test
293+ fun testSyncUserSetsLanguageFromResponse () {
294+ val appContext = InstrumentationRegistry .getInstrumentation().targetContext
295+ Formbricks .setup(appContext, FormbricksConfig .Builder (appUrl, environmentId).setLoggingEnabled(true ).build())
296+ waitForSeconds(1 )
297+
298+ assertEquals(" default" , Formbricks .language)
299+
300+ // Override the mock to return a user response that includes a language
301+ val mockService = FormbricksApi .service as MockFormbricksApiService
302+ val originalUser = mockService.user
303+ mockService.user = originalUser.copy(
304+ data = originalUser.data.copy(
305+ state = originalUser.data.state.copy(
306+ data = originalUser.data.state.data.copy(
307+ language = " fr"
308+ )
309+ )
310+ )
311+ )
312+
313+ // setUserId triggers syncUser, which should pick up the language from the response
314+ Formbricks .setUserId(userId)
315+ waitForSeconds(2 )
316+
317+ assertEquals(userId, UserManager .userId)
318+ assertEquals(" fr" , Formbricks .language)
319+ }
320+
321+ @Test
322+ fun testSyncUserCatchBlockOnApiError () {
323+ val appContext = InstrumentationRegistry .getInstrumentation().targetContext
324+ Formbricks .setup(appContext, FormbricksConfig .Builder (appUrl, environmentId).setLoggingEnabled(true ).build())
325+ waitForSeconds(1 )
326+
327+ // Enable error mode so postUser returns a failure, exercising the catch block
328+ (FormbricksApi .service as MockFormbricksApiService ).isErrorResponseNeeded = true
329+
330+ Formbricks .setUserId(userId)
331+ waitForSeconds(2 )
332+
333+ // The sync should have failed gracefully — userId should not be set from the response
334+ assertNull(UserManager .expiresAt)
335+ }
336+
337+ @Test
338+ fun testLogoutClearsAllUserState () {
339+ val appContext = InstrumentationRegistry .getInstrumentation().targetContext
340+ Formbricks .setup(appContext, FormbricksConfig .Builder (appUrl, environmentId).setLoggingEnabled(true ).build())
341+ waitForSeconds(1 )
342+
343+ // Set up a user so we have state to clear
344+ Formbricks .setUserId(userId)
345+ waitForSeconds(2 )
346+ assertEquals(userId, UserManager .userId)
347+ assertNotNull(UserManager .expiresAt)
348+ assertNotNull(UserManager .contactId)
349+
350+ // Set language to something other than default
351+ Formbricks .setLanguage(" de" )
352+ assertEquals(" de" , Formbricks .language)
353+
354+ // Logout should clear all user state
355+ UserManager .logout()
356+
357+ assertNull(UserManager .userId)
358+ assertNull(UserManager .contactId)
359+ assertNull(UserManager .expiresAt)
360+ assertNull(UserManager .lastDisplayedAt)
361+ assertEquals(" default" , Formbricks .language)
362+ }
363+
291364 private fun waitForSeconds (seconds : Long ) {
292365 val latch = CountDownLatch (1 )
293366 latch.await(seconds, TimeUnit .SECONDS )
0 commit comments