Skip to content

Commit 33d95e1

Browse files
committed
Add tests for UserAccountManager.migrateRefreshToken, TokenMigrationActivity and MigrationCallbackRegistry.
1 parent 71fb91f commit 33d95e1

5 files changed

Lines changed: 755 additions & 5 deletions

File tree

.github/test-shards/SalesforceSDK.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"shards": [
44
{
55
"name": "network",
6-
"comment": "REST client tests that make live server calls - isolated",
6+
"comment": "REST client tests that make live server calls",
77
"targets": [
88
"class com.salesforce.androidsdk.rest.RestClientTest",
99
"class com.salesforce.androidsdk.rest.ClientManagerTest",
@@ -14,7 +14,7 @@
1414
},
1515
{
1616
"name": "ui",
17-
"comment": "UI tests and security tests that may require user interaction",
17+
"comment": "Tests that exercise Activities/UI",
1818
"targets": [
1919
"class com.salesforce.androidsdk.ui.LoginViewActivityTest",
2020
"class com.salesforce.androidsdk.ui.PickerBottomSheetTest",
@@ -23,7 +23,8 @@
2323
"class com.salesforce.androidsdk.ui.PickerBottomSheetActivityTest",
2424
"class com.salesforce.androidsdk.ui.DevInfoActivityTest",
2525
"class com.salesforce.androidsdk.security.ScreenLockManagerTest",
26-
"class com.salesforce.androidsdk.security.BiometricAuthenticationManagerTest"
26+
"class com.salesforce.androidsdk.security.BiometricAuthenticationManagerTest",
27+
"class com.salesforce.androidsdk.ui.TokenMigrationActivityTest"
2728
]
2829
},
2930
{
@@ -68,7 +69,8 @@
6869
"notClass com.salesforce.androidsdk.rest.NotificationsActionsResponseBodyTest",
6970
"notClass com.salesforce.androidsdk.rest.files.RenditionTypeTest",
7071
"notClass com.salesforce.androidsdk.rest.files.ConnectUriBuilderTest",
71-
"notClass com.salesforce.androidsdk.rest.files.FileRequestsTest"
72+
"notClass com.salesforce.androidsdk.rest.files.FileRequestsTest",
73+
"notClass com.salesforce.androidsdk.ui.TokenMigrationActivityTest"
7274
]
7375
}
7476
]

libs/SalesforceSDK/src/com/salesforce/androidsdk/ui/TokenMigrationActivity.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ internal class TokenMigrationActivity : ComponentActivity() {
9292
override fun onCreate(savedInstanceState: Bundle?) {
9393
super.onCreate(savedInstanceState)
9494
enableEdgeToEdge()
95-
WindowCompat.getInsetsController(window, window.decorView).isAppearanceLightStatusBars = true
9695

9796
val callbackKey = intent.getStringExtra(EXTRA_CALLBACK_ID) ?: run {
9897
SalesforceSDKLogger.e(TAG, "Unable to parse MigrationResult callback id.")
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/*
2+
* Copyright (c) 2026-present, salesforce.com, inc.
3+
* All rights reserved.
4+
* Redistribution and use of this software in source and binary forms, with or
5+
* without modification, are permitted provided that the following conditions
6+
* are met:
7+
* - Redistributions of source code must retain the above copyright notice, this
8+
* list of conditions and the following disclaimer.
9+
* - Redistributions in binary form must reproduce the above copyright notice,
10+
* this list of conditions and the following disclaimer in the documentation
11+
* and/or other materials provided with the distribution.
12+
* - Neither the name of salesforce.com, inc. nor the names of its contributors
13+
* may be used to endorse or promote products derived from this software without
14+
* specific prior written permission of salesforce.com, inc.
15+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25+
* POSSIBILITY OF SUCH DAMAGE.
26+
*/
27+
package com.salesforce.androidsdk.accounts
28+
29+
import androidx.test.ext.junit.runners.AndroidJUnit4
30+
import androidx.test.filters.SmallTest
31+
import io.mockk.mockk
32+
import io.mockk.verify
33+
import org.junit.Assert.assertEquals
34+
import org.junit.Assert.assertNotEquals
35+
import org.junit.Assert.assertNotNull
36+
import org.junit.Assert.assertNull
37+
import org.junit.Test
38+
import org.junit.runner.RunWith
39+
40+
/**
41+
* Tests for MigrationCallbackRegistry.
42+
*/
43+
@RunWith(AndroidJUnit4::class)
44+
@SmallTest
45+
class MigrationCallbackRegistryTest {
46+
47+
@Test
48+
fun register_returnsUniqueKey() {
49+
// Given
50+
val onSuccess: (UserAccount) -> Unit = mockk(relaxed = true)
51+
val onError: (String, String?, Throwable?) -> Unit = mockk(relaxed = true)
52+
val callbacks = MigrationCallbackRegistry.MigrationCallbacks(
53+
onMigrationSuccess = onSuccess,
54+
onMigrationError = onError
55+
)
56+
57+
// When
58+
val key1 = MigrationCallbackRegistry.register(callbacks)
59+
val key2 = MigrationCallbackRegistry.register(callbacks)
60+
61+
// Then
62+
assertNotNull("Key should not be null", key1)
63+
assertNotNull("Key should not be null", key2)
64+
assertNotEquals("Keys should be unique", key1, key2)
65+
66+
// Cleanup
67+
MigrationCallbackRegistry.consume(key1)
68+
MigrationCallbackRegistry.consume(key2)
69+
}
70+
71+
@Test
72+
fun consume_returnsCallbacksAndRemovesThem() {
73+
// Given
74+
val onSuccess: (UserAccount) -> Unit = mockk(relaxed = true)
75+
val onError: (String, String?, Throwable?) -> Unit = mockk(relaxed = true)
76+
val callbacks = MigrationCallbackRegistry.MigrationCallbacks(
77+
onMigrationSuccess = onSuccess,
78+
onMigrationError = onError
79+
)
80+
val key = MigrationCallbackRegistry.register(callbacks)
81+
82+
// When
83+
val consumedCallbacks = MigrationCallbackRegistry.consume(key)
84+
85+
// Then
86+
assertNotNull("Consumed callbacks should not be null", consumedCallbacks)
87+
assertEquals("Consumed callbacks should match registered callbacks", callbacks, consumedCallbacks)
88+
}
89+
90+
@Test
91+
fun consume_returnsNullForNonExistentKey() {
92+
// When
93+
val result = MigrationCallbackRegistry.consume("non-existent-key")
94+
95+
// Then
96+
assertNull("Should return null for non-existent key", result)
97+
}
98+
99+
@Test
100+
fun consume_returnsNullOnSecondAttempt() {
101+
// Given
102+
val onSuccess: (UserAccount) -> Unit = mockk(relaxed = true)
103+
val onError: (String, String?, Throwable?) -> Unit = mockk(relaxed = true)
104+
val callbacks = MigrationCallbackRegistry.MigrationCallbacks(
105+
onMigrationSuccess = onSuccess,
106+
onMigrationError = onError
107+
)
108+
val key = MigrationCallbackRegistry.register(callbacks)
109+
110+
// When
111+
val firstConsume = MigrationCallbackRegistry.consume(key)
112+
val secondConsume = MigrationCallbackRegistry.consume(key)
113+
114+
// Then
115+
assertNotNull("First consume should return callbacks", firstConsume)
116+
assertNull("Second consume should return null", secondConsume)
117+
}
118+
119+
@Test
120+
fun migrationCallbacks_onMigrationSuccess_invokesCallback() {
121+
// Given
122+
val mockAccount: UserAccount = mockk()
123+
val onSuccess: (UserAccount) -> Unit = mockk(relaxed = true)
124+
val onError: (String, String?, Throwable?) -> Unit = mockk(relaxed = true)
125+
val callbacks = MigrationCallbackRegistry.MigrationCallbacks(
126+
onMigrationSuccess = onSuccess,
127+
onMigrationError = onError
128+
)
129+
130+
// When
131+
callbacks.onMigrationSuccess(mockAccount)
132+
133+
// Then
134+
verify(exactly = 1) { onSuccess(mockAccount) }
135+
}
136+
137+
@Test
138+
fun migrationCallbacks_onMigrationError_invokesCallbackWithAllParams() {
139+
// Given
140+
val error = "Test error"
141+
val errorDesc = "Test error description"
142+
val throwable = RuntimeException("Test exception")
143+
val onSuccess: (UserAccount) -> Unit = mockk(relaxed = true)
144+
val onError: (String, String?, Throwable?) -> Unit = mockk(relaxed = true)
145+
val callbacks = MigrationCallbackRegistry.MigrationCallbacks(
146+
onMigrationSuccess = onSuccess,
147+
onMigrationError = onError
148+
)
149+
150+
// When
151+
callbacks.onMigrationError(error, errorDesc, throwable)
152+
153+
// Then
154+
verify(exactly = 1) { onError(error, errorDesc, throwable) }
155+
}
156+
157+
@Test
158+
fun migrationCallbacks_onMigrationError_invokesCallbackWithNullParams() {
159+
// Given
160+
val error = "Test error"
161+
val onSuccess: (UserAccount) -> Unit = mockk(relaxed = true)
162+
val onError: (String, String?, Throwable?) -> Unit = mockk(relaxed = true)
163+
val callbacks = MigrationCallbackRegistry.MigrationCallbacks(
164+
onMigrationSuccess = onSuccess,
165+
onMigrationError = onError
166+
)
167+
168+
// When
169+
callbacks.onMigrationError(error, null, null)
170+
171+
// Then
172+
verify(exactly = 1) { onError(error, null, null) }
173+
}
174+
175+
@Test
176+
fun multipleCallbacks_canBeRegisteredAndConsumedIndependently() {
177+
// Given
178+
val onSuccess1: (UserAccount) -> Unit = mockk(relaxed = true)
179+
val onError1: (String, String?, Throwable?) -> Unit = mockk(relaxed = true)
180+
val callbacks1 = MigrationCallbackRegistry.MigrationCallbacks(
181+
onMigrationSuccess = onSuccess1,
182+
onMigrationError = onError1
183+
)
184+
185+
val onSuccess2: (UserAccount) -> Unit = mockk(relaxed = true)
186+
val onError2: (String, String?, Throwable?) -> Unit = mockk(relaxed = true)
187+
val callbacks2 = MigrationCallbackRegistry.MigrationCallbacks(
188+
onMigrationSuccess = onSuccess2,
189+
onMigrationError = onError2
190+
)
191+
192+
// When
193+
val key1 = MigrationCallbackRegistry.register(callbacks1)
194+
val key2 = MigrationCallbackRegistry.register(callbacks2)
195+
196+
// Then - consume in reverse order
197+
val consumed2 = MigrationCallbackRegistry.consume(key2)
198+
val consumed1 = MigrationCallbackRegistry.consume(key1)
199+
200+
assertEquals("Callbacks 2 should be consumed correctly", callbacks2, consumed2)
201+
assertEquals("Callbacks 1 should be consumed correctly", callbacks1, consumed1)
202+
}
203+
}

0 commit comments

Comments
 (0)