blob: 72c7334a11c7c9ce653c1ee5bb3ea9c8f2c03d79 [file] [log] [blame]
// Copyright 2015 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.
#include "chrome/browser/profiles/profile_statistics.h"
#include <map>
#include <memory>
#include <set>
#include <utility>
#include <vector>
#include "base/files/file_path.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/bookmarks/chrome_bookmark_client.h"
#include "chrome/browser/bookmarks/managed_bookmark_service_factory.h"
#include "chrome/browser/profiles/profile_statistics_aggregator.h"
#include "chrome/browser/profiles/profile_statistics_common.h"
#include "chrome/browser/profiles/profile_statistics_factory.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
std::unique_ptr<KeyedService> BuildBookmarkModelWithoutLoad(
content::BrowserContext* context) {
Profile* profile = Profile::FromBrowserContext(context);
std::unique_ptr<bookmarks::BookmarkModel> bookmark_model(
new bookmarks::BookmarkModel(base::MakeUnique<ChromeBookmarkClient>(
profile, ManagedBookmarkServiceFactory::GetForProfile(profile))));
return std::move(bookmark_model);
}
void LoadBookmarkModel(Profile* profile,
bookmarks::BookmarkModel* bookmark_model) {
bookmark_model->Load(profile->GetPrefs(), profile->GetPath(),
profile->GetIOTaskRunner(),
content::BrowserThread::GetTaskRunnerForThread(
content::BrowserThread::UI));
}
bookmarks::BookmarkModel* CreateBookmarkModelWithoutLoad(Profile* profile) {
return static_cast<bookmarks::BookmarkModel*>(
BookmarkModelFactory::GetInstance()->SetTestingFactoryAndUse(
profile, BuildBookmarkModelWithoutLoad));
}
class BookmarkStatHelper {
public:
BookmarkStatHelper() : num_of_times_called_(0) {}
void StatsCallback(profiles::ProfileCategoryStats stats) {
if (stats.back().category == profiles::kProfileStatisticsBookmarks)
++num_of_times_called_;
}
int GetNumOfTimesCalled() { return num_of_times_called_; }
private:
base::Closure quit_closure_;
int num_of_times_called_;
};
void VerifyStatisticsCache(const base::FilePath& profile_path,
const std::map<std::string, int>& expected,
const std::vector<std::string>& categories_to_check) {
const profiles::ProfileCategoryStats actual =
ProfileStatistics::GetProfileStatisticsFromAttributesStorage(
profile_path);
EXPECT_EQ(categories_to_check.size(), actual.size());
std::set<std::string> checked;
for (const auto& stat : actual) {
bool has_category = expected.count(stat.category);
EXPECT_EQ(has_category, stat.success);
EXPECT_EQ(has_category ? expected.at(stat.category) : 0, stat.count);
EXPECT_TRUE(checked.insert(stat.category).second);
}
}
} // namespace
class ProfileStatisticsTest : public testing::Test {
public:
ProfileStatisticsTest() : manager_(TestingBrowserProcess::GetGlobal()) {}
~ProfileStatisticsTest() override {}
protected:
void SetUp() override {
ASSERT_TRUE(manager_.SetUp());
}
void TearDown() override {
}
TestingProfileManager* manager() { return &manager_; }
private:
content::TestBrowserThreadBundle thread_bundle_;
TestingProfileManager manager_;
};
TEST_F(ProfileStatisticsTest, ProfileAttributesStorage) {
TestingProfile* profile = manager()->CreateTestingProfile("Test 1");
ASSERT_TRUE(profile);
base::FilePath profile_path = profile->GetPath();
std::vector<std::string> categories_to_check;
categories_to_check.push_back(profiles::kProfileStatisticsBrowsingHistory);
categories_to_check.push_back(profiles::kProfileStatisticsPasswords);
categories_to_check.push_back(profiles::kProfileStatisticsBookmarks);
categories_to_check.push_back(profiles::kProfileStatisticsSettings);
std::vector<std::pair<std::string, int>> insertions;
int num = 3;
// Insert for the first round, overwrite for the second round.
for (int i = 0; i < 2; i++) {
for (const auto& category : categories_to_check)
insertions.push_back(std::make_pair(category, num++));
}
std::map<std::string, int> expected;
// Now no keys are set.
VerifyStatisticsCache(profile_path, expected, categories_to_check);
// Insert items and test after each insert.
for (const auto& item : insertions) {
ProfileStatistics::SetProfileStatisticsToAttributesStorage(
profile_path, item.first, item.second);
expected[item.first] = item.second;
VerifyStatisticsCache(profile_path, expected, categories_to_check);
}
}
TEST_F(ProfileStatisticsTest, WaitOrCountBookmarks) {
TestingProfile* profile = manager()->CreateTestingProfile("Test 1");
ASSERT_TRUE(profile);
bookmarks::BookmarkModel* bookmark_model =
CreateBookmarkModelWithoutLoad(profile);
ASSERT_TRUE(bookmark_model);
// Run ProfileStatisticsAggregator::WaitOrCountBookmarks.
BookmarkStatHelper bookmark_stat_helper;
base::RunLoop run_loop_aggregator_done;
scoped_refptr<ProfileStatisticsAggregator> aggregator =
new ProfileStatisticsAggregator(profile,
run_loop_aggregator_done.QuitClosure());
aggregator->AddCallbackAndStartAggregator(
base::Bind(&BookmarkStatHelper::StatsCallback,
base::Unretained(&bookmark_stat_helper)));
// Wait until ProfileStatisticsAggregator::WaitOrCountBookmarks is run.
base::RunLoop run_loop1;
run_loop1.RunUntilIdle();
EXPECT_EQ(0, bookmark_stat_helper.GetNumOfTimesCalled());
// Run ProfileStatisticsAggregator::WaitOrCountBookmarks again.
aggregator->AddCallbackAndStartAggregator(
profiles::ProfileStatisticsCallback());
// Wait until ProfileStatisticsAggregator::WaitOrCountBookmarks is run.
base::RunLoop run_loop2;
run_loop2.RunUntilIdle();
EXPECT_EQ(0, bookmark_stat_helper.GetNumOfTimesCalled());
// Load the bookmark model. When the model is loaded (asynchronously), the
// observer added by WaitOrCountBookmarks is run.
LoadBookmarkModel(profile, bookmark_model);
run_loop_aggregator_done.Run();
EXPECT_EQ(1, bookmark_stat_helper.GetNumOfTimesCalled());
}