Skip to content

Commit

Permalink
📐 Implement resize
Browse files Browse the repository at this point in the history
  • Loading branch information
viktor-rasevych-criteo committed Nov 3, 2023
1 parent 7ba3f24 commit e8bd0f0
Show file tree
Hide file tree
Showing 30 changed files with 1,097 additions and 142 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ import androidx.test.filters.FlakyTest
import androidx.test.rule.ActivityTestRule
import com.criteo.publisher.CriteoBannerView
import com.criteo.publisher.CriteoUtil
import com.criteo.publisher.DependencyProvider
import com.criteo.publisher.MraidData
import com.criteo.publisher.MraidPosition
import com.criteo.publisher.R
import com.criteo.publisher.TestAdUnits
import com.criteo.publisher.adview.MraidResizeCustomClosePosition
import com.criteo.publisher.adview.MraidState
import com.criteo.publisher.adview.Redirection
import com.criteo.publisher.callMraidObjectBlocking
Expand Down Expand Up @@ -83,6 +86,7 @@ class MraidBannerFunctionalTest {
private lateinit var onExpanded: CountDownLatch
private lateinit var onHidden: CountDownLatch
private lateinit var onDefault: CountDownLatch
private lateinit var onResized: CountDownLatch

@Before
fun setUp() {
Expand All @@ -92,6 +96,7 @@ class MraidBannerFunctionalTest {
onExpanded = CountDownLatch(1)
onHidden = CountDownLatch(1)
onDefault = CountDownLatch(1)
resetResizeCounter()

givenInitializedSdk(validBannerAdUnit)
bannerView = whenLoadingABanner(validBannerAdUnit)!!
Expand All @@ -105,12 +110,7 @@ class MraidBannerFunctionalTest {
onExpanded.await()
mockedDependenciesRule.waitForIdleState()

assertThat(getCurrentState()).isEqualTo(MraidState.EXPANDED)
assertThat(getWebView().parent).isNotNull
assertThat(getWebView().parent).isNotEqualTo(bannerView)
assertThat(bannerView.childCount).isEqualTo(1)
assertThat(bannerView.getChildAt(0).id).isEqualTo(R.id.adWebViewPlaceholder)
assertThat((getWebView().parent as ViewGroup).id).isEqualTo(R.id.adWebViewDialogContainer)
assertExpandedCorrectly()
}

@Test
Expand Down Expand Up @@ -138,18 +138,110 @@ class MraidBannerFunctionalTest {
onDefault.await()
mockedDependenciesRule.waitForIdleState()

assertClosedCorrectly(originalLayoutParams)
}

private fun assertClosedCorrectly(originalLayoutParams: ViewGroup.LayoutParams?) {
assertThat(getCurrentState()).isEqualTo(MraidState.DEFAULT)
assertThat(getWebView().parent).isEqualTo(bannerView)
assertThat(getWebView().layoutParams).isEqualTo(originalLayoutParams)
}

@Test
@FlakyTest(detail = "Flakiness comes from UI and concurrency")
fun whenExpandFromResizedState_ShouldMoveWebViewToDialogAndUpdateState() {
setResizeProperties(100, 100, 0, 0, MraidResizeCustomClosePosition.Center, true)
resize()

onResized.await()
mockedDependenciesRule.waitForIdleState()

expand()

onExpanded.await()
mockedDependenciesRule.waitForIdleState()

assertExpandedCorrectly()
}

@Test
@FlakyTest(detail = "Flakiness comes from UI and concurrency")
fun whenOpen_ShouldDelegateToRedirection() {
open()
mockedDependenciesRule.waitForIdleState()

verify(redirection).redirect(eq("https://www.criteo.com"), eq(activityRule.activity.componentName), any())
verify(redirection).redirect(
eq("https://www.criteo.com"),
eq(activityRule.activity.componentName),
any()
)
}

@Test
@FlakyTest(detail = "Flakiness comes from UI and concurrency")
fun whenResize_shouldMoveViewAboveAllViewsWithProperParamsAndUpdateState() {
val originalPosition = getCurrentPosition()

setResizeProperties(100, 100, 20, 20, MraidResizeCustomClosePosition.Center, true)
resize()

onResized.await()
mockedDependenciesRule.waitForIdleState()

assertThat(getCurrentState()).isEqualTo(MraidState.RESIZED)
val currentPosition = getCurrentPosition()
assertThat(currentPosition.width).isEqualTo(100)
assertThat(currentPosition.height).isEqualTo(100)
assertThat(currentPosition.x).isEqualTo(originalPosition.x + 20)
assertThat(currentPosition.y).isEqualTo(originalPosition.y + 20)
assertThat(getWebView().parent).isNotEqualTo(bannerView)
assertThat(bannerView.getChildAt(0).id).isEqualTo(R.id.adWebViewPlaceholder)
}

@Test
@FlakyTest(detail = "Flakiness comes from UI and concurrency")
fun whenResizeAndThenResizeWithDifferentParameter_shouldMoveViewAboveAllViewsWithProperParamsAndUpdateState() {
val originalPosition = getCurrentPosition()

setResizeProperties(100, 100, 15, 15, MraidResizeCustomClosePosition.Center, true)
resize()

onResized.await()
mockedDependenciesRule.waitForIdleState()

resetResizeCounter()
setResizeProperties(150, 150, 10, 10, MraidResizeCustomClosePosition.TopCenter, false)
resize()

onResized.await()
mockedDependenciesRule.waitForIdleState()

assertThat(getCurrentState()).isEqualTo(MraidState.RESIZED)
val currentPosition = getCurrentPosition()
assertThat(currentPosition.width).isEqualTo(150)
assertThat(currentPosition.height).isEqualTo(150)
assertThat(currentPosition.x).isEqualTo(originalPosition.x + 15 + 10)
assertThat(currentPosition.y).isEqualTo(originalPosition.y + 15 + 10)

assertThat(getWebView().parent).isNotEqualTo(bannerView)
assertThat(bannerView.getChildAt(0).id).isEqualTo(R.id.adWebViewPlaceholder)
}

@Test
@FlakyTest(detail = "Flakiness comes from UI and concurrency")
fun whenResizeAndThenClose_ShouldMoveBackToOriginalContainer() {
val originalLayoutParams = getWebView().layoutParams
setResizeProperties(100, 100, 0, 0, MraidResizeCustomClosePosition.Center, true)
resize()

onResized.await()
mockedDependenciesRule.waitForIdleState()

close()
onDefault.await()
mockedDependenciesRule.waitForIdleState()

assertClosedCorrectly(originalLayoutParams)
}

private fun givenInitializedSdk(vararg preloadedAdUnits: AdUnit) {
Expand Down Expand Up @@ -189,6 +281,15 @@ class MraidBannerFunctionalTest {
waitForBids()
}

private fun assertExpandedCorrectly() {
assertThat(getCurrentState()).isEqualTo(MraidState.EXPANDED)
assertThat(getWebView().parent).isNotNull
assertThat(getWebView().parent).isNotEqualTo(bannerView)
assertThat(bannerView.childCount).isEqualTo(1)
assertThat(bannerView.getChildAt(0).id).isEqualTo(R.id.adWebViewPlaceholder)
assertThat((getWebView().parent as ViewGroup).id).isEqualTo(R.id.adWebViewDialogContainer)
}

private fun expand() {
getWebView().callMraidObjectBlocking("expand()")
}
Expand All @@ -197,13 +298,51 @@ class MraidBannerFunctionalTest {
getWebView().callMraidObjectBlocking("close()")
}

private fun setResizeProperties(
width: Int,
height: Int,
offsetX: Int,
offsetY: Int,
customClosePosition: MraidResizeCustomClosePosition,
allowOffscreen: Boolean
) {
getWebView().callMraidObjectBlocking(buildString {
append("setResizeProperties")
append("(")
append("{")
append("width:")
append(width)
append(", height:")
append(height)
append(", offsetX:")
append(offsetX)
append(", offsetY:")
append(offsetY)
append(", customClosePosition:")
append("\"")
append(customClosePosition.value)
append("\"")
append(", allowOffscreen:")
append(allowOffscreen)
append("}")
append(")")
})
}

private fun resize() {
getWebView().callMraidObjectBlocking("resize()")
}

private fun open() {
getWebView().callMraidObjectBlocking("open(\"https://www.criteo.com\")")
}

private fun getCurrentState() = getWebView().getJavascriptResultBlocking("window.mraid.getState()")
.toMraidState()

private fun getCurrentPosition() = getWebView().getJavascriptResultBlocking("window.mraid.getCurrentPosition()")
.toMraidPosition()

private fun getWebView(): WebView {
return bannerView.adWebView
}
Expand All @@ -217,18 +356,28 @@ class MraidBannerFunctionalTest {
onReady.countDown()
}

fun resetResizeCounter() {
onResized = CountDownLatch(1)
}

@JavascriptInterface
fun onStateChange(newState: String) {
when (newState.toMraidState()) {
MraidState.LOADING -> Unit
MraidState.DEFAULT -> onDefault.countDown()
MraidState.EXPANDED -> onExpanded.countDown()
MraidState.HIDDEN -> onHidden.countDown()
MraidState.RESIZED -> onResized.countDown()
}
}

private fun String.toMraidState(): MraidState {
val unquotedState = this.replace("\"", "")
return MraidState.values().first { it.stringValue == unquotedState }
}

private fun String.toMraidPosition(): MraidPosition = DependencyProvider.getInstance()
.provideMoshi()
.adapter(MraidPosition::class.java)
.fromJson(this)!!
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package com.criteo.publisher.interstitial
import androidx.test.rule.ActivityTestRule
import com.criteo.publisher.adview.MraidActionResult
import com.criteo.publisher.adview.MraidPlacementType
import com.criteo.publisher.adview.MraidResizeActionResult
import com.criteo.publisher.adview.MraidResizeCustomClosePosition
import com.criteo.publisher.adview.MraidState
import com.criteo.publisher.concurrent.RunOnUiThreadExecutor
import com.criteo.publisher.mock.MockedDependenciesRule
Expand Down Expand Up @@ -91,6 +93,23 @@ class CriteoInterstitialMraidControllerTest {
verify(callbackMock).invoke(argThat { this is MraidActionResult.Error })
}

@Test
fun doResize_ShouldCallbackError() {
val callbackMock = mock<(result: MraidResizeActionResult) -> Unit>()

criteoInterstitialMraidController.doResize(
100.0,
100.0,
0.0,
0.0,
MraidResizeCustomClosePosition.Center,
true,
callbackMock
)

verify(callbackMock).invoke(argThat { this is MraidResizeActionResult.Error })
}

@Test
fun doClose_givenLoadingState_ShouldCallbackError() {
val callbackMock = mock<(result: MraidActionResult) -> Unit>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ class ViewPositionTrackerTest {
view.getLocationInWindow(outWindowLocation)

verify(listener, atLeastOnce()).onPositionChange(
eq(deviceUtil.pxToDp(outWindowLocation[0])),
eq(deviceUtil.pxToDp(outWindowLocation[1])),
eq(deviceUtil.pxToDp(view.width)),
eq(deviceUtil.pxToDp(view.height))
eq(deviceUtil.pixelToDp(outWindowLocation[0])),
eq(deviceUtil.pixelToDp(outWindowLocation[1])),
eq(deviceUtil.pixelToDp(view.width)),
eq(deviceUtil.pixelToDp(view.height))
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,11 @@ internal object BannerLogMessage {
level = Log.ERROR,
throwable = throwable
)

@JvmStatic
fun onBannerFailedToResize(bannerView: CriteoBannerView?, throwable: Throwable) = LogMessage(
message = "BannerView(${bannerView?.bannerAdUnit}) failed to resize",
level = Log.ERROR,
throwable = throwable
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class CriteoBannerAdWebViewFactory {
criteo: Criteo?,
parentContainer: CriteoBannerView
): CriteoBannerAdWebView {
return CriteoBannerAdWebView(context, attrs, bannerAdUnit, criteo, parentContainer)
return CriteoBannerAdWebView(context, attrs, bannerAdUnit, criteo, parentContainer).also {
it.id = R.id.bannerAdWebView
}
}
}
Loading

0 comments on commit e8bd0f0

Please sign in to comment.