blob: 04e48a9e20531f90e77568fe4fd5df4bb527f870 [file] [log] [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/external_pref_loader.h"
#include <memory>
#include <utility>
#include "ash/constants/ash_pref_names.h"
#include "base/bind.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/extensions/external_provider_impl.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sync/sync_service_factory.h"
#include "chrome/test/base/testing_profile.h"
#include "components/prefs/pref_service.h"
#include "components/sync/test/fake_sync_change_processor.h"
#include "components/sync/test/sync_error_factory_mock.h"
#include "components/sync/test/test_sync_service.h"
#include "components/sync_preferences/pref_model_associator.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/browser_task_environment.h"
#include "extensions/common/extension.h"
#include "testing/gtest/include/gtest/gtest.h"
using extensions::mojom::ManifestLocation;
namespace extensions {
namespace {
class TestSyncService : public syncer::TestSyncService {
public:
TestSyncService() {}
TestSyncService(const TestSyncService&) = delete;
TestSyncService& operator=(const TestSyncService&) = delete;
~TestSyncService() override {}
// syncer::SyncService:
void AddObserver(syncer::SyncServiceObserver* observer) override {
ASSERT_FALSE(observer_);
observer_ = observer;
}
void RemoveObserver(syncer::SyncServiceObserver* observer) override {
EXPECT_EQ(observer_, observer);
}
void FireOnStateChanged() {
ASSERT_TRUE(observer_);
observer_->OnStateChanged(this);
}
private:
syncer::SyncServiceObserver* observer_ = nullptr;
};
std::unique_ptr<KeyedService> TestingSyncFactoryFunction(
content::BrowserContext* context) {
return std::make_unique<TestSyncService>();
}
} // namespace
// Test version of ExternalPrefLoader that doesn't do any IO.
class TestExternalPrefLoader : public ExternalPrefLoader {
public:
TestExternalPrefLoader(Profile* profile, base::OnceClosure load_callback)
: ExternalPrefLoader(
// Invalid value, doesn't matter since it's not used.
-1,
// Make sure ExternalPrefLoader waits for priority sync.
ExternalPrefLoader::DELAY_LOAD_UNTIL_PRIORITY_SYNC,
profile),
load_callback_(std::move(load_callback)) {}
TestExternalPrefLoader(const TestExternalPrefLoader&) = delete;
TestExternalPrefLoader& operator=(const TestExternalPrefLoader&) = delete;
void LoadOnFileThread() override {
content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
std::move(load_callback_));
}
private:
~TestExternalPrefLoader() override {}
base::OnceClosure load_callback_;
};
class ExternalPrefLoaderTest : public ::testing::Test {
public:
ExternalPrefLoaderTest(ExternalPrefLoaderTest&) = delete;
ExternalPrefLoaderTest& operator=(ExternalPrefLoaderTest&) = delete;
void SetUp() override {
profile_ = std::make_unique<TestingProfile>();
sync_service_ = static_cast<TestSyncService*>(
SyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
profile(), base::BindRepeating(&TestingSyncFactoryFunction)));
sync_service_->SetFirstSetupComplete(true);
}
void TearDown() override { profile_.reset(); }
TestingProfile* profile() { return profile_.get(); }
TestSyncService* sync_service() { return sync_service_; }
protected:
ExternalPrefLoaderTest() = default;
~ExternalPrefLoaderTest() override = default;
base::test::ScopedFeatureList feature_list_;
private:
content::BrowserTaskEnvironment task_environment_;
std::unique_ptr<TestingProfile> profile_;
TestSyncService* sync_service_ = nullptr;
};
// TODO(lazyboy): Add a test to cover
// PrioritySyncReadyWaiter::OnIsSyncingChanged().
// Tests that we fire pref reading correctly after priority sync state
// is resolved by ExternalPrefLoader. This test checks that the flow works
// regardless of the state of SyncSettingsCategorization.
TEST_F(ExternalPrefLoaderTest, PrefReadInitiatesCorrectly) {
base::RunLoop run_loop;
scoped_refptr<ExternalPrefLoader> loader(
new TestExternalPrefLoader(profile(), run_loop.QuitWhenIdleClosure()));
ExternalProviderImpl provider(
nullptr, loader, profile(), ManifestLocation::kInvalidLocation,
ManifestLocation::kInvalidLocation, Extension::NO_FLAGS);
provider.VisitRegisteredExtension();
// Initially CanSyncFeatureStart() returns true, returning false will let
// |loader| proceed.
sync_service()->SetDisableReasons(
syncer::SyncService::DISABLE_REASON_USER_CHOICE);
ASSERT_FALSE(sync_service()->CanSyncFeatureStart());
sync_service()->FireOnStateChanged();
run_loop.Run();
}
} // namespace extensions