| Index: chrome/android/junit/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchStateTest.java
|
| diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchStateTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchStateTest.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e53cdfefd585788aa5404f1979d1ae6f958549ad
|
| --- /dev/null
|
| +++ b/chrome/android/junit/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchStateTest.java
|
| @@ -0,0 +1,187 @@
|
| +// Copyright 2017 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.contextualsearch;
|
| +
|
| +import static org.mockito.Mockito.*;
|
| +
|
| +import static org.junit.Assert.*;
|
| +import static org.hamcrest.CoreMatchers.*;
|
| +
|
| +import org.junit.Before;
|
| +import org.junit.Test;
|
| +import org.junit.runner.RunWith;
|
| +import org.junit.runners.BlockJUnit4ClassRunner;
|
| +
|
| +import org.chromium.base.test.util.Feature;
|
| +import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason;
|
| +import org.chromium.chrome.browser.contextualsearch.ContextualSearchSelectionController.SelectionType;
|
| +import org.chromium.chrome.browser.contextualsearch.ContextualSearchStateController.State;
|
| +
|
| +/**
|
| + * Tests for the {@link ContextualSearchStateController} class.
|
| + */
|
| +@RunWith(BlockJUnit4ClassRunner.class)
|
| +public class ContextualSearchStateTest {
|
| + private ContextualSearchStateController mController;
|
| +
|
| + private class ContextualSearchStateControlledStub implements ContextualSearchStateControlled {
|
| + /**
|
| + * Hides the Contextual Search UX.
|
| + */
|
| + @Override
|
| + public void hideContextualSearchUx(StateChangeReason reason) {
|
| + mDidHide = true;
|
| + }
|
| +
|
| + /**
|
| + * Shows the Contextual Search UX.
|
| + */
|
| + @Override
|
| + public void showContextualSearchUx(StateChangeReason reason) {
|
| + mDidShow = true;
|
| + }
|
| +
|
| + /**
|
| + * Gathers text surrounding the current selection, which may have been created by either a
|
| + * Tap or a Long-press gesture.
|
| + */
|
| + @Override
|
| + public void gatherSurroundingText() {
|
| + stubForWorkOnState(State.GATHERING_SURROUNDINGS);
|
| + }
|
| +
|
| + /**
|
| + * Starts the process of deciding if we'll suppress the current Tap gesture or not.
|
| + */
|
| + @Override
|
| + public void decideTapSuppression() {
|
| + stubForWorkOnState(State.DECIDING_SUPPRESSION);
|
| + }
|
| +
|
| + /**
|
| + * Waits for possible navigation.
|
| + * Many web pages have non-link elements that actually do navigation, so we pause before
|
| + * advancing to the next processing state in order to detect the navigation before showing
|
| + * our UX. See crbug.com/428368.
|
| + */
|
| + @Override
|
| + public void waitForPossibleNavigation() {
|
| + stubForWorkOnState(State.WAITING_FOR_POSSIBLE_NAVIGATION);
|
| + }
|
| +
|
| + /**
|
| + * Starts the process of selecting a word around the current caret.
|
| + */
|
| + @Override
|
| + public void selectWordAroundCaret() {
|
| + stubForWorkOnState(State.SELECTING_WORD);
|
| + }
|
| +
|
| + /**
|
| + * Starts a Resolve request to our server for the best Search Term.
|
| + */
|
| + @Override
|
| + public void startSearchTermResolutionRequest() {
|
| + mController.notifyStartingWorkOn(State.RESOLVING);
|
| + if (mController.isStillWorkingOn(State.RESOLVING)) {
|
| + mDidResolve = true;
|
| + mController.notifyFinishedWorkOn(State.RESOLVING);
|
| + }
|
| + }
|
| +
|
| + boolean didResolve() {
|
| + return mDidResolve;
|
| + }
|
| +
|
| + // Stub for doing work some async task.
|
| + private void stubForWorkOnState(State state) {
|
| + mController.notifyStartingWorkOn(state);
|
| + // Async task completes:
|
| + mController.notifyFinishedWorkOn(state);
|
| + }
|
| + }
|
| +
|
| + private ContextualSearchStateControlledStub mControlledStub;
|
| + private ContextualSearchPolicy mMockedPolicy;
|
| + private ContextualSearchSelectionController mMockedSelectionController;
|
| +
|
| + private boolean mDidHide;
|
| + private boolean mDidShow;
|
| + private boolean mDidResolve;
|
| +
|
| + boolean didHide() {
|
| + return mDidHide;
|
| + }
|
| +
|
| + boolean didShow() {
|
| + return mDidShow;
|
| + }
|
| +
|
| + boolean didResolve() {
|
| + return mDidResolve;
|
| + }
|
| +
|
| + private void reset() {
|
| + mDidHide = false;
|
| + mDidShow = false;
|
| + mDidResolve = false;
|
| + }
|
| +
|
| + @Before
|
| + public void setup() {
|
| + reset();
|
| + mMockedPolicy = mock(ContextualSearchPolicy.class);
|
| + mMockedSelectionController = mock(ContextualSearchSelectionController.class);
|
| + mControlledStub = new ContextualSearchStateControlledStub();
|
| + mController = new ContextualSearchStateController(
|
| + mMockedSelectionController, mMockedPolicy, mControlledStub);
|
| + }
|
| +
|
| + private void mocksForTap() {
|
| + when(mMockedSelectionController.getSelectionType()).thenReturn(SelectionType.TAP);
|
| + when(mMockedPolicy.shouldPreviousTapResolve()).thenReturn(true);
|
| + }
|
| +
|
| + // TODO(donnd): Test non-resolving taps using this helper.
|
| + private void mocksForNonResolvingTap() {
|
| + when(mMockedSelectionController.getSelectionType()).thenReturn(SelectionType.TAP);
|
| + when(mMockedPolicy.shouldPreviousTapResolve()).thenReturn(false);
|
| + }
|
| +
|
| + private void mocksForLongpress() {
|
| + when(mMockedSelectionController.getSelectionType()).thenReturn(SelectionType.LONG_PRESS);
|
| + }
|
| +
|
| + @Test
|
| + @Feature({"ContextualSearch"})
|
| + public void testStateNormalTapSequence() {
|
| + mocksForTap();
|
| + mController.reset(StateChangeReason.UNKNOWN);
|
| + mController.enter(State.TAP_RECOGNIZED);
|
| + assertTrue("Did not Resolve!", mControlledStub.didResolve());
|
| + }
|
| +
|
| + @Test
|
| + @Feature({"ContextualSearch"})
|
| + public void testStateNormalLongpressSequence() {
|
| + mocksForLongpress();
|
| + mController.reset(StateChangeReason.UNKNOWN);
|
| + mController.enter(State.LONG_PRESS_RECOGNIZED);
|
| + assertFalse("A Resolve should not be done on Long-press!", mControlledStub.didResolve());
|
| + assertThat(mController.getState(), is(State.SHOWING_LONGPRESS_SEARCH));
|
| + }
|
| +
|
| + /*
|
| + // TODO(donnd): test that some assertions are firing when expected, e.g:
|
| + @Test(expected = AssertionError.class)
|
| + @Feature({"ContextualSearch"})
|
| + public void testFinishedWithoutStarting() {
|
| + // Make a subclass of ContextualSearchStateControlledStub that forgets to startWorkingOn
|
| + // one of the states.
|
| + }
|
| + */
|
| +
|
| + // TODO(donnd): add more tests!
|
| +}
|
|
|