OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/translate/core/browser/translate_manager.h" | 5 #include "components/translate/core/browser/translate_manager.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
12 #include "base/test/histogram_tester.h" | 12 #include "base/test/histogram_tester.h" |
13 #include "base/test/scoped_feature_list.h" | 13 #include "base/test/scoped_feature_list.h" |
14 #include "build/build_config.h" | 14 #include "build/build_config.h" |
15 #include "components/infobars/core/infobar.h" | 15 #include "components/infobars/core/infobar.h" |
16 #include "components/metrics/proto/translate_event.pb.h" | |
16 #include "components/pref_registry/pref_registry_syncable.h" | 17 #include "components/pref_registry/pref_registry_syncable.h" |
17 #include "components/sync_preferences/testing_pref_service_syncable.h" | 18 #include "components/sync_preferences/testing_pref_service_syncable.h" |
18 #include "components/translate/core/browser/mock_translate_driver.h" | 19 #include "components/translate/core/browser/mock_translate_driver.h" |
19 #include "components/translate/core/browser/mock_translate_ranker.h" | 20 #include "components/translate/core/browser/mock_translate_ranker.h" |
21 #include "components/translate/core/browser/translate_accept_languages.h" | |
20 #include "components/translate/core/browser/translate_browser_metrics.h" | 22 #include "components/translate/core/browser/translate_browser_metrics.h" |
21 #include "components/translate/core/browser/translate_client.h" | 23 #include "components/translate/core/browser/translate_client.h" |
22 #include "components/translate/core/browser/translate_download_manager.h" | 24 #include "components/translate/core/browser/translate_download_manager.h" |
23 #include "components/translate/core/browser/translate_prefs.h" | 25 #include "components/translate/core/browser/translate_prefs.h" |
24 #include "components/translate/core/common/translate_pref_names.h" | 26 #include "components/translate/core/common/translate_pref_names.h" |
25 #include "components/variations/variations_associated_data.h" | 27 #include "components/variations/variations_associated_data.h" |
26 #include "net/base/network_change_notifier.h" | 28 #include "net/base/network_change_notifier.h" |
27 #include "testing/gmock/include/gmock/gmock.h" | 29 #include "testing/gmock/include/gmock/gmock.h" |
28 #include "testing/gtest/include/gtest/gtest.h" | 30 #include "testing/gtest/include/gtest/gtest.h" |
29 | 31 |
(...skipping 28 matching lines...) Expand all Loading... | |
58 // objects that are NetworkChangeNotifiers. | 60 // objects that are NetworkChangeNotifiers. |
59 void SimulateNetworkConnectionChange( | 61 void SimulateNetworkConnectionChange( |
60 net::NetworkChangeNotifier::ConnectionType type) { | 62 net::NetworkChangeNotifier::ConnectionType type) { |
61 connection_type_to_return_ = type; | 63 connection_type_to_return_ = type; |
62 net::NetworkChangeNotifier::NotifyObserversOfConnectionTypeChangeForTests( | 64 net::NetworkChangeNotifier::NotifyObserversOfConnectionTypeChangeForTests( |
63 connection_type_to_return_); | 65 connection_type_to_return_); |
64 base::RunLoop().RunUntilIdle(); | 66 base::RunLoop().RunUntilIdle(); |
65 } | 67 } |
66 | 68 |
67 void SimulateOffline() { | 69 void SimulateOffline() { |
68 connection_type_to_return_ =net::NetworkChangeNotifier::CONNECTION_NONE; | 70 connection_type_to_return_ = net::NetworkChangeNotifier::CONNECTION_NONE; |
69 } | 71 } |
70 | 72 |
71 void SimulateOnline() { | 73 void SimulateOnline() { |
72 connection_type_to_return_ = net::NetworkChangeNotifier::CONNECTION_UNKNOWN; | 74 connection_type_to_return_ = net::NetworkChangeNotifier::CONNECTION_UNKNOWN; |
73 } | 75 } |
74 | 76 |
75 private: | 77 private: |
76 ConnectionType GetCurrentConnectionType() const override { | 78 ConnectionType GetCurrentConnectionType() const override { |
77 return connection_type_to_return_; | 79 return connection_type_to_return_; |
78 } | 80 } |
79 | 81 |
80 // The currently simulated network connection type. If this is set to | 82 // The currently simulated network connection type. If this is set to |
81 // CONNECTION_NONE, then NetworkChangeNotifier::IsOffline will return true. | 83 // CONNECTION_NONE, then NetworkChangeNotifier::IsOffline will return true. |
82 net::NetworkChangeNotifier::ConnectionType connection_type_to_return_; | 84 net::NetworkChangeNotifier::ConnectionType connection_type_to_return_; |
83 | 85 |
84 DISALLOW_COPY_AND_ASSIGN(TestNetworkChangeNotifier); | 86 DISALLOW_COPY_AND_ASSIGN(TestNetworkChangeNotifier); |
85 }; | 87 }; |
86 | 88 |
89 class MockTranslateAcceptLanguages : public TranslateAcceptLanguages { | |
90 public: | |
91 MockTranslateAcceptLanguages() { | |
92 ON_CALL(*this, IsAcceptLanguage(_)).WillByDefault(Return(true)); | |
93 } | |
94 virtual ~MockTranslateAcceptLanguages() {} | |
95 MOCK_METHOD1(IsAcceptLanguage, bool(const std::string&)); | |
96 }; | |
97 | |
87 // TODO(groby): Combine with MockTranslateClient in TranslateUiDelegateTest. | 98 // TODO(groby): Combine with MockTranslateClient in TranslateUiDelegateTest. |
88 class MockTranslateClient : public TranslateClient { | 99 class MockTranslateClient : public TranslateClient { |
89 public: | 100 public: |
90 MockTranslateClient(TranslateDriver* driver, PrefService* prefs) | 101 MockTranslateClient(TranslateDriver* driver, PrefService* prefs) |
91 : driver_(driver), prefs_(prefs) {} | 102 : mock_translate_accept_languages_(), driver_(driver), prefs_(prefs) { |
groby-ooo-7-16
2017/04/10 20:52:47
Likely the TODO() here would be a good step to tak
hamelphi
2017/04/11 22:46:07
I agree that test utils would be great. Maybe a bi
| |
103 ON_CALL(*this, GetTranslateAcceptLanguages()) | |
104 .WillByDefault(Return(&mock_translate_accept_languages_)); | |
105 } | |
92 | 106 |
93 // TODO(groby): Does TranslateClient need a virtual dtor? | 107 // TODO(groby): Does TranslateClient need a virtual dtor? |
94 virtual ~MockTranslateClient() {} | 108 virtual ~MockTranslateClient() {} |
95 | 109 |
96 TranslateDriver* GetTranslateDriver() { return driver_; } | 110 TranslateDriver* GetTranslateDriver() { return driver_; } |
97 PrefService* GetPrefs() { return prefs_; } | 111 PrefService* GetPrefs() { return prefs_; } |
98 | 112 |
99 std::unique_ptr<TranslatePrefs> GetTranslatePrefs() { | 113 std::unique_ptr<TranslatePrefs> GetTranslatePrefs() { |
100 return base::MakeUnique<TranslatePrefs>(prefs_, kAcceptLanguages, | 114 return base::MakeUnique<TranslatePrefs>(prefs_, kAcceptLanguages, |
101 kLanguagePreferredLanguages); | 115 kLanguagePreferredLanguages); |
(...skipping 15 matching lines...) Expand all Loading... | |
117 const std::string&, | 131 const std::string&, |
118 const std::string&, | 132 const std::string&, |
119 TranslateErrors::Type, | 133 TranslateErrors::Type, |
120 bool)); | 134 bool)); |
121 | 135 |
122 MOCK_METHOD1(IsTranslatableURL, bool(const GURL&)); | 136 MOCK_METHOD1(IsTranslatableURL, bool(const GURL&)); |
123 MOCK_METHOD1(ShowReportLanguageDetectionErrorUI, | 137 MOCK_METHOD1(ShowReportLanguageDetectionErrorUI, |
124 void(const GURL& report_url)); | 138 void(const GURL& report_url)); |
125 | 139 |
126 private: | 140 private: |
141 MockTranslateAcceptLanguages mock_translate_accept_languages_; | |
127 TranslateDriver* driver_; | 142 TranslateDriver* driver_; |
128 PrefService* prefs_; | 143 PrefService* prefs_; |
129 }; | 144 }; |
130 | 145 |
131 } // namespace | 146 } // namespace |
132 | 147 |
133 namespace testing { | 148 namespace testing { |
134 | 149 |
135 class TranslateManagerTest : public ::testing::Test { | 150 class TranslateManagerTest : public ::testing::Test { |
136 protected: | 151 protected: |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
183 | 198 |
184 std::unique_ptr<base::Value> CreateProfileFromJSON(const char* json) { | 199 std::unique_ptr<base::Value> CreateProfileFromJSON(const char* json) { |
185 int error_code = 0; | 200 int error_code = 0; |
186 std::string error_msg; | 201 std::string error_msg; |
187 int error_line = 0; | 202 int error_line = 0; |
188 int error_column = 0; | 203 int error_column = 0; |
189 | 204 |
190 std::unique_ptr<base::Value> profile(base::JSONReader::ReadAndReturnError( | 205 std::unique_ptr<base::Value> profile(base::JSONReader::ReadAndReturnError( |
191 json, 0, &error_code, &error_msg, &error_line, &error_column)); | 206 json, 0, &error_code, &error_msg, &error_line, &error_column)); |
192 | 207 |
193 EXPECT_EQ(0, error_code) << error_msg << " at " << error_line << ":" | 208 EXPECT_EQ(0, error_code) |
194 << error_column << std::endl | 209 << error_msg << " at " << error_line << ":" << error_column << std::endl |
195 << json; | 210 << json; |
196 return profile; | 211 return profile; |
197 } | 212 } |
198 | 213 |
199 void TurnOnTranslateByULP() { | 214 void TurnOnTranslateByULP() { |
200 scoped_refptr<base::FieldTrial> trial( | 215 scoped_refptr<base::FieldTrial> trial( |
201 CreateFieldTrial(kTrialName, 100, "Enabled", NULL)); | 216 CreateFieldTrial(kTrialName, 100, "Enabled", NULL)); |
202 std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); | 217 std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); |
203 feature_list->RegisterFieldTrialOverride( | 218 feature_list->RegisterFieldTrialOverride( |
204 translate::kTranslateLanguageByULP.name, | 219 translate::kTranslateLanguageByULP.name, |
205 base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get()); | 220 base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get()); |
(...skipping 28 matching lines...) Expand all Loading... | |
234 | 249 |
235 TestNetworkChangeNotifier network_notifier_; | 250 TestNetworkChangeNotifier network_notifier_; |
236 translate::testing::MockTranslateDriver driver_; | 251 translate::testing::MockTranslateDriver driver_; |
237 translate::testing::MockTranslateRanker mock_translate_ranker_; | 252 translate::testing::MockTranslateRanker mock_translate_ranker_; |
238 ::testing::NiceMock<MockTranslateClient> mock_translate_client_; | 253 ::testing::NiceMock<MockTranslateClient> mock_translate_client_; |
239 std::unique_ptr<TranslateManager> translate_manager_; | 254 std::unique_ptr<TranslateManager> translate_manager_; |
240 std::unique_ptr<base::FieldTrialList> field_trial_list_; | 255 std::unique_ptr<base::FieldTrialList> field_trial_list_; |
241 base::test::ScopedFeatureList scoped_feature_list_; | 256 base::test::ScopedFeatureList scoped_feature_list_; |
242 }; | 257 }; |
243 | 258 |
244 | |
245 // Target language comes from application locale if the locale's language | 259 // Target language comes from application locale if the locale's language |
246 // is supported. | 260 // is supported. |
247 TEST_F(TranslateManagerTest, GetTargetLanguageDefaultsToAppLocale) { | 261 TEST_F(TranslateManagerTest, GetTargetLanguageDefaultsToAppLocale) { |
248 // Ensure the locale is set to a supported language. | 262 // Ensure the locale is set to a supported language. |
249 ASSERT_TRUE(TranslateDownloadManager::IsSupportedLanguage("en")); | 263 ASSERT_TRUE(TranslateDownloadManager::IsSupportedLanguage("en")); |
250 manager_->set_application_locale("en"); | 264 manager_->set_application_locale("en"); |
251 EXPECT_EQ("en", TranslateManager::GetTargetLanguage(&translate_prefs_)); | 265 EXPECT_EQ("en", TranslateManager::GetTargetLanguage(&translate_prefs_)); |
252 | 266 |
253 // Try a second supported language. | 267 // Try a second supported language. |
254 ASSERT_TRUE(TranslateDownloadManager::IsSupportedLanguage("de")); | 268 ASSERT_TRUE(TranslateDownloadManager::IsSupportedLanguage("de")); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
312 1); | 326 1); |
313 } | 327 } |
314 | 328 |
315 // Utility function to set the threshold params | 329 // Utility function to set the threshold params |
316 void ChangeThresholdInParams( | 330 void ChangeThresholdInParams( |
317 const char* initiate_translation_confidence_threshold, | 331 const char* initiate_translation_confidence_threshold, |
318 const char* initiate_translation_probability_threshold, | 332 const char* initiate_translation_probability_threshold, |
319 const char* target_language_confidence_threshold, | 333 const char* target_language_confidence_threshold, |
320 const char* target_language_probability_threshold) { | 334 const char* target_language_probability_threshold) { |
321 ASSERT_TRUE(variations::AssociateVariationParams( | 335 ASSERT_TRUE(variations::AssociateVariationParams( |
322 kTrialName, "Enabled", {{"initiate_translation_ulp_confidence_threshold", | 336 kTrialName, "Enabled", |
323 initiate_translation_confidence_threshold}, | 337 {{"initiate_translation_ulp_confidence_threshold", |
324 {"initiate_translation_ulp_probability_threshold", | 338 initiate_translation_confidence_threshold}, |
325 initiate_translation_probability_threshold}, | 339 {"initiate_translation_ulp_probability_threshold", |
326 {"target_language_ulp_confidence_threshold", | 340 initiate_translation_probability_threshold}, |
327 target_language_confidence_threshold}, | 341 {"target_language_ulp_confidence_threshold", |
328 {"target_language_ulp_probability_threshold", | 342 target_language_confidence_threshold}, |
329 target_language_probability_threshold}})); | 343 {"target_language_ulp_probability_threshold", |
344 target_language_probability_threshold}})); | |
330 } | 345 } |
331 | 346 |
332 // Normal ULP in Json | 347 // Normal ULP in Json |
333 const char ulp_1[] = | 348 const char ulp_1[] = |
334 "{\n" | 349 "{\n" |
335 " \"reading\": {\n" | 350 " \"reading\": {\n" |
336 " \"confidence\": 0.8,\n" | 351 " \"confidence\": 0.8,\n" |
337 " \"preference\": [\n" | 352 " \"preference\": [\n" |
338 " {\n" | 353 " {\n" |
339 " \"language\": \"fr\",\n" | 354 " \"language\": \"fr\",\n" |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
447 PrepareULPTest(ulp_1, true); | 462 PrepareULPTest(ulp_1, true); |
448 ChangeThresholdInParams("0.79", "0.39", "", ""); | 463 ChangeThresholdInParams("0.79", "0.39", "", ""); |
449 // Both "fr" and "pt" should reutrn true because the confidence threshold is | 464 // Both "fr" and "pt" should reutrn true because the confidence threshold is |
450 // 0.79 and lower than 0.8 and the probability threshold is lower than both | 465 // 0.79 and lower than 0.8 and the probability threshold is lower than both |
451 // the one with "fr" (0.6) and "pt-PT" (0.4). | 466 // the one with "fr" (0.6) and "pt-PT" (0.4). |
452 EXPECT_TRUE(CallLanguageInULP("fr")); | 467 EXPECT_TRUE(CallLanguageInULP("fr")); |
453 EXPECT_TRUE(CallLanguageInULP("pt")); | 468 EXPECT_TRUE(CallLanguageInULP("pt")); |
454 EXPECT_FALSE(CallLanguageInULP("zh-TW")); | 469 EXPECT_FALSE(CallLanguageInULP("zh-TW")); |
455 } | 470 } |
456 | 471 |
472 TEST_F(TranslateManagerTest, TestRecordTranslateEvent) { | |
473 PrepareTranslateManager(); | |
474 const std::string locale = "zh-TW"; | |
475 const std::string page_lang = "zh-CN"; | |
476 | |
477 network_notifier_.SimulateOnline(); | |
478 manager_->set_application_locale(locale); | |
479 ON_CALL(mock_translate_client_, IsTranslatableURL(_)) | |
480 .WillByDefault(Return(true)); | |
481 translate_manager_->GetLanguageState().LanguageDetermined(page_lang, true); | |
482 | |
483 translate_manager_->InitiateTranslation(page_lang); | |
484 | |
485 std::vector<metrics::TranslateEventProto> events_cache; | |
486 mock_translate_ranker_.FlushTranslateEvents(&events_cache); | |
487 EXPECT_EQ(0U, events_cache.size()); | |
488 | |
489 translate_manager_->RecordTranslateEvent( | |
490 metrics::TranslateEventProto::USER_ACCEPT); | |
491 mock_translate_ranker_.FlushTranslateEvents(&events_cache); | |
492 EXPECT_EQ(1U, events_cache.size()); | |
493 const metrics::TranslateEventProto& tep = events_cache[0]; | |
494 EXPECT_EQ(page_lang, tep.source_language()); | |
495 EXPECT_EQ(locale, tep.target_language()); | |
496 EXPECT_EQ(0L, tep.decision_overrides_size()); | |
497 EXPECT_EQ(metrics::TranslateEventProto::USER_ACCEPT, tep.event_type()); | |
498 } | |
499 | |
500 TEST_F(TranslateManagerTest, TestShouldOverrideDecisionTrue) { | |
501 mock_translate_ranker_.set_is_decision_override_enabled(true); | |
502 PrepareTranslateManager(); | |
503 const std::string locale = "zh-TW"; | |
504 const std::string page_lang = "zh-CN"; | |
505 | |
506 network_notifier_.SimulateOnline(); | |
507 manager_->set_application_locale(locale); | |
508 ON_CALL(mock_translate_client_, IsTranslatableURL(_)) | |
509 .WillByDefault(Return(true)); | |
510 translate_manager_->GetLanguageState().LanguageDetermined(page_lang, true); | |
511 | |
512 translate_manager_->InitiateTranslation(page_lang); | |
513 | |
514 std::vector<metrics::TranslateEventProto> events_cache; | |
515 EXPECT_TRUE(translate_manager_->ShouldOverrideDecision( | |
516 metrics::TranslateEventProto::MATCHES_PREVIOUS_LANGUAGE)); | |
517 EXPECT_TRUE(translate_manager_->ShouldOverrideDecision( | |
518 metrics::TranslateEventProto::LANGUAGE_DISABLED_BY_AUTO_BLACKLIST)); | |
519 | |
520 translate_manager_->RecordTranslateEvent( | |
521 metrics::TranslateEventProto::USER_DECLINE); | |
522 mock_translate_ranker_.FlushTranslateEvents(&events_cache); | |
523 EXPECT_EQ(1U, events_cache.size()); | |
524 const metrics::TranslateEventProto& tep = events_cache[0]; | |
525 EXPECT_EQ(page_lang, tep.source_language()); | |
526 EXPECT_EQ(locale, tep.target_language()); | |
527 EXPECT_EQ(2L, tep.decision_overrides_size()); | |
528 EXPECT_THAT( | |
529 tep.decision_overrides(), | |
530 ::testing::ElementsAre( | |
531 metrics::TranslateEventProto::MATCHES_PREVIOUS_LANGUAGE, | |
532 metrics::TranslateEventProto::LANGUAGE_DISABLED_BY_AUTO_BLACKLIST)); | |
533 EXPECT_EQ(metrics::TranslateEventProto::USER_DECLINE, tep.event_type()); | |
534 } | |
535 | |
536 TEST_F(TranslateManagerTest, TestShouldOverrideDecisionFalse) { | |
537 mock_translate_ranker_.set_is_decision_override_enabled(false); | |
538 PrepareTranslateManager(); | |
539 const std::string locale = "zh-TW"; | |
540 const std::string page_lang = "zh-CN"; | |
541 | |
542 network_notifier_.SimulateOnline(); | |
543 manager_->set_application_locale(locale); | |
544 ON_CALL(mock_translate_client_, IsTranslatableURL(_)) | |
545 .WillByDefault(Return(true)); | |
546 translate_manager_->GetLanguageState().LanguageDetermined(page_lang, true); | |
547 | |
548 translate_manager_->InitiateTranslation(page_lang); | |
549 std::vector<metrics::TranslateEventProto> events_cache; | |
550 EXPECT_FALSE(translate_manager_->ShouldOverrideDecision( | |
551 metrics::TranslateEventProto::MATCHES_PREVIOUS_LANGUAGE)); | |
552 | |
553 mock_translate_ranker_.FlushTranslateEvents(&events_cache); | |
554 EXPECT_EQ(1U, events_cache.size()); | |
555 const metrics::TranslateEventProto& tep = events_cache[0]; | |
556 EXPECT_EQ(page_lang, tep.source_language()); | |
557 EXPECT_EQ(locale, tep.target_language()); | |
558 EXPECT_EQ(0L, tep.decision_overrides_size()); | |
559 EXPECT_EQ(metrics::TranslateEventProto::MATCHES_PREVIOUS_LANGUAGE, | |
560 tep.event_type()); | |
561 } | |
562 | |
457 } // namespace testing | 563 } // namespace testing |
458 | 564 |
459 } // namespace translate | 565 } // namespace translate |
OLD | NEW |