Skip to content

Commit ad0df64

Browse files
committed
make pendingLoginResult and pendingLogoutResult private, use reflection in tests
1 parent 6b7675c commit ad0df64

2 files changed

Lines changed: 84 additions & 61 deletions

File tree

auth0/src/main/java/com/auth0/android/provider/WebAuthProvider.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ public object WebAuthProvider {
5050
data class Failure(val error: AuthenticationException) : PendingResult<Nothing>()
5151
}
5252

53-
internal val pendingLoginResult = AtomicReference<PendingResult<Credentials>?>(null)
53+
private val pendingLoginResult = AtomicReference<PendingResult<Credentials>?>(null)
5454

55-
internal val pendingLogoutResult = AtomicReference<PendingResult<Void?>?>(null)
55+
private val pendingLogoutResult = AtomicReference<PendingResult<Void?>?>(null)
5656

5757
/**
5858
* Registers login (and optionally logout) callbacks for the duration of the given

auth0/src/test/java/com/auth0/android/provider/WebAuthProviderTest.kt

Lines changed: 82 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ import java.io.InputStream
6565
import java.nio.file.Files
6666
import java.nio.file.Paths
6767
import java.util.*
68+
import java.util.concurrent.atomic.AtomicReference
6869

6970
@RunWith(RobolectricTestRunner::class)
7071
@Config(shadows = [ThreadSwitcherShadow::class])
@@ -118,8 +119,8 @@ public class WebAuthProviderTest {
118119
`when`(mockKeyStore.hasKeyPair()).thenReturn(false)
119120

120121
// Clear any pending results left over from previous tests
121-
WebAuthProvider.pendingLoginResult.set(null)
122-
WebAuthProvider.pendingLogoutResult.set(null)
122+
setPendingLoginResult(null)
123+
setPendingLogoutResult(null)
123124
}
124125

125126

@@ -3074,7 +3075,8 @@ public class WebAuthProviderTest {
30743075
@Test
30753076
public fun shouldCacheLoginResultWhenLifecycleCallbackIsDetachedOnDestroy() {
30763077
val credentials = Mockito.mock(Credentials::class.java)
3077-
WebAuthProvider.pendingLoginResult.set(null)
3078+
var capturedSuccess: Credentials? = null
3079+
var capturedError: AuthenticationException? = null
30783080

30793081
val lifecycleOwner = Mockito.mock(LifecycleOwner::class.java)
30803082
val lifecycle = Mockito.mock(Lifecycle::class.java)
@@ -3084,26 +3086,24 @@ public class WebAuthProviderTest {
30843086
delegateCallback = callback,
30853087
lifecycleOwner = lifecycleOwner,
30863088
onDetached = { success, error ->
3087-
if (success != null) WebAuthProvider.pendingLoginResult.set(WebAuthProvider.PendingResult.Success(success))
3088-
else if (error != null) WebAuthProvider.pendingLoginResult.set(WebAuthProvider.PendingResult.Failure(error))
3089+
capturedSuccess = success
3090+
capturedError = error
30893091
}
30903092
)
30913093

30923094
lifecycleCallback.onDestroy(lifecycleOwner)
3093-
30943095
lifecycleCallback.onSuccess(credentials)
30953096

3096-
val pending = WebAuthProvider.pendingLoginResult.get()
3097-
Assert.assertNotNull(pending)
3098-
Assert.assertTrue(pending is WebAuthProvider.PendingResult.Success)
3099-
Assert.assertEquals(credentials, (pending as WebAuthProvider.PendingResult.Success).result)
3097+
Assert.assertEquals(credentials, capturedSuccess)
3098+
Assert.assertNull(capturedError)
31003099
verify(callback, Mockito.never()).onSuccess(any()) // old callback never called
31013100
}
31023101

31033102
@Test
31043103
public fun shouldCacheLoginFailureWhenLifecycleCallbackIsDetachedOnDestroy() {
31053104
val error = AuthenticationException("canceled", "User canceled")
3106-
WebAuthProvider.pendingLoginResult.set(null)
3105+
var capturedSuccess: Credentials? = null
3106+
var capturedError: AuthenticationException? = null
31073107

31083108
val lifecycleOwner = Mockito.mock(LifecycleOwner::class.java)
31093109
val lifecycle = Mockito.mock(Lifecycle::class.java)
@@ -3113,23 +3113,23 @@ public class WebAuthProviderTest {
31133113
delegateCallback = callback,
31143114
lifecycleOwner = lifecycleOwner,
31153115
onDetached = { success, detachedError ->
3116-
if (success != null) WebAuthProvider.pendingLoginResult.set(WebAuthProvider.PendingResult.Success(success))
3117-
else if (detachedError != null) WebAuthProvider.pendingLoginResult.set(WebAuthProvider.PendingResult.Failure(detachedError))
3116+
capturedSuccess = success
3117+
capturedError = detachedError
31183118
}
31193119
)
31203120

31213121
lifecycleCallback.onDestroy(lifecycleOwner)
31223122
lifecycleCallback.onFailure(error)
31233123

3124-
val pending = WebAuthProvider.pendingLoginResult.get()
3125-
Assert.assertNotNull(pending)
3126-
Assert.assertTrue(pending is WebAuthProvider.PendingResult.Failure)
3124+
Assert.assertNull(capturedSuccess)
3125+
Assert.assertEquals(error, capturedError)
31273126
verify(callback, Mockito.never()).onFailure(any())
31283127
}
31293128

31303129
@Test
31313130
public fun shouldDeliverDirectlyWhenLifecycleCallbackIsAlive() {
31323131
val credentials = Mockito.mock(Credentials::class.java)
3132+
var onDetachedCalled = false
31333133

31343134
val lifecycleOwner = Mockito.mock(LifecycleOwner::class.java)
31353135
val lifecycle = Mockito.mock(Lifecycle::class.java)
@@ -3138,21 +3138,19 @@ public class WebAuthProviderTest {
31383138
val lifecycleCallback = LifecycleAwareCallback<Credentials>(
31393139
delegateCallback = callback,
31403140
lifecycleOwner = lifecycleOwner,
3141-
onDetached = { success, error ->
3142-
if (success != null) WebAuthProvider.pendingLoginResult.set(WebAuthProvider.PendingResult.Success(success))
3143-
else if (error != null) WebAuthProvider.pendingLoginResult.set(WebAuthProvider.PendingResult.Failure(error))
3144-
}
3141+
onDetached = { _, _ -> onDetachedCalled = true }
31453142
)
31463143

31473144
lifecycleCallback.onSuccess(credentials)
31483145

31493146
verify(callback).onSuccess(credentials)
3150-
Assert.assertNull(WebAuthProvider.pendingLoginResult.get())
3147+
Assert.assertFalse(onDetachedCalled)
31513148
}
31523149

31533150
@Test
31543151
public fun shouldDeliverFailureDirectlyWhenLifecycleCallbackIsAlive() {
31553152
val error = AuthenticationException("canceled", "User canceled")
3153+
var onDetachedCalled = false
31563154

31573155
val lifecycleOwner = Mockito.mock(LifecycleOwner::class.java)
31583156
val lifecycle = Mockito.mock(Lifecycle::class.java)
@@ -3161,21 +3159,19 @@ public class WebAuthProviderTest {
31613159
val lifecycleCallback = LifecycleAwareCallback<Credentials>(
31623160
delegateCallback = callback,
31633161
lifecycleOwner = lifecycleOwner,
3164-
onDetached = { success, detachedError ->
3165-
if (success != null) WebAuthProvider.pendingLoginResult.set(WebAuthProvider.PendingResult.Success(success))
3166-
else if (detachedError != null) WebAuthProvider.pendingLoginResult.set(WebAuthProvider.PendingResult.Failure(detachedError))
3167-
}
3162+
onDetached = { _, _ -> onDetachedCalled = true }
31683163
)
31693164

31703165
lifecycleCallback.onFailure(error)
31713166

31723167
verify(callback).onFailure(error)
3173-
Assert.assertNull(WebAuthProvider.pendingLoginResult.get())
3168+
Assert.assertFalse(onDetachedCalled)
31743169
}
31753170

31763171
@Test
31773172
public fun shouldCacheLogoutSuccessWhenLifecycleCallbackIsDetachedOnDestroy() {
3178-
WebAuthProvider.pendingLogoutResult.set(null)
3173+
var capturedSuccess = false
3174+
var capturedError: AuthenticationException? = null
31793175

31803176
val lifecycleOwner = Mockito.mock(LifecycleOwner::class.java)
31813177
val lifecycle = Mockito.mock(Lifecycle::class.java)
@@ -3184,25 +3180,25 @@ public class WebAuthProviderTest {
31843180
val lifecycleCallback = LifecycleAwareCallback<Void?>(
31853181
delegateCallback = voidCallback,
31863182
lifecycleOwner = lifecycleOwner,
3187-
onDetached = { success, error ->
3188-
if (error != null) WebAuthProvider.pendingLogoutResult.set(WebAuthProvider.PendingResult.Failure(error))
3189-
else WebAuthProvider.pendingLogoutResult.set(WebAuthProvider.PendingResult.Success(success))
3183+
onDetached = { _, error ->
3184+
capturedError = error
3185+
if (error == null) capturedSuccess = true
31903186
}
31913187
)
31923188

31933189
lifecycleCallback.onDestroy(lifecycleOwner)
31943190
lifecycleCallback.onSuccess(null)
31953191

3196-
val pending = WebAuthProvider.pendingLogoutResult.get()
3197-
Assert.assertNotNull(pending)
3198-
Assert.assertTrue(pending is WebAuthProvider.PendingResult.Success)
3192+
Assert.assertTrue(capturedSuccess)
3193+
Assert.assertNull(capturedError)
31993194
verify(voidCallback, Mockito.never()).onSuccess(any())
32003195
}
32013196

32023197
@Test
32033198
public fun shouldCacheLogoutFailureWhenLifecycleCallbackIsDetachedOnDestroy() {
32043199
val error = AuthenticationException("canceled", "User closed the browser")
3205-
WebAuthProvider.pendingLogoutResult.set(null)
3200+
var capturedSuccess = false
3201+
var capturedError: AuthenticationException? = null
32063202

32073203
val lifecycleOwner = Mockito.mock(LifecycleOwner::class.java)
32083204
val lifecycle = Mockito.mock(Lifecycle::class.java)
@@ -3211,40 +3207,38 @@ public class WebAuthProviderTest {
32113207
val lifecycleCallback = LifecycleAwareCallback<Void?>(
32123208
delegateCallback = voidCallback,
32133209
lifecycleOwner = lifecycleOwner,
3214-
onDetached = { success, detachedError ->
3215-
if (detachedError != null) WebAuthProvider.pendingLogoutResult.set(WebAuthProvider.PendingResult.Failure(detachedError))
3216-
else WebAuthProvider.pendingLogoutResult.set(WebAuthProvider.PendingResult.Success(success))
3210+
onDetached = { _, detachedError ->
3211+
capturedError = detachedError
3212+
if (detachedError == null) capturedSuccess = true
32173213
}
32183214
)
32193215

32203216
lifecycleCallback.onDestroy(lifecycleOwner)
32213217
lifecycleCallback.onFailure(error)
32223218

3223-
val pending = WebAuthProvider.pendingLogoutResult.get()
3224-
Assert.assertNotNull(pending)
3225-
Assert.assertTrue(pending is WebAuthProvider.PendingResult.Failure)
3219+
Assert.assertFalse(capturedSuccess)
3220+
Assert.assertEquals(error, capturedError)
32263221
verify(voidCallback, Mockito.never()).onFailure(any())
32273222
}
32283223

32293224
@Test
32303225
public fun shouldDeliverLogoutDirectlyWhenLifecycleCallbackIsAlive() {
3226+
var onDetachedCalled = false
3227+
32313228
val lifecycleOwner = Mockito.mock(LifecycleOwner::class.java)
32323229
val lifecycle = Mockito.mock(Lifecycle::class.java)
32333230
Mockito.`when`(lifecycleOwner.lifecycle).thenReturn(lifecycle)
32343231

32353232
val lifecycleCallback = LifecycleAwareCallback<Void?>(
32363233
delegateCallback = voidCallback,
32373234
lifecycleOwner = lifecycleOwner,
3238-
onDetached = { success, error ->
3239-
if (error != null) WebAuthProvider.pendingLogoutResult.set(WebAuthProvider.PendingResult.Failure(error))
3240-
else WebAuthProvider.pendingLogoutResult.set(WebAuthProvider.PendingResult.Success(success))
3241-
}
3235+
onDetached = { _, _ -> onDetachedCalled = true }
32423236
)
32433237

32443238
lifecycleCallback.onSuccess(null)
32453239

32463240
verify(voidCallback).onSuccess(null)
3247-
Assert.assertNull(WebAuthProvider.pendingLogoutResult.get())
3241+
Assert.assertFalse(onDetachedCalled)
32483242
}
32493243

32503244
@Test
@@ -3282,27 +3276,27 @@ public class WebAuthProviderTest {
32823276
@Test
32833277
public fun shouldClearPendingLoginResultOnNewLoginStart() {
32843278
val staleCredentials = Mockito.mock(Credentials::class.java)
3285-
WebAuthProvider.pendingLoginResult.set(WebAuthProvider.PendingResult.Success(staleCredentials))
3279+
setPendingLoginResult(WebAuthProvider.PendingResult.Success(staleCredentials))
32863280

32873281
login(account).start(activity, callback)
32883282

3289-
Assert.assertNull(WebAuthProvider.pendingLoginResult.get())
3283+
Assert.assertNull(getPendingLoginResult())
32903284
}
32913285

32923286
@Test
32933287
public fun shouldClearPendingLogoutResultOnNewLogoutStart() {
3294-
WebAuthProvider.pendingLogoutResult.set(WebAuthProvider.PendingResult.Success(null))
3288+
setPendingLogoutResult(WebAuthProvider.PendingResult.Success(null))
32953289

32963290
logout(account).start(activity, voidCallback)
32973291

3298-
Assert.assertNull(WebAuthProvider.pendingLogoutResult.get())
3292+
Assert.assertNull(getPendingLogoutResult())
32993293
}
33003294

33013295

33023296
@Test
33033297
public fun shouldDeliverPendingLoginResultOnResume() {
33043298
val credentials = Mockito.mock(Credentials::class.java)
3305-
WebAuthProvider.pendingLoginResult.set(WebAuthProvider.PendingResult.Success(credentials))
3299+
setPendingLoginResult(WebAuthProvider.PendingResult.Success(credentials))
33063300

33073301
val lifecycleOwner = Mockito.mock(LifecycleOwner::class.java)
33083302
val lifecycle = Mockito.mock(Lifecycle::class.java)
@@ -3317,13 +3311,13 @@ public class WebAuthProviderTest {
33173311
observerCaptor.firstValue.onResume(lifecycleOwner)
33183312

33193313
verify(callback).onSuccess(credentials)
3320-
Assert.assertNull(WebAuthProvider.pendingLoginResult.get())
3314+
Assert.assertNull(getPendingLoginResult())
33213315
}
33223316

33233317
@Test
33243318
public fun shouldDeliverPendingLoginFailureOnResume() {
33253319
val error = AuthenticationException("canceled", "User canceled")
3326-
WebAuthProvider.pendingLoginResult.set(WebAuthProvider.PendingResult.Failure(error))
3320+
setPendingLoginResult(WebAuthProvider.PendingResult.Failure(error))
33273321

33283322
val lifecycleOwner = Mockito.mock(LifecycleOwner::class.java)
33293323
val lifecycle = Mockito.mock(Lifecycle::class.java)
@@ -3336,12 +3330,12 @@ public class WebAuthProviderTest {
33363330
observerCaptor.firstValue.onResume(lifecycleOwner)
33373331

33383332
verify(callback).onFailure(error)
3339-
Assert.assertNull(WebAuthProvider.pendingLoginResult.get())
3333+
Assert.assertNull(getPendingLoginResult())
33403334
}
33413335

33423336
@Test
33433337
public fun shouldDeliverPendingLogoutResultOnResume() {
3344-
WebAuthProvider.pendingLogoutResult.set(WebAuthProvider.PendingResult.Success(null))
3338+
setPendingLogoutResult(WebAuthProvider.PendingResult.Success(null))
33453339

33463340
val lifecycleOwner = Mockito.mock(LifecycleOwner::class.java)
33473341
val lifecycle = Mockito.mock(Lifecycle::class.java)
@@ -3354,13 +3348,13 @@ public class WebAuthProviderTest {
33543348
observerCaptor.firstValue.onResume(lifecycleOwner)
33553349

33563350
verify(voidCallback).onSuccess(null)
3357-
Assert.assertNull(WebAuthProvider.pendingLogoutResult.get())
3351+
Assert.assertNull(getPendingLogoutResult())
33583352
}
33593353

33603354
@Test
33613355
public fun shouldDeliverPendingLogoutFailureOnResume() {
33623356
val error = AuthenticationException("canceled", "User closed the browser")
3363-
WebAuthProvider.pendingLogoutResult.set(WebAuthProvider.PendingResult.Failure(error))
3357+
setPendingLogoutResult(WebAuthProvider.PendingResult.Failure(error))
33643358

33653359
val lifecycleOwner = Mockito.mock(LifecycleOwner::class.java)
33663360
val lifecycle = Mockito.mock(Lifecycle::class.java)
@@ -3373,7 +3367,7 @@ public class WebAuthProviderTest {
33733367
observerCaptor.firstValue.onResume(lifecycleOwner)
33743368

33753369
verify(voidCallback).onFailure(error)
3376-
Assert.assertNull(WebAuthProvider.pendingLogoutResult.get())
3370+
Assert.assertNull(getPendingLogoutResult())
33773371
}
33783372

33793373
@Test
@@ -3407,7 +3401,7 @@ public class WebAuthProviderTest {
34073401

34083402
@Test
34093403
public fun shouldNotDeliverLogoutResultWhenNoLogoutCallbackPassedToRegisterCallbacks() {
3410-
WebAuthProvider.pendingLogoutResult.set(WebAuthProvider.PendingResult.Success(null))
3404+
setPendingLogoutResult(WebAuthProvider.PendingResult.Success(null))
34113405

34123406
val lifecycleOwner = Mockito.mock(LifecycleOwner::class.java)
34133407
val lifecycle = Mockito.mock(Lifecycle::class.java)
@@ -3421,7 +3415,36 @@ public class WebAuthProviderTest {
34213415
observerCaptor.firstValue.onResume(lifecycleOwner)
34223416

34233417
verify(voidCallback, Mockito.never()).onSuccess(any())
3424-
Assert.assertNotNull(WebAuthProvider.pendingLogoutResult.get())
3418+
Assert.assertNotNull(getPendingLogoutResult())
3419+
}
3420+
3421+
// Reflection helpers — pendingLoginResult/pendingLogoutResult are private in WebAuthProvider
3422+
@Suppress("UNCHECKED_CAST")
3423+
private fun setPendingLoginResult(result: WebAuthProvider.PendingResult<Credentials>?) {
3424+
val field = WebAuthProvider::class.java.getDeclaredField("pendingLoginResult")
3425+
field.isAccessible = true
3426+
(field.get(WebAuthProvider) as AtomicReference<WebAuthProvider.PendingResult<Credentials>?>).set(result)
3427+
}
3428+
3429+
@Suppress("UNCHECKED_CAST")
3430+
private fun getPendingLoginResult(): WebAuthProvider.PendingResult<Credentials>? {
3431+
val field = WebAuthProvider::class.java.getDeclaredField("pendingLoginResult")
3432+
field.isAccessible = true
3433+
return (field.get(WebAuthProvider) as AtomicReference<WebAuthProvider.PendingResult<Credentials>?>).get()
3434+
}
3435+
3436+
@Suppress("UNCHECKED_CAST")
3437+
private fun setPendingLogoutResult(result: WebAuthProvider.PendingResult<Void?>?) {
3438+
val field = WebAuthProvider::class.java.getDeclaredField("pendingLogoutResult")
3439+
field.isAccessible = true
3440+
(field.get(WebAuthProvider) as AtomicReference<WebAuthProvider.PendingResult<Void?>?>).set(result)
3441+
}
3442+
3443+
@Suppress("UNCHECKED_CAST")
3444+
private fun getPendingLogoutResult(): WebAuthProvider.PendingResult<Void?>? {
3445+
val field = WebAuthProvider::class.java.getDeclaredField("pendingLogoutResult")
3446+
field.isAccessible = true
3447+
return (field.get(WebAuthProvider) as AtomicReference<WebAuthProvider.PendingResult<Void?>?>).get()
34253448
}
34263449

34273450
private companion object {

0 commit comments

Comments
 (0)