OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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 | |
6 #include <set> | |
7 | |
8 #include "base/utf_string_conversions.h" | |
9 #include "chrome/app/chrome_command_ids.h" | |
10 #include "chrome/browser/prefs/pref_service.h" | |
11 #include "chrome/browser/prefs/pref_change_registrar.h" | |
12 #include "chrome/browser/tab_contents/render_view_context_menu.h" | |
13 #include "chrome/browser/translate/translate_infobar_delegate.h" | |
14 #include "chrome/browser/translate/translate_manager.h" | |
15 #include "chrome/browser/translate/translate_prefs.h" | |
16 #include "chrome/common/notification_details.h" | |
17 #include "chrome/common/notification_observer_mock.h" | |
18 #include "chrome/common/notification_registrar.h" | |
19 #include "chrome/common/notification_type.h" | |
20 #include "chrome/common/pref_names.h" | |
21 #include "chrome/common/render_messages.h" | |
22 #include "chrome/common/net/test_url_fetcher_factory.h" | |
23 #include "chrome/test/testing_browser_process.h" | |
24 #include "chrome/test/testing_profile.h" | |
25 #include "content/browser/renderer_host/mock_render_process_host.h" | |
26 #include "content/browser/renderer_host/test_render_view_host.h" | |
27 #include "content/browser/tab_contents/navigation_controller.h" | |
28 #include "content/browser/tab_contents/test_tab_contents.h" | |
29 #include "grit/generated_resources.h" | |
30 #include "ipc/ipc_test_sink.h" | |
31 #include "testing/gmock/include/gmock/gmock.h" | |
32 #include "third_party/cld/languages/public/languages.h" | |
33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h" | |
34 | |
35 using testing::_; | |
36 using testing::Pointee; | |
37 using testing::Property; | |
38 using WebKit::WebContextMenuData; | |
39 | |
40 class TranslateManagerTest : public RenderViewHostTestHarness, | |
41 public NotificationObserver { | |
42 public: | |
43 TranslateManagerTest() {} | |
44 | |
45 // Simluates navigating to a page and getting the page contents and language | |
46 // for that navigation. | |
47 void SimulateNavigation(const GURL& url, | |
48 const std::string& contents, | |
49 const std::string& lang, | |
50 bool page_translatable) { | |
51 NavigateAndCommit(url); | |
52 int page_id = RenderViewHostTestHarness::contents()->controller(). | |
53 GetLastCommittedEntry()->page_id(); | |
54 SimulateOnPageContents(url, page_id, contents, lang, page_translatable); | |
55 } | |
56 | |
57 void SimulateOnPageContents(const GURL& url, int page_id, | |
58 const std::string& contents, | |
59 const std::string& lang, | |
60 bool page_translatable) { | |
61 rvh()->TestOnMessageReceived(ViewHostMsg_PageContents(0, url, page_id, | |
62 UTF8ToUTF16(contents), | |
63 lang, | |
64 page_translatable)); | |
65 } | |
66 | |
67 bool GetTranslateMessage(int* page_id, | |
68 std::string* original_lang, | |
69 std::string* target_lang) { | |
70 const IPC::Message* message = | |
71 process()->sink().GetFirstMessageMatching(ViewMsg_TranslatePage::ID); | |
72 if (!message) | |
73 return false; | |
74 Tuple4<int, std::string, std::string, std::string> translate_param; | |
75 ViewMsg_TranslatePage::Read(message, &translate_param); | |
76 if (page_id) | |
77 *page_id = translate_param.a; | |
78 // Ignore translate_param.b which is the script injected in the page. | |
79 if (original_lang) | |
80 *original_lang = translate_param.c; | |
81 if (target_lang) | |
82 *target_lang = translate_param.d; | |
83 return true; | |
84 } | |
85 | |
86 // Returns the translate infobar if there is 1 infobar and it is a translate | |
87 // infobar. | |
88 TranslateInfoBarDelegate* GetTranslateInfoBar() { | |
89 return (contents()->infobar_count() == 1) ? | |
90 contents()->GetInfoBarDelegateAt(0)->AsTranslateInfoBarDelegate() : | |
91 NULL; | |
92 } | |
93 | |
94 // If there is 1 infobar and it is a translate infobar, closes it and returns | |
95 // true. Returns false otherwise. | |
96 bool CloseTranslateInfoBar() { | |
97 InfoBarDelegate* infobar = GetTranslateInfoBar(); | |
98 if (!infobar) | |
99 return false; | |
100 infobar->InfoBarDismissed(); // Simulates closing the infobar. | |
101 contents()->RemoveInfoBar(infobar); | |
102 return true; | |
103 } | |
104 | |
105 // Checks whether |infobar| has been removed and clears the removed infobar | |
106 // list. | |
107 bool CheckInfoBarRemovedAndReset(InfoBarDelegate* delegate) { | |
108 bool found = removed_infobars_.count(delegate) != 0; | |
109 removed_infobars_.clear(); | |
110 return found; | |
111 } | |
112 | |
113 // Returns true if at least one infobar was closed. | |
114 bool InfoBarRemoved() { | |
115 return !removed_infobars_.empty(); | |
116 } | |
117 | |
118 // Clears the list of stored removed infobars. | |
119 void ClearRemovedInfoBars() { | |
120 removed_infobars_.clear(); | |
121 } | |
122 | |
123 void ExpireTranslateScriptImmediately() { | |
124 TranslateManager::GetInstance()->set_translate_script_expiration_delay(0); | |
125 } | |
126 | |
127 // If there is 1 infobar and it is a translate infobar, deny translation and | |
128 // returns true. Returns false otherwise. | |
129 bool DenyTranslation() { | |
130 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
131 if (!infobar) | |
132 return false; | |
133 infobar->TranslationDeclined(); | |
134 contents()->RemoveInfoBar(infobar); | |
135 return true; | |
136 } | |
137 | |
138 virtual void Observe(NotificationType type, | |
139 const NotificationSource& source, | |
140 const NotificationDetails& details) { | |
141 DCHECK_EQ(NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, type.value); | |
142 removed_infobars_.insert(Details<InfoBarDelegate>(details).ptr()); | |
143 } | |
144 | |
145 protected: | |
146 virtual void SetUp() { | |
147 URLFetcher::set_factory(&url_fetcher_factory_); | |
148 | |
149 // Access the TranslateManager singleton so it is created before we call | |
150 // RenderViewHostTestHarness::SetUp() to match what's done in Chrome, where | |
151 // the TranslateManager is created before the TabContents. This matters as | |
152 // they both register for similar events and we want the notifications to | |
153 // happen in the same sequence (TranslateManager first, TabContents second). | |
154 // Also clears the translate script so it is fetched everytime and sets the | |
155 // expiration delay to a large value by default (in case it was zeroed in | |
156 // a previous test). | |
157 TranslateManager::GetInstance()->ClearTranslateScript(); | |
158 TranslateManager::GetInstance()-> | |
159 set_translate_script_expiration_delay(60 * 60 * 1000); | |
160 | |
161 RenderViewHostTestHarness::SetUp(); | |
162 | |
163 notification_registrar_.Add(this, | |
164 NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, | |
165 Source<TabContents>(contents())); | |
166 } | |
167 | |
168 virtual void TearDown() { | |
169 process()->sink().ClearMessages(); | |
170 | |
171 notification_registrar_.Remove(this, | |
172 NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, | |
173 Source<TabContents>(contents())); | |
174 | |
175 RenderViewHostTestHarness::TearDown(); | |
176 | |
177 URLFetcher::set_factory(NULL); | |
178 } | |
179 | |
180 void SimulateURLFetch(bool success) { | |
181 TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); | |
182 ASSERT_TRUE(fetcher); | |
183 net::URLRequestStatus status; | |
184 status.set_status(success ? net::URLRequestStatus::SUCCESS : | |
185 net::URLRequestStatus::FAILED); | |
186 fetcher->delegate()->OnURLFetchComplete(fetcher, fetcher->original_url(), | |
187 status, success ? 200 : 500, | |
188 ResponseCookies(), | |
189 std::string()); | |
190 } | |
191 | |
192 void SetPrefObserverExpectation(const char* path) { | |
193 EXPECT_CALL( | |
194 pref_observer_, | |
195 Observe(NotificationType(NotificationType::PREF_CHANGED), | |
196 _, | |
197 Property(&Details<std::string>::ptr, Pointee(path)))); | |
198 } | |
199 | |
200 NotificationObserverMock pref_observer_; | |
201 | |
202 private: | |
203 NotificationRegistrar notification_registrar_; | |
204 TestURLFetcherFactory url_fetcher_factory_; | |
205 | |
206 // The infobars that have been removed. | |
207 // WARNING: the pointers point to deleted objects, use only for comparison. | |
208 std::set<InfoBarDelegate*> removed_infobars_; | |
209 | |
210 DISALLOW_COPY_AND_ASSIGN(TranslateManagerTest); | |
211 }; | |
212 | |
213 // An observer that keeps track of whether a navigation entry was committed. | |
214 class NavEntryCommittedObserver : public NotificationObserver { | |
215 public: | |
216 explicit NavEntryCommittedObserver(TabContents* tab_contents) { | |
217 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, | |
218 Source<NavigationController>(&tab_contents->controller())); | |
219 } | |
220 | |
221 virtual void Observe(NotificationType type, | |
222 const NotificationSource& source, | |
223 const NotificationDetails& details) { | |
224 DCHECK(type == NotificationType::NAV_ENTRY_COMMITTED); | |
225 details_ = | |
226 *(Details<NavigationController::LoadCommittedDetails>(details).ptr()); | |
227 } | |
228 | |
229 const NavigationController::LoadCommittedDetails& | |
230 get_load_commited_details() const { | |
231 return details_; | |
232 } | |
233 | |
234 private: | |
235 NavigationController::LoadCommittedDetails details_; | |
236 NotificationRegistrar registrar_; | |
237 | |
238 DISALLOW_COPY_AND_ASSIGN(NavEntryCommittedObserver); | |
239 }; | |
240 | |
241 class TestRenderViewContextMenu : public RenderViewContextMenu { | |
242 public: | |
243 static TestRenderViewContextMenu* CreateContextMenu( | |
244 TabContents* tab_contents) { | |
245 ContextMenuParams params; | |
246 params.media_type = WebKit::WebContextMenuData::MediaTypeNone; | |
247 params.x = 0; | |
248 params.y = 0; | |
249 params.is_image_blocked = false; | |
250 params.media_flags = 0; | |
251 params.spellcheck_enabled = false; | |
252 params.is_editable = false; | |
253 params.page_url = tab_contents->controller().GetActiveEntry()->url(); | |
254 #if defined(OS_MACOSX) | |
255 params.writing_direction_default = 0; | |
256 params.writing_direction_left_to_right = 0; | |
257 params.writing_direction_right_to_left = 0; | |
258 #endif // OS_MACOSX | |
259 params.edit_flags = WebContextMenuData::CanTranslate; | |
260 return new TestRenderViewContextMenu(tab_contents, params); | |
261 } | |
262 | |
263 bool IsItemPresent(int id) { | |
264 return menu_model_.GetIndexOfCommandId(id) != -1; | |
265 } | |
266 | |
267 virtual void PlatformInit() { } | |
268 virtual bool GetAcceleratorForCommandId( | |
269 int command_id, | |
270 ui::Accelerator* accelerator) { return false; } | |
271 | |
272 private: | |
273 TestRenderViewContextMenu(TabContents* tab_contents, | |
274 const ContextMenuParams& params) | |
275 : RenderViewContextMenu(tab_contents, params) { | |
276 } | |
277 | |
278 DISALLOW_COPY_AND_ASSIGN(TestRenderViewContextMenu); | |
279 }; | |
280 | |
281 TEST_F(TranslateManagerTest, NormalTranslate) { | |
282 // Simulate navigating to a page. | |
283 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
284 | |
285 // We should have an infobar. | |
286 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
287 ASSERT_TRUE(infobar != NULL); | |
288 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, infobar->type()); | |
289 | |
290 // Simulate clicking translate. | |
291 process()->sink().ClearMessages(); | |
292 infobar->Translate(); | |
293 | |
294 // The "Translating..." infobar should be showing. | |
295 infobar = GetTranslateInfoBar(); | |
296 ASSERT_TRUE(infobar != NULL); | |
297 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING, infobar->type()); | |
298 | |
299 // Simulate the translate script being retrieved (it only needs to be done | |
300 // once in the test as it is cached). | |
301 SimulateURLFetch(true); | |
302 | |
303 // Test that we sent the right message to the renderer. | |
304 int page_id = 0; | |
305 std::string original_lang, target_lang; | |
306 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
307 EXPECT_EQ("fr", original_lang); | |
308 EXPECT_EQ("en", target_lang); | |
309 | |
310 // Simulate the render notifying the translation has been done. | |
311 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en", | |
312 TranslateErrors::NONE)); | |
313 | |
314 // The after translate infobar should be showing. | |
315 infobar = GetTranslateInfoBar(); | |
316 ASSERT_TRUE(infobar != NULL); | |
317 EXPECT_EQ(TranslateInfoBarDelegate::AFTER_TRANSLATE, infobar->type()); | |
318 | |
319 // Simulate changing the original language, this should trigger a translation. | |
320 process()->sink().ClearMessages(); | |
321 std::string new_original_lang = infobar->GetLanguageCodeAt(0); | |
322 infobar->SetOriginalLanguage(0); | |
323 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
324 EXPECT_EQ(new_original_lang, original_lang); | |
325 EXPECT_EQ("en", target_lang); | |
326 // Simulate the render notifying the translation has been done. | |
327 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, | |
328 new_original_lang, "en", TranslateErrors::NONE)); | |
329 // infobar is now invalid. | |
330 TranslateInfoBarDelegate* new_infobar = GetTranslateInfoBar(); | |
331 ASSERT_TRUE(new_infobar != NULL); | |
332 infobar = new_infobar; | |
333 | |
334 // Simulate changing the target language, this should trigger a translation. | |
335 process()->sink().ClearMessages(); | |
336 std::string new_target_lang = infobar->GetLanguageCodeAt(1); | |
337 infobar->SetTargetLanguage(1); | |
338 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
339 EXPECT_EQ(new_original_lang, original_lang); | |
340 EXPECT_EQ(new_target_lang, target_lang); | |
341 // Simulate the render notifying the translation has been done. | |
342 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, | |
343 new_original_lang, new_target_lang, TranslateErrors::NONE)); | |
344 // infobar is now invalid. | |
345 new_infobar = GetTranslateInfoBar(); | |
346 ASSERT_TRUE(new_infobar != NULL); | |
347 } | |
348 | |
349 TEST_F(TranslateManagerTest, TranslateScriptNotAvailable) { | |
350 // Simulate navigating to a page. | |
351 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
352 | |
353 // We should have an infobar. | |
354 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
355 ASSERT_TRUE(infobar != NULL); | |
356 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, infobar->type()); | |
357 | |
358 // Simulate clicking translate. | |
359 process()->sink().ClearMessages(); | |
360 infobar->Translate(); | |
361 // Simulate a failure retrieving the translate script. | |
362 SimulateURLFetch(false); | |
363 | |
364 // We should not have sent any message to translate to the renderer. | |
365 EXPECT_FALSE(GetTranslateMessage(NULL, NULL, NULL)); | |
366 | |
367 // And we should have an error infobar showing. | |
368 infobar = GetTranslateInfoBar(); | |
369 ASSERT_TRUE(infobar != NULL); | |
370 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR, infobar->type()); | |
371 } | |
372 | |
373 // Ensures we deal correctly with pages for which the browser does not recognize | |
374 // the language (the translate server may or not detect the language). | |
375 TEST_F(TranslateManagerTest, TranslateUnknownLanguage) { | |
376 // Simulate navigating to a page ("und" is the string returned by the CLD for | |
377 // languages it does not recognize). | |
378 SimulateNavigation(GURL("http://www.google.mys"), "G00g1e", "und", true); | |
379 | |
380 // We should not have an infobar as we don't know the language. | |
381 ASSERT_TRUE(GetTranslateInfoBar() == NULL); | |
382 | |
383 // Translate the page anyway throught the context menu. | |
384 scoped_ptr<TestRenderViewContextMenu> menu( | |
385 TestRenderViewContextMenu::CreateContextMenu(contents())); | |
386 menu->Init(); | |
387 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE); | |
388 | |
389 // To test that bug #49018 if fixed, make sure we deal correctly with errors. | |
390 SimulateURLFetch(false); // Simulate a failure to fetch the translate script. | |
391 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
392 ASSERT_TRUE(infobar != NULL); | |
393 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR, infobar->type()); | |
394 EXPECT_TRUE(infobar->IsError()); | |
395 infobar->MessageInfoBarButtonPressed(); | |
396 SimulateURLFetch(true); // This time succeed. | |
397 | |
398 // Simulate the render notifying the translation has been done, the server | |
399 // having detected the page was in a known and supported language. | |
400 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en", | |
401 TranslateErrors::NONE)); | |
402 | |
403 // The after translate infobar should be showing. | |
404 infobar = GetTranslateInfoBar(); | |
405 ASSERT_TRUE(infobar != NULL); | |
406 EXPECT_EQ(TranslateInfoBarDelegate::AFTER_TRANSLATE, infobar->type()); | |
407 EXPECT_EQ("fr", infobar->GetOriginalLanguageCode()); | |
408 EXPECT_EQ("en", infobar->GetTargetLanguageCode()); | |
409 | |
410 // Let's run the same steps but this time the server detects the page is | |
411 // already in English. | |
412 SimulateNavigation(GURL("http://www.google.com"), "The Google", "und", true); | |
413 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
414 menu->Init(); | |
415 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE); | |
416 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(1, 0, "en", "en", | |
417 TranslateErrors::IDENTICAL_LANGUAGES)); | |
418 infobar = GetTranslateInfoBar(); | |
419 ASSERT_TRUE(infobar != NULL); | |
420 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR, infobar->type()); | |
421 EXPECT_EQ(TranslateErrors::IDENTICAL_LANGUAGES, infobar->error()); | |
422 | |
423 // Let's run the same steps again but this time the server fails to detect the | |
424 // page's language (it returns an empty string). | |
425 SimulateNavigation(GURL("http://www.google.com"), "The Google", "und", true); | |
426 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
427 menu->Init(); | |
428 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE); | |
429 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(2, 0, "", "en", | |
430 TranslateErrors::UNKNOWN_LANGUAGE)); | |
431 infobar = GetTranslateInfoBar(); | |
432 ASSERT_TRUE(infobar != NULL); | |
433 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR, infobar->type()); | |
434 EXPECT_EQ(TranslateErrors::UNKNOWN_LANGUAGE, infobar->error()); | |
435 } | |
436 | |
437 // Tests that we show/don't show an info-bar for all languages the CLD can | |
438 // report. | |
439 TEST_F(TranslateManagerTest, TestAllLanguages) { | |
440 // The index in kExpectation are the Language enum (see languages.pb.h). | |
441 // true if we expect a translate infobar for that language. | |
442 // Note the supported languages are in translation_manager.cc, see | |
443 // kSupportedLanguages. | |
444 bool kExpectations[] = { | |
445 // 0-9 | |
446 false, true, true, true, true, true, true, true, true, true, | |
447 // 10-19 | |
448 true, true, true, true, true, true, true, true, true, true, | |
449 // 20-29 | |
450 true, true, true, true, true, false, false, true, true, true, | |
451 // 30-39 | |
452 true, true, true, true, true, true, true, false, true, false, | |
453 // 40-49 | |
454 true, false, true, false, false, true, false, true, false, false, | |
455 // 50-59 | |
456 true, false, false, true, true, true, false, true, false, false, | |
457 // 60-69 | |
458 false, false, true, true, false, true, true, false, true, true, | |
459 // 70-79 | |
460 false, false, false, false, true, true, false, true, false, false, | |
461 // 80-89 | |
462 false, false, false, false, false, false, false, false, false, false, | |
463 // 90-99 | |
464 false, true, false, false, false, false, false, true, false, false, | |
465 // 100-109 | |
466 false, true, false, false, false, false, false, false, false, false, | |
467 // 110-119 | |
468 false, false, false, false, false, false, false, false, false, false, | |
469 // 120-129 | |
470 false, false, false, false, false, false, false, false, false, false, | |
471 // 130-139 | |
472 false, false, false, false, false, false, false, false, false, true, | |
473 // 140-149 | |
474 false, false, false, false, false, false, false, false, false, false, | |
475 // 150-159 | |
476 false, false, false, false, false, false, false, false, false, false, | |
477 // 160 | |
478 false | |
479 }; | |
480 | |
481 GURL url("http://www.google.com"); | |
482 for (size_t i = 0; i < arraysize(kExpectations); ++i) { | |
483 ASSERT_LT(i, static_cast<size_t>(NUM_LANGUAGES)); | |
484 | |
485 std::string lang = LanguageCodeWithDialects(static_cast<Language>(i)); | |
486 SCOPED_TRACE(::testing::Message::Message() << "Iteration " << i << | |
487 " language=" << lang); | |
488 | |
489 // We should not have a translate infobar. | |
490 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
491 ASSERT_TRUE(infobar == NULL); | |
492 | |
493 // Simulate navigating to a page. | |
494 NavigateAndCommit(url); | |
495 SimulateOnPageContents(url, i, "", lang, true); | |
496 | |
497 // Verify we have/don't have an info-bar as expected. | |
498 infobar = GetTranslateInfoBar(); | |
499 EXPECT_EQ(kExpectations[i], infobar != NULL); | |
500 | |
501 // Close the info-bar if applicable. | |
502 if (infobar != NULL) | |
503 EXPECT_TRUE(CloseTranslateInfoBar()); | |
504 } | |
505 } | |
506 | |
507 // Tests auto-translate on page. | |
508 TEST_F(TranslateManagerTest, AutoTranslateOnNavigate) { | |
509 // Simulate navigating to a page and getting its language. | |
510 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
511 | |
512 // Simulate the user translating. | |
513 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
514 ASSERT_TRUE(infobar != NULL); | |
515 infobar->Translate(); | |
516 SimulateURLFetch(true); // Simulate the translate script being retrieved. | |
517 | |
518 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en", | |
519 TranslateErrors::NONE)); | |
520 | |
521 // Now navigate to a new page in the same language. | |
522 process()->sink().ClearMessages(); | |
523 SimulateNavigation(GURL("http://news.google.fr"), "Les news", "fr", true); | |
524 | |
525 // This should have automatically triggered a translation. | |
526 int page_id = 0; | |
527 std::string original_lang, target_lang; | |
528 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
529 EXPECT_EQ(1, page_id); | |
530 EXPECT_EQ("fr", original_lang); | |
531 EXPECT_EQ("en", target_lang); | |
532 | |
533 // Now navigate to a page in a different language. | |
534 process()->sink().ClearMessages(); | |
535 SimulateNavigation(GURL("http://news.google.es"), "Las news", "es", true); | |
536 | |
537 // This should not have triggered a translate. | |
538 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
539 } | |
540 | |
541 // Tests that multiple OnPageContents do not cause multiple infobars. | |
542 TEST_F(TranslateManagerTest, MultipleOnPageContents) { | |
543 // Simulate navigating to a page and getting its language. | |
544 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
545 | |
546 // Simulate clicking 'Nope' (don't translate). | |
547 EXPECT_TRUE(DenyTranslation()); | |
548 EXPECT_EQ(0U, contents()->infobar_count()); | |
549 | |
550 // Send a new PageContents, we should not show an infobar. | |
551 SimulateOnPageContents(GURL("http://www.google.fr"), 0, "Le Google", "fr", | |
552 true); | |
553 EXPECT_EQ(0U, contents()->infobar_count()); | |
554 | |
555 // Do the same steps but simulate closing the infobar this time. | |
556 SimulateNavigation(GURL("http://www.youtube.fr"), "Le YouTube", "fr", | |
557 true); | |
558 EXPECT_TRUE(CloseTranslateInfoBar()); | |
559 EXPECT_EQ(0U, contents()->infobar_count()); | |
560 SimulateOnPageContents(GURL("http://www.youtube.fr"), 1, "Le YouTube", "fr", | |
561 true); | |
562 EXPECT_EQ(0U, contents()->infobar_count()); | |
563 } | |
564 | |
565 // Test that reloading the page brings back the infobar. | |
566 TEST_F(TranslateManagerTest, Reload) { | |
567 // Simulate navigating to a page and getting its language. | |
568 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
569 | |
570 // Close the infobar. | |
571 EXPECT_TRUE(CloseTranslateInfoBar()); | |
572 | |
573 // Reload should bring back the infobar. | |
574 NavEntryCommittedObserver nav_observer(contents()); | |
575 Reload(); | |
576 | |
577 // Ensures it is really handled a reload. | |
578 const NavigationController::LoadCommittedDetails& nav_details = | |
579 nav_observer.get_load_commited_details(); | |
580 EXPECT_TRUE(nav_details.entry != NULL); // There was a navigation. | |
581 EXPECT_EQ(NavigationType::EXISTING_PAGE, nav_details.type); | |
582 | |
583 // The TranslateManager class processes the navigation entry committed | |
584 // notification in a posted task; process that task. | |
585 MessageLoop::current()->RunAllPending(); | |
586 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
587 } | |
588 | |
589 // Test that reloading the page by way of typing again the URL in the | |
590 // location bar brings back the infobar. | |
591 TEST_F(TranslateManagerTest, ReloadFromLocationBar) { | |
592 GURL url("http://www.google.fr"); | |
593 | |
594 // Simulate navigating to a page and getting its language. | |
595 SimulateNavigation(url, "Le Google", "fr", true); | |
596 | |
597 // Close the infobar. | |
598 EXPECT_TRUE(CloseTranslateInfoBar()); | |
599 | |
600 // Create a pending navigation and simulate a page load. That should be the | |
601 // equivalent of typing the URL again in the location bar. | |
602 NavEntryCommittedObserver nav_observer(contents()); | |
603 contents()->controller().LoadURL(url, GURL(), PageTransition::TYPED); | |
604 rvh()->SendNavigate(0, url); | |
605 | |
606 // Test that we are really getting a same page navigation, the test would be | |
607 // useless if it was not the case. | |
608 const NavigationController::LoadCommittedDetails& nav_details = | |
609 nav_observer.get_load_commited_details(); | |
610 EXPECT_TRUE(nav_details.entry != NULL); // There was a navigation. | |
611 EXPECT_EQ(NavigationType::SAME_PAGE, nav_details.type); | |
612 | |
613 // The TranslateManager class processes the navigation entry committed | |
614 // notification in a posted task; process that task. | |
615 MessageLoop::current()->RunAllPending(); | |
616 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
617 } | |
618 | |
619 // Tests that a closed translate infobar does not reappear when navigating | |
620 // in-page. | |
621 TEST_F(TranslateManagerTest, CloseInfoBarInPageNavigation) { | |
622 // Simulate navigating to a page and getting its language. | |
623 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
624 | |
625 // Close the infobar. | |
626 EXPECT_TRUE(CloseTranslateInfoBar()); | |
627 | |
628 // Navigate in page, no infobar should be shown. | |
629 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "Le Google", "fr", | |
630 true); | |
631 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
632 | |
633 // Navigate out of page, a new infobar should show. | |
634 SimulateNavigation(GURL("http://www.google.fr/foot"), "Le Google", "fr", | |
635 true); | |
636 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
637 } | |
638 | |
639 // Tests that a closed translate infobar does not reappear when navigating | |
640 // in a subframe. (http://crbug.com/48215) | |
641 TEST_F(TranslateManagerTest, CloseInfoBarInSubframeNavigation) { | |
642 // Simulate navigating to a page and getting its language. | |
643 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
644 | |
645 // Close the infobar. | |
646 EXPECT_TRUE(CloseTranslateInfoBar()); | |
647 | |
648 // Simulate a sub-frame auto-navigating. | |
649 rvh()->SendNavigateWithTransition(1, GURL("http://pub.com"), | |
650 PageTransition::AUTO_SUBFRAME); | |
651 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
652 | |
653 // Simulate the user navigating in a sub-frame. | |
654 rvh()->SendNavigateWithTransition(2, GURL("http://pub.com"), | |
655 PageTransition::MANUAL_SUBFRAME); | |
656 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
657 | |
658 // Navigate out of page, a new infobar should show. | |
659 SimulateNavigation(GURL("http://www.google.fr/foot"), "Le Google", "fr", | |
660 true); | |
661 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
662 } | |
663 | |
664 | |
665 | |
666 // Tests that denying translation is sticky when navigating in page. | |
667 TEST_F(TranslateManagerTest, DenyTranslateInPageNavigation) { | |
668 // Simulate navigating to a page and getting its language. | |
669 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
670 | |
671 // Simulate clicking 'Nope' (don't translate). | |
672 EXPECT_TRUE(DenyTranslation()); | |
673 | |
674 // Navigate in page, no infobar should be shown. | |
675 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "Le Google", "fr", | |
676 true); | |
677 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
678 | |
679 // Navigate out of page, a new infobar should show. | |
680 SimulateNavigation(GURL("http://www.google.fr/foot"), "Le Google", "fr", | |
681 true); | |
682 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
683 } | |
684 | |
685 // Tests that after translating and closing the infobar, the infobar does not | |
686 // return when navigating in page. | |
687 TEST_F(TranslateManagerTest, TranslateCloseInfoBarInPageNavigation) { | |
688 // Simulate navigating to a page and getting its language. | |
689 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
690 | |
691 // Simulate the user translating. | |
692 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
693 ASSERT_TRUE(infobar != NULL); | |
694 infobar->Translate(); | |
695 SimulateURLFetch(true); // Simulate the translate script being retrieved. | |
696 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en", | |
697 TranslateErrors::NONE)); | |
698 | |
699 // Close the infobar. | |
700 EXPECT_TRUE(CloseTranslateInfoBar()); | |
701 | |
702 // Navigate in page, no infobar should be shown. | |
703 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "Le Google", "fr", | |
704 true); | |
705 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
706 | |
707 // Navigate out of page, a new infobar should show. | |
708 // Note that we navigate to a page in a different language so we don't trigger | |
709 // the auto-translate feature (it would translate the page automatically and | |
710 // the before translate inforbar would not be shown). | |
711 SimulateNavigation(GURL("http://www.google.de"), "Das Google", "de", true); | |
712 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
713 } | |
714 | |
715 // Tests that the after translate the infobar still shows when navigating | |
716 // in-page. | |
717 TEST_F(TranslateManagerTest, TranslateInPageNavigation) { | |
718 // Simulate navigating to a page and getting its language. | |
719 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
720 | |
721 // Simulate the user translating. | |
722 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
723 ASSERT_TRUE(infobar != NULL); | |
724 infobar->Translate(); | |
725 SimulateURLFetch(true); // Simulate the translate script being retrieved. | |
726 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en", | |
727 TranslateErrors::NONE)); | |
728 // The after translate infobar is showing. | |
729 infobar = GetTranslateInfoBar(); | |
730 ASSERT_TRUE(infobar != NULL); | |
731 | |
732 // Navigate in page, the same infobar should still be shown. | |
733 ClearRemovedInfoBars(); | |
734 SimulateNavigation(GURL("http://www.google.fr/#ref1"), "Le Google", "fr", | |
735 true); | |
736 EXPECT_FALSE(InfoBarRemoved()); | |
737 EXPECT_EQ(infobar, GetTranslateInfoBar()); | |
738 | |
739 // Navigate out of page, a new infobar should show. | |
740 // See note in TranslateCloseInfoBarInPageNavigation test on why it is | |
741 // important to navigate to a page in a different language for this test. | |
742 SimulateNavigation(GURL("http://www.google.de"), "Das Google", "de", true); | |
743 // The old infobar is gone. | |
744 EXPECT_TRUE(CheckInfoBarRemovedAndReset(infobar)); | |
745 // And there is a new one. | |
746 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
747 } | |
748 | |
749 // Tests that no translate infobar is shown when navigating to a page in an | |
750 // unsupported language. | |
751 TEST_F(TranslateManagerTest, CLDReportsUnsupportedPageLanguage) { | |
752 // Simulate navigating to a page and getting an unsupported language. | |
753 SimulateNavigation(GURL("http://www.google.com"), "Google", "qbz", true); | |
754 | |
755 // No info-bar should be shown. | |
756 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
757 } | |
758 | |
759 // Tests that we deal correctly with unsupported languages returned by the | |
760 // server. | |
761 // The translation server might return a language we don't support. | |
762 TEST_F(TranslateManagerTest, ServerReportsUnsupportedLanguage) { | |
763 // Simulate navigating to a page and translating it. | |
764 SimulateNavigation(GURL("http://mail.google.fr"), "Le Google", "fr", true); | |
765 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
766 ASSERT_TRUE(infobar != NULL); | |
767 process()->sink().ClearMessages(); | |
768 infobar->Translate(); | |
769 SimulateURLFetch(true); | |
770 // Simulate the render notifying the translation has been done, but it | |
771 // reports a language we don't support. | |
772 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "qbz", "en", | |
773 TranslateErrors::NONE)); | |
774 | |
775 // An error infobar should be showing to report that we don't support this | |
776 // language. | |
777 infobar = GetTranslateInfoBar(); | |
778 ASSERT_TRUE(infobar != NULL); | |
779 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR, infobar->type()); | |
780 | |
781 // This infobar should have a button (so the string should not be empty). | |
782 ASSERT_FALSE(infobar->GetMessageInfoBarButtonText().empty()); | |
783 | |
784 // Pressing the button on that infobar should revert to the original language. | |
785 process()->sink().ClearMessages(); | |
786 infobar->MessageInfoBarButtonPressed(); | |
787 const IPC::Message* message = | |
788 process()->sink().GetFirstMessageMatching(ViewMsg_RevertTranslation::ID); | |
789 EXPECT_TRUE(message != NULL); | |
790 // And it should have removed the infobar. | |
791 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
792 } | |
793 | |
794 // Tests that no translate infobar is shown when Chrome is in a language that | |
795 // the translate server does not support. | |
796 TEST_F(TranslateManagerTest, UnsupportedUILanguage) { | |
797 TestingBrowserProcess* browser_process = | |
798 static_cast<TestingBrowserProcess*>(g_browser_process); | |
799 std::string original_lang = browser_process->GetApplicationLocale(); | |
800 browser_process->SetApplicationLocale("qbz"); | |
801 | |
802 // Simulate navigating to a page in a language supported by the translate | |
803 // server. | |
804 SimulateNavigation(GURL("http://www.google.com"), "Google", "en", true); | |
805 | |
806 // No info-bar should be shown. | |
807 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
808 | |
809 browser_process->SetApplicationLocale(original_lang); | |
810 } | |
811 | |
812 // Tests that the translate enabled preference is honored. | |
813 TEST_F(TranslateManagerTest, TranslateEnabledPref) { | |
814 // Make sure the pref allows translate. | |
815 PrefService* prefs = contents()->profile()->GetPrefs(); | |
816 prefs->SetBoolean(prefs::kEnableTranslate, true); | |
817 | |
818 // Simulate navigating to a page and getting its language. | |
819 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
820 | |
821 // An infobar should be shown. | |
822 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
823 EXPECT_TRUE(infobar != NULL); | |
824 | |
825 // Disable translate. | |
826 prefs->SetBoolean(prefs::kEnableTranslate, false); | |
827 | |
828 // Navigate to a new page, that should close the previous infobar. | |
829 GURL url("http://www.youtube.fr"); | |
830 NavigateAndCommit(url); | |
831 infobar = GetTranslateInfoBar(); | |
832 EXPECT_TRUE(infobar == NULL); | |
833 | |
834 // Simulate getting the page contents and language, that should not trigger | |
835 // a translate infobar. | |
836 SimulateOnPageContents(url, 1, "Le YouTube", "fr", true); | |
837 infobar = GetTranslateInfoBar(); | |
838 EXPECT_TRUE(infobar == NULL); | |
839 } | |
840 | |
841 // Tests the "Never translate <language>" pref. | |
842 TEST_F(TranslateManagerTest, NeverTranslateLanguagePref) { | |
843 // Simulate navigating to a page and getting its language. | |
844 GURL url("http://www.google.fr"); | |
845 SimulateNavigation(url, "Le Google", "fr", true); | |
846 | |
847 // An infobar should be shown. | |
848 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
849 | |
850 // Select never translate this language. | |
851 PrefService* prefs = contents()->profile()->GetPrefs(); | |
852 PrefChangeRegistrar registrar; | |
853 registrar.Init(prefs); | |
854 registrar.Add(TranslatePrefs::kPrefTranslateLanguageBlacklist, | |
855 &pref_observer_); | |
856 TranslatePrefs translate_prefs(prefs); | |
857 EXPECT_FALSE(translate_prefs.IsLanguageBlacklisted("fr")); | |
858 EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url)); | |
859 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateLanguageBlacklist); | |
860 translate_prefs.BlacklistLanguage("fr"); | |
861 EXPECT_TRUE(translate_prefs.IsLanguageBlacklisted("fr")); | |
862 EXPECT_FALSE(translate_prefs.CanTranslate(prefs, "fr", url)); | |
863 | |
864 // Close the infobar. | |
865 EXPECT_TRUE(CloseTranslateInfoBar()); | |
866 | |
867 // Navigate to a new page also in French. | |
868 SimulateNavigation(GURL("http://wwww.youtube.fr"), "Le YouTube", "fr", true); | |
869 | |
870 // There should not be a translate infobar. | |
871 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
872 | |
873 // Remove the language from the blacklist. | |
874 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateLanguageBlacklist); | |
875 translate_prefs.RemoveLanguageFromBlacklist("fr"); | |
876 EXPECT_FALSE(translate_prefs.IsLanguageBlacklisted("fr")); | |
877 EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url)); | |
878 | |
879 // Navigate to a page in French. | |
880 SimulateNavigation(url, "Le Google", "fr", true); | |
881 | |
882 // There should be a translate infobar. | |
883 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
884 } | |
885 | |
886 // Tests the "Never translate this site" pref. | |
887 TEST_F(TranslateManagerTest, NeverTranslateSitePref) { | |
888 // Simulate navigating to a page and getting its language. | |
889 GURL url("http://www.google.fr"); | |
890 std::string host(url.host()); | |
891 SimulateNavigation(url, "Le Google", "fr", true); | |
892 | |
893 // An infobar should be shown. | |
894 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
895 | |
896 // Select never translate this site. | |
897 PrefService* prefs = contents()->profile()->GetPrefs(); | |
898 PrefChangeRegistrar registrar; | |
899 registrar.Init(prefs); | |
900 registrar.Add(TranslatePrefs::kPrefTranslateSiteBlacklist, | |
901 &pref_observer_); | |
902 TranslatePrefs translate_prefs(prefs); | |
903 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(host)); | |
904 EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url)); | |
905 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateSiteBlacklist); | |
906 translate_prefs.BlacklistSite(host); | |
907 EXPECT_TRUE(translate_prefs.IsSiteBlacklisted(host)); | |
908 EXPECT_FALSE(translate_prefs.CanTranslate(prefs, "fr", url)); | |
909 | |
910 // Close the infobar. | |
911 EXPECT_TRUE(CloseTranslateInfoBar()); | |
912 | |
913 // Navigate to a new page also on the same site. | |
914 SimulateNavigation(GURL("http://www.google.fr/hello"), "Bonjour", "fr", true); | |
915 | |
916 // There should not be a translate infobar. | |
917 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
918 | |
919 // Remove the site from the blacklist. | |
920 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateSiteBlacklist); | |
921 translate_prefs.RemoveSiteFromBlacklist(host); | |
922 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(host)); | |
923 EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url)); | |
924 | |
925 // Navigate to a page in French. | |
926 SimulateNavigation(url, "Le Google", "fr", true); | |
927 | |
928 // There should be a translate infobar. | |
929 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
930 } | |
931 | |
932 // Tests the "Always translate this language" pref. | |
933 TEST_F(TranslateManagerTest, AlwaysTranslateLanguagePref) { | |
934 // Select always translate French to English. | |
935 PrefService* prefs = contents()->profile()->GetPrefs(); | |
936 PrefChangeRegistrar registrar; | |
937 registrar.Init(prefs); | |
938 registrar.Add(TranslatePrefs::kPrefTranslateWhitelists, | |
939 &pref_observer_); | |
940 TranslatePrefs translate_prefs(prefs); | |
941 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateWhitelists); | |
942 translate_prefs.WhitelistLanguagePair("fr", "en"); | |
943 | |
944 // Load a page in French. | |
945 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
946 | |
947 // It should have triggered an automatic translation to English. | |
948 | |
949 // The translating infobar should be showing. | |
950 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
951 ASSERT_TRUE(infobar != NULL); | |
952 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING, infobar->type()); | |
953 | |
954 SimulateURLFetch(true); // Simulate the translate script being retrieved. | |
955 int page_id = 0; | |
956 std::string original_lang, target_lang; | |
957 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
958 EXPECT_EQ("fr", original_lang); | |
959 EXPECT_EQ("en", target_lang); | |
960 process()->sink().ClearMessages(); | |
961 | |
962 // Try another language, it should not be autotranslated. | |
963 SimulateNavigation(GURL("http://www.google.es"), "El Google", "es", true); | |
964 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
965 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
966 EXPECT_TRUE(CloseTranslateInfoBar()); | |
967 | |
968 // Let's switch to incognito mode, it should not be autotranslated in that | |
969 // case either. | |
970 TestingProfile* test_profile = | |
971 static_cast<TestingProfile*>(contents()->profile()); | |
972 test_profile->set_off_the_record(true); | |
973 SimulateNavigation(GURL("http://www.youtube.fr"), "Le YouTube", "fr", true); | |
974 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
975 EXPECT_TRUE(GetTranslateInfoBar() != NULL); | |
976 EXPECT_TRUE(CloseTranslateInfoBar()); | |
977 test_profile->set_off_the_record(false); // Get back to non incognito. | |
978 | |
979 // Now revert the always translate pref and make sure we go back to expected | |
980 // behavior, which is show a "before translate" infobar. | |
981 SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateWhitelists); | |
982 translate_prefs.RemoveLanguagePairFromWhitelist("fr", "en"); | |
983 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
984 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
985 infobar = GetTranslateInfoBar(); | |
986 ASSERT_TRUE(infobar != NULL); | |
987 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, infobar->type()); | |
988 } | |
989 | |
990 // Context menu. | |
991 TEST_F(TranslateManagerTest, ContextMenu) { | |
992 // Blacklist www.google.fr and French for translation. | |
993 GURL url("http://www.google.fr"); | |
994 TranslatePrefs translate_prefs(contents()->profile()->GetPrefs()); | |
995 translate_prefs.BlacklistLanguage("fr"); | |
996 translate_prefs.BlacklistSite(url.host()); | |
997 EXPECT_TRUE(translate_prefs.IsLanguageBlacklisted("fr")); | |
998 EXPECT_TRUE(translate_prefs.IsSiteBlacklisted(url.host())); | |
999 | |
1000 // Simulate navigating to a page in French. The translate menu should show but | |
1001 // should only be enabled when the page language has been received. | |
1002 NavigateAndCommit(url); | |
1003 scoped_ptr<TestRenderViewContextMenu> menu( | |
1004 TestRenderViewContextMenu::CreateContextMenu(contents())); | |
1005 menu->Init(); | |
1006 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
1007 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
1008 | |
1009 // Simulate receiving the language. | |
1010 SimulateOnPageContents(url, 0, "Le Google", "fr", true); | |
1011 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
1012 menu->Init(); | |
1013 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
1014 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
1015 | |
1016 // Use the menu to translate the page. | |
1017 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE); | |
1018 | |
1019 // That should have triggered a translation. | |
1020 // The "translating..." infobar should be showing. | |
1021 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
1022 ASSERT_TRUE(infobar != NULL); | |
1023 EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATING, infobar->type()); | |
1024 SimulateURLFetch(true); // Simulate the translate script being retrieved. | |
1025 int page_id = 0; | |
1026 std::string original_lang, target_lang; | |
1027 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
1028 EXPECT_EQ("fr", original_lang); | |
1029 EXPECT_EQ("en", target_lang); | |
1030 process()->sink().ClearMessages(); | |
1031 | |
1032 // This should also have reverted the blacklisting of this site and language. | |
1033 EXPECT_FALSE(translate_prefs.IsLanguageBlacklisted("fr")); | |
1034 EXPECT_FALSE(translate_prefs.IsSiteBlacklisted(url.host())); | |
1035 | |
1036 // Let's simulate the page being translated. | |
1037 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en", | |
1038 TranslateErrors::NONE)); | |
1039 | |
1040 // The translate menu should now be disabled. | |
1041 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
1042 menu->Init(); | |
1043 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
1044 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
1045 | |
1046 // Test that selecting translate in the context menu WHILE the page is being | |
1047 // translated does nothing (this could happen if autotranslate kicks-in and | |
1048 // the user selects the menu while the translation is being performed). | |
1049 SimulateNavigation(GURL("http://www.google.es"), "El Google", "es", true); | |
1050 infobar = GetTranslateInfoBar(); | |
1051 ASSERT_TRUE(infobar != NULL); | |
1052 infobar->Translate(); | |
1053 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
1054 process()->sink().ClearMessages(); | |
1055 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
1056 menu->Init(); | |
1057 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
1058 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE); | |
1059 // No message expected since the translation should have been ignored. | |
1060 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
1061 | |
1062 // Now test that selecting translate in the context menu AFTER the page has | |
1063 // been translated does nothing. | |
1064 SimulateNavigation(GURL("http://www.google.de"), "Das Google", "de", true); | |
1065 infobar = GetTranslateInfoBar(); | |
1066 ASSERT_TRUE(infobar != NULL); | |
1067 infobar->Translate(); | |
1068 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
1069 process()->sink().ClearMessages(); | |
1070 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
1071 menu->Init(); | |
1072 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
1073 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "de", "en", | |
1074 TranslateErrors::NONE)); | |
1075 menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE); | |
1076 // No message expected since the translation should have been ignored. | |
1077 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
1078 | |
1079 // Test that the translate context menu is disabled when the page is in the | |
1080 // same language as the UI. | |
1081 SimulateNavigation(url, "Google", "en", true); | |
1082 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
1083 menu->Init(); | |
1084 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
1085 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
1086 | |
1087 // Test that the translate context menu is enabled when the page is in an | |
1088 // unknown language. | |
1089 SimulateNavigation(url, "G00g1e", "und", true); | |
1090 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
1091 menu->Init(); | |
1092 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
1093 EXPECT_TRUE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
1094 | |
1095 // Test that the translate context menu is disabled when the page is in an | |
1096 // unsupported language. | |
1097 SimulateNavigation(url, "G00g1e", "qbz", true); | |
1098 menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); | |
1099 menu->Init(); | |
1100 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
1101 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
1102 } | |
1103 | |
1104 // Tests that an extra always/never translate button is shown on the "before | |
1105 // translate" infobar when the translation is accepted/declined 3 times, | |
1106 // only when not in incognito mode. | |
1107 TEST_F(TranslateManagerTest, BeforeTranslateExtraButtons) { | |
1108 TranslatePrefs translate_prefs(contents()->profile()->GetPrefs()); | |
1109 translate_prefs.ResetTranslationAcceptedCount("fr"); | |
1110 translate_prefs.ResetTranslationDeniedCount("fr"); | |
1111 translate_prefs.ResetTranslationAcceptedCount("de"); | |
1112 translate_prefs.ResetTranslationDeniedCount("de"); | |
1113 | |
1114 // We'll do 4 times in incognito mode first to make sure the button is not | |
1115 // shown in that case, then 4 times in normal mode. | |
1116 TranslateInfoBarDelegate* infobar; | |
1117 TestingProfile* test_profile = | |
1118 static_cast<TestingProfile*>(contents()->profile()); | |
1119 test_profile->set_off_the_record(true); | |
1120 for (int i = 0; i < 8; ++i) { | |
1121 SCOPED_TRACE(::testing::Message::Message() << "Iteration " << i << | |
1122 " incognito mode=" << test_profile->IsOffTheRecord()); | |
1123 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
1124 infobar = GetTranslateInfoBar(); | |
1125 ASSERT_TRUE(infobar != NULL); | |
1126 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, infobar->type()); | |
1127 if (i < 7) { | |
1128 EXPECT_FALSE(infobar->ShouldShowAlwaysTranslateButton()); | |
1129 infobar->Translate(); | |
1130 process()->sink().ClearMessages(); | |
1131 } else { | |
1132 EXPECT_TRUE(infobar->ShouldShowAlwaysTranslateButton()); | |
1133 } | |
1134 if (i == 3) | |
1135 test_profile->set_off_the_record(false); | |
1136 } | |
1137 // Simulate the user pressing "Always translate French". | |
1138 infobar->AlwaysTranslatePageLanguage(); | |
1139 EXPECT_TRUE(translate_prefs.IsLanguagePairWhitelisted("fr", "en")); | |
1140 // Simulate the translate script being retrieved (it only needs to be done | |
1141 // once in the test as it is cached). | |
1142 SimulateURLFetch(true); | |
1143 // That should have triggered a page translate. | |
1144 int page_id = 0; | |
1145 std::string original_lang, target_lang; | |
1146 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
1147 process()->sink().ClearMessages(); | |
1148 | |
1149 // Now test that declining the translation causes a "never translate" button | |
1150 // to be shown (in non incognito mode only). | |
1151 test_profile->set_off_the_record(true); | |
1152 for (int i = 0; i < 8; ++i) { | |
1153 SCOPED_TRACE(::testing::Message::Message() << "Iteration " << i << | |
1154 " incognito mode=" << test_profile->IsOffTheRecord()); | |
1155 SimulateNavigation(GURL("http://www.google.de"), "Das Google", "de", true); | |
1156 infobar = GetTranslateInfoBar(); | |
1157 ASSERT_TRUE(infobar != NULL); | |
1158 EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, infobar->type()); | |
1159 if (i < 7) { | |
1160 EXPECT_FALSE(infobar->ShouldShowNeverTranslateButton()); | |
1161 infobar->TranslationDeclined(); | |
1162 } else { | |
1163 EXPECT_TRUE(infobar->ShouldShowNeverTranslateButton()); | |
1164 } | |
1165 if (i == 3) | |
1166 test_profile->set_off_the_record(false); | |
1167 } | |
1168 // Simulate the user pressing "Never translate French". | |
1169 infobar->NeverTranslatePageLanguage(); | |
1170 EXPECT_TRUE(translate_prefs.IsLanguageBlacklisted("de")); | |
1171 // No translation should have occured and the infobar should be gone. | |
1172 EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
1173 process()->sink().ClearMessages(); | |
1174 ASSERT_TRUE(GetTranslateInfoBar() == NULL); | |
1175 } | |
1176 | |
1177 // Tests that we don't show a translate infobar when a page instructs that it | |
1178 // should not be translated. | |
1179 TEST_F(TranslateManagerTest, NonTranslatablePage) { | |
1180 // Simulate navigating to a page. | |
1181 SimulateNavigation(GURL("http://mail.google.fr"), "Le Google", "fr", false); | |
1182 | |
1183 // We should not have an infobar. | |
1184 EXPECT_TRUE(GetTranslateInfoBar() == NULL); | |
1185 | |
1186 // The context menu should be disabled. | |
1187 scoped_ptr<TestRenderViewContextMenu> menu( | |
1188 TestRenderViewContextMenu::CreateContextMenu(contents())); | |
1189 menu->Init(); | |
1190 EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
1191 EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); | |
1192 } | |
1193 | |
1194 // Tests that the script is expired and refetched as expected. | |
1195 TEST_F(TranslateManagerTest, ScriptExpires) { | |
1196 ExpireTranslateScriptImmediately(); | |
1197 | |
1198 // Simulate navigating to a page and translating it. | |
1199 SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); | |
1200 TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); | |
1201 ASSERT_TRUE(infobar != NULL); | |
1202 process()->sink().ClearMessages(); | |
1203 infobar->Translate(); | |
1204 SimulateURLFetch(true); | |
1205 rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en", | |
1206 TranslateErrors::NONE)); | |
1207 | |
1208 // A task should have been posted to clear the script, run it. | |
1209 MessageLoop::current()->RunAllPending(); | |
1210 | |
1211 // Do another navigation and translation. | |
1212 SimulateNavigation(GURL("http://www.google.es"), "El Google", "es", true); | |
1213 infobar = GetTranslateInfoBar(); | |
1214 ASSERT_TRUE(infobar != NULL); | |
1215 process()->sink().ClearMessages(); | |
1216 infobar->Translate(); | |
1217 // If we don't simulate the URL fetch, the TranslateManager should be waiting | |
1218 // for the script and no message should have been sent to the renderer. | |
1219 EXPECT_TRUE( | |
1220 process()->sink().GetFirstMessageMatching(ViewMsg_TranslatePage::ID) == | |
1221 NULL); | |
1222 // Now simulate the URL fetch. | |
1223 SimulateURLFetch(true); | |
1224 // Now the message should have been sent. | |
1225 int page_id = 0; | |
1226 std::string original_lang, target_lang; | |
1227 EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); | |
1228 EXPECT_EQ("es", original_lang); | |
1229 EXPECT_EQ("en", target_lang); | |
1230 } | |
OLD | NEW |