diff --git a/android-components/components/browser/menu/src/main/java/mozilla/components/browser/menu/BrowserMenuPositioning.kt b/android-components/components/browser/menu/src/main/java/mozilla/components/browser/menu/BrowserMenuPositioning.kt index 480fa2c32345..b6bce41f6b74 100644 --- a/android-components/components/browser/menu/src/main/java/mozilla/components/browser/menu/BrowserMenuPositioning.kt +++ b/android-components/components/browser/menu/src/main/java/mozilla/components/browser/menu/BrowserMenuPositioning.kt @@ -74,8 +74,8 @@ internal fun inferMenuPositioningData( val (availableHeightToTop, availableHeightToBottom) = getMaxAvailableHeightToTopAndBottom(anchor) val containerHeight = containerView.measuredHeight - val fitsUp = availableHeightToTop >= containerHeight - val fitsDown = availableHeightToBottom >= containerHeight + val fitsUp = availableHeightToTop >= containerHeight || availableHeightToTop > availableHeightToBottom + val fitsDown = availableHeightToBottom >= containerHeight || availableHeightToBottom > availableHeightToTop return inferMenuPosition( anchor, diff --git a/android-components/components/browser/menu/src/test/java/mozilla/components/browser/menu/BrowserMenuPositioningTest.kt b/android-components/components/browser/menu/src/test/java/mozilla/components/browser/menu/BrowserMenuPositioningTest.kt index 42ce169281f9..43bf8b6d2de8 100644 --- a/android-components/components/browser/menu/src/test/java/mozilla/components/browser/menu/BrowserMenuPositioningTest.kt +++ b/android-components/components/browser/menu/src/test/java/mozilla/components/browser/menu/BrowserMenuPositioningTest.kt @@ -9,10 +9,12 @@ import android.view.ViewGroup import androidx.test.ext.junit.runners.AndroidJUnit4 import mozilla.components.support.test.mock import mozilla.components.support.test.robolectric.testContext +import mozilla.components.support.test.whenever import org.junit.Assert import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito +import org.mockito.Mockito.spy import org.robolectric.Shadows import org.robolectric.shadows.ShadowDisplay @@ -41,6 +43,56 @@ class BrowserMenuPositioningTest { Assert.assertEquals(expected, result) } + @Test + fun `GIVEN inferMenuPositioningData WHEN availableHeightToBottom is bigger than availableHeightToTop THEN it returns a new MenuPositioningData populated with all data needed to show a PopupWindow that fits down`() { + val view: ViewGroup = mock() + Mockito.doReturn(70).`when`(view).measuredHeight + val anchor = View(testContext) + anchor.layoutParams = ViewGroup.LayoutParams(20, 40) + + setScreenHeight(50) + + val result = inferMenuPositioningData(view, anchor, MenuPositioningData()) + + val expected = MenuPositioningData( + BrowserMenuPlacement.AnchoredToTop.Dropdown(anchor), // orientation DOWN and fitsDown + askedOrientation = BrowserMenu.Orientation.DOWN, // default + fitsUp = false, // availableHeightToTop(0) is smaller than containerHeight(70) and smaller than availableHeightToBottom(50) + fitsDown = true, // availableHeightToBottom(50) is smaller than containerHeight(70) and bigger than availableHeightToTop(0) + availableHeightToTop = 0, + availableHeightToBottom = 50, // mocked by us above + containerViewHeight = 70, // mocked by us above + ) + Assert.assertEquals(expected, result) + } + + @Test + fun `GIVEN inferMenuPositioningData WHEN availableHeightToTop is bigger than availableHeightToBottom THEN it returns a new MenuPositioningData populated with all data needed to show a PopupWindow that fits up`() { + val view: ViewGroup = mock() + Mockito.doReturn(70).`when`(view).measuredHeight + val anchor = spy(View(testContext)) + anchor.layoutParams = ViewGroup.LayoutParams(20, 40) + + whenever(anchor.getLocationOnScreen(IntArray(2))).thenAnswer { invocation -> + val args = invocation.arguments + val location = args[0] as IntArray + location[0] = 0 + location[1] = 60 + location + } + + setScreenHeight(100) + + val result = inferMenuPositioningData(view, anchor, MenuPositioningData()) + + Assert.assertEquals(result.askedOrientation, BrowserMenu.Orientation.DOWN) // default + Assert.assertEquals(result.fitsUp, true) // availableHeightToTop(60) is smaller than containerHeight(70) and bigger than availableHeightToBottom(40) + Assert.assertEquals(result.fitsDown, false) // availableHeightToBottom(450) is smaller than containerHeight(70) and smaller than availableHeightToTop(60) + Assert.assertEquals(result.availableHeightToTop, 60) // mocked by us above + Assert.assertEquals(result.availableHeightToBottom, 40) + Assert.assertEquals(result.containerViewHeight, 70) // mocked by us above + } + @Test fun `GIVEN inferMenuPosition WHEN called with an anchor and the current menu data THEN it returns a new MenuPositioningData with data about positioning the menu`() { val view: View = mock()