blob: b95edd0b4b206de320a4f77d5e04b1efabf842e5 [file] [log] [blame]
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/translate/chrome_ios_translate_client.h"
#import "base/files/file_util.h"
#import "base/metrics/metrics_hashes.h"
#import "base/path_service.h"
#import "base/test/metrics/histogram_tester.h"
#import "base/test/scoped_feature_list.h"
#import "base/test/task_environment.h"
#import "base/values.h"
#import "components/language/ios/browser/ios_language_detection_tab_helper.h"
#import "components/translate/core/browser/translate_metrics_logger.h"
#import "components/translate/core/common/translate_util.h"
#import "components/translate/core/language_detection/language_detection_model.h"
#import "components/translate/ios/browser/language_detection_controller.h"
#import "components/translate/ios/browser/language_detection_model_service.h"
#import "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
#include "ios/chrome/browser/infobars/infobar_manager_impl.h"
#import "ios/chrome/browser/language/language_model_manager_factory.h"
#import "ios/chrome/browser/optimization_guide/optimization_guide_service.h"
#import "ios/chrome/browser/optimization_guide/optimization_guide_service_factory.h"
#import "ios/chrome/browser/translate/language_detection_model_service_factory.h"
#import "ios/chrome/browser/translate/translate_model_service_factory.h"
#import "ios/chrome/browser/translate/translate_ranker_factory.h"
#import "ios/web/public/test/fakes/fake_navigation_context.h"
#import "ios/web/public/test/fakes/fake_navigation_manager.h"
#import "ios/web/public/test/fakes/fake_web_state.h"
#import "testing/platform_test.h"
#import "url/gurl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
class ChromeIOSTranslateClientTest : public PlatformTest {
public:
void SetUp() override {
PlatformTest::SetUp();
scoped_feature_list_.InitWithFeatures(
{translate::kTFLiteLanguageDetectionEnabled}, {});
TestChromeBrowserState::Builder builder;
builder.AddTestingFactory(
OptimizationGuideServiceFactory::GetInstance(),
OptimizationGuideServiceFactory::GetDefaultFactory());
browser_state_ = builder.Build();
web_state_.SetNavigationManager(
std::make_unique<web::FakeNavigationManager>());
web_state_.SetBrowserState(browser_state_.get());
language::IOSLanguageDetectionTabHelper::CreateForWebState(
&web_state_, /*url_language_histogram=*/nullptr);
ChromeIOSTranslateClient::CreateForWebState(&web_state_);
InfoBarManagerImpl::CreateForWebState(&web_state_);
}
protected:
base::test::TaskEnvironment task_environment_;
base::test::ScopedFeatureList scoped_feature_list_;
base::HistogramTester histogram_tester_;
std::unique_ptr<TestChromeBrowserState> browser_state_;
web::FakeWebState web_state_;
};
base::File GetValidModelFile() {
base::FilePath source_root_dir;
base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &source_root_dir);
base::FilePath model_file_path = source_root_dir.AppendASCII("components")
.AppendASCII("test")
.AppendASCII("data")
.AppendASCII("translate")
.AppendASCII("valid_model.tflite");
base::File file(model_file_path,
(base::File::FLAG_OPEN | base::File::FLAG_READ));
return file;
}
TEST_F(ChromeIOSTranslateClientTest, TranslateUICreated) {
ChromeIOSTranslateClient* translate_client =
ChromeIOSTranslateClient::FromWebState(&web_state_);
translate_client->ShowTranslateUI(translate::TRANSLATE_STEP_AFTER_TRANSLATE,
"en", "en",
translate::TranslateErrors::NONE,
/*triggered_from_menu=*/false);
EXPECT_EQ(1U, InfoBarManagerImpl::FromWebState(&web_state_)->infobar_count());
}
TEST_F(ChromeIOSTranslateClientTest, NewMetricsOnPageLoadCommits) {
ChromeIOSTranslateClient* translate_client =
ChromeIOSTranslateClient::FromWebState(&web_state_);
web::FakeNavigationContext context;
translate_client->DidStartNavigation(&web_state_, &context);
translate_client->DidFinishNavigation(&web_state_, &context);
base::RunLoop().RunUntilIdle();
histogram_tester_.ExpectTotalCount("Translate.PageLoad.NumTranslations", 0);
// Navigate to new URL within same tab (web state).
translate_client->DidStartNavigation(&web_state_, &context);
translate_client->DidFinishNavigation(&web_state_, &context);
base::RunLoop().RunUntilIdle();
histogram_tester_.ExpectUniqueSample("Translate.PageLoad.NumTranslations", 0,
1);
// Close tab (web state).
translate_client->WebStateDestroyed(&web_state_);
histogram_tester_.ExpectUniqueSample("Translate.PageLoad.NumTranslations", 0,
2);
}
TEST_F(ChromeIOSTranslateClientTest, NoNewMetricsOnErrorPage) {
ChromeIOSTranslateClient* translate_client =
ChromeIOSTranslateClient::FromWebState(&web_state_);
web::FakeNavigationContext context;
translate_client->DidStartNavigation(&web_state_, &context); // needed?
context.SetError([NSError
errorWithDomain:@"commm"
code:200
userInfo:@{@"Error reason" : @"Invalid Input"}]);
EXPECT_TRUE(context.GetError());
translate_client->DidFinishNavigation(&web_state_, &context);
translate_client->WebStateDestroyed(&web_state_);
histogram_tester_.ExpectTotalCount("Translate.PageLoad.NumTranslations", 0);
}
TEST_F(ChromeIOSTranslateClientTest, PageTranslationCorrectlyUpdatesMetrics) {
ChromeIOSTranslateClient* translate_client =
ChromeIOSTranslateClient::FromWebState(&web_state_);
histogram_tester_.ExpectTotalCount("Translate.PageLoad.InitialSourceLanguage",
0);
histogram_tester_.ExpectTotalCount("Translate.PageLoad.FinalTargetLanguage",
0);
histogram_tester_.ExpectTotalCount("Translate.PageLoad.NumTranslations", 0);
web::FakeNavigationContext context;
translate_client->DidStartNavigation(&web_state_, &context);
translate_client->DidFinishNavigation(&web_state_, &context);
translate_client->translate_metrics_logger_->LogInitialSourceLanguage(
"en", /*is_in_users_content_language=*/true);
translate_client->translate_metrics_logger_->LogTargetLanguage(
"ko", /*target_language_origin=*/translate::TranslateBrowserMetrics::
TargetLanguageOrigin::kUninitialized);
translate_client->translate_metrics_logger_->LogTranslationStarted(
translate::TranslationType::kUninitialized);
translate_client->translate_metrics_logger_->LogTranslationFinished(
true, translate::TranslateErrors::NONE);
translate_client->WebStateDestroyed(&web_state_);
histogram_tester_.ExpectUniqueSample(
"Translate.PageLoad.InitialSourceLanguage", base::HashMetricName("en"),
1);
histogram_tester_.ExpectUniqueSample("Translate.PageLoad.FinalTargetLanguage",
base::HashMetricName("ko"), 1);
histogram_tester_.ExpectUniqueSample("Translate.PageLoad.NumTranslations", 1,
1);
}
TEST_F(ChromeIOSTranslateClientTest, TFLiteLanguageDetectionDurationRecorded) {
ChromeIOSTranslateClient* translate_client =
ChromeIOSTranslateClient::FromWebState(&web_state_);
histogram_tester_.ExpectTotalCount(
"Translate.LanguageDetection.TFLiteModelEvaluationDuration", 0);
translate::LanguageDetectionController* language_detection_controller =
translate_client->GetTranslateDriver()->language_detection_controller();
language_detection_controller->language_detection_model_->UpdateWithFile(
GetValidModelFile());
EXPECT_TRUE(
language_detection_controller->language_detection_model_->IsAvailable());
base::Value text_content("hello world");
language_detection_controller->OnTextRetrieved(true, "en", "en", GURL(""),
&text_content);
histogram_tester_.ExpectTotalCount(
"Translate.LanguageDetection.TFLiteModelEvaluationDuration", 1);
}