blob: 5f631c3183e5aa5e636b34eb1da65681ce81edb6 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/profile/model/test_with_profile.h"
#import "base/check_op.h"
#import "base/feature_list.h"
#import "base/functional/bind.h"
#import "base/functional/callback.h"
#import "base/run_loop.h"
#import "base/test/test_file_util.h"
#import "ios/chrome/browser/optimization_guide/model/optimization_guide_global_state.h"
#import "ios/chrome/browser/policy/model/browser_policy_connector_ios.h"
#import "ios/chrome/browser/profile/model/ios_chrome_io_thread.h"
#import "ios/chrome/browser/shared/model/application_context/application_context.h"
#import "ios/chrome/browser/shared/model/profile/scoped_profile_keep_alive_ios.h"
#import "ios/chrome/browser/signin/model/account_profile_mapper.h"
#import "ios/chrome/test/testing_application_context.h"
#import "ios/web/public/thread/web_task_traits.h"
#import "ios/web/public/thread/web_thread.h"
#import "services/network/public/cpp/shared_url_loader_factory.h"
namespace {
// Returns a callback that accept a single arguments and store it to `output`.
// The callback must not outlive the `output` parameter.
template <typename T>
base::OnceCallback<void(T)> CaptureArg(T& output) {
return base::BindOnce([](T& output, T param) { output = std::move(param); },
std::ref(output));
}
} // namespace
TestWithProfile::InitializedFeatureList::InitializedFeatureList(
const std::vector<base::test::FeatureRef>& enabled_features,
const std::vector<base::test::FeatureRef>& disabled_features) {
scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
}
TestWithProfile::InitializedFeatureList::~InitializedFeatureList() = default;
TestWithProfile::TestWithProfile()
: TestWithProfile(/*enabled_features=*/{}, /*disabled_features=*/{}) {}
TestWithProfile::TestWithProfile(
const std::vector<base::test::FeatureRef>& enabled_features,
const std::vector<base::test::FeatureRef>& disabled_features)
: initialized_scoped_feature_list_(enabled_features, disabled_features),
profile_data_dir_(base::CreateUniqueTempDirectoryScopedToTest()),
profile_manager_(GetApplicationContext()->GetLocalState(),
profile_data_dir_) {
TestingApplicationContext* application_context =
TestingApplicationContext::GetGlobal();
// IOSChromeIOThread needs to be created before the IO thread is started.
// Thus DELAY_IO_THREAD_START is set in WebTaskEnvironment's options. The
// thread is then started after the creation of IOSChromeIOThread.
chrome_io_ = std::make_unique<IOSChromeIOThread>(
application_context->GetLocalState(), application_context->GetNetLog());
account_profile_mapper_ = std::make_unique<AccountProfileMapper>(
application_context->GetSystemIdentityManager(), &profile_manager_,
application_context->GetLocalState());
// Register the objects with the TestingApplicationContext.
application_context->SetIOSChromeIOThread(chrome_io_.get());
application_context->SetProfileManagerAndAccountProfileMapper(
&profile_manager_, account_profile_mapper_.get());
application_context->GetOptimizationGuideGlobalState()
->prediction_model_store()
.Initialize(base::CreateUniqueTempDirectoryScopedToTest());
// Start the IO thread.
web_task_environment_.StartIOThread();
// Post a task to initialize the IOSChromeIOThread object on the IO thread.
web::GetIOThreadTaskRunner({})->PostTask(
FROM_HERE, base::BindOnce(&IOSChromeIOThread::InitOnIO,
base::Unretained(chrome_io_.get())));
// Init the BrowserPolicyConnect as this is required to create an instance
// of ProfileIOSImpl.
application_context->GetBrowserPolicyConnector()->Init(
application_context->GetLocalState(),
application_context->GetSharedURLLoaderFactory());
// IOSChromeIOThread requires the SystemURLRequestContextGetter() to be
// created before the object is shutdown, so force its creation here.
std::ignore = chrome_io_->system_url_request_context_getter();
}
TestWithProfile::~TestWithProfile() {
TestingApplicationContext* application_context =
TestingApplicationContext::GetGlobal();
// The profiles must have been unloaded by this point. This is because
// their KeyedService may depends on the AccountProfileMapper when the
// AccountProfileMapper depends on the ProfileManagerIOS.
profile_manager_.PrepareForDestruction();
CHECK_EQ(profile_manager_.GetLoadedProfiles().size(), 0u);
application_context->GetBrowserPolicyConnector()->Shutdown();
application_context->GetIOSChromeIOThread()->NetworkTearDown();
application_context->SetProfileManagerAndAccountProfileMapper(nullptr,
nullptr);
application_context->SetIOSChromeIOThread(nullptr);
}
ScopedProfileKeepAliveIOS TestWithProfile::LoadProfile(
std::string_view profile_name) {
ScopedProfileKeepAliveIOS keep_alive;
base::RunLoop run_loop;
profile_manager_.LoadProfileAsync(
profile_name, CaptureArg(keep_alive).Then(run_loop.QuitClosure()), {});
run_loop.Run();
return keep_alive;
}
ScopedProfileKeepAliveIOS TestWithProfile::CreateProfile(
std::string_view profile_name) {
ScopedProfileKeepAliveIOS keep_alive;
base::RunLoop run_loop;
profile_manager_.CreateProfileAsync(
profile_name, CaptureArg(keep_alive).Then(run_loop.QuitClosure()), {});
run_loop.Run();
return keep_alive;
}