package com.mopub.mobileads; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Build.VERSION_CODES; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.webkit.WebViewClient; import android.widget.FrameLayout; import com.mopub.common.test.support.SdkTestRunner; import com.mopub.mraid.MraidBridge; import com.mopub.mraid.MraidBridge.MraidWebView; import com.mopub.mraid.MraidController; import com.mopub.mraid.MraidController.MraidListener; import org.fest.assertions.api.ANDROID; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.robolectric.Robolectric; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowLocalBroadcastManager; import static com.mopub.mobileads.EventForwardingBroadcastReceiver.ACTION_INTERSTITIAL_CLICK; import static com.mopub.mobileads.EventForwardingBroadcastReceiver.ACTION_INTERSTITIAL_DISMISS; import static com.mopub.mobileads.EventForwardingBroadcastReceiver.ACTION_INTERSTITIAL_SHOW; import static com.mopub.common.DataKeys.BROADCAST_IDENTIFIER_KEY; import static com.mopub.mobileads.EventForwardingBroadcastReceiver.getHtmlInterstitialIntentFilter; import static com.mopub.mobileads.EventForwardingBroadcastReceiverTest.getIntentForActionAndIdentifier; import static com.mopub.common.DataKeys.HTML_RESPONSE_BODY_KEY; import static org.fest.assertions.api.Assertions.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.robolectric.Robolectric.shadowOf; @RunWith(SdkTestRunner.class) public class MraidActivityTest { static final String EXPECTED_SOURCE = "expected source"; @Mock MraidWebView mraidWebView; @Mock MraidBridge mraidBridge; @Mock MraidController mraidController; @Mock CustomEventInterstitial.CustomEventInterstitialListener customEventInterstitialListener; @Mock BroadcastReceiver broadcastReceiver; long testBroadcastIdentifier = 2222; TestMraidActivity subject; // Make a concrete version of the abstract class for testing purposes. private static class TestMraidActivity extends MraidActivity { View mraidWebView; @Override public View getAdView() { return mraidWebView; } } @Before public void setUp() throws Exception { subject = Robolectric.buildActivity(TestMraidActivity.class).get(); subject.mraidWebView = mraidWebView; Robolectric.shadowOf(subject).callOnCreate(null); } @Ignore("Mraid 2.0") @Test public void preRenderHtml_shouldDisablePluginsSetListenersAndLoadHtml() throws Exception { MraidActivity.preRenderHtml(subject, customEventInterstitialListener, "3:27"); verify(mraidWebView).enablePlugins(eq(false)); verify(mraidController).setMraidListener(any(MraidListener.class)); verify(mraidWebView).setWebViewClient(any(WebViewClient.class)); verify(mraidBridge).setContentHtml(eq("3:27")); } @Ignore("Mraid 2.0") @Test public void preRenderHtml_shouldCallCustomEventInterstitialOnInterstitialLoaded_whenMraidListenerOnReady() throws Exception { MraidActivity.preRenderHtml(subject, customEventInterstitialListener, ""); ArgumentCaptor<MraidListener> mraidListenerArgumentCaptorr = ArgumentCaptor.forClass(MraidListener.class); verify(mraidController).setMraidListener(mraidListenerArgumentCaptorr.capture()); MraidListener mraidListener = mraidListenerArgumentCaptorr.getValue(); mraidListener.onLoaded(null); verify(customEventInterstitialListener).onInterstitialLoaded(); } @Ignore("Mraid 2.0") @Test public void preRenderHtml_shouldCallCustomEventInterstitialOnInterstitialFailed_whenMraidListenerOnFailure() throws Exception { MraidActivity.preRenderHtml(subject, customEventInterstitialListener, ""); ArgumentCaptor<MraidListener> mraidListenerArgumentCaptorr = ArgumentCaptor.forClass(MraidListener.class); verify(mraidController).setMraidListener(mraidListenerArgumentCaptorr.capture()); MraidListener mraidListener = mraidListenerArgumentCaptorr.getValue(); mraidListener.onFailedToLoad(); verify(customEventInterstitialListener).onInterstitialFailed(null); } @Ignore("Mraid 2.0") @Test public void preRenderHtml_whenWebViewClientShouldOverrideUrlLoading_shouldReturnTrue() throws Exception { MraidActivity.preRenderHtml(subject, customEventInterstitialListener, ""); ArgumentCaptor<WebViewClient> webViewClientArgumentCaptor = ArgumentCaptor.forClass(WebViewClient.class); verify(mraidWebView).setWebViewClient(webViewClientArgumentCaptor.capture()); WebViewClient webViewClient = webViewClientArgumentCaptor.getValue(); boolean consumeUrlLoading = webViewClient.shouldOverrideUrlLoading(null, null); assertThat(consumeUrlLoading).isTrue(); verify(customEventInterstitialListener, never()).onInterstitialLoaded(); verify(customEventInterstitialListener, never()).onInterstitialFailed( any(MoPubErrorCode.class)); } @Ignore("Mraid 2.0") @Test public void preRenderHtml_shouldCallCustomEventInterstitialOnInterstitialLoaded_whenWebViewClientOnPageFinished() throws Exception { MraidActivity.preRenderHtml(subject, customEventInterstitialListener, ""); ArgumentCaptor<WebViewClient> webViewClientArgumentCaptor = ArgumentCaptor.forClass(WebViewClient.class); verify(mraidWebView).setWebViewClient(webViewClientArgumentCaptor.capture()); WebViewClient webViewClient = webViewClientArgumentCaptor.getValue(); webViewClient.onPageFinished(null, null); verify(customEventInterstitialListener).onInterstitialLoaded(); } @Ignore("Mraid 2.0") @Test public void onCreate_shouldSetContentView() throws Exception { subject.onCreate(null); assertThat(getContentView().getChildCount()).isEqualTo(1); } @Ignore("Mraid 2.0") @Test public void onCreate_shouldSetupAnMraidView() throws Exception { subject.onCreate(null); assertThat(getContentView().getChildAt(0)).isSameAs(mraidWebView); verify(mraidController).setMraidListener(any(MraidListener.class)); verify(mraidBridge).setContentHtml(EXPECTED_SOURCE); } @Ignore("Mraid 2.0") @Test public void onCreate_shouldSetLayoutOfMraidView() throws Exception { subject.onCreate(null); ArgumentCaptor<FrameLayout.LayoutParams> captor = ArgumentCaptor.forClass( FrameLayout.LayoutParams.class); verify(mraidWebView).setLayoutParams(captor.capture()); FrameLayout.LayoutParams actualLayoutParams = captor.getValue(); assertThat(actualLayoutParams.width).isEqualTo(FrameLayout.LayoutParams.MATCH_PARENT); assertThat(actualLayoutParams.height).isEqualTo(FrameLayout.LayoutParams.MATCH_PARENT); } @Config(reportSdk = VERSION_CODES.ICE_CREAM_SANDWICH) @Ignore("Mraid 2.0") @Test public void onCreate_atLeastIcs_shouldSetHardwareAcceleratedFlag() throws Exception { subject.onCreate(null); boolean hardwareAccelerated = shadowOf(subject.getWindow()).getFlag(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); assertThat(hardwareAccelerated).isTrue(); } @Config(reportSdk = VERSION_CODES.HONEYCOMB_MR2) @Ignore("Mraid 2.0") @Test public void onCreate_beforeIcs_shouldNotSetHardwareAcceleratedFlag() throws Exception { subject.onCreate(null); boolean hardwareAccelerated = shadowOf(subject.getWindow()).getFlag(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); assertThat(hardwareAccelerated).isFalse(); } @Ignore("Mraid 2.0") @Test public void onDestroy_DestroyMraidView() throws Exception { Intent expectedIntent = getIntentForActionAndIdentifier(ACTION_INTERSTITIAL_DISMISS, subject.getBroadcastIdentifier()); ShadowLocalBroadcastManager.getInstance(subject).registerReceiver(broadcastReceiver, getHtmlInterstitialIntentFilter()); subject.onDestroy(); verify(broadcastReceiver).onReceive(any(Context.class), eq(expectedIntent)); verify(mraidWebView).destroy(); assertThat(getContentView().getChildCount()).isEqualTo(0); } @Ignore("Mraid 2.0") @Test public void getAdView_shouldSetupOnReadyListener() throws Exception { reset(mraidWebView); ArgumentCaptor<MraidListener> captor = ArgumentCaptor.forClass(MraidListener.class); View actualAdView = subject.getAdView(); assertThat(actualAdView).isSameAs(mraidWebView); verify(mraidController).setMraidListener(captor.capture()); subject.hideInterstitialCloseButton(); captor.getValue().onLoaded(null); } @Ignore("Mraid 2.0") @Test public void baseMraidListenerOnReady_shouldFireJavascriptWebViewDidAppear() throws Exception { reset(mraidWebView); ArgumentCaptor<MraidListener> captor = ArgumentCaptor.forClass(MraidListener.class); View actualAdView = subject.getAdView(); assertThat(actualAdView).isSameAs(mraidWebView); verify(mraidController).setMraidListener(captor.capture()); MraidListener baseMraidListener = captor.getValue(); baseMraidListener.onLoaded(null); verify(mraidWebView).loadUrl(eq("javascript:webviewDidAppear();")); } @Ignore("Mraid 2.0") @Test public void baseMraidListenerOnClose_shouldFireJavascriptWebViewDidClose() throws Exception { reset(mraidWebView); ArgumentCaptor<MraidListener> captor = ArgumentCaptor.forClass(MraidListener.class); View actualAdView = subject.getAdView(); assertThat(actualAdView).isSameAs(mraidWebView); verify(mraidController).setMraidListener(captor.capture()); MraidListener baseMraidListener = captor.getValue(); baseMraidListener.onClose(); verify(mraidWebView).loadUrl(eq("javascript:webviewDidClose();")); } @Ignore("Mraid 2.0") @Test public void baseMraidListenerOnOpen_shouldBroadcastClickEvent() throws Exception { Intent expectedIntent = getIntentForActionAndIdentifier(ACTION_INTERSTITIAL_CLICK, testBroadcastIdentifier); ShadowLocalBroadcastManager.getInstance(subject).registerReceiver(broadcastReceiver, getHtmlInterstitialIntentFilter()); reset(mraidWebView); ArgumentCaptor<MraidListener> captor = ArgumentCaptor.forClass(MraidListener.class); View actualAdView = subject.getAdView(); assertThat(actualAdView).isSameAs(mraidWebView); verify(mraidController).setMraidListener(captor.capture()); MraidListener baseMraidListener = captor.getValue(); baseMraidListener.onOpen(); verify(broadcastReceiver).onReceive(any(Context.class), eq(expectedIntent)); } @Ignore("Mraid 2.0") @Test public void getAdView_shouldSetupOnCloseListener() throws Exception { reset(mraidWebView); ArgumentCaptor<MraidListener> captor = ArgumentCaptor.forClass(MraidListener.class); View actualAdView = subject.getAdView(); assertThat(actualAdView).isSameAs(mraidWebView); verify(mraidController).setMraidListener(captor.capture()); captor.getValue().onClose(); ANDROID.assertThat(subject).isFinishing(); } @Ignore("Mraid 2.0") @Test public void onPause_shouldOnPauseMraidView() throws Exception { Robolectric.shadowOf(subject).callOnPause(); verify(mraidWebView).onPause(); } @Ignore("Mraid 2.0") @Test public void onResume_shouldResumeMraidView() throws Exception { subject.onCreate(null); Robolectric.shadowOf(subject).pauseAndThenResume(); verify(mraidWebView).onResume(); } private Intent createMraidActivityIntent(String expectedSource) { Intent mraidActivityIntent = new Intent(); mraidActivityIntent.setComponent(new ComponentName("", "")); mraidActivityIntent.putExtra(HTML_RESPONSE_BODY_KEY, expectedSource); mraidActivityIntent.putExtra(BROADCAST_IDENTIFIER_KEY, testBroadcastIdentifier); return mraidActivityIntent; } @Ignore("Mraid 2.0") @Test public void onCreate_shouldBroadcastInterstitialShow() throws Exception { Intent expectedIntent = getIntentForActionAndIdentifier(ACTION_INTERSTITIAL_SHOW, testBroadcastIdentifier); ShadowLocalBroadcastManager.getInstance(subject).registerReceiver(broadcastReceiver, getHtmlInterstitialIntentFilter()); verify(broadcastReceiver).onReceive(any(Context.class), eq(expectedIntent)); } @Ignore("Mraid 2.0") @Test public void onDestroy_shouldBroadcastInterstitialDismiss() throws Exception { Intent expectedIntent = getIntentForActionAndIdentifier(ACTION_INTERSTITIAL_DISMISS, testBroadcastIdentifier); ShadowLocalBroadcastManager.getInstance(subject).registerReceiver(broadcastReceiver, getHtmlInterstitialIntentFilter()); subject.onDestroy(); verify(broadcastReceiver).onReceive(any(Context.class), eq(expectedIntent)); } private FrameLayout getContentView() { return (FrameLayout) ((ViewGroup) subject.findViewById(android.R.id.content)).getChildAt(0); } }