| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/renderer_context_menu/spelling_menu_observer.h" | 5 #include "chrome/browser/renderer_context_menu/spelling_menu_observer.h" |
| 6 | 6 |
| 7 #include "base/macros.h" | 7 #include "base/macros.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "base/values.h" | 9 #include "base/values.h" |
| 10 #include "chrome/app/chrome_command_ids.h" | 10 #include "chrome/app/chrome_command_ids.h" |
| 11 #include "chrome/browser/renderer_context_menu/mock_render_view_context_menu.h" | 11 #include "chrome/browser/renderer_context_menu/mock_render_view_context_menu.h" |
| 12 #include "chrome/browser/spellchecker/spelling_service_client.h" | |
| 13 #include "chrome/common/pref_names.h" | |
| 14 #include "chrome/test/base/in_process_browser_test.h" | 12 #include "chrome/test/base/in_process_browser_test.h" |
| 15 #include "components/prefs/pref_service.h" | 13 #include "components/prefs/pref_service.h" |
| 14 #include "components/spellcheck/browser/pref_names.h" |
| 15 #include "components/spellcheck/browser/spelling_service_client.h" |
| 16 #include "content/public/common/context_menu_params.h" | 16 #include "content/public/common/context_menu_params.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 18 |
| 19 namespace { | 19 namespace { |
| 20 | 20 |
| 21 // A test class used in this file. This test should be a browser test because it | 21 // A test class used in this file. This test should be a browser test because it |
| 22 // accesses resources. | 22 // accesses resources. |
| 23 class SpellingMenuObserverTest : public InProcessBrowserTest { | 23 class SpellingMenuObserverTest : public InProcessBrowserTest { |
| 24 public: | 24 public: |
| 25 SpellingMenuObserverTest(); | 25 SpellingMenuObserverTest(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 42 content::ContextMenuParams params; | 42 content::ContextMenuParams params; |
| 43 params.is_editable = true; | 43 params.is_editable = true; |
| 44 params.misspelled_word = base::ASCIIToUTF16(word); | 44 params.misspelled_word = base::ASCIIToUTF16(word); |
| 45 params.dictionary_suggestions.clear(); | 45 params.dictionary_suggestions.clear(); |
| 46 if (suggestion) | 46 if (suggestion) |
| 47 params.dictionary_suggestions.push_back(base::ASCIIToUTF16(suggestion)); | 47 params.dictionary_suggestions.push_back(base::ASCIIToUTF16(suggestion)); |
| 48 observer_->InitMenu(params); | 48 observer_->InitMenu(params); |
| 49 } | 49 } |
| 50 | 50 |
| 51 void ForceSuggestMode() { | 51 void ForceSuggestMode() { |
| 52 menu()->GetPrefs()->SetBoolean(prefs::kSpellCheckUseSpellingService, true); | 52 menu()->GetPrefs()->SetBoolean( |
| 53 spellcheck::prefs::kSpellCheckUseSpellingService, true); |
| 53 // Force a non-empty and non-"en" locale so SUGGEST is available. | 54 // Force a non-empty and non-"en" locale so SUGGEST is available. |
| 54 base::ListValue dictionary; | 55 base::ListValue dictionary; |
| 55 dictionary.AppendString("fr"); | 56 dictionary.AppendString("fr"); |
| 56 menu()->GetPrefs()->Set(prefs::kSpellCheckDictionaries, dictionary); | 57 menu()->GetPrefs()->Set(spellcheck::prefs::kSpellCheckDictionaries, |
| 58 dictionary); |
| 57 | 59 |
| 58 ASSERT_TRUE(SpellingServiceClient::IsAvailable( | 60 ASSERT_TRUE(SpellingServiceClient::IsAvailable( |
| 59 menu()->GetBrowserContext(), SpellingServiceClient::SUGGEST)); | 61 menu()->GetBrowserContext(), SpellingServiceClient::SUGGEST)); |
| 60 ASSERT_FALSE(SpellingServiceClient::IsAvailable( | 62 ASSERT_FALSE(SpellingServiceClient::IsAvailable( |
| 61 menu()->GetBrowserContext(), SpellingServiceClient::SPELLCHECK)); | 63 menu()->GetBrowserContext(), SpellingServiceClient::SPELLCHECK)); |
| 62 } | 64 } |
| 63 | 65 |
| 64 ~SpellingMenuObserverTest() override; | 66 ~SpellingMenuObserverTest() override; |
| 65 MockRenderViewContextMenu* menu() { return menu_.get(); } | 67 MockRenderViewContextMenu* menu() { return menu_.get(); } |
| 66 SpellingMenuObserver* observer() { return observer_.get(); } | 68 SpellingMenuObserver* observer() { return observer_.get(); } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 EXPECT_FALSE(item.enabled); | 111 EXPECT_FALSE(item.enabled); |
| 110 EXPECT_FALSE(item.hidden); | 112 EXPECT_FALSE(item.hidden); |
| 111 } | 113 } |
| 112 | 114 |
| 113 // Tests that right-clicking a correct word when we enable spelling-service | 115 // Tests that right-clicking a correct word when we enable spelling-service |
| 114 // integration to verify an item "Ask Google for suggestions" is checked. Even | 116 // integration to verify an item "Ask Google for suggestions" is checked. Even |
| 115 // though this meanu itself does not add this item, its sub-menu adds the item | 117 // though this meanu itself does not add this item, its sub-menu adds the item |
| 116 // and calls SpellingMenuObserver::IsChecked() to check it. | 118 // and calls SpellingMenuObserver::IsChecked() to check it. |
| 117 IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest, | 119 IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest, |
| 118 EnableSpellingServiceWithCorrectWord) { | 120 EnableSpellingServiceWithCorrectWord) { |
| 119 menu()->GetPrefs()->SetBoolean(prefs::kSpellCheckUseSpellingService, true); | 121 menu()->GetPrefs()->SetBoolean( |
| 122 spellcheck::prefs::kSpellCheckUseSpellingService, true); |
| 120 InitMenu("", nullptr); | 123 InitMenu("", nullptr); |
| 121 | 124 |
| 122 EXPECT_TRUE( | 125 EXPECT_TRUE( |
| 123 observer()->IsCommandIdChecked(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE)); | 126 observer()->IsCommandIdChecked(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE)); |
| 124 } | 127 } |
| 125 | 128 |
| 126 // Tests that right-clicking a misspelled word when we enable spelling-service | 129 // Tests that right-clicking a misspelled word when we enable spelling-service |
| 127 // integration to verify an item "Ask Google for suggestions" is checked. (This | 130 // integration to verify an item "Ask Google for suggestions" is checked. (This |
| 128 // test does not actually send JSON-RPC requests to the service because it makes | 131 // test does not actually send JSON-RPC requests to the service because it makes |
| 129 // this test flaky.) | 132 // this test flaky.) |
| 130 IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest, EnableSpellingService) { | 133 IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest, EnableSpellingService) { |
| 131 menu()->GetPrefs()->SetBoolean(prefs::kSpellCheckUseSpellingService, true); | 134 menu()->GetPrefs()->SetBoolean( |
| 135 spellcheck::prefs::kSpellCheckUseSpellingService, true); |
| 132 base::ListValue dictionary; | 136 base::ListValue dictionary; |
| 133 menu()->GetPrefs()->Set(prefs::kSpellCheckDictionaries, dictionary); | 137 menu()->GetPrefs()->Set(spellcheck::prefs::kSpellCheckDictionaries, |
| 138 dictionary); |
| 134 | 139 |
| 135 InitMenu("wiimode", nullptr); | 140 InitMenu("wiimode", nullptr); |
| 136 EXPECT_EQ(3U, menu()->GetMenuSize()); | 141 EXPECT_EQ(3U, menu()->GetMenuSize()); |
| 137 | 142 |
| 138 // To avoid duplicates, this test reads only the "Ask Google for suggestions" | 143 // To avoid duplicates, this test reads only the "Ask Google for suggestions" |
| 139 // item and verifies it is enabled and checked. | 144 // item and verifies it is enabled and checked. |
| 140 MockRenderViewContextMenu::MockMenuItem item; | 145 MockRenderViewContextMenu::MockMenuItem item; |
| 141 menu()->GetMenuItem(1, &item); | 146 menu()->GetMenuItem(1, &item); |
| 142 EXPECT_EQ(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE, item.command_id); | 147 EXPECT_EQ(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE, item.command_id); |
| 143 EXPECT_TRUE(item.enabled); | 148 EXPECT_TRUE(item.enabled); |
| 144 EXPECT_TRUE(item.checked); | 149 EXPECT_TRUE(item.checked); |
| 145 EXPECT_FALSE(item.hidden); | 150 EXPECT_FALSE(item.hidden); |
| 146 } | 151 } |
| 147 | 152 |
| 148 // Test that we don't show "No more suggestions from Google" if the spelling | 153 // Test that we don't show "No more suggestions from Google" if the spelling |
| 149 // service is enabled and that there is only one suggestion. | 154 // service is enabled and that there is only one suggestion. |
| 150 IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest, | 155 IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest, |
| 151 NoMoreSuggestionsNotDisplayed) { | 156 NoMoreSuggestionsNotDisplayed) { |
| 152 menu()->GetPrefs()->SetBoolean(prefs::kSpellCheckUseSpellingService, true); | 157 menu()->GetPrefs()->SetBoolean( |
| 158 spellcheck::prefs::kSpellCheckUseSpellingService, true); |
| 153 | 159 |
| 154 // Force a non-empty locale so SPELLCHECK is available. | 160 // Force a non-empty locale so SPELLCHECK is available. |
| 155 base::ListValue dictionary; | 161 base::ListValue dictionary; |
| 156 dictionary.AppendString("en"); | 162 dictionary.AppendString("en"); |
| 157 menu()->GetPrefs()->Set(prefs::kSpellCheckDictionaries, dictionary); | 163 menu()->GetPrefs()->Set(spellcheck::prefs::kSpellCheckDictionaries, |
| 164 dictionary); |
| 158 | 165 |
| 159 EXPECT_TRUE(SpellingServiceClient::IsAvailable( | 166 EXPECT_TRUE(SpellingServiceClient::IsAvailable( |
| 160 menu()->GetBrowserContext(), SpellingServiceClient::SPELLCHECK)); | 167 menu()->GetBrowserContext(), SpellingServiceClient::SPELLCHECK)); |
| 161 InitMenu("asdfkj", "asdf"); | 168 InitMenu("asdfkj", "asdf"); |
| 162 | 169 |
| 163 // The test should see a separator, suggestion, "Add to dictionary", | 170 // The test should see a separator, suggestion, "Add to dictionary", |
| 164 // "Ask Google for suggestions", and a separator. Possibly more items (not | 171 // "Ask Google for suggestions", and a separator. Possibly more items (not |
| 165 // relevant here). | 172 // relevant here). |
| 166 EXPECT_LT(3U, menu()->GetMenuSize()); | 173 EXPECT_LT(3U, menu()->GetMenuSize()); |
| 167 | 174 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 198 // TODO(rlp): Include graying out of autocorrect in this test when autocorrect | 205 // TODO(rlp): Include graying out of autocorrect in this test when autocorrect |
| 199 // is functional. | 206 // is functional. |
| 200 IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest, | 207 IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest, |
| 201 NoSpellingServiceWhenOffTheRecord) { | 208 NoSpellingServiceWhenOffTheRecord) { |
| 202 // Create a menu in an incognito profile. | 209 // Create a menu in an incognito profile. |
| 203 Reset(true); | 210 Reset(true); |
| 204 | 211 |
| 205 // This means spellchecking is allowed. Default is that the service is | 212 // This means spellchecking is allowed. Default is that the service is |
| 206 // contacted but this test makes sure that if profile is incognito, that | 213 // contacted but this test makes sure that if profile is incognito, that |
| 207 // is not an option. | 214 // is not an option. |
| 208 menu()->GetPrefs()->SetBoolean(prefs::kSpellCheckUseSpellingService, true); | 215 menu()->GetPrefs()->SetBoolean( |
| 216 spellcheck::prefs::kSpellCheckUseSpellingService, true); |
| 209 | 217 |
| 210 // Force a non-empty locale so SUGGEST normally would be available. | 218 // Force a non-empty locale so SUGGEST normally would be available. |
| 211 base::ListValue dictionary; | 219 base::ListValue dictionary; |
| 212 dictionary.AppendString("en"); | 220 dictionary.AppendString("en"); |
| 213 menu()->GetPrefs()->Set(prefs::kSpellCheckDictionaries, dictionary); | 221 menu()->GetPrefs()->Set(spellcheck::prefs::kSpellCheckDictionaries, |
| 222 dictionary); |
| 214 | 223 |
| 215 EXPECT_FALSE(SpellingServiceClient::IsAvailable( | 224 EXPECT_FALSE(SpellingServiceClient::IsAvailable( |
| 216 menu()->GetBrowserContext(), SpellingServiceClient::SUGGEST)); | 225 menu()->GetBrowserContext(), SpellingServiceClient::SUGGEST)); |
| 217 EXPECT_FALSE(SpellingServiceClient::IsAvailable( | 226 EXPECT_FALSE(SpellingServiceClient::IsAvailable( |
| 218 menu()->GetBrowserContext(), SpellingServiceClient::SPELLCHECK)); | 227 menu()->GetBrowserContext(), SpellingServiceClient::SPELLCHECK)); |
| 219 | 228 |
| 220 InitMenu("sjxdjiiiiii", nullptr); | 229 InitMenu("sjxdjiiiiii", nullptr); |
| 221 | 230 |
| 222 // There should not be a "No more Google suggestions" (from SpellingService) | 231 // There should not be a "No more Google suggestions" (from SpellingService) |
| 223 // or a separator. The next 2 items should be "Add to Dictionary" followed | 232 // or a separator. The next 2 items should be "Add to Dictionary" followed |
| 224 // by "Ask Google for suggestions" which should be disabled. | 233 // by "Ask Google for suggestions" which should be disabled. |
| 225 // TODO(rlp): add autocorrect here when it is functional. | 234 // TODO(rlp): add autocorrect here when it is functional. |
| 226 EXPECT_LT(2U, menu()->GetMenuSize()); | 235 EXPECT_LT(2U, menu()->GetMenuSize()); |
| 227 | 236 |
| 228 MockRenderViewContextMenu::MockMenuItem item; | 237 MockRenderViewContextMenu::MockMenuItem item; |
| 229 menu()->GetMenuItem(0, &item); | 238 menu()->GetMenuItem(0, &item); |
| 230 EXPECT_EQ(IDC_SPELLCHECK_ADD_TO_DICTIONARY, item.command_id); | 239 EXPECT_EQ(IDC_SPELLCHECK_ADD_TO_DICTIONARY, item.command_id); |
| 231 EXPECT_TRUE(item.enabled); | 240 EXPECT_TRUE(item.enabled); |
| 232 EXPECT_FALSE(item.hidden); | 241 EXPECT_FALSE(item.hidden); |
| 233 | 242 |
| 234 menu()->GetMenuItem(1, &item); | 243 menu()->GetMenuItem(1, &item); |
| 235 EXPECT_EQ(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE, item.command_id); | 244 EXPECT_EQ(IDC_CONTENT_CONTEXT_SPELLING_TOGGLE, item.command_id); |
| 236 EXPECT_FALSE(item.enabled); | 245 EXPECT_FALSE(item.enabled); |
| 237 EXPECT_FALSE(item.hidden); | 246 EXPECT_FALSE(item.hidden); |
| 238 } | 247 } |
| 239 | 248 |
| 240 // Test that the menu is preceeded by a separator if there are any suggestions, | 249 // Test that the menu is preceeded by a separator if there are any suggestions, |
| 241 // or if the SpellingServiceClient is available | 250 // or if the SpellingServiceClient is available |
| 242 IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest, SuggestionsForceTopSeparator) { | 251 IN_PROC_BROWSER_TEST_F(SpellingMenuObserverTest, SuggestionsForceTopSeparator) { |
| 243 menu()->GetPrefs()->SetBoolean(prefs::kSpellCheckUseSpellingService, false); | 252 menu()->GetPrefs()->SetBoolean( |
| 253 spellcheck::prefs::kSpellCheckUseSpellingService, false); |
| 244 | 254 |
| 245 // First case: Misspelled word, no suggestions, no spellcheck service. | 255 // First case: Misspelled word, no suggestions, no spellcheck service. |
| 246 InitMenu("asdfkj", nullptr); | 256 InitMenu("asdfkj", nullptr); |
| 247 // See SpellingMenuObserverTest.InitMenuWithMisspelledWord on why 3 items. | 257 // See SpellingMenuObserverTest.InitMenuWithMisspelledWord on why 3 items. |
| 248 EXPECT_EQ(3U, menu()->GetMenuSize()); | 258 EXPECT_EQ(3U, menu()->GetMenuSize()); |
| 249 MockRenderViewContextMenu::MockMenuItem item; | 259 MockRenderViewContextMenu::MockMenuItem item; |
| 250 menu()->GetMenuItem(0, &item); | 260 menu()->GetMenuItem(0, &item); |
| 251 EXPECT_NE(-1, item.command_id); | 261 EXPECT_NE(-1, item.command_id); |
| 252 | 262 |
| 253 // Case #2. Misspelled word, suggestions, no spellcheck service. | 263 // Case #2. Misspelled word, suggestions, no spellcheck service. |
| 254 Reset(false); | 264 Reset(false); |
| 255 menu()->GetPrefs()->SetBoolean(prefs::kSpellCheckUseSpellingService, false); | 265 menu()->GetPrefs()->SetBoolean( |
| 266 spellcheck::prefs::kSpellCheckUseSpellingService, false); |
| 256 InitMenu("asdfkj", "asdf"); | 267 InitMenu("asdfkj", "asdf"); |
| 257 | 268 |
| 258 // Expect at least separator and 4 default entries. | 269 // Expect at least separator and 4 default entries. |
| 259 EXPECT_LT(4U, menu()->GetMenuSize()); | 270 EXPECT_LT(4U, menu()->GetMenuSize()); |
| 260 // This test only cares that the first one is a separator. | 271 // This test only cares that the first one is a separator. |
| 261 menu()->GetMenuItem(0, &item); | 272 menu()->GetMenuItem(0, &item); |
| 262 EXPECT_EQ(-1, item.command_id); | 273 EXPECT_EQ(-1, item.command_id); |
| 263 | 274 |
| 264 // Case #3. Misspelled word, suggestion service is on. | 275 // Case #3. Misspelled word, suggestion service is on. |
| 265 Reset(false); | 276 Reset(false); |
| 266 ForceSuggestMode(); | 277 ForceSuggestMode(); |
| 267 InitMenu("asdfkj", nullptr); | 278 InitMenu("asdfkj", nullptr); |
| 268 | 279 |
| 269 // Should have at least 2 entries. Separator, suggestion. | 280 // Should have at least 2 entries. Separator, suggestion. |
| 270 EXPECT_LT(2U, menu()->GetMenuSize()); | 281 EXPECT_LT(2U, menu()->GetMenuSize()); |
| 271 menu()->GetMenuItem(0, &item); | 282 menu()->GetMenuItem(0, &item); |
| 272 EXPECT_EQ(-1, item.command_id); | 283 EXPECT_EQ(-1, item.command_id); |
| 273 menu()->GetMenuItem(1, &item); | 284 menu()->GetMenuItem(1, &item); |
| 274 EXPECT_EQ(IDC_CONTENT_CONTEXT_SPELLING_SUGGESTION, item.command_id); | 285 EXPECT_EQ(IDC_CONTENT_CONTEXT_SPELLING_SUGGESTION, item.command_id); |
| 275 } | 286 } |
| OLD | NEW |