@@ -200,4 +200,85 @@ class AuthProviderTest : RobolectricTestBase() {
200200 assert (result is AuthResult .Success )
201201 assert ((result as AuthResult .Success ).uberToken.authCode == " authCode" )
202202 }
203+
204+ @Test
205+ fun `test authenticate when PAR request fails should continue without metadata` () = runTest {
206+ whenever(ssoLink.execute(any())).thenReturn(" authCode" )
207+ // Mock PAR request to return error response (e.g., 500)
208+ val errorResponse: Response <PARResponse > = Response .error(500 , mock())
209+ whenever(authService.loginParRequest(any(), any(), any(), any())).thenReturn(errorResponse)
210+ val prefillInfo = PrefillInfo (" email" , " firstName" , " lastName" , " phoneNumber" )
211+ val authContext =
212+ AuthContext (
213+ AuthDestination .CrossAppSso (listOf (CrossApp .Rider )),
214+ AuthType .AuthCode ,
215+ prefillInfo,
216+ )
217+ val authProvider = AuthProvider (activity, authContext, authService, codeVerifierGenerator)
218+ val argumentCaptor = argumentCaptor<Map <String , String >>()
219+ val result = authProvider.authenticate()
220+ // Verify PAR request was attempted
221+ verify(authService).loginParRequest(any(), any(), any(), any())
222+ // Verify authentication continued without request_uri
223+ verify(ssoLink).execute(argumentCaptor.capture())
224+ assert (argumentCaptor.lastValue.containsKey(REQUEST_URI ).not ())
225+ // Verify authentication succeeded
226+ assert (result is AuthResult .Success )
227+ assert ((result as AuthResult .Success ).uberToken.authCode == " authCode" )
228+ }
229+
230+ @Test
231+ fun `test authenticate when PAR request throws exception should continue without metadata` () =
232+ runTest {
233+ whenever(ssoLink.execute(any())).thenReturn(" authCode" )
234+ // Mock PAR request to throw network exception
235+ whenever(authService.loginParRequest(any(), any(), any(), any()))
236+ .thenThrow(RuntimeException (" Network error" ))
237+ val prefillInfo = PrefillInfo (" email" , " firstName" , " lastName" , " phoneNumber" )
238+ val authContext =
239+ AuthContext (
240+ AuthDestination .CrossAppSso (listOf (CrossApp .Rider )),
241+ AuthType .AuthCode ,
242+ prefillInfo,
243+ )
244+ val authProvider = AuthProvider (activity, authContext, authService, codeVerifierGenerator)
245+ val argumentCaptor = argumentCaptor<Map <String , String >>()
246+ val result = authProvider.authenticate()
247+ // Verify PAR request was attempted
248+ verify(authService).loginParRequest(any(), any(), any(), any())
249+ // Verify authentication continued without request_uri
250+ verify(ssoLink).execute(argumentCaptor.capture())
251+ assert (argumentCaptor.lastValue.containsKey(REQUEST_URI ).not ())
252+ // Verify authentication succeeded
253+ assert (result is AuthResult .Success )
254+ assert ((result as AuthResult .Success ).uberToken.authCode == " authCode" )
255+ }
256+
257+ @Test
258+ fun `test authenticate with PKCE when PAR fails should still include code challenge` () = runTest {
259+ whenever(ssoLink.execute(any())).thenReturn(" authCode" )
260+ whenever(codeVerifierGenerator.generateCodeVerifier()).thenReturn(" verifier" )
261+ whenever(codeVerifierGenerator.generateCodeChallenge(" verifier" )).thenReturn(" challenge" )
262+ whenever(authService.token(any(), any(), any(), any(), any()))
263+ .thenReturn(Response .success(UberToken (accessToken = " accessToken" )))
264+ // Mock PAR request to fail
265+ val errorResponse: Response <PARResponse > = Response .error(500 , mock())
266+ whenever(authService.loginParRequest(any(), any(), any(), any())).thenReturn(errorResponse)
267+ val prefillInfo = PrefillInfo (" email" , " firstName" , " lastName" , " phoneNumber" )
268+ val authContext =
269+ AuthContext (AuthDestination .CrossAppSso (listOf (CrossApp .Rider )), AuthType .PKCE (), prefillInfo)
270+ val authProvider = AuthProvider (activity, authContext, authService, codeVerifierGenerator)
271+ val argumentCaptor = argumentCaptor<Map <String , String >>()
272+ val result = authProvider.authenticate()
273+ // Verify PAR request was attempted
274+ verify(authService).loginParRequest(any(), any(), any(), any())
275+ // Verify authentication continued with code challenge but without request_uri
276+ verify(ssoLink).execute(argumentCaptor.capture())
277+ assert (argumentCaptor.lastValue.containsKey(REQUEST_URI ).not ())
278+ assert (argumentCaptor.lastValue[CODE_CHALLENGE_PARAM ] == " challenge" )
279+ assert (argumentCaptor.lastValue[CODE_CHALLENGE_METHOD ] == CODE_CHALLENGE_METHOD_VAL )
280+ // Verify authentication succeeded
281+ assert (result is AuthResult .Success )
282+ assert ((result as AuthResult .Success ).uberToken.accessToken == " accessToken" )
283+ }
203284}
0 commit comments