Chromium Code Reviews| 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 |