Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
.idea/
.DS_Store
build/
doc/
doc-store/
docs/
docs-store/
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ class AuthorizationClient(
override fun onCancel() {
Log.i(TAG, "Spotify auth response: User cancelled")
val response = AuthorizationResponse.Builder()
.setType(AuthorizationResponse.Type.EMPTY)
.setType(AuthorizationResponse.Type.CANCELLED)
.build()
sendComplete(authHandler, response)
}
Expand Down Expand Up @@ -301,7 +301,7 @@ class AuthorizationClient(
if (currentHandler?.isAuthInProgress() == true) {
Log.i(TAG, "Spotify auth response: User cancelled")
val response = AuthorizationResponse.Builder()
.setType(AuthorizationResponse.Type.EMPTY)
.setType(AuthorizationResponse.Type.CANCELLED)
.build()
complete(response)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,15 @@ data class AuthorizationResponse internal constructor(
ERROR("error"),

/**
* Response doesn't contain data because auth flow was cancelled or LoginActivity killed.
* Response doesn't contain data due to technical error (malformed response, missing data, etc.)
*/
EMPTY("empty"),

/**
* User explicitly cancelled the authorization flow (closed browser, pressed back, etc.)
*/
CANCELLED("cancelled"),

/**
* The response is unknown.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,10 @@ class LoginActivity : Activity(), AuthorizationClient.AuthorizationClientListene
}
}

} else if (resultCode == RESULT_CANCELED) {
response.setType(Type.CANCELLED)
} else {
// Unknown/invalid result code - treat as technical error
response.setType(Type.EMPTY)
}

Expand All @@ -201,7 +204,15 @@ class LoginActivity : Activity(), AuthorizationClient.AuthorizationClientListene
bundle.putParcelable(RESPONSE_KEY, response)

resultIntent.putExtra(EXTRA_AUTH_RESPONSE, bundle)
setResult(RESULT_OK, resultIntent)

// Return RESULT_CANCELED for user cancellations
val resultCode = if (response.type == Type.CANCELLED) {
RESULT_CANCELED
} else {
RESULT_OK
}

setResult(resultCode, resultIntent)
finish()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,17 @@
@RunWith(RobolectricTestRunner.class)
public class LoginActivityAuthTest {

@Test
public void shouldFinishLoginActivityWhenCompleted() {
private static class LoginActivitySetup {
final LoginActivity loginActivity;
final ShadowActivity shadowLoginActivity;

LoginActivitySetup(LoginActivity loginActivity, ShadowActivity shadowLoginActivity) {
this.loginActivity = loginActivity;
this.shadowLoginActivity = shadowLoginActivity;
}
}

private LoginActivitySetup createLoginActivity() {
Activity context = Robolectric
.buildActivity(Activity.class)
.create()
Expand All @@ -57,34 +65,65 @@ public void shouldFinishLoginActivityWhenCompleted() {
AuthorizationRequest request = new AuthorizationRequest.Builder("test", AuthorizationResponse.Type.TOKEN, "test://test")
.setPkceInformation(pkceInfo)
.build();
AuthorizationResponse response = new AuthorizationResponse.Builder()
.setType(AuthorizationResponse.Type.TOKEN)
.setAccessToken("test_token")
.setExpiresIn(3600)
.build();

Bundle bundle = new Bundle();
bundle.putParcelable(LoginActivity.REQUEST_KEY, request);

Intent intent = new Intent(context, LoginActivity.class);
intent.putExtra(LoginActivity.EXTRA_AUTH_REQUEST, bundle);

ActivityController<LoginActivity> loginActivityActivityController = buildActivity(LoginActivity.class, intent);
ActivityController<LoginActivity> loginActivityController = buildActivity(LoginActivity.class, intent);
LoginActivity loginActivity = loginActivityController.get();
ShadowActivity shadowLoginActivity = shadowOf(loginActivity);
shadowLoginActivity.setCallingActivity(context.getComponentName());
loginActivityController.create();

final LoginActivity loginActivity = loginActivityActivityController.get();
return new LoginActivitySetup(loginActivity, shadowLoginActivity);
}

final ShadowActivity shadowLoginActivity = shadowOf(loginActivity);
shadowLoginActivity.setCallingActivity(context.getComponentName());
private void assertCompletion(LoginActivitySetup setup, AuthorizationResponse response, int expectedResultCode) {
setup.loginActivity.onClientComplete(response);

assertTrue(setup.loginActivity.isFinishing());
assertEquals(expectedResultCode, setup.shadowLoginActivity.getResultCode());
assertEquals(response, setup.shadowLoginActivity.getResultIntent().getBundleExtra(LoginActivity.EXTRA_AUTH_RESPONSE).get(LoginActivity.RESPONSE_KEY));
}

@Test
public void shouldFinishLoginActivityWhenCompleted() {
LoginActivitySetup setup = createLoginActivity();

AuthorizationResponse response = new AuthorizationResponse.Builder()
.setType(AuthorizationResponse.Type.TOKEN)
.setAccessToken("test_token")
.setExpiresIn(3600)
.build();

loginActivityActivityController.create();
assertFalse(setup.loginActivity.isFinishing());

assertFalse(loginActivity.isFinishing());
assertCompletion(setup, response, Activity.RESULT_OK);
}

@Test
public void shouldReturnResultCanceledWhenUserCancels() {
LoginActivitySetup setup = createLoginActivity();

loginActivity.onClientComplete(response);
AuthorizationResponse response = new AuthorizationResponse.Builder()
.setType(AuthorizationResponse.Type.CANCELLED)
.build();

assertCompletion(setup, response, Activity.RESULT_CANCELED);
}

@Test
public void shouldReturnResultOkForTechnicalErrors() {
LoginActivitySetup setup = createLoginActivity();

AuthorizationResponse response = new AuthorizationResponse.Builder()
.setType(AuthorizationResponse.Type.EMPTY)
.build();

assertTrue(loginActivity.isFinishing());
assertEquals(Activity.RESULT_OK, shadowLoginActivity.getResultCode());
assertEquals(response, shadowLoginActivity.getResultIntent().getBundleExtra(LoginActivity.EXTRA_AUTH_RESPONSE).get(LoginActivity.RESPONSE_KEY));
assertCompletion(setup, response, Activity.RESULT_OK);
}

}
2 changes: 2 additions & 0 deletions auth-sample/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

plugins {
id("com.android.application")
id("kotlin-android")
id("kotlin-parcelize")
}

android {
Expand Down

This file was deleted.

Loading