Commit 4bf17b4f authored by Mehran Mahmoudi's avatar Mehran Mahmoudi Committed by Commit Bot

[Touchless] Add unit tests for KeyFunctionsIPHMediator

This adds some unit tests for the KeyFunctionsMediator class. Tests
involving Distillability will be added in a future CL for end-to-end
tests.

Bug: 967457
Change-Id: I7c33e0c03081eb90074516b00915b3bb48a2c970
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1640826Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Reviewed-by: default avatarMichael Thiessen <mthiesse@chromium.org>
Commit-Queue: Mehran Mahmoudi <mahmoudi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#665984}
parent 5810ed59
include_rules = [ include_rules = [
"+components/feature_engagement/public",
"+content/public/android/java/src/org/chromium/content_public", "+content/public/android/java/src/org/chromium/content_public",
] ]
...@@ -7,6 +7,9 @@ package org.chromium.chrome.browser.touchless.ui.iph; ...@@ -7,6 +7,9 @@ package org.chromium.chrome.browser.touchless.ui.iph;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.touchless.ui.tooltip.TooltipView; import org.chromium.chrome.browser.touchless.ui.tooltip.TooltipView;
import org.chromium.chrome.touchless.R; import org.chromium.chrome.touchless.R;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
...@@ -27,7 +30,9 @@ public class KeyFunctionsIPHCoordinator { ...@@ -27,7 +30,9 @@ public class KeyFunctionsIPHCoordinator {
(KeyFunctionsIPHView) LayoutInflater.from(tooltipView.getContext()) (KeyFunctionsIPHView) LayoutInflater.from(tooltipView.getContext())
.inflate(R.layout.notouch_key_functions_view, null); .inflate(R.layout.notouch_key_functions_view, null);
PropertyModelChangeProcessor.create(model, view, KeyFunctionsIPHViewBinder::bind); PropertyModelChangeProcessor.create(model, view, KeyFunctionsIPHViewBinder::bind);
mMediator = new KeyFunctionsIPHMediator(model, activityTabProvider); mMediator = new KeyFunctionsIPHMediator(model, activityTabProvider,
ChromePreferenceManager.getInstance(),
TrackerFactory.getTrackerForProfile(Profile.getLastUsedProfile()));
} }
public void destroy() { public void destroy() {
......
...@@ -9,11 +9,10 @@ import android.support.annotation.IntDef; ...@@ -9,11 +9,10 @@ import android.support.annotation.IntDef;
import org.chromium.base.task.PostTask; import org.chromium.base.task.PostTask;
import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.dom_distiller.TabDistillabilityProvider; import org.chromium.chrome.browser.dom_distiller.TabDistillabilityProvider;
import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
import org.chromium.chrome.browser.native_page.NativePageFactory; import org.chromium.chrome.browser.native_page.NativePageFactory;
import org.chromium.chrome.browser.preferences.ChromePreferenceManager; import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.components.feature_engagement.Tracker;
import org.chromium.components.feature_engagement.Tracker.DisplayLockHandle; import org.chromium.components.feature_engagement.Tracker.DisplayLockHandle;
import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.UiThreadTaskTraits;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
...@@ -30,9 +29,11 @@ import java.util.concurrent.FutureTask; ...@@ -30,9 +29,11 @@ import java.util.concurrent.FutureTask;
public class KeyFunctionsIPHMediator implements CursorObserver { public class KeyFunctionsIPHMediator implements CursorObserver {
private final PropertyModel mModel; private final PropertyModel mModel;
private final KeyFunctionsIPHTabObserver mKeyFunctionsIPHTabObserver; private final KeyFunctionsIPHTabObserver mKeyFunctionsIPHTabObserver;
private final ChromePreferenceManager mChromePreferenceManager;
private final Tracker mTracker;
private FutureTask mHideTask; private FutureTask mHideTask;
private int mPageLoadCount;
private DisplayLockHandle mDisplayLockHandle; private DisplayLockHandle mDisplayLockHandle;
private int mPageLoadCount;
private boolean mIsFallbackCursorModeOn; private boolean mIsFallbackCursorModeOn;
private boolean mShowedWhenPageLoadStarted; private boolean mShowedWhenPageLoadStarted;
...@@ -40,8 +41,8 @@ public class KeyFunctionsIPHMediator implements CursorObserver { ...@@ -40,8 +41,8 @@ public class KeyFunctionsIPHMediator implements CursorObserver {
// For the first INTRODUCTORY_SESSIONS sessions, show the IPH every INTRODUCTORY_PAGE_LOAD_CYCLE // For the first INTRODUCTORY_SESSIONS sessions, show the IPH every INTRODUCTORY_PAGE_LOAD_CYCLE
// page loads. // page loads.
private static final int INTRODUCTORY_SESSIONS = 6; static final int INTRODUCTORY_SESSIONS = 6;
private static final int INTRODUCTORY_PAGE_LOAD_CYCLE = 3; static final int INTRODUCTORY_PAGE_LOAD_CYCLE = 3;
@IntDef({DisplayCause.PAGE_LOAD_STARTED, DisplayCause.PAGE_LOAD_FINISHED, @IntDef({DisplayCause.PAGE_LOAD_STARTED, DisplayCause.PAGE_LOAD_FINISHED,
DisplayCause.FALLBACK_CURSOR_TOGGLED}) DisplayCause.FALLBACK_CURSOR_TOGGLED})
...@@ -52,9 +53,12 @@ public class KeyFunctionsIPHMediator implements CursorObserver { ...@@ -52,9 +53,12 @@ public class KeyFunctionsIPHMediator implements CursorObserver {
int FALLBACK_CURSOR_TOGGLED = 2; int FALLBACK_CURSOR_TOGGLED = 2;
} }
KeyFunctionsIPHMediator(PropertyModel model, ActivityTabProvider activityTabProvider) { KeyFunctionsIPHMediator(PropertyModel model, ActivityTabProvider activityTabProvider,
ChromePreferenceManager chromePreferenceManager, Tracker tracker) {
mModel = model; mModel = model;
mKeyFunctionsIPHTabObserver = new KeyFunctionsIPHTabObserver(activityTabProvider); mKeyFunctionsIPHTabObserver = new KeyFunctionsIPHTabObserver(activityTabProvider);
mChromePreferenceManager = chromePreferenceManager;
mTracker = tracker;
TouchlessEventHandler.addCursorObserver(this); TouchlessEventHandler.addCursorObserver(this);
} }
...@@ -70,14 +74,13 @@ public class KeyFunctionsIPHMediator implements CursorObserver { ...@@ -70,14 +74,13 @@ public class KeyFunctionsIPHMediator implements CursorObserver {
private void show(@DisplayCause int displayCause) { private void show(@DisplayCause int displayCause) {
if (displayCause == DisplayCause.PAGE_LOAD_STARTED) { if (displayCause == DisplayCause.PAGE_LOAD_STARTED) {
mShowedWhenPageLoadStarted = false; mShowedWhenPageLoadStarted = false;
int totalSessionCount = ChromePreferenceManager.getInstance().readInt( int totalSessionCount = mChromePreferenceManager.readInt(
ChromePreferenceManager.TOUCHLESS_BROWSING_SESSION_COUNT); ChromePreferenceManager.TOUCHLESS_BROWSING_SESSION_COUNT);
if (totalSessionCount <= INTRODUCTORY_SESSIONS if (totalSessionCount <= INTRODUCTORY_SESSIONS
&& mPageLoadCount % INTRODUCTORY_PAGE_LOAD_CYCLE != 1) { && mPageLoadCount % INTRODUCTORY_PAGE_LOAD_CYCLE != 1) {
return; return;
} }
if (totalSessionCount > INTRODUCTORY_SESSIONS && mPageLoadCount > 1) return; if (totalSessionCount > INTRODUCTORY_SESSIONS && mPageLoadCount > 1) return;
mShowedWhenPageLoadStarted = true;
} else if (mShowedWhenPageLoadStarted && displayCause == DisplayCause.PAGE_LOAD_FINISHED) { } else if (mShowedWhenPageLoadStarted && displayCause == DisplayCause.PAGE_LOAD_FINISHED) {
// If we have already shown the IPH when page load started, we should avoid showing it // If we have already shown the IPH when page load started, we should avoid showing it
// again when page load is finished. // again when page load is finished.
...@@ -86,11 +89,12 @@ public class KeyFunctionsIPHMediator implements CursorObserver { ...@@ -86,11 +89,12 @@ public class KeyFunctionsIPHMediator implements CursorObserver {
// If we are already showing this IPH, we should release the lock. // If we are already showing this IPH, we should release the lock.
if (mDisplayLockHandle != null) mDisplayLockHandle.release(); if (mDisplayLockHandle != null) mDisplayLockHandle.release();
mDisplayLockHandle = TrackerFactory.getTrackerForProfile(Profile.getLastUsedProfile()) mDisplayLockHandle = mTracker.acquireDisplayLock();
.acquireDisplayLock();
// If another IPH UI is currently shown, return. // If another IPH UI is currently shown, return.
if (mDisplayLockHandle == null) return; if (mDisplayLockHandle == null) return;
if (displayCause == DisplayCause.PAGE_LOAD_STARTED) mShowedWhenPageLoadStarted = true;
if (mHideTask != null) mHideTask.cancel(false); if (mHideTask != null) mHideTask.cancel(false);
mHideTask = new FutureTask<Void>(() -> { mHideTask = new FutureTask<Void>(() -> {
mModel.set(KeyFunctionsIPHProperties.IS_VISIBLE, false); mModel.set(KeyFunctionsIPHProperties.IS_VISIBLE, false);
......
include_rules = [
"+components/feature_engagement/public",
]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.touchless.ui.iph;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowLooper;
import org.chromium.base.task.test.ShadowPostTask;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabObserver;
import org.chromium.components.feature_engagement.Tracker;
import org.chromium.ui.modelutil.PropertyModel;
/**
* Unit tests for the {@link KeyFunctionsIPHMediator} class.
*/
@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE, shadows = {ShadowPostTask.class})
public class KeyFunctionsIPHMediatorTest {
private static final String SAMPLE_URL = "https://google.com/chrome/";
private PropertyModel mModel;
private ArgumentCaptor<TabObserver> mTabObserver;
private Tab mTab;
private ChromePreferenceManager mChromePreferenceManager;
private Tracker mTracker;
private KeyFunctionsIPHMediator mKeyFunctionsIPHMediator;
@Before
public void setUp() {
mTab = mock(Tab.class);
mChromePreferenceManager = mock(ChromePreferenceManager.class);
mTracker = mock(Tracker.class);
mTabObserver = ArgumentCaptor.forClass(TabObserver.class);
mModel = spy(new PropertyModel.Builder(KeyFunctionsIPHProperties.ALL_KEYS).build());
ActivityTabProvider activityTabProvider = spy(ActivityTabProvider.class);
TrackerFactory.setTrackerForTests(mTracker);
when(mTracker.acquireDisplayLock()).thenReturn(mock(Tracker.DisplayLockHandle.class));
when(activityTabProvider.get()).thenReturn(mTab);
when(mChromePreferenceManager.readInt(
ChromePreferenceManager.TOUCHLESS_BROWSING_SESSION_COUNT))
.thenReturn(0);
mKeyFunctionsIPHMediator = spy(new KeyFunctionsIPHMediator(
mModel, activityTabProvider, mChromePreferenceManager, mTracker));
verify(mTab).addObserver(mTabObserver.capture());
}
@Test
public void visibilityTest() {
when(mTab.getUrl()).thenReturn(SAMPLE_URL);
mTabObserver.getValue().onPageLoadStarted(mTab, SAMPLE_URL);
Assert.assertEquals(mModel.get(KeyFunctionsIPHProperties.IS_CURSOR_VISIBLE), false);
Assert.assertEquals(mModel.get(KeyFunctionsIPHProperties.IS_VISIBLE), true);
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
Assert.assertEquals(mModel.get(KeyFunctionsIPHProperties.IS_VISIBLE), false);
for (int i = 1; i < KeyFunctionsIPHMediator.INTRODUCTORY_PAGE_LOAD_CYCLE; i++) {
mTabObserver.getValue().onPageLoadStarted(mTab, SAMPLE_URL);
Assert.assertEquals(mModel.get(KeyFunctionsIPHProperties.IS_VISIBLE), false);
}
mTabObserver.getValue().onPageLoadStarted(mTab, SAMPLE_URL);
Assert.assertEquals(mModel.get(KeyFunctionsIPHProperties.IS_VISIBLE), true);
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
when(mChromePreferenceManager.readInt(
ChromePreferenceManager.TOUCHLESS_BROWSING_SESSION_COUNT))
.thenReturn(KeyFunctionsIPHMediator.INTRODUCTORY_SESSIONS + 1);
for (int i = 0; i <= KeyFunctionsIPHMediator.INTRODUCTORY_PAGE_LOAD_CYCLE; i++) {
mTabObserver.getValue().onPageLoadStarted(mTab, SAMPLE_URL);
Assert.assertEquals(mModel.get(KeyFunctionsIPHProperties.IS_VISIBLE), false);
}
}
@Test
public void cursorVisibilityToggleTest() {
mKeyFunctionsIPHMediator.onFallbackCursorModeToggled(true);
Assert.assertEquals(mModel.get(KeyFunctionsIPHProperties.IS_CURSOR_VISIBLE), true);
Assert.assertEquals(mModel.get(KeyFunctionsIPHProperties.IS_VISIBLE), true);
mKeyFunctionsIPHMediator.onFallbackCursorModeToggled(false);
Assert.assertEquals(mModel.get(KeyFunctionsIPHProperties.IS_CURSOR_VISIBLE), false);
Assert.assertEquals(mModel.get(KeyFunctionsIPHProperties.IS_VISIBLE), true);
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
Assert.assertEquals(mModel.get(KeyFunctionsIPHProperties.IS_VISIBLE), false);
mKeyFunctionsIPHMediator.onFallbackCursorModeToggled(true);
Assert.assertEquals(mModel.get(KeyFunctionsIPHProperties.IS_CURSOR_VISIBLE), true);
Assert.assertEquals(mModel.get(KeyFunctionsIPHProperties.IS_VISIBLE), true);
}
@Test
public void otherIPHShowingTest() {
when(mTracker.acquireDisplayLock()).thenReturn(null);
mKeyFunctionsIPHMediator.onFallbackCursorModeToggled(true);
Assert.assertEquals(mModel.get(KeyFunctionsIPHProperties.IS_VISIBLE), false);
when(mTracker.acquireDisplayLock()).thenReturn(mock(Tracker.DisplayLockHandle.class));
mKeyFunctionsIPHMediator.onFallbackCursorModeToggled(false);
Assert.assertEquals(mModel.get(KeyFunctionsIPHProperties.IS_VISIBLE), true);
}
@After
public void tearDown() {
TrackerFactory.setTrackerForTests(null);
}
}
...@@ -75,6 +75,7 @@ touchless_test_java_sources = [ ...@@ -75,6 +75,7 @@ touchless_test_java_sources = [
touchless_junit_test_java_sources = [ touchless_junit_test_java_sources = [
"touchless/junit/src/org/chromium/chrome/browser/touchless/ScrollPositionInfoTest.java", "touchless/junit/src/org/chromium/chrome/browser/touchless/ScrollPositionInfoTest.java",
"touchless/junit/src/org/chromium/chrome/browser/touchless/TouchlessActionItemViewHolderTest.java", "touchless/junit/src/org/chromium/chrome/browser/touchless/TouchlessActionItemViewHolderTest.java",
"touchless/junit/src/org/chromium/chrome/browser/touchless/ui/iph/KeyFunctionsIPHMediatorTest.java",
"touchless/junit/src/org/chromium/chrome/browser/touchless/ui/progressbar/ProgressBarMediatorTest.java", "touchless/junit/src/org/chromium/chrome/browser/touchless/ui/progressbar/ProgressBarMediatorTest.java",
] ]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment