From 586a712fe18312e0dddfeb48d5096aed22588cf6 Mon Sep 17 00:00:00 2001 From: Mobile Ads Developer Relations Date: Fri, 20 Sep 2024 16:57:17 -0700 Subject: [PATCH] Add unit tests for myTarget Rewarded Ad and related callback methods. PiperOrigin-RevId: 677018051 --- .../mytarget/MyTargetMediationAdapter.java | 2 +- .../mediation/mytarget/MyTargetSdkWrapper.kt | 5 + .../ads/mediation/mytarget/MyTargetTools.java | 3 +- .../mytarget/MyTargetMediationAdapterTest.kt | 286 +++++++++++++++++- 4 files changed, 290 insertions(+), 6 deletions(-) diff --git a/ThirdPartyAdapters/mytarget/mytarget/src/main/java/com/google/ads/mediation/mytarget/MyTargetMediationAdapter.java b/ThirdPartyAdapters/mytarget/mytarget/src/main/java/com/google/ads/mediation/mytarget/MyTargetMediationAdapter.java index 5f29b1e9e..51e05ee8c 100644 --- a/ThirdPartyAdapters/mytarget/mytarget/src/main/java/com/google/ads/mediation/mytarget/MyTargetMediationAdapter.java +++ b/ThirdPartyAdapters/mytarget/mytarget/src/main/java/com/google/ads/mediation/mytarget/MyTargetMediationAdapter.java @@ -160,7 +160,7 @@ public void loadRewardedAd( mAdLoadCallback = mediationAdLoadCallback; - mRewardedAd = new RewardedAd(slotId, context); + mRewardedAd = MyTargetSdkWrapper.createRewardedAd(slotId, context); CustomParams params = mRewardedAd.getCustomParams(); handleMediationExtras(TAG, mediationRewardedAdConfiguration.getMediationExtras(), params); params.setCustomParam(MyTargetTools.PARAM_MEDIATION_KEY, diff --git a/ThirdPartyAdapters/mytarget/mytarget/src/main/java/com/google/ads/mediation/mytarget/MyTargetSdkWrapper.kt b/ThirdPartyAdapters/mytarget/mytarget/src/main/java/com/google/ads/mediation/mytarget/MyTargetSdkWrapper.kt index bdfc77ce2..4cf224597 100644 --- a/ThirdPartyAdapters/mytarget/mytarget/src/main/java/com/google/ads/mediation/mytarget/MyTargetSdkWrapper.kt +++ b/ThirdPartyAdapters/mytarget/mytarget/src/main/java/com/google/ads/mediation/mytarget/MyTargetSdkWrapper.kt @@ -14,10 +14,15 @@ package com.google.ads.mediation.mytarget +import android.content.Context +import com.my.target.ads.RewardedAd import com.my.target.common.MyTargetVersion object MyTargetSdkWrapper { @JvmStatic val sdkVersion: String get() = MyTargetVersion.VERSION + + @JvmStatic + fun createRewardedAd(slotId: Int, context: Context): RewardedAd = RewardedAd(slotId, context) } diff --git a/ThirdPartyAdapters/mytarget/mytarget/src/main/java/com/google/ads/mediation/mytarget/MyTargetTools.java b/ThirdPartyAdapters/mytarget/mytarget/src/main/java/com/google/ads/mediation/mytarget/MyTargetTools.java index 0ecf20685..27ff821e1 100644 --- a/ThirdPartyAdapters/mytarget/mytarget/src/main/java/com/google/ads/mediation/mytarget/MyTargetTools.java +++ b/ThirdPartyAdapters/mytarget/mytarget/src/main/java/com/google/ads/mediation/mytarget/MyTargetTools.java @@ -21,6 +21,7 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import com.google.android.gms.ads.AdSize; import com.my.target.ads.MyTargetView; import com.my.target.common.CustomParams; @@ -30,7 +31,7 @@ */ class MyTargetTools { - private static final String KEY_SLOT_ID = "slotId"; + @VisibleForTesting protected static final String KEY_SLOT_ID = "slotId"; @NonNull static final String PARAM_MEDIATION_KEY = "mediation"; @NonNull diff --git a/ThirdPartyAdapters/mytarget/mytarget/src/test/kotlin/com/google/ads/mediation/mytarget/MyTargetMediationAdapterTest.kt b/ThirdPartyAdapters/mytarget/mytarget/src/test/kotlin/com/google/ads/mediation/mytarget/MyTargetMediationAdapterTest.kt index 7304ca9ef..bef0871e1 100644 --- a/ThirdPartyAdapters/mytarget/mytarget/src/test/kotlin/com/google/ads/mediation/mytarget/MyTargetMediationAdapterTest.kt +++ b/ThirdPartyAdapters/mytarget/mytarget/src/test/kotlin/com/google/ads/mediation/mytarget/MyTargetMediationAdapterTest.kt @@ -1,21 +1,45 @@ package com.google.ads.mediation.mytarget import android.content.Context +import android.os.Bundle import androidx.core.os.bundleOf import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.ads.mediation.adaptertestkit.AdErrorMatcher +import com.google.ads.mediation.adaptertestkit.AdapterTestKitConstants.TEST_WATERMARK import com.google.ads.mediation.adaptertestkit.assertGetSdkVersion import com.google.ads.mediation.adaptertestkit.assertGetVersionInfo import com.google.ads.mediation.adaptertestkit.mediationAdapterInitializeVerifySuccess import com.google.ads.mediation.mytarget.MyTargetAdapterUtils.adapterVersion +import com.google.ads.mediation.mytarget.MyTargetMediationAdapter.ERROR_DOMAIN +import com.google.ads.mediation.mytarget.MyTargetMediationAdapter.ERROR_INVALID_SERVER_PARAMETERS +import com.google.ads.mediation.mytarget.MyTargetMediationAdapter.ERROR_MY_TARGET_SDK +import com.google.ads.mediation.mytarget.MyTargetMediationAdapter.MY_TARGET_SDK_ERROR_DOMAIN import com.google.ads.mediation.mytarget.MyTargetSdkWrapper.sdkVersion +import com.google.ads.mediation.mytarget.MyTargetTools.KEY_SLOT_ID +import com.google.ads.mediation.mytarget.MyTargetTools.PARAM_MEDIATION_KEY +import com.google.ads.mediation.mytarget.MyTargetTools.PARAM_MEDIATION_VALUE +import com.google.android.gms.ads.AdError +import com.google.android.gms.ads.RequestConfiguration import com.google.android.gms.ads.mediation.InitializationCompleteCallback +import com.google.android.gms.ads.mediation.MediationAdLoadCallback +import com.google.android.gms.ads.mediation.MediationRewardedAd +import com.google.android.gms.ads.mediation.MediationRewardedAdCallback +import com.google.android.gms.ads.mediation.MediationRewardedAdConfiguration +import com.my.target.ads.Reward +import com.my.target.ads.RewardedAd +import com.my.target.common.CustomParams +import com.my.target.common.models.IAdLoadingError import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mockito.mock import org.mockito.Mockito.mockStatic +import org.mockito.kotlin.any +import org.mockito.kotlin.argThat import org.mockito.kotlin.doReturn +import org.mockito.kotlin.eq +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify import org.mockito.kotlin.whenever /** Class containing unit tests for MyTargetMediationAdapter.java */ @@ -23,8 +47,14 @@ import org.mockito.kotlin.whenever class MyTargetMediationAdapterTest { private var myTargetMediationAdapter: MyTargetMediationAdapter = MyTargetMediationAdapter() + private val context = ApplicationProvider.getApplicationContext() private val mockInitializationCompleteCallback = mock() + private val mockRewardedAdCallback = mock() + private val mockMediationRewardedAdLoadCallback = + mock> { + on { onSuccess(any()) } doReturn mockRewardedAdCallback + } @Before fun setUp() { @@ -32,20 +62,18 @@ class MyTargetMediationAdapterTest { } // region Initialize Tests - @Test fun initialize_invokesOnInitializationSucceeded() { myTargetMediationAdapter.mediationAdapterInitializeVerifySuccess( context, mockInitializationCompleteCallback, - /* serverParameters= */ bundleOf() + /* serverParameters= */ bundleOf(), ) } // endregion // region Version Info Tests - @Test fun getVersionInfo_returnsCorrectVersionInfo() { mockStatic(MyTargetAdapterUtils::class.java).use { @@ -105,4 +133,254 @@ class MyTargetMediationAdapterTest { } // endregion + + // region Rewarded ad tests + @Test + fun loadRewardedAd_withNullSlotId_invokesOnFailure() { + val rewardedAdConfiguration = createRewardedAdConfiguration(context = context) + + myTargetMediationAdapter.loadRewardedAd( + rewardedAdConfiguration, + mockMediationRewardedAdLoadCallback, + ) + + val expectedAdError = + AdError(ERROR_INVALID_SERVER_PARAMETERS, "Missing or invalid Slot ID.", ERROR_DOMAIN) + verify(mockMediationRewardedAdLoadCallback).onFailure(argThat(AdErrorMatcher(expectedAdError))) + } + + @Test + fun loadRewardedAd_withEmptyKeyMedia_invokesOnFailure() { + val serverParameters = bundleOf(KEY_SLOT_ID to "") + val rewardedAdConfiguration = createRewardedAdConfiguration(serverParameters = serverParameters) + + myTargetMediationAdapter.loadRewardedAd( + rewardedAdConfiguration, + mockMediationRewardedAdLoadCallback, + ) + + val expectedAdError = + AdError(ERROR_INVALID_SERVER_PARAMETERS, "Missing or invalid Slot ID.", ERROR_DOMAIN) + verify(mockMediationRewardedAdLoadCallback).onFailure(argThat(AdErrorMatcher(expectedAdError))) + } + + @Test + fun loadRewardedAd_slotIdIsNotParseableToInt_invokesOnFailure() { + val serverParameters = bundleOf(KEY_SLOT_ID to "NotAnInt") + val rewardedAdConfiguration = createRewardedAdConfiguration(serverParameters = serverParameters) + + myTargetMediationAdapter.loadRewardedAd( + rewardedAdConfiguration, + mockMediationRewardedAdLoadCallback, + ) + + val expectedAdError = + AdError(ERROR_INVALID_SERVER_PARAMETERS, "Missing or invalid Slot ID.", ERROR_DOMAIN) + verify(mockMediationRewardedAdLoadCallback).onFailure(argThat(AdErrorMatcher(expectedAdError))) + } + + @Test + fun loadRewardedAd_withValidValues_invokesLoadAdAfterInitialization() { + mockStatic(MyTargetSdkWrapper::class.java).use { + val mockRewardedAd = mock() + val mockCustomParams = mock() + whenever(MyTargetSdkWrapper.createRewardedAd(eq(1234), eq(context))) doReturn mockRewardedAd + whenever(mockRewardedAd.customParams) doReturn mockCustomParams + val serverParameters = bundleOf(KEY_SLOT_ID to TEST_SLOT_ID) + val rewardedAdConfiguration = + createRewardedAdConfiguration(serverParameters = serverParameters) + + myTargetMediationAdapter.loadRewardedAd( + rewardedAdConfiguration, + mockMediationRewardedAdLoadCallback, + ) + + verify(mockRewardedAd).customParams + verify(mockCustomParams).setCustomParam(eq(PARAM_MEDIATION_KEY), eq(PARAM_MEDIATION_VALUE)) + verify(mockRewardedAd).listener = myTargetMediationAdapter + verify(mockRewardedAd).load() + } + } + + @Test + fun showAd_invokesShow() { + mockStatic(MyTargetSdkWrapper::class.java).use { + val mockRewardedAd = mock() + val mockCustomParams = mock() + whenever(MyTargetSdkWrapper.createRewardedAd(eq(1234), eq(context))) doReturn mockRewardedAd + whenever(mockRewardedAd.customParams) doReturn mockCustomParams + val serverParameters = bundleOf(KEY_SLOT_ID to TEST_SLOT_ID) + val rewardedAdConfiguration = + createRewardedAdConfiguration(serverParameters = serverParameters) + myTargetMediationAdapter.loadRewardedAd( + rewardedAdConfiguration, + mockMediationRewardedAdLoadCallback, + ) + + myTargetMediationAdapter.showAd(context) + + verify(mockRewardedAd).show() + } + } + + @Test + fun onLoad_invokesOnSuccess() { + mockStatic(MyTargetSdkWrapper::class.java).use { + val mockRewardedAd = mock() + val mockCustomParams = mock() + whenever(MyTargetSdkWrapper.createRewardedAd(eq(1234), eq(context))) doReturn mockRewardedAd + whenever(mockRewardedAd.customParams) doReturn mockCustomParams + val serverParameters = bundleOf(KEY_SLOT_ID to TEST_SLOT_ID) + val rewardedAdConfiguration = + createRewardedAdConfiguration(serverParameters = serverParameters) + myTargetMediationAdapter.loadRewardedAd( + rewardedAdConfiguration, + mockMediationRewardedAdLoadCallback, + ) + + myTargetMediationAdapter.onLoad(mockRewardedAd) + + verify(mockMediationRewardedAdLoadCallback).onSuccess(eq(myTargetMediationAdapter)) + } + } + + @Test + fun onNoAd_invokesOnFailure() { + mockStatic(MyTargetSdkWrapper::class.java).use { + val mockRewardedAd = mock() + val mockCustomParams = mock() + val mockAdLoadingError = mock() + whenever(mockAdLoadingError.message) doReturn "TEST_ERROR_MESSAGE" + whenever(MyTargetSdkWrapper.createRewardedAd(eq(1234), eq(context))) doReturn mockRewardedAd + whenever(mockRewardedAd.customParams) doReturn mockCustomParams + val serverParameters = bundleOf(KEY_SLOT_ID to TEST_SLOT_ID) + val rewardedAdConfiguration = + createRewardedAdConfiguration(serverParameters = serverParameters) + myTargetMediationAdapter.loadRewardedAd( + rewardedAdConfiguration, + mockMediationRewardedAdLoadCallback, + ) + + myTargetMediationAdapter.onNoAd(mockAdLoadingError, mockRewardedAd) + + val expectedAdError = + AdError(ERROR_MY_TARGET_SDK, "TEST_ERROR_MESSAGE", MY_TARGET_SDK_ERROR_DOMAIN) + verify(mockMediationRewardedAdLoadCallback) + .onFailure(argThat(AdErrorMatcher(expectedAdError))) + } + } + + @Test + fun onClick_invokesReportAdClicked() { + mockStatic(MyTargetSdkWrapper::class.java).use { + val mockRewardedAd = mock() + val mockCustomParams = mock() + whenever(MyTargetSdkWrapper.createRewardedAd(eq(1234), eq(context))) doReturn mockRewardedAd + whenever(mockRewardedAd.customParams) doReturn mockCustomParams + val serverParameters = bundleOf(KEY_SLOT_ID to TEST_SLOT_ID) + val rewardedAdConfiguration = + createRewardedAdConfiguration(serverParameters = serverParameters) + myTargetMediationAdapter.loadRewardedAd( + rewardedAdConfiguration, + mockMediationRewardedAdLoadCallback, + ) + myTargetMediationAdapter.onLoad(mockRewardedAd) + + myTargetMediationAdapter.onClick(mockRewardedAd) + + verify(mockRewardedAdCallback).reportAdClicked() + } + } + + @Test + fun onDismiss_invokesOnAdClosed() { + mockStatic(MyTargetSdkWrapper::class.java).use { + val mockRewardedAd = mock() + val mockCustomParams = mock() + whenever(MyTargetSdkWrapper.createRewardedAd(eq(1234), eq(context))) doReturn mockRewardedAd + whenever(mockRewardedAd.customParams) doReturn mockCustomParams + val serverParameters = bundleOf(KEY_SLOT_ID to TEST_SLOT_ID) + val rewardedAdConfiguration = + createRewardedAdConfiguration(serverParameters = serverParameters) + myTargetMediationAdapter.loadRewardedAd( + rewardedAdConfiguration, + mockMediationRewardedAdLoadCallback, + ) + myTargetMediationAdapter.onLoad(mockRewardedAd) + + myTargetMediationAdapter.onDismiss(mockRewardedAd) + + verify(mockRewardedAdCallback).onAdClosed() + } + } + + @Test + fun onReward_invokesOnVideoCompleteAndOnUserEarnedReward() { + mockStatic(MyTargetSdkWrapper::class.java).use { + val mockRewardedAd = mock() + val mockCustomParams = mock() + whenever(MyTargetSdkWrapper.createRewardedAd(eq(1234), eq(context))) doReturn mockRewardedAd + whenever(mockRewardedAd.customParams) doReturn mockCustomParams + val serverParameters = bundleOf(KEY_SLOT_ID to TEST_SLOT_ID) + val rewardedAdConfiguration = + createRewardedAdConfiguration(serverParameters = serverParameters) + myTargetMediationAdapter.loadRewardedAd( + rewardedAdConfiguration, + mockMediationRewardedAdLoadCallback, + ) + myTargetMediationAdapter.onLoad(mockRewardedAd) + + myTargetMediationAdapter.onReward(mock(), mockRewardedAd) + + verify(mockRewardedAdCallback).onVideoComplete() + verify(mockRewardedAdCallback).onUserEarnedReward(any()) + } + } + + @Test + fun onDisplay_invokesOnAdOpenedOnVideoStartAndReportAdImpression() { + mockStatic(MyTargetSdkWrapper::class.java).use { + val mockRewardedAd = mock() + val mockCustomParams = mock() + whenever(MyTargetSdkWrapper.createRewardedAd(eq(1234), eq(context))) doReturn mockRewardedAd + whenever(mockRewardedAd.customParams) doReturn mockCustomParams + val serverParameters = bundleOf(KEY_SLOT_ID to TEST_SLOT_ID) + val rewardedAdConfiguration = + createRewardedAdConfiguration(serverParameters = serverParameters) + myTargetMediationAdapter.loadRewardedAd( + rewardedAdConfiguration, + mockMediationRewardedAdLoadCallback, + ) + myTargetMediationAdapter.onLoad(mockRewardedAd) + + myTargetMediationAdapter.onDisplay(mockRewardedAd) + + verify(mockRewardedAdCallback).onAdOpened() + verify(mockRewardedAdCallback).onVideoStart() + verify(mockRewardedAdCallback).reportAdImpression() + } + } + + private fun createRewardedAdConfiguration( + context: Context = this.context, + serverParameters: Bundle = bundleOf(), + ) = + MediationRewardedAdConfiguration( + context, + /*bidresponse=*/ "", + serverParameters, + /*mediationExtras=*/ Bundle(), + /*isTesting=*/ true, + /*location=*/ null, + RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_UNSPECIFIED, + RequestConfiguration.TAG_FOR_UNDER_AGE_OF_CONSENT_UNSPECIFIED, + /*maxAdContentRating=*/ "", + TEST_WATERMARK, + ) + + // endregion + + private companion object { + const val TEST_SLOT_ID = "1234" + } }