@@ -30,7 +30,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
3030import androidx.test.filters.SmallTest
3131import com.salesforce.androidsdk.app.Features.FEATURE_BROWSER_LOGIN_FOR_ADMIN
3232import com.salesforce.androidsdk.app.Features.FEATURE_BROWSER_LOGIN_FORCE_FLAG
33- import com.salesforce.androidsdk.app.Features.FEATURE_BROWSER_LOGIN_MDM
3433import com.salesforce.androidsdk.app.Features.FEATURE_BROWSER_LOGIN_SERVER_AUTH_CONFIG
3534import com.salesforce.androidsdk.app.Features.FEATURE_LOGIN_SERVER_CUSTOM
3635import com.salesforce.androidsdk.app.Features.FEATURE_LOGIN_SERVER_MY_DOMAIN
@@ -56,6 +55,19 @@ import org.junit.runner.RunWith
5655 * which are `internal` helpers extracted for testability and annotated `@VisibleForTesting`.
5756 * We call them via a relaxed mockk and `callOriginal()` so the real logic executes without
5857 * needing a running Android Activity context.
58+ *
59+ * L-marker mapping:
60+ * L1 = Production server
61+ * L2 = Sandbox server
62+ * L3 = welcome.salesforce.com (Welcome Discovery flow)
63+ * L4 = My Domain (host ending in .my.salesforce.com)
64+ * L5 = Everything else (custom)
65+ *
66+ * B-marker mapping (Android):
67+ * B1 = Server auth config (fallthrough)
68+ * B2 = MDM — defined but never selected on Android (MDM forces cert auth, a different path)
69+ * B3 = Admin Custom Tab
70+ * B4 = Force-advanced-auth flag
5971 */
6072@RunWith(AndroidJUnit4 ::class )
6173@SmallTest
@@ -88,7 +100,7 @@ class BrowserLoginTelemetryTest {
88100 fun test_givenBrowserLoginViaServerAuthConfig_whenSelectBMarker_thenB1Returned () {
89101 every { activity.selectBMarker(any(), any(), any(), any()) } answers { callOriginal() }
90102
91- // B1: browser tab, not admin, not MDM, not force-flag
103+ // B1: browser tab, not admin, not force-flag (MDM ignored on Android)
92104 val result = activity.selectBMarker(
93105 completedViaBrowserTab = true ,
94106 completedViaAdminCustomTab = false ,
@@ -100,18 +112,20 @@ class BrowserLoginTelemetryTest {
100112 }
101113
102114 @Test
103- fun test_givenBrowserLoginViaMDM_whenSelectBMarker_thenB2Returned () {
115+ fun test_givenBrowserLoginViaMDM_whenSelectBMarker_thenB1ReturnedNotB2 () {
104116 every { activity.selectBMarker(any(), any(), any(), any()) } answers { callOriginal() }
105117
106- // B2: browser tab, not admin, MDM forced
118+ // On Android, MDM forces cert auth (different code path — completedViaBrowserTab never
119+ // becomes true in that flow). When isMdmForced=true is passed, it is ignored and B1
120+ // is returned as the fallthrough because no real Android MDM-browser-login signal exists.
107121 val result = activity.selectBMarker(
108122 completedViaBrowserTab = true ,
109123 completedViaAdminCustomTab = false ,
110124 isMdmForced = true ,
111125 forceAdvancedAuth = false ,
112126 )
113- assertEquals(" MDM-forced browser login should yield B2 " ,
114- FEATURE_BROWSER_LOGIN_MDM , result)
127+ assertEquals(" MDM flag is ignored on Android; should fall through to B1 " ,
128+ FEATURE_BROWSER_LOGIN_SERVER_AUTH_CONFIG , result)
115129 }
116130
117131 @Test
@@ -133,7 +147,7 @@ class BrowserLoginTelemetryTest {
133147 fun test_givenBrowserLoginViaForceFlag_whenSelectBMarker_thenB4Returned () {
134148 every { activity.selectBMarker(any(), any(), any(), any()) } answers { callOriginal() }
135149
136- // B4: browser tab, not admin, not MDM, force flag ON
150+ // B4: browser tab, not admin, force flag ON
137151 val result = activity.selectBMarker(
138152 completedViaBrowserTab = true ,
139153 completedViaAdminCustomTab = false ,
@@ -145,33 +159,33 @@ class BrowserLoginTelemetryTest {
145159 }
146160
147161 @Test
148- fun test_givenAdminTabAndMdmAndForceFlag_whenSelectBMarker_thenB3Wins () {
162+ fun test_givenAdminTabAndForceFlag_whenSelectBMarker_thenB3Wins () {
149163 every { activity.selectBMarker(any(), any(), any(), any()) } answers { callOriginal() }
150164
151- // Priority: B3 > B2 > B4 > B1
165+ // Priority on Android: B3 > B4 > B1
152166 val result = activity.selectBMarker(
153167 completedViaBrowserTab = true ,
154168 completedViaAdminCustomTab = true ,
155- isMdmForced = true ,
169+ isMdmForced = false ,
156170 forceAdvancedAuth = true ,
157171 )
158172 assertEquals(" Admin tab should take highest priority (B3)" ,
159173 FEATURE_BROWSER_LOGIN_FOR_ADMIN , result)
160174 }
161175
162176 @Test
163- fun test_givenMdmAndForceFlag_whenSelectBMarker_thenB2Wins () {
177+ fun test_givenForceFlagAndMdm_whenSelectBMarker_thenB4Wins () {
164178 every { activity.selectBMarker(any(), any(), any(), any()) } answers { callOriginal() }
165179
166- // Priority: B2 > B4
180+ // On Android MDM is ignored; force flag wins over B1 fallthrough
167181 val result = activity.selectBMarker(
168182 completedViaBrowserTab = true ,
169183 completedViaAdminCustomTab = false ,
170184 isMdmForced = true ,
171185 forceAdvancedAuth = true ,
172186 )
173- assertEquals(" MDM should take priority over force flag (B2 > B4)" ,
174- FEATURE_BROWSER_LOGIN_MDM , result)
187+ assertEquals(" Force flag should win over ignored MDM signal ( B4)" ,
188+ FEATURE_BROWSER_LOGIN_FORCE_FLAG , result)
175189 }
176190
177191 // endregion
@@ -202,49 +216,62 @@ class BrowserLoginTelemetryTest {
202216 }
203217
204218 @Test
205- fun test_givenMyDomainServer_whenSelectLMarker_thenL3Returned () {
219+ fun test_givenWelcomeDiscovery_whenSelectLMarker_thenL3Returned () {
206220 every { activity.selectLMarker(any(), any()) } answers { callOriginal() }
207221
208- // My Domain is a non-pool, non-WD URL
222+ // L3: Welcome Discovery flow — WD flag takes precedence regardless of the resolved URL
209223 val result = activity.selectLMarker(
210- usedWelcomeDiscovery = false ,
224+ usedWelcomeDiscovery = true ,
211225 loginServerUrl = " https://myorg.my.salesforce.com" ,
212226 )
213- assertEquals(" My Domain login server should yield L3" ,
214- FEATURE_LOGIN_SERVER_MY_DOMAIN , result)
227+ assertEquals(" Welcome Discovery should yield L3" ,
228+ FEATURE_LOGIN_SERVER_WELCOME_DISCOVERY , result)
215229 }
216230
217231 @Test
218- fun test_givenWelcomeDiscovery_whenSelectLMarker_thenL4Returned () {
232+ fun test_givenWelcomeDiscoveryWithProductionUrl_whenSelectLMarker_thenL3Returned () {
219233 every { activity.selectLMarker(any(), any()) } answers { callOriginal() }
220234
221- // WD flag takes precedence regardless of the resolved server URL
235+ // WD flag wins even when the resolved URL is production
222236 val result = activity.selectLMarker(
223237 usedWelcomeDiscovery = true ,
224- loginServerUrl = " https://myorg.my.salesforce.com " ,
238+ loginServerUrl = LoginServerManager . PRODUCTION_LOGIN_URL ,
225239 )
226- assertEquals(" Welcome Discovery should yield L4 " ,
240+ assertEquals(" WD flag should override production URL and yield L3 " ,
227241 FEATURE_LOGIN_SERVER_WELCOME_DISCOVERY , result)
228242 }
229243
230244 @Test
231- fun test_givenWelcomeDiscoveryWithProductionUrl_whenSelectLMarker_thenL4Returned () {
245+ fun test_givenMyDomainServer_whenSelectLMarker_thenL4Returned () {
232246 every { activity.selectLMarker(any(), any()) } answers { callOriginal() }
233247
234- // WD flag wins even when the resolved URL is production
248+ // L4: host ends with .my.salesforce.com
235249 val result = activity.selectLMarker(
236- usedWelcomeDiscovery = true ,
237- loginServerUrl = LoginServerManager . PRODUCTION_LOGIN_URL ,
250+ usedWelcomeDiscovery = false ,
251+ loginServerUrl = " https://myorg.my.salesforce.com " ,
238252 )
239- assertEquals(" WD flag should override production URL and yield L4" ,
240- FEATURE_LOGIN_SERVER_WELCOME_DISCOVERY , result)
253+ assertEquals(" My Domain login server should yield L4" ,
254+ FEATURE_LOGIN_SERVER_MY_DOMAIN , result)
255+ }
256+
257+ @Test
258+ fun test_givenMyDomainSandboxServer_whenSelectLMarker_thenL4Returned () {
259+ every { activity.selectLMarker(any(), any()) } answers { callOriginal() }
260+
261+ // Sandbox My Domain also ends with .my.salesforce.com (L4, not L2, because URL != sandbox constant)
262+ val result = activity.selectLMarker(
263+ usedWelcomeDiscovery = false ,
264+ loginServerUrl = " https://myorg.sandbox.my.salesforce.com" ,
265+ )
266+ assertEquals(" My Domain sandbox server should yield L4" ,
267+ FEATURE_LOGIN_SERVER_MY_DOMAIN , result)
241268 }
242269
243270 @Test
244271 fun test_givenWelcomeLoginUrl_whenSelectLMarker_thenL5Returned () {
245272 every { activity.selectLMarker(any(), any()) } answers { callOriginal() }
246273
247- // The WD URL itself is a pool server, so when usedWelcomeDiscovery=false it falls to L5.
274+ // The WD URL itself: when usedWelcomeDiscovery=false it falls to L5 (custom)
248275 val result = activity.selectLMarker(
249276 usedWelcomeDiscovery = false ,
250277 loginServerUrl = LoginServerManager .WELCOME_LOGIN_URL ,
@@ -253,15 +280,27 @@ class BrowserLoginTelemetryTest {
253280 FEATURE_LOGIN_SERVER_CUSTOM , result)
254281 }
255282
283+ @Test
284+ fun test_givenCustomServer_whenSelectLMarker_thenL5Returned () {
285+ every { activity.selectLMarker(any(), any()) } answers { callOriginal() }
286+
287+ val result = activity.selectLMarker(
288+ usedWelcomeDiscovery = false ,
289+ loginServerUrl = " https://custom.example.com" ,
290+ )
291+ assertEquals(" Custom server should yield L5" ,
292+ FEATURE_LOGIN_SERVER_CUSTOM , result)
293+ }
294+
256295 @Test
257296 fun test_givenExactlyOneL_whenProductionServer_thenOnlyL1Selected () {
258297 every { activity.selectLMarker(any(), any()) } answers { callOriginal() }
259298
260299 val allLMarkers = listOf (
261300 FEATURE_LOGIN_SERVER_PRODUCTION ,
262301 FEATURE_LOGIN_SERVER_SANDBOX ,
263- FEATURE_LOGIN_SERVER_MY_DOMAIN ,
264302 FEATURE_LOGIN_SERVER_WELCOME_DISCOVERY ,
303+ FEATURE_LOGIN_SERVER_MY_DOMAIN ,
265304 FEATURE_LOGIN_SERVER_CUSTOM ,
266305 )
267306 val selected = activity.selectLMarker(
@@ -273,20 +312,5 @@ class BrowserLoginTelemetryTest {
273312 assertEquals(" The selected marker should be L1" , FEATURE_LOGIN_SERVER_PRODUCTION , selected)
274313 }
275314
276- @Test
277- fun test_givenMyDomainWithTrailingSpace_whenSelectLMarker_thenL3Returned () {
278- every { activity.selectLMarker(any(), any()) } answers { callOriginal() }
279-
280- // selectLMarker trims the URL, so trailing spaces should not affect the result.
281- // Note: the trimming is done in onAuthFlowSuccess before calling selectLMarker,
282- // but selectLMarker still receives pre-trimmed input here.
283- val result = activity.selectLMarker(
284- usedWelcomeDiscovery = false ,
285- loginServerUrl = " https://myorg.my.salesforce.com" ,
286- )
287- assertEquals(" My Domain URL should yield L3" ,
288- FEATURE_LOGIN_SERVER_MY_DOMAIN , result)
289- }
290-
291315 // endregion
292316}
0 commit comments