1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/renderer_context_menu/spellchecker_submenu_observer.h"
6
7#include "base/prefs/pref_service.h"
8#include "base/strings/utf_string_conversions.h"
9#include "chrome/app/chrome_command_ids.h"
10#include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
11#include "chrome/common/pref_names.h"
12#include "chrome/test/base/in_process_browser_test.h"
13#include "chrome/test/base/testing_profile.h"
14#include "components/renderer_context_menu/render_view_context_menu_observer.h"
15
16using content::RenderViewHost;
17using content::WebContents;
18
19namespace {
20
21// A mock context menu used in this test. This class overrides virtual methods
22// derived from the RenderViewContextMenuProxy class to monitor calls from the
23// SpellingMenuObserver class.
24class MockRenderViewContextMenu : public ui::SimpleMenuModel::Delegate,
25                                  public RenderViewContextMenuProxy {
26 public:
27  // A menu item used in this test.
28  struct MockMenuItem {
29    MockMenuItem()
30        : command_id(0),
31          enabled(false),
32          checked(false),
33          hidden(true) {}
34    int command_id;
35    bool enabled;
36    bool checked;
37    bool hidden;
38    base::string16 title;
39  };
40
41  MockRenderViewContextMenu() : observer_(NULL), profile_(new TestingProfile) {}
42  virtual ~MockRenderViewContextMenu() {}
43
44  // SimpleMenuModel::Delegate implementation.
45  virtual bool IsCommandIdChecked(int command_id) const OVERRIDE {
46    return observer_->IsCommandIdChecked(command_id);
47  }
48  virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE {
49    return observer_->IsCommandIdEnabled(command_id);
50  }
51  virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE {
52    observer_->ExecuteCommand(command_id);
53  }
54  virtual void MenuWillShow(ui::SimpleMenuModel* source) OVERRIDE {}
55  virtual void MenuClosed(ui::SimpleMenuModel* source) OVERRIDE {}
56  virtual bool GetAcceleratorForCommandId(
57      int command_id,
58      ui::Accelerator* accelerator) OVERRIDE {
59    return false;
60  }
61
62  // RenderViewContextMenuProxy implementation.
63  virtual void AddMenuItem(int command_id,
64                           const base::string16& title) OVERRIDE {}
65  virtual void AddCheckItem(int command_id,
66                            const base::string16& title) OVERRIDE {}
67  virtual void AddSeparator() OVERRIDE {}
68  virtual void AddSubMenu(int command_id,
69                          const base::string16& label,
70                          ui::MenuModel* model) OVERRIDE {}
71  virtual void UpdateMenuItem(int command_id,
72                              bool enabled,
73                              bool hidden,
74                              const base::string16& title) OVERRIDE {}
75  virtual RenderViewHost* GetRenderViewHost() const OVERRIDE {
76    return NULL;
77  }
78  virtual content::BrowserContext* GetBrowserContext() const OVERRIDE {
79    return profile_.get();
80  }
81  virtual content::WebContents* GetWebContents() const OVERRIDE {
82    return NULL;
83  }
84
85  // Attaches a RenderViewContextMenuObserver to be tested.
86  void SetObserver(RenderViewContextMenuObserver* observer) {
87    observer_ = observer;
88  }
89
90  // Returns the number of items added by the test.
91  size_t GetMenuSize() const {
92    return 0;
93  }
94
95  // Returns the i-th item.
96  bool GetMenuItem(size_t i, MockMenuItem* item) const {
97    return false;
98  }
99
100  // Returns the writable profile used in this test.
101  PrefService* GetPrefs() {
102    return profile_->GetPrefs();
103  }
104
105 private:
106  // An observer used for initializing the status of menu items added in this
107  // test. This is a weak pointer, the test is responsible for deleting this
108  // object.
109  RenderViewContextMenuObserver* observer_;
110
111  // A dummy profile used in this test. Call GetPrefs() when a test needs to
112  // change this profile and use PrefService methods.
113  scoped_ptr<TestingProfile> profile_;
114
115  DISALLOW_COPY_AND_ASSIGN(MockRenderViewContextMenu);
116};
117
118// A test class used in this file. This test should be a browser test because it
119// accesses resources.
120class SpellCheckerSubMenuObserverTest : public InProcessBrowserTest {
121 public:
122  SpellCheckerSubMenuObserverTest() {}
123  virtual ~SpellCheckerSubMenuObserverTest() {}
124
125 private:
126  DISALLOW_COPY_AND_ASSIGN(SpellCheckerSubMenuObserverTest);
127};
128
129}  // namespace
130
131// Tests that selecting the "Check Spelling While Typing" item toggles the value
132// of the "browser.enable_spellchecking" profile.
133IN_PROC_BROWSER_TEST_F(SpellCheckerSubMenuObserverTest, ToggleSpelling) {
134  // Initialize a menu consisting only of a "Spell-checker Options" submenu.
135  scoped_ptr<MockRenderViewContextMenu> menu(new MockRenderViewContextMenu);
136  scoped_ptr<SpellCheckerSubMenuObserver> observer(
137      new SpellCheckerSubMenuObserver(menu.get(), menu.get(), 1));
138  menu->SetObserver(observer.get());
139  menu->GetPrefs()->SetString(prefs::kAcceptLanguages, "en-US");
140  menu->GetPrefs()->SetString(prefs::kSpellCheckDictionary, "en-US");
141  menu->GetPrefs()->SetBoolean(prefs::kEnableContinuousSpellcheck, true);
142  content::ContextMenuParams params;
143  observer->InitMenu(params);
144
145  // Verify this menu has the "Check Spelling While Typing" item and this item
146  // is checked.
147  EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CHECK_SPELLING_WHILE_TYPING));
148  EXPECT_TRUE(menu->IsCommandIdChecked(IDC_CHECK_SPELLING_WHILE_TYPING));
149
150  // Select this item and verify that the "Check Spelling While Typing" item is
151  // not checked. Also, verify that the value of "browser.enable_spellchecking"
152  // is now false.
153  menu->ExecuteCommand(IDC_CHECK_SPELLING_WHILE_TYPING, 0);
154  EXPECT_FALSE(
155      menu->GetPrefs()->GetBoolean(prefs::kEnableContinuousSpellcheck));
156  EXPECT_FALSE(menu->IsCommandIdChecked(IDC_CHECK_SPELLING_WHILE_TYPING));
157}
158