blob: ef5f84c8500ecfeee985ba019bfa241df3a55706 [file] [log] [blame]
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/renderer_context_menu/spelling_menu_observer.h"
#include <memory>
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/renderer_context_menu/mock_render_view_context_menu.h"
#include "chrome/browser/spellchecker/spellcheck_factory.h"
#include "chrome/browser/spellchecker/spellcheck_service.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/prefs/pref_service.h"
#include "components/spellcheck/browser/pref_names.h"
#include "components/spellcheck/browser/spelling_service_client.h"
#include "components/spellcheck/common/spellcheck_features.h"
#include "components/spellcheck/spellcheck_buildflags.h"
#include "content/public/browser/context_menu_params.h"
#include "content/public/test/browser_test.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
// A test class used in this file. This test should be a browser test because it
// accesses resources.
class SpellingMenuObserverTest : public InProcessBrowserTest {
public:
SpellingMenuObserverTest();
void SetUpOnMainThread() override {
Reset(false);
#if BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
base::Value::List dictionary;
dictionary.Append("en-US");
menu()->GetPrefs()->SetList(spellcheck::prefs::kSpellCheckDictionaries,
std::move(dictionary));
// Use SetTestingFactoryAndUse to force creation and initialization of
// SpellcheckService using the TestingProfile browser context.
SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
menu()->GetBrowserContext(),
base::BindRepeating(&SpellingMenuObserverTest::BuildSpellcheckService,
base::Unretained(this)));
#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
}
#if BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
std::unique_ptr<KeyedService> BuildSpellcheckService(
content::BrowserContext* context) {
auto spellcheck_service = std::make_unique<SpellcheckService>(context);
// Call SetLanguage to assure that the platform spellchecker is initialized.
spellcheck_platform::SetLanguage(
spellcheck_service->platform_spell_checker(), "en-US",
base::BindOnce(&SpellingMenuObserverTest::OnSetLanguageComplete,
base::Unretained(this)));
RunUntilCallbackReceived();
return spellcheck_service;
}
void OnSetLanguageComplete(bool result) {
ASSERT_TRUE(result);
callback_received_ = true;
if (quit_)
std::move(quit_).Run();
}
void OnSuggestionsComplete() {
callback_received_ = true;
if (quit_)
std::move(quit_).Run();
}
void RunUntilCallbackReceived() {
if (callback_received_)
return;
base::RunLoop run_loop;
quit_ = run_loop.QuitClosure();
run_loop.Run();
// Reset status.
callback_received_ = false;
}
#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
void TearDownOnMainThread() override {
observer_.reset();
menu_.reset();
}
void Reset(bool incognito) {
observer_.reset();
menu_ = std::make_unique<MockRenderViewContextMenu>(incognito);
observer_ = std::make_unique<SpellingMenuObserver>(menu_.get());
menu_->SetObserver(observer_.get());
}
void InitMenu(const char* word, const char* suggestion) {
content::ContextMenuParams params;
params.is_editable = true;
params.misspelled_word = base::ASCIIToUTF16(word);
params.dictionary_suggestions.clear();
if (suggestion)
params.dictionary_suggestions.push_back(base::ASCIIToUTF16(suggestion));
#if BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
// Expect early return if word is spelled correctly.
if (params.misspelled_word.empty())
callback_received_ = true;
observer_->RegisterSuggestionsCompleteCallbackForTesting(
base::BindOnce(&SpellingMenuObserverTest::OnSuggestionsComplete,
base::Unretained(this)));
#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
observer_->InitMenu(params);
// Windows behavior needs this to be called as well to update placeholder
// menu items. Doesn't hurt for non-Windows platforms either.
observer_->OnContextMenuShown(params, gfx::Rect());
#if BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
RunUntilCallbackReceived();
#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
}
void ForceSuggestMode() {
menu()->GetPrefs()->SetBoolean(
spellcheck::prefs::kSpellCheckUseSpellingService, true);
// Force a non-empty and non-"en" locale so SUGGEST is available.
base::Value::List dictionary;
dictionary.Append("fr");
menu()->GetPrefs()->SetList(spellcheck::prefs::kSpellCheckDictionaries,
std::move(dictionary));
ASSERT_TRUE(SpellingServiceClient::IsAvailable(
menu()->GetBrowserContext(), SpellingServiceClient::SUGGEST));
ASSERT_FALSE(SpellingServiceClient::IsAvailable(
menu()->GetBrowserContext(), SpellingServiceClient::SPELLCHECK));
}
SpellingMenuObserverTest(const SpellingMenuObserverTest&) = delete;
SpellingMenuObserverTest& operator=(const SpellingMenuObserverTest&) = delete;
~SpellingMenuObserverTest() override;
MockRenderViewContextMenu* menu() { return menu_.get(); }
SpellingMenuObserver* observer() { return observer_.get(); }
private:
std::unique_ptr<SpellingMenuObserver> observer_;
std::unique_ptr<MockRenderViewContextMenu> menu_;
#if BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
// Quits the RunLoop on receiving callbacks.
base::OnceClosure quit_;
// Flag used for early exit from RunLoop if callback already received.
bool callback_received_ = false;
base::test::ScopedFeatureList feature_list_;
#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
};
#if BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
SpellingMenuObserverTest::SpellingMenuObserverTest() {
feature_list_.InitWithFeatures(
/*enabled_features=*/{},
/*disabled_features=*/{spellcheck::kWinDelaySpellcheckServiceInit});
}
#else
SpellingMenuObserverTest::SpellingMenuObserverTest() = default;
#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
SpellingMenuObserverTest::~SpellingMenuObserverTest() = default;
} // namespace
// TODO(https://crbug.com/410751413): Deleting temporary directories using
// test_file_util is flaky on Windows.
// Tests that right-clicking a correct word does not add any items.
#if BUILDFLAG(IS_WIN)
#define MAYBE_InitMenuWithCorrectWord DISABLED_InitMenuWithCorrectWord
#else
#define MAYBE_InitMenuWithCorrectWord InitMenuWithCorrectWord
#endif
IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest,
MAYBE_InitMenuWithCorrectWord) {
InitMenu("", nullptr);
EXPECT_EQ(static_cast<size_t>(0), menu()->GetMenuSize());
}
// Tests that right-clicking a misspelled word adds two items:
// "Add to dictionary", "Use enhanced spell check".
IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest, InitMenuWithMisspelledWord) {
// Pick word that Windows platform spellcheck has no suggestions for.
InitMenu("missssspelling", nullptr);
EXPECT_EQ(2U, menu()->GetMenuSize());
// Read all the context-menu items added by this test and verify they are
// expected ones. We do not check the item titles to prevent resource changes
// from breaking this test. (I think it is not expected by those who change
// resources.)
MockRenderViewContextMenu::MockMenuItem item;
menu()->GetMenuItem(0, &item);
EXPECT_EQ(IDC_SPELLCHECK_ADD_TO_DICTIONARY, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.hidden);
menu()->GetMenuItem(1, &item);
EXPECT_EQ(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.checked);
EXPECT_FALSE(item.hidden);
menu()->GetMenuItem(2, &item);
}
#if BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
// Tests that right-clicking a misspelled word that is identified as misspelled
// by both Hunspell and Windows platform combines their suggestions.
IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest,
WinInitMenuWithMisspelledWordCombined) {
InitMenu("mispelled", "misspelling");
EXPECT_EQ(6U, menu()->GetMenuSize());
// Read all the context-menu items added by this test and verify they are
// expected ones.
MockRenderViewContextMenu::MockMenuItem item;
// First separator.
menu()->GetMenuItem(0, &item);
EXPECT_EQ(-1, item.command_id);
EXPECT_FALSE(item.enabled);
EXPECT_FALSE(item.hidden);
// First suggestion.
menu()->GetMenuItem(1, &item);
EXPECT_EQ(IDC_SPELLCHECK_SUGGESTION_0, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.hidden);
EXPECT_EQ(u"misspelled", item.title);
// Second suggestion.
menu()->GetMenuItem(2, &item);
EXPECT_EQ(IDC_SPELLCHECK_SUGGESTION_0 + 1, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.hidden);
EXPECT_EQ(u"misspelling", item.title);
// Second separator.
menu()->GetMenuItem(3, &item);
EXPECT_EQ(-1, item.command_id);
EXPECT_FALSE(item.enabled);
EXPECT_FALSE(item.hidden);
// Add to dictionary.
menu()->GetMenuItem(4, &item);
EXPECT_EQ(IDC_SPELLCHECK_ADD_TO_DICTIONARY, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.hidden);
// Enhanced spellcheck toggle.
menu()->GetMenuItem(5, &item);
EXPECT_EQ(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.checked);
EXPECT_FALSE(item.hidden);
}
// Tests that right-clicking a misspelled word that is identified as misspelled
// by both Hunspell and Windows platform with the same suggestion leads to a
// single suggestion.
IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest,
WinInitMenuWithMisspelledWordNoDuplicateSuggestions) {
InitMenu("mispelled", "misspelled");
EXPECT_EQ(5U, menu()->GetMenuSize());
// Read all the context-menu items added by this test and verify they are
// expected ones.
MockRenderViewContextMenu::MockMenuItem item;
// First separator.
menu()->GetMenuItem(0, &item);
EXPECT_EQ(-1, item.command_id);
EXPECT_FALSE(item.enabled);
EXPECT_FALSE(item.hidden);
// First and only suggestion.
menu()->GetMenuItem(1, &item);
EXPECT_EQ(IDC_SPELLCHECK_SUGGESTION_0, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.hidden);
EXPECT_EQ(u"misspelled", item.title);
// Second separator.
menu()->GetMenuItem(2, &item);
EXPECT_EQ(-1, item.command_id);
EXPECT_FALSE(item.enabled);
EXPECT_FALSE(item.hidden);
// Add to dictionary.
menu()->GetMenuItem(3, &item);
EXPECT_EQ(IDC_SPELLCHECK_ADD_TO_DICTIONARY, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.hidden);
// Enhanced spellcheck toggle.
menu()->GetMenuItem(4, &item);
EXPECT_EQ(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.checked);
EXPECT_FALSE(item.hidden);
}
// Tests that right-clicking a misspelled word that is identified as misspelled
// by both Hunspell and Windows platform that has > 3 suggestions only displays
// 3 suggestions.
IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest,
WinInitMenuWithMisspelledWordMaxSuggestions) {
InitMenu("wtree", "wee");
EXPECT_EQ(7U, menu()->GetMenuSize());
std::set<std::u16string> suggestions(
{u"tree", u"twee", u"wee", u"ware", u"were"});
bool wee_suggested = false;
for (unsigned int i = 1; i < menu()->GetMenuSize(); i++) {
MockRenderViewContextMenu::MockMenuItem item;
menu()->GetMenuItem(i, &item);
if (!item.title.compare(u"wee")) {
wee_suggested = true;
break;
}
}
EXPECT_TRUE(wee_suggested);
// Read all the context-menu items added by this test and verify they are
// among the expected possibilities.
MockRenderViewContextMenu::MockMenuItem item;
// First separator.
menu()->GetMenuItem(0, &item);
EXPECT_EQ(-1, item.command_id);
EXPECT_FALSE(item.enabled);
EXPECT_FALSE(item.hidden);
// First suggestion.
menu()->GetMenuItem(1, &item);
EXPECT_EQ(IDC_SPELLCHECK_SUGGESTION_0, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.hidden);
EXPECT_TRUE(suggestions.contains(item.title));
// Second suggestion.
menu()->GetMenuItem(2, &item);
EXPECT_EQ(IDC_SPELLCHECK_SUGGESTION_0 + 1, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.hidden);
EXPECT_TRUE(suggestions.contains(item.title));
// Third suggestion.
menu()->GetMenuItem(3, &item);
EXPECT_EQ(IDC_SPELLCHECK_SUGGESTION_0 + 2, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.hidden);
EXPECT_TRUE(suggestions.contains(item.title));
// Second separator.
menu()->GetMenuItem(4, &item);
EXPECT_EQ(-1, item.command_id);
EXPECT_FALSE(item.enabled);
EXPECT_FALSE(item.hidden);
// Add to dictionary.
menu()->GetMenuItem(5, &item);
EXPECT_EQ(IDC_SPELLCHECK_ADD_TO_DICTIONARY, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.hidden);
// Enhanced spellcheck toggle.
menu()->GetMenuItem(6, &item);
EXPECT_EQ(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.checked);
EXPECT_FALSE(item.hidden);
}
#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
// Tests that right-clicking a correct word when we enable spelling-service
// integration to verify an item "Use enhanced spell check" is checked. Even
// though this menu itself does not add this item, its sub-menu adds the item
// and calls SpellingMenuObserver::IsChecked() to check it.
IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest,
EnableSpellingServiceWithCorrectWord) {
menu()->GetPrefs()->SetBoolean(
spellcheck::prefs::kSpellCheckUseSpellingService, true);
InitMenu("", nullptr);
EXPECT_TRUE(
observer()->IsCommandIdChecked(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE));
}
// Tests that right-clicking a misspelled word when we enable spelling-service
// integration to verify an item "Use enhanced spell check" is checked. (This
// test does not actually send JSON-RPC requests to the service because it makes
// this test flaky.)
// TODO(https://crbug.com/410751413): Deleting temporary directories using
// test_file_util is flaky on Windows.
#if BUILDFLAG(IS_WIN)
#define MAYBE_EnableSpellingService DISABLED_EnableSpellingService
#else
#define MAYBE_EnableSpellingService EnableSpellingService
#endif
IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest,
MAYBE_EnableSpellingService) {
menu()->GetPrefs()->SetBoolean(
spellcheck::prefs::kSpellCheckUseSpellingService, true);
base::Value::List dictionary;
menu()->GetPrefs()->SetList(spellcheck::prefs::kSpellCheckDictionaries,
std::move(dictionary));
// Pick word that Windows platform spellcheck has no suggestions for.
InitMenu("missssspelling", nullptr);
EXPECT_EQ(2U, menu()->GetMenuSize());
// To avoid duplicates, this test reads only the "Use enhanced spell check"
// item and verifies it is enabled and checked.
MockRenderViewContextMenu::MockMenuItem item;
menu()->GetMenuItem(1, &item);
EXPECT_EQ(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_TRUE(item.checked);
EXPECT_FALSE(item.hidden);
}
// Tests that right-clicking a misspelled word when spelling-service
// integration is enabled but the browser's spell check preference is disabled
// shows the "Use enhanced spell check" as unchecked. Clicking on this item
// enables spell check on the browser.
IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest,
EnableSpellingServiceWhenSpellcheckDisabled) {
menu()->GetPrefs()->SetBoolean(spellcheck::prefs::kSpellCheckEnable, false);
menu()->GetPrefs()->SetBoolean(
spellcheck::prefs::kSpellCheckUseSpellingService, true);
MockRenderViewContextMenu::MockMenuItem item;
menu()->GetMenuItem(1, &item);
EXPECT_FALSE(item.checked);
menu()->ExecuteCommand(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE, 1);
EXPECT_TRUE(
menu()->GetPrefs()->GetBoolean(spellcheck::prefs::kSpellCheckEnable));
EXPECT_TRUE(menu()->IsCommandIdChecked(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE));
}
// Test that we don't show "No more suggestions from Google" if the spelling
// service is enabled and that there is only one suggestion.
IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest,
NoMoreSuggestionsNotDisplayed) {
menu()->GetPrefs()->SetBoolean(
spellcheck::prefs::kSpellCheckUseSpellingService, true);
// Force a non-empty locale so SPELLCHECK is available.
base::Value::List dictionary;
dictionary.Append("en");
menu()->GetPrefs()->SetList(spellcheck::prefs::kSpellCheckDictionaries,
std::move(dictionary));
EXPECT_TRUE(SpellingServiceClient::IsAvailable(
menu()->GetBrowserContext(), SpellingServiceClient::SPELLCHECK));
InitMenu("asdfkj", "asdf");
// The test should see a suggestion, separator, "Add to dictionary",
// "Use enhanced spell check".
// Possibly more items (not relevant here).
EXPECT_LT(3U, menu()->GetMenuSize());
MockRenderViewContextMenu::MockMenuItem item;
menu()->GetMenuItem(0, &item);
EXPECT_EQ(-1, item.command_id);
EXPECT_FALSE(item.enabled);
EXPECT_FALSE(item.hidden);
menu()->GetMenuItem(1, &item);
EXPECT_EQ(IDC_SPELLCHECK_SUGGESTION_0, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.hidden);
menu()->GetMenuItem(2, &item);
EXPECT_EQ(-1, item.command_id);
EXPECT_FALSE(item.enabled);
EXPECT_FALSE(item.hidden);
menu()->GetMenuItem(3, &item);
EXPECT_EQ(IDC_SPELLCHECK_ADD_TO_DICTIONARY, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.hidden);
menu()->GetMenuItem(4, &item);
EXPECT_EQ(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_TRUE(item.checked);
EXPECT_FALSE(item.hidden);
}
// crbug.com/899935
#if BUILDFLAG(IS_WIN)
#define MAYBE_NoSpellingServiceWhenOffTheRecord \
DISABLED_NoSpellingServiceWhenOffTheRecord
#else
#define MAYBE_NoSpellingServiceWhenOffTheRecord \
NoSpellingServiceWhenOffTheRecord
#endif
// Test that "Use enhanced spell check" is grayed out when using an
// off the record profile.
// TODO(rlp): Include graying out of autocorrect in this test when autocorrect
// is functional.
IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest,
MAYBE_NoSpellingServiceWhenOffTheRecord) {
// Create a menu in an incognito profile.
Reset(true);
// This means spellchecking is allowed. Default is that the service is
// contacted but this test makes sure that if profile is incognito, that
// is not an option.
menu()->GetPrefs()->SetBoolean(
spellcheck::prefs::kSpellCheckUseSpellingService, true);
// Force a non-empty locale so SUGGEST normally would be available.
base::Value::List dictionary;
dictionary.Append("en");
menu()->GetPrefs()->SetList(spellcheck::prefs::kSpellCheckDictionaries,
std::move(dictionary));
EXPECT_FALSE(SpellingServiceClient::IsAvailable(
menu()->GetBrowserContext(), SpellingServiceClient::SUGGEST));
EXPECT_FALSE(SpellingServiceClient::IsAvailable(
menu()->GetBrowserContext(), SpellingServiceClient::SPELLCHECK));
InitMenu("sjxdjiiiiii", nullptr);
// There should not be a "No more Google suggestions" (from SpellingService)
// or a separator. The next 2 items should be "Add to Dictionary" followed
// by "Use enhanced spell check" which should be disabled.
// TODO(rlp): add autocorrect here when it is functional.
EXPECT_LT(1U, menu()->GetMenuSize());
MockRenderViewContextMenu::MockMenuItem item;
menu()->GetMenuItem(0, &item);
EXPECT_EQ(IDC_SPELLCHECK_ADD_TO_DICTIONARY, item.command_id);
EXPECT_TRUE(item.enabled);
EXPECT_FALSE(item.hidden);
menu()->GetMenuItem(1, &item);
EXPECT_EQ(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE, item.command_id);
EXPECT_FALSE(item.enabled);
EXPECT_FALSE(item.hidden);
}
// crbug.com/899935
#if BUILDFLAG(IS_WIN)
#define MAYBE_SuggestionsForceTopSeparator DISABLED_SuggestionsForceTopSeparator
#else
#define MAYBE_SuggestionsForceTopSeparator SuggestionsForceTopSeparator
#endif
// Test that the menu is preceeded by a separator if there are any suggestions,
// or if the SpellingServiceClient is available
IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest,
MAYBE_SuggestionsForceTopSeparator) {
menu()->GetPrefs()->SetBoolean(
spellcheck::prefs::kSpellCheckUseSpellingService, false);
// First case: Misspelled word, no suggestions, no spellcheck service.
InitMenu("asdfkj", nullptr);
// See SpellingMenuObserverTest.InitMenuWithMisspelledWord on why 2 items.
EXPECT_EQ(2U, menu()->GetMenuSize());
MockRenderViewContextMenu::MockMenuItem item;
menu()->GetMenuItem(0, &item);
EXPECT_NE(-1, item.command_id);
// Case #2. Misspelled word, suggestions, no spellcheck service.
Reset(false);
menu()->GetPrefs()->SetBoolean(
spellcheck::prefs::kSpellCheckUseSpellingService, false);
InitMenu("asdfkj", "asdf");
// Expect at least separator and 4 default entries.
EXPECT_LT(4U, menu()->GetMenuSize());
// This test only cares that the first one is a separator.
menu()->GetMenuItem(0, &item);
EXPECT_EQ(-1, item.command_id);
// Case #3. Misspelled word, suggestion service is on.
Reset(false);
ForceSuggestMode();
InitMenu("asdfkj", nullptr);
// Should have at least 2 entries. Separator, suggestion.
EXPECT_LT(2U, menu()->GetMenuSize());
menu()->GetMenuItem(0, &item);
EXPECT_EQ(-1, item.command_id);
menu()->GetMenuItem(1, &item);
EXPECT_EQ(IDC_CONTENT_CONTEXT_SPELLING_SUGGESTION, item.command_id);
}