/** * Copyright 2012 Facebook * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.facebook; import android.content.Intent; import android.content.IntentFilter; import android.support.v4.content.LocalBroadcastManager; import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; import com.facebook.internal.Utility; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; public class SessionTests extends SessionTestsBase { @Override protected void setUp() throws Exception { super.setUp(); new SharedPreferencesTokenCachingStrategy(getActivity()).clear(); } @SmallTest @MediumTest @LargeTest public void testFailNullArguments() { try { new Session(null); // Should not get here assertFalse(true); } catch (NullPointerException e) { // got expected exception } } @SmallTest @MediumTest @LargeTest public void testActiveSessionChangeRegistration() { final WaitForBroadcastReceiver receiver0 = new WaitForBroadcastReceiver(); final WaitForBroadcastReceiver receiver1 = new WaitForBroadcastReceiver(); final WaitForBroadcastReceiver receiver2 = new WaitForBroadcastReceiver(); final LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(getActivity()); try { // Register these on the blocker thread so they will send // notifications there as well. The notifications need to be on a // different thread than the progress. Runnable initialize0 = new Runnable() { @Override public void run() { broadcastManager.registerReceiver(receiver0, getActiveSessionAllFilter()); broadcastManager.registerReceiver(receiver1, getActiveSessionFilter(Session.ACTION_ACTIVE_SESSION_SET)); broadcastManager.registerReceiver(receiver1, getActiveSessionFilter(Session.ACTION_ACTIVE_SESSION_OPENED)); broadcastManager.registerReceiver(receiver1, getActiveSessionFilter(Session.ACTION_ACTIVE_SESSION_CLOSED)); broadcastManager.registerReceiver(receiver2, getActiveSessionFilter(Session.ACTION_ACTIVE_SESSION_OPENED)); broadcastManager.registerReceiver(receiver2, getActiveSessionFilter(Session.ACTION_ACTIVE_SESSION_CLOSED)); } }; runOnBlockerThread(initialize0, true); // Verify all actions show up where they are expected WaitForBroadcastReceiver.incrementExpectCounts(receiver0, receiver1, receiver2); Session.postActiveSessionAction(Session.ACTION_ACTIVE_SESSION_OPENED); WaitForBroadcastReceiver.waitForExpectedCalls(receiver0, receiver1, receiver2); WaitForBroadcastReceiver.incrementExpectCounts(receiver0, receiver1, receiver2); Session.postActiveSessionAction(Session.ACTION_ACTIVE_SESSION_CLOSED); WaitForBroadcastReceiver.waitForExpectedCalls(receiver0, receiver1, receiver2); WaitForBroadcastReceiver.incrementExpectCounts(receiver0, receiver1); Session.postActiveSessionAction(Session.ACTION_ACTIVE_SESSION_SET); WaitForBroadcastReceiver.waitForExpectedCalls(receiver0, receiver1); receiver0.incrementExpectCount(); Session.postActiveSessionAction(Session.ACTION_ACTIVE_SESSION_UNSET); receiver0.waitForExpectedCalls(); // Remove receiver1 and verify actions continue to show up where // expected broadcastManager.unregisterReceiver(receiver1); WaitForBroadcastReceiver.incrementExpectCounts(receiver0, receiver2); Session.postActiveSessionAction(Session.ACTION_ACTIVE_SESSION_OPENED); WaitForBroadcastReceiver.waitForExpectedCalls(receiver0, receiver2); WaitForBroadcastReceiver.incrementExpectCounts(receiver0, receiver2); Session.postActiveSessionAction(Session.ACTION_ACTIVE_SESSION_CLOSED); WaitForBroadcastReceiver.waitForExpectedCalls(receiver0, receiver2); receiver0.incrementExpectCount(); Session.postActiveSessionAction(Session.ACTION_ACTIVE_SESSION_SET); receiver0.waitForExpectedCalls(); receiver0.incrementExpectCount(); Session.postActiveSessionAction(Session.ACTION_ACTIVE_SESSION_UNSET); receiver0.waitForExpectedCalls(); // Remove receiver0 and register receiver1 multiple times for one // action broadcastManager.unregisterReceiver(receiver0); Runnable initialize1 = new Runnable() { @Override public void run() { broadcastManager.registerReceiver(receiver1, getActiveSessionFilter(Session.ACTION_ACTIVE_SESSION_OPENED)); broadcastManager.registerReceiver(receiver1, getActiveSessionFilter(Session.ACTION_ACTIVE_SESSION_OPENED)); broadcastManager.registerReceiver(receiver1, getActiveSessionFilter(Session.ACTION_ACTIVE_SESSION_OPENED)); } }; runOnBlockerThread(initialize1, true); receiver1.incrementExpectCount(3); receiver2.incrementExpectCount(); Session.postActiveSessionAction(Session.ACTION_ACTIVE_SESSION_OPENED); receiver1.waitForExpectedCalls(); receiver2.waitForExpectedCalls(); receiver2.incrementExpectCount(); Session.postActiveSessionAction(Session.ACTION_ACTIVE_SESSION_CLOSED); receiver2.waitForExpectedCalls(); Session.postActiveSessionAction(Session.ACTION_ACTIVE_SESSION_SET); Session.postActiveSessionAction(Session.ACTION_ACTIVE_SESSION_UNSET); closeBlockerAndAssertSuccess(); } finally { broadcastManager.unregisterReceiver(receiver0); broadcastManager.unregisterReceiver(receiver1); broadcastManager.unregisterReceiver(receiver2); Session.setActiveSession(null); } } @SmallTest @MediumTest @LargeTest public void testSetActiveSession() { Session.setActiveSession(null); final WaitForBroadcastReceiver receiverOpened = new WaitForBroadcastReceiver(); final WaitForBroadcastReceiver receiverClosed = new WaitForBroadcastReceiver(); final WaitForBroadcastReceiver receiverSet = new WaitForBroadcastReceiver(); final WaitForBroadcastReceiver receiverUnset = new WaitForBroadcastReceiver(); final LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(getActivity()); try { Runnable initializeOnBlockerThread = new Runnable() { @Override public void run() { broadcastManager.registerReceiver(receiverOpened, getActiveSessionFilter(Session.ACTION_ACTIVE_SESSION_OPENED)); broadcastManager.registerReceiver(receiverClosed, getActiveSessionFilter(Session.ACTION_ACTIVE_SESSION_CLOSED)); broadcastManager.registerReceiver(receiverSet, getActiveSessionFilter(Session.ACTION_ACTIVE_SESSION_SET)); broadcastManager.registerReceiver(receiverUnset, getActiveSessionFilter(Session.ACTION_ACTIVE_SESSION_UNSET)); } }; runOnBlockerThread(initializeOnBlockerThread, true); // null -> null should not fire events assertEquals(null, Session.getActiveSession()); Session.setActiveSession(null); assertEquals(null, Session.getActiveSession()); Session session0 = new Session.Builder(getActivity()). setApplicationId("FakeAppId"). setTokenCachingStrategy(new MockTokenCachingStrategy()). build(); assertEquals(SessionState.CREATED_TOKEN_LOADED, session0.getState()); // For unopened session, we should only see the Set event. receiverSet.incrementExpectCount(); Session.setActiveSession(session0); assertEquals(session0, Session.getActiveSession()); receiverSet.waitForExpectedCalls(); // When we open it, then we should see the Opened event. receiverOpened.incrementExpectCount(); session0.openForRead(null); receiverOpened.waitForExpectedCalls(); // Setting to itself should not fire events Session.setActiveSession(session0); assertEquals(session0, Session.getActiveSession()); // Setting from one opened session to another should deliver a full // cycle of events WaitForBroadcastReceiver.incrementExpectCounts(receiverClosed, receiverUnset, receiverSet, receiverOpened); Session session1 = new Session.Builder(getActivity()). setApplicationId("FakeAppId"). setTokenCachingStrategy(new MockTokenCachingStrategy()). build(); assertEquals(SessionState.CREATED_TOKEN_LOADED, session1.getState()); session1.openForRead(null); assertEquals(SessionState.OPENED, session1.getState()); Session.setActiveSession(session1); WaitForBroadcastReceiver.waitForExpectedCalls(receiverClosed, receiverUnset, receiverSet, receiverOpened); assertEquals(SessionState.CLOSED, session0.getState()); assertEquals(session1, Session.getActiveSession()); closeBlockerAndAssertSuccess(); } finally { broadcastManager.unregisterReceiver(receiverOpened); broadcastManager.unregisterReceiver(receiverClosed); broadcastManager.unregisterReceiver(receiverSet); broadcastManager.unregisterReceiver(receiverUnset); Session.setActiveSession(null); } } @SmallTest @MediumTest @LargeTest public void testOpenSuccess() { ArrayList<String> permissions = new ArrayList<String>(); MockTokenCachingStrategy cache = new MockTokenCachingStrategy(null, 0); SessionStatusCallbackRecorder statusRecorder = new SessionStatusCallbackRecorder(); ScriptedSession session = createScriptedSessionOnBlockerThread(cache); AccessToken openToken = AccessToken .createFromString("A token of thanks", permissions, AccessTokenSource.TEST_USER); // Verify state with no token in cache assertEquals(SessionState.CREATED, session.getState()); session.addAuthorizeResult(openToken); session.openForRead(new Session.OpenRequest(getActivity()).setCallback(statusRecorder)); statusRecorder.waitForCall(session, SessionState.OPENING, null); statusRecorder.waitForCall(session, SessionState.OPENED, null); verifySessionHasToken(session, openToken); // Verify we get a close callback. session.close(); statusRecorder.waitForCall(session, SessionState.CLOSED, null); // Verify we saved the token to cache. assertTrue(cache.getSavedState() != null); assertEquals(openToken.getToken(), TokenCachingStrategy.getToken(cache.getSavedState())); // Verify token information is cleared. session.closeAndClearTokenInformation(); assertTrue(cache.getSavedState() == null); // Wait a bit so we can fail if any unexpected calls arrive on the // recorder. stall(STRAY_CALLBACK_WAIT_MILLISECONDS); statusRecorder.close(); } @SmallTest @MediumTest @LargeTest public void testOpenForPublishSuccess() { ArrayList<String> permissions = new ArrayList<String>(); MockTokenCachingStrategy cache = new MockTokenCachingStrategy(null, 0); SessionStatusCallbackRecorder statusRecorder = new SessionStatusCallbackRecorder(); ScriptedSession session = createScriptedSessionOnBlockerThread(cache); AccessToken openToken = AccessToken .createFromString("A token of thanks", permissions, AccessTokenSource.TEST_USER); // Verify state with no token in cache assertEquals(SessionState.CREATED, session.getState()); session.addAuthorizeResult(openToken); session.openForPublish(new Session.OpenRequest(getActivity()).setCallback(statusRecorder). setPermissions(Arrays.asList(new String[]{ "publish_something", "manage_something", "ads_management", "create_event", "rsvp_event" }))); statusRecorder.waitForCall(session, SessionState.OPENING, null); statusRecorder.waitForCall(session, SessionState.OPENED, null); verifySessionHasToken(session, openToken); // Verify we get a close callback. session.close(); statusRecorder.waitForCall(session, SessionState.CLOSED, null); // Verify we saved the token to cache. assertTrue(cache.getSavedState() != null); assertEquals(openToken.getToken(), TokenCachingStrategy.getToken(cache.getSavedState())); // Verify token information is cleared. session.closeAndClearTokenInformation(); assertTrue(cache.getSavedState() == null); // Wait a bit so we can fail if any unexpected calls arrive on the // recorder. stall(STRAY_CALLBACK_WAIT_MILLISECONDS); statusRecorder.close(); } @SmallTest @MediumTest @LargeTest public void testOpenForPublishSuccessWithReadPermissions() { ArrayList<String> permissions = new ArrayList<String>(); MockTokenCachingStrategy cache = new MockTokenCachingStrategy(null, 0); SessionStatusCallbackRecorder statusRecorder = new SessionStatusCallbackRecorder(); ScriptedSession session = createScriptedSessionOnBlockerThread(cache); AccessToken openToken = AccessToken .createFromString("A token of thanks", permissions, AccessTokenSource.TEST_USER); // Verify state with no token in cache assertEquals(SessionState.CREATED, session.getState()); session.addAuthorizeResult(openToken); session.openForPublish(new Session.OpenRequest(getActivity()).setCallback(statusRecorder). setPermissions(Arrays.asList(new String[]{ "publish_something", "manage_something", "ads_management", "create_event", "rsvp_event", "read_something" }))); statusRecorder.waitForCall(session, SessionState.OPENING, null); statusRecorder.waitForCall(session, SessionState.OPENED, null); verifySessionHasToken(session, openToken); // Verify we get a close callback. session.close(); statusRecorder.waitForCall(session, SessionState.CLOSED, null); // Verify we saved the token to cache. assertTrue(cache.getSavedState() != null); assertEquals(openToken.getToken(), TokenCachingStrategy.getToken(cache.getSavedState())); // Verify token information is cleared. session.closeAndClearTokenInformation(); assertTrue(cache.getSavedState() == null); // Wait a bit so we can fail if any unexpected calls arrive on the // recorder. stall(STRAY_CALLBACK_WAIT_MILLISECONDS); statusRecorder.close(); } @SmallTest @MediumTest @LargeTest public void testOpenFromTokenCache() { SessionStatusCallbackRecorder statusRecorder = new SessionStatusCallbackRecorder(); String token = "A token less unique than most"; MockTokenCachingStrategy cache = new MockTokenCachingStrategy(token, DEFAULT_TIMEOUT_MILLISECONDS); ScriptedSession session = createScriptedSessionOnBlockerThread("app-id", cache); // Verify state when we have a token in cache. assertEquals(SessionState.CREATED_TOKEN_LOADED, session.getState()); session.openForRead(new Session.OpenRequest(getActivity()).setCallback(statusRecorder)); // Verify we open with no authorize call. statusRecorder.waitForCall(session, SessionState.OPENED, null); // Verify no token information is saved. assertTrue(cache.getSavedState() == null); // Verify we get a close callback. session.close(); statusRecorder.waitForCall(session, SessionState.CLOSED, null); // Wait a bit so we can fail if any unexpected calls arrive on the // recorder. stall(STRAY_CALLBACK_WAIT_MILLISECONDS); statusRecorder.close(); } @SmallTest @MediumTest @LargeTest public void testOpenActiveFromEmptyTokenCache() { new SharedPreferencesTokenCachingStrategy(getActivity()).clear(); assertNull(Session.openActiveSessionFromCache(getActivity())); } @SmallTest @MediumTest @LargeTest public void testOpenFailure() { SessionStatusCallbackRecorder statusRecorder = new SessionStatusCallbackRecorder(); MockTokenCachingStrategy cache = new MockTokenCachingStrategy(null, 0); ScriptedSession session = createScriptedSessionOnBlockerThread(cache); Exception openException = new Exception(); session.addAuthorizeResult(openException); session.openForRead(new Session.OpenRequest(getActivity()).setCallback(statusRecorder)); statusRecorder.waitForCall(session, SessionState.OPENING, null); // Verify we get the expected exception and no saved state. statusRecorder.waitForCall(session, SessionState.CLOSED_LOGIN_FAILED, openException); assertTrue(cache.getSavedState() == null); // Wait a bit so we can fail if any unexpected calls arrive on the // recorder. stall(STRAY_CALLBACK_WAIT_MILLISECONDS); statusRecorder.close(); } @SmallTest @MediumTest @LargeTest public void testOpenForReadFailure() { SessionStatusCallbackRecorder statusRecorder = new SessionStatusCallbackRecorder(); MockTokenCachingStrategy cache = new MockTokenCachingStrategy(null, 0); ScriptedSession session = createScriptedSessionOnBlockerThread(cache); try { session.openForRead(new Session.OpenRequest(getActivity()).setCallback(statusRecorder). setPermissions(Arrays.asList(new String[]{"publish_something"}))); fail("should not reach here without an exception"); } catch (FacebookException e) { assertTrue(e.getMessage().contains("Cannot pass a publish or manage permission")); } finally { stall(STRAY_CALLBACK_WAIT_MILLISECONDS); statusRecorder.close(); } } @SmallTest @MediumTest @LargeTest public void testRequestNewReadPermissionsSuccess() { ArrayList<String> permissions = new ArrayList<String>(); SessionStatusCallbackRecorder statusRecorder = new SessionStatusCallbackRecorder(); MockTokenCachingStrategy cache = new MockTokenCachingStrategy(null, 0); ScriptedSession session = createScriptedSessionOnBlockerThread(cache); // Session.open final AccessToken openToken = AccessToken .createFromString("Allows playing outside", permissions, AccessTokenSource.TEST_USER); permissions.add("play_outside"); session.addAuthorizeResult(openToken, "play_outside"); session.openForRead(new Session.OpenRequest(getActivity()).setCallback(statusRecorder)); statusRecorder.waitForCall(session, SessionState.OPENING, null); statusRecorder.waitForCall(session, SessionState.OPENED, null); verifySessionHasToken(session, openToken); assertTrue(cache.getSavedState() != null); assertEquals(openToken.getToken(), TokenCachingStrategy.getToken(cache.getSavedState())); // Successful Session.reauthorize with new permissions final AccessToken reauthorizeToken = AccessToken.createFromString( "Allows playing outside and eating ice cream", permissions, AccessTokenSource.TEST_USER); permissions.add("eat_ice_cream"); session.addAuthorizeResult(reauthorizeToken, "play_outside", "eat_ice_cream"); session.requestNewReadPermissions(new Session.NewPermissionsRequest(getActivity(), permissions)); statusRecorder.waitForCall(session, SessionState.OPENED_TOKEN_UPDATED, null); verifySessionHasToken(session, reauthorizeToken); assertTrue(cache.getSavedState() != null); assertEquals(reauthorizeToken.getToken(), TokenCachingStrategy.getToken(cache.getSavedState())); // Failing reauthorization with new permissions final Exception reauthorizeException = new Exception("Don't run with scissors"); permissions.add("run_with_scissors"); session.addAuthorizeResult(reauthorizeException); session.requestNewReadPermissions(new Session.NewPermissionsRequest(getActivity(), permissions)); statusRecorder.waitForCall(session, SessionState.OPENED_TOKEN_UPDATED, reauthorizeException); // Verify we do not overwrite cache if reauthorize fails assertTrue(cache.getSavedState() != null); assertEquals(reauthorizeToken.getToken(), TokenCachingStrategy.getToken(cache.getSavedState())); // Wait a bit so we can fail if any unexpected calls arrive on the // recorders. stall(STRAY_CALLBACK_WAIT_MILLISECONDS); statusRecorder.close(); } @SmallTest @MediumTest @LargeTest public void testRequestNewPublishPermissionsSuccess() { ArrayList<String> permissions = new ArrayList<String>(); SessionStatusCallbackRecorder statusRecorder = new SessionStatusCallbackRecorder(); MockTokenCachingStrategy cache = new MockTokenCachingStrategy(null, 0); ScriptedSession session = createScriptedSessionOnBlockerThread(cache); // Session.open final AccessToken openToken = AccessToken .createFromString("Allows playing outside", permissions, AccessTokenSource.TEST_USER); permissions.add("play_outside"); session.addAuthorizeResult(openToken, "play_outside"); session.openForRead(new Session.OpenRequest(getActivity()).setCallback(statusRecorder)); statusRecorder.waitForCall(session, SessionState.OPENING, null); statusRecorder.waitForCall(session, SessionState.OPENED, null); verifySessionHasToken(session, openToken); assertTrue(cache.getSavedState() != null); assertEquals(openToken.getToken(), TokenCachingStrategy.getToken(cache.getSavedState())); // Successful Session.reauthorize with new permissions final AccessToken reauthorizeToken = AccessToken.createFromString( "Allows playing outside and publish eating ice cream", permissions, AccessTokenSource.TEST_USER); permissions.add("publish_eat_ice_cream"); session.addAuthorizeResult(reauthorizeToken, "play_outside", "publish_eat_ice_cream"); session.requestNewPublishPermissions(new Session.NewPermissionsRequest(getActivity(), permissions)); statusRecorder.waitForCall(session, SessionState.OPENED_TOKEN_UPDATED, null); verifySessionHasToken(session, reauthorizeToken); assertTrue(cache.getSavedState() != null); assertEquals(reauthorizeToken.getToken(), TokenCachingStrategy.getToken(cache.getSavedState())); // Failing reauthorization with publish permissions on a read request permissions.add("publish_run_with_scissors"); try { session.requestNewReadPermissions(new Session.NewPermissionsRequest(getActivity(), permissions)); fail("Should not reach here without an exception"); } catch (FacebookException e) { assertTrue(e.getMessage().contains("Cannot pass a publish or manage permission")); } finally { stall(STRAY_CALLBACK_WAIT_MILLISECONDS); statusRecorder.close(); } } @SmallTest @MediumTest @LargeTest public void testOpenWithAccessToken() { String token = "This is a fake token."; Date expirationDate = new Date(new Date().getTime() + 3600 * 1000); Date lastRefreshDate = new Date(); List<String> permissions = Arrays.asList(new String[]{"email", "publish_stream"}); MockTokenCachingStrategy cache = new MockTokenCachingStrategy(null, 0); SessionStatusCallbackRecorder statusRecorder = new SessionStatusCallbackRecorder(); ScriptedSession session = createScriptedSessionOnBlockerThread(cache); // Verify state with no token in cache assertEquals(SessionState.CREATED, session.getState()); AccessToken accessToken = AccessToken.createFromExistingAccessToken(token, expirationDate, lastRefreshDate, AccessTokenSource.FACEBOOK_APPLICATION_WEB, permissions); session.open(accessToken, statusRecorder); statusRecorder.waitForCall(session, SessionState.OPENED, null); AccessToken expectedToken = new AccessToken(token, expirationDate, permissions, AccessTokenSource.FACEBOOK_APPLICATION_WEB, lastRefreshDate); verifySessionHasToken(session, expectedToken); // Verify we get a close callback. session.close(); statusRecorder.waitForCall(session, SessionState.CLOSED, null); // Verify we saved the token to cache. assertTrue(cache.getSavedState() != null); assertEquals(expectedToken.getToken(), TokenCachingStrategy.getToken(cache.getSavedState())); // Verify token information is cleared. session.closeAndClearTokenInformation(); assertTrue(cache.getSavedState() == null); // Wait a bit so we can fail if any unexpected calls arrive on the // recorder. stall(STRAY_CALLBACK_WAIT_MILLISECONDS); statusRecorder.close(); } @SmallTest @MediumTest @LargeTest public void testOpenWithAccessTokenWithDefaults() { String token = "This is a fake token."; MockTokenCachingStrategy cache = new MockTokenCachingStrategy(null, 0); SessionStatusCallbackRecorder statusRecorder = new SessionStatusCallbackRecorder(); ScriptedSession session = createScriptedSessionOnBlockerThread(cache); // Verify state with no token in cache assertEquals(SessionState.CREATED, session.getState()); AccessToken accessToken = AccessToken.createFromExistingAccessToken(token, null, null, null, null); session.open(accessToken, statusRecorder); statusRecorder.waitForCall(session, SessionState.OPENED, null); assertEquals(token, session.getAccessToken()); assertEquals(new Date(Long.MAX_VALUE), session.getExpirationDate()); assertEquals(0, session.getPermissions().size()); // Verify we get a close callback. session.close(); statusRecorder.waitForCall(session, SessionState.CLOSED, null); // Verify we saved the token to cache. assertTrue(cache.getSavedState() != null); // Verify token information is cleared. session.closeAndClearTokenInformation(); assertTrue(cache.getSavedState() == null); // Wait a bit so we can fail if any unexpected calls arrive on the // recorder. stall(STRAY_CALLBACK_WAIT_MILLISECONDS); statusRecorder.close(); } @MediumTest @LargeTest public void testSessionWillExtendTokenIfNeeded() { TestSession session = openTestSessionWithSharedUser(); session.forceExtendAccessToken(true); Request request = Request.newMeRequest(session, null); request.executeAndWait(); assertTrue(session.getWasAskedToExtendAccessToken()); } @MediumTest @LargeTest public void testSessionWillNotExtendTokenIfCurrentlyAttempting() { TestSession session = openTestSessionWithSharedUser(); session.forceExtendAccessToken(true); session.fakeTokenRefreshAttempt(); Request request = Request.newMeRequest(session, null); request.executeAndWait(); assertFalse(session.getWasAskedToExtendAccessToken()); } @LargeTest public void testBasicSerialization() throws IOException, ClassNotFoundException { // Try to test the happy path, that there are no unserializable fields // in the session. Session session0 = new Session.Builder(getActivity()).setApplicationId("fakeID").build(); Session session1 = TestUtils.serializeAndUnserialize(session0); // do some basic assertions assertNotNull(session0.getAccessToken()); assertEquals(session0, session1); Session.AuthorizationRequest authRequest0 = new Session.OpenRequest(getActivity()). setRequestCode(123). setLoginBehavior(SessionLoginBehavior.SSO_ONLY); Session.AuthorizationRequest authRequest1 = TestUtils.serializeAndUnserialize(authRequest0); assertEquals(authRequest0.getLoginBehavior(), authRequest1.getLoginBehavior()); assertEquals(authRequest0.getRequestCode(), authRequest1.getRequestCode()); } @SmallTest @MediumTest @LargeTest public void testOpenSessionWithNativeLinkingIntent() { String token = "A token less unique than most"; Intent intent = new Intent(Intent.ACTION_MAIN); intent.putExtras(getNativeLinkingExtras(token)); SessionStatusCallbackRecorder statusRecorder = new SessionStatusCallbackRecorder(); MockTokenCachingStrategy cache = new MockTokenCachingStrategy(null, DEFAULT_TIMEOUT_MILLISECONDS); ScriptedSession session = createScriptedSessionOnBlockerThread(cache); assertEquals(SessionState.CREATED, session.getState()); AccessToken accessToken = AccessToken.createFromNativeLinkingIntent(intent); assertNotNull(accessToken); session.open(accessToken, statusRecorder); statusRecorder.waitForCall(session, SessionState.OPENED, null); assertEquals(token, session.getAccessToken()); // Expiration time should be 3600s after now (allow 5s variation for test execution time) long delta = session.getExpirationDate().getTime() - new Date().getTime(); assertTrue(Math.abs(delta - 3600 * 1000) < 5000); assertEquals(0, session.getPermissions().size()); assertEquals(Utility.getMetadataApplicationId(getActivity()), session.getApplicationId()); // Verify we get a close callback. session.close(); statusRecorder.waitForCall(session, SessionState.CLOSED, null); assertFalse(cache.getSavedState() == null); // Wait a bit so we can fail if any unexpected calls arrive on the // recorder. stall(STRAY_CALLBACK_WAIT_MILLISECONDS); statusRecorder.close(); } @SmallTest @MediumTest @LargeTest public void testOpenActiveSessionWithNativeLinkingIntent() { Session activeSession = Session.getActiveSession(); if (activeSession != null) { activeSession.closeAndClearTokenInformation(); } SharedPreferencesTokenCachingStrategy tokenCache = new SharedPreferencesTokenCachingStrategy(getActivity()); assertEquals(0, tokenCache.load().size()); String token = "A token less unique than most"; Intent intent = new Intent(Intent.ACTION_MAIN); intent.putExtras(getNativeLinkingExtras(token)); SessionStatusCallbackRecorder statusRecorder = new SessionStatusCallbackRecorder(); AccessToken accessToken = AccessToken.createFromNativeLinkingIntent(intent); assertNotNull(accessToken); Session session = Session.openActiveSessionWithAccessToken(getActivity(), accessToken, statusRecorder); assertEquals(session, Session.getActiveSession()); statusRecorder.waitForCall(session, SessionState.OPENED, null); assertNotSame(0, tokenCache.load().size()); assertEquals(token, session.getAccessToken()); // Expiration time should be 3600s after now (allow 5s variation for test execution time) long delta = session.getExpirationDate().getTime() - new Date().getTime(); assertTrue(Math.abs(delta - 3600 * 1000) < 5000); assertEquals(0, session.getPermissions().size()); assertEquals(Utility.getMetadataApplicationId(getActivity()), session.getApplicationId()); // Verify we get a close callback. session.close(); statusRecorder.waitForCall(session, SessionState.CLOSED, null); // Wait a bit so we can fail if any unexpected calls arrive on the // recorder. stall(STRAY_CALLBACK_WAIT_MILLISECONDS); statusRecorder.close(); } @SmallTest @MediumTest @LargeTest public void testOpeningSessionWithPendingRequestResultsInExceptionCallback() { ArrayList<String> permissions = new ArrayList<String>(); MockTokenCachingStrategy cache = new MockTokenCachingStrategy(null, 0); SessionStatusCallbackRecorder statusRecorder = new SessionStatusCallbackRecorder(); ScriptedSession session = createScriptedSessionOnBlockerThread(cache); AccessToken openToken = AccessToken .createFromString("A token of thanks", permissions, AccessTokenSource.TEST_USER); // Verify state with no token in cache assertEquals(SessionState.CREATED, session.getState()); session.addPendingAuthorizeResult(); session.openForRead(new Session.OpenRequest(getActivity()).setCallback(statusRecorder)); session.openForRead(new Session.OpenRequest(getActivity()).setCallback(statusRecorder)); statusRecorder.waitForCall(session, SessionState.OPENING, null); statusRecorder.waitForCall(session, SessionState.OPENING, new UnsupportedOperationException()); stall(STRAY_CALLBACK_WAIT_MILLISECONDS); statusRecorder.close(); } static IntentFilter getActiveSessionFilter(String... actions) { IntentFilter filter = new IntentFilter(); for (String action : actions) { filter.addAction(action); } return filter; } static IntentFilter getActiveSessionAllFilter() { return getActiveSessionFilter(Session.ACTION_ACTIVE_SESSION_CLOSED, Session.ACTION_ACTIVE_SESSION_OPENED, Session.ACTION_ACTIVE_SESSION_SET, Session.ACTION_ACTIVE_SESSION_UNSET); } private void verifySessionHasToken(Session session, AccessToken token) { assertEquals(token.getToken(), session.getAccessToken()); assertEquals(token.getExpires(), session.getExpirationDate()); TestUtils.assertAtLeastExpectedPermissions(token.getPermissions(), session.getPermissions()); } }