/* * Copyright (C) 2014 SCVNGR, Inc. d/b/a LevelUp * * 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.scvngr.levelup.deeplinkauth; import android.app.Activity; import android.app.AlertDialog; import android.app.Instrumentation.ActivityMonitor; import android.app.Instrumentation.ActivityResult; import android.content.DialogInterface; import android.content.DialogInterface.OnDismissListener; import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.test.suitebuilder.annotation.MediumTest; import android.widget.Button; import com.scvngr.levelup.core.test.SupportActivityInstrumentationTestCase; import com.scvngr.levelup.ui.activity.TestFragmentActivity; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; /** * Tests {@link LevelUpDeepLinkIntegrator}. */ public final class LevelUpDeepLinkAuthIntegratorTest extends SupportActivityInstrumentationTestCase<TestFragmentActivity> { private static final int APP_ID_FIXTURE = 5; private static final String ACCESS_TOKEN_FIXTURE = "test_access_token"; private static final List<String> PERMISSIONS_FIXTURE = Collections.unmodifiableList(Arrays .asList("test_permission", "test_permission_ii")); public LevelUpDeepLinkAuthIntegratorTest() { super(TestFragmentActivity.class); } /** * Tests that the integrator creates the correct launch intent. * * @throws Throwable */ @MediumTest public void testRequestPermissions() throws Throwable { final TestFragmentActivity activity = getActivity(); final LevelUpDeepLinkIntegrator integrator = new LevelUpDeepLinkIntegrator(activity, APP_ID_FIXTURE); integrator .setLevelUpAppSignatures(new String[] { DeepLinkAuthUtilTest.APP_SIGNATURE_THIS }); // This intent filter needs to match the one defined in the AndroidManifest final IntentFilter permissionsRequestFilter = new IntentFilter(DeepLinkAuthUtil.ACTION_REQUEST_PERMISSIONS); permissionsRequestFilter.addCategory(Intent.CATEGORY_DEFAULT); permissionsRequestFilter.addDataScheme("lutest"); permissionsRequestFilter.addDataAuthority("authorization", null); final Intent expectedResultIntent = DeepLinkAuthUtil.toIntent(activity, APP_ID_FIXTURE, PERMISSIONS_FIXTURE); expectedResultIntent.putExtra(DeepLinkAuthUtil.EXTRA_STRING_ACCESS_TOKEN, ACCESS_TOKEN_FIXTURE); final ActivityResult expectedResult = new ActivityResult(Activity.RESULT_OK, expectedResultIntent); final ActivityMonitor monitor = getInstrumentation().addMonitor(permissionsRequestFilter, expectedResult, true); final AtomicReference<AlertDialog> ad = new AtomicReference<AlertDialog>(); runTestOnUiThread(new Runnable() { @Override public void run() { ad.set(integrator.requestPermissions(PERMISSIONS_FIXTURE)); } }); assertNull(ad.get()); final ActivityResult actualResult = monitor.getResult(); assertTrue(getInstrumentation().checkMonitorHit(monitor, 1)); assertEquals(expectedResult.getResultCode(), actualResult.getResultCode()); assertEquals(expectedResultIntent.getAction(), actualResult.getResultData().getAction()); } @MediumTest public void testRequestPermissions_notInstalled_install() throws Throwable { final TestFragmentActivity activity = getActivity(); final LevelUpDeepLinkIntegrator integrator = new LevelUpDeepLinkIntegrator(activity, APP_ID_FIXTURE); integrator.setLevelUpAppSignatures(new String[] { /* intentionally empty */}); final CountDownLatch dismissLatch = new CountDownLatch(1); integrator.setOnDismissListener(new OnDismissListener() { @Override public void onDismiss(final DialogInterface dialog) { dismissLatch.countDown(); } }); final IntentFilter installIntentFilter = new IntentFilter(Intent.ACTION_VIEW); installIntentFilter.addDataScheme("market"); installIntentFilter.addDataAuthority("details", null); installIntentFilter.addCategory(Intent.CATEGORY_DEFAULT); getInstrumentation().addMonitor(installIntentFilter, null, true); final AtomicReference<AlertDialog> ad = new AtomicReference<AlertDialog>(); runTestOnUiThread(new Runnable() { @Override public void run() { ad.set(integrator.requestPermissions(PERMISSIONS_FIXTURE)); } }); assertNotNull(ad.get()); assertNull(integrator.getLastStartedIntent()); runTestOnUiThread(new Runnable() { @Override public void run() { final Button positive = ad.get().getButton(DialogInterface.BUTTON_POSITIVE); assertTrue(positive.performClick()); } }); assertTrue(dismissLatch.await(4, TimeUnit.SECONDS)); final Intent startedIntent = integrator.getLastStartedIntent(); assertNotNull(startedIntent); final Uri startedIntentData = startedIntent.getData(); assertNotNull(startedIntentData); assertEquals(startedIntentData.getQueryParameter("id"), "com.scvngr.levelup.app"); } @MediumTest public void testRequestPermissions_notInstalled_cancel() throws Throwable { final TestFragmentActivity activity = getActivity(); final LevelUpDeepLinkIntegrator integrator = new LevelUpDeepLinkIntegrator(activity, APP_ID_FIXTURE); integrator.setLevelUpAppSignatures(new String[] { /* intentionally empty */}); final CountDownLatch dismissLatch = new CountDownLatch(1); integrator.setOnDismissListener(new OnDismissListener() { @Override public void onDismiss(final DialogInterface dialog) { dismissLatch.countDown(); } }); final AtomicReference<AlertDialog> ad = new AtomicReference<AlertDialog>(); runTestOnUiThread(new Runnable() { @Override public void run() { ad.set(integrator.requestPermissions(PERMISSIONS_FIXTURE)); } }); assertNotNull(ad.get()); final IntentFilter installIntentFilter = new IntentFilter(Intent.ACTION_VIEW); installIntentFilter.addDataScheme("market"); installIntentFilter.addCategory(Intent.CATEGORY_DEFAULT); final ActivityMonitor monitor = getInstrumentation().addMonitor(installIntentFilter, null, true); runTestOnUiThread(new Runnable() { @Override public void run() { final Button negative = ad.get().getButton(DialogInterface.BUTTON_NEGATIVE); assertTrue(negative.performClick()); } }); assertTrue(dismissLatch.await(4, TimeUnit.SECONDS)); // Double-negative here, as getHits() isn't threadsafe and there's no checkMonitorNotHit() assertFalse(getInstrumentation().checkMonitorHit(monitor, 1)); } }