1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/renderer_context_menu/spellchecker_submenu_observer.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_command_ids.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/renderer_context_menu/render_view_context_menu.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/testing_profile.h" 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/renderer_context_menu/render_view_context_menu_observer.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A mock context menu used in this test. This class overrides virtual methods 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// derived from the RenderViewContextMenuProxy class to monitor calls from the 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SpellingMenuObserver class. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockRenderViewContextMenu : public ui::SimpleMenuModel::Delegate, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public RenderViewContextMenuProxy { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A menu item used in this test. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct MockMenuItem { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockMenuItem() 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : command_id(0), 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enabled(false), 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checked(false), 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hidden(true) {} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int command_id; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enabled; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool checked; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool hidden; 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 title; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockRenderViewContextMenu() : observer_(NULL), profile_(new TestingProfile) {} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~MockRenderViewContextMenu() {} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SimpleMenuModel::Delegate implementation. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsCommandIdChecked(int command_id) const OVERRIDE { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return observer_->IsCommandIdChecked(command_id); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return observer_->IsCommandIdEnabled(command_id); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->ExecuteCommand(command_id); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void MenuWillShow(ui::SimpleMenuModel* source) OVERRIDE {} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void MenuClosed(ui::SimpleMenuModel* source) OVERRIDE {} 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetAcceleratorForCommandId( 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int command_id, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::Accelerator* accelerator) OVERRIDE { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RenderViewContextMenuProxy implementation. 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void AddMenuItem(int command_id, 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& title) OVERRIDE {} 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void AddCheckItem(int command_id, 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& title) OVERRIDE {} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AddSeparator() OVERRIDE {} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AddSubMenu(int command_id, 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& label, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::MenuModel* model) OVERRIDE {} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void UpdateMenuItem(int command_id, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enabled, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool hidden, 74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& title) OVERRIDE {} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual RenderViewHost* GetRenderViewHost() const OVERRIDE { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual content::BrowserContext* GetBrowserContext() const OVERRIDE { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return profile_.get(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual content::WebContents* GetWebContents() const OVERRIDE { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Attaches a RenderViewContextMenuObserver to be tested. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetObserver(RenderViewContextMenuObserver* observer) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_ = observer; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the number of items added by the test. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t GetMenuSize() const { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the i-th item. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetMenuItem(size_t i, MockMenuItem* item) const { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the writable profile used in this test. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefService* GetPrefs() { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return profile_->GetPrefs(); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An observer used for initializing the status of menu items added in this 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // test. This is a weak pointer, the test is responsible for deleting this 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderViewContextMenuObserver* observer_; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A dummy profile used in this test. Call GetPrefs() when a test needs to 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // change this profile and use PrefService methods. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<TestingProfile> profile_; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MockRenderViewContextMenu); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A test class used in this file. This test should be a browser test because it 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// accesses resources. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpellCheckerSubMenuObserverTest : public InProcessBrowserTest { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpellCheckerSubMenuObserverTest() {} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~SpellCheckerSubMenuObserverTest() {} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SpellCheckerSubMenuObserverTest); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that selecting the "Check Spelling While Typing" item toggles the value 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the "browser.enable_spellchecking" profile. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(SpellCheckerSubMenuObserverTest, ToggleSpelling) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize a menu consisting only of a "Spell-checker Options" submenu. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<MockRenderViewContextMenu> menu(new MockRenderViewContextMenu); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SpellCheckerSubMenuObserver> observer( 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new SpellCheckerSubMenuObserver(menu.get(), menu.get(), 1)); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu->SetObserver(observer.get()); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu->GetPrefs()->SetString(prefs::kAcceptLanguages, "en-US"); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu->GetPrefs()->SetString(prefs::kSpellCheckDictionary, "en-US"); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) menu->GetPrefs()->SetBoolean(prefs::kEnableContinuousSpellcheck, true); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::ContextMenuParams params; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer->InitMenu(params); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify this menu has the "Check Spelling While Typing" item and this item 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is checked. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CHECK_SPELLING_WHILE_TYPING)); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(menu->IsCommandIdChecked(IDC_CHECK_SPELLING_WHILE_TYPING)); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Select this item and verify that the "Check Spelling While Typing" item is 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not checked. Also, verify that the value of "browser.enable_spellchecking" 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is now false. 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) menu->ExecuteCommand(IDC_CHECK_SPELLING_WHILE_TYPING, 0); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE( 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) menu->GetPrefs()->GetBoolean(prefs::kEnableContinuousSpellcheck)); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(menu->IsCommandIdChecked(IDC_CHECK_SPELLING_WHILE_TYPING)); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 158