| Index: chrome/browser/sync/test/integration/single_client_app_list_sync_test.cc
|
| diff --git a/chrome/browser/sync/test/integration/single_client_app_list_sync_test.cc b/chrome/browser/sync/test/integration/single_client_app_list_sync_test.cc
|
| index 7edc917dcc242a81a746f017d56a2c95e44cd92c..11a0b5f7814041e87b7cb77c14ed2cfa301b315f 100644
|
| --- a/chrome/browser/sync/test/integration/single_client_app_list_sync_test.cc
|
| +++ b/chrome/browser/sync/test/integration/single_client_app_list_sync_test.cc
|
| @@ -6,13 +6,17 @@
|
|
|
| #include "base/command_line.h"
|
| #include "base/macros.h"
|
| +#include "base/run_loop.h"
|
| +#include "chrome/browser/sync/profile_sync_service_factory.h"
|
| #include "chrome/browser/sync/test/integration/apps_helper.h"
|
| +#include "chrome/browser/sync/test/integration/status_change_checker.h"
|
| #include "chrome/browser/sync/test/integration/sync_app_list_helper.h"
|
| #include "chrome/browser/sync/test/integration/sync_test.h"
|
| #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h"
|
| #include "chrome/browser/ui/app_list/app_list_syncable_service.h"
|
| #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h"
|
| #include "components/browser_sync/profile_sync_service.h"
|
| +#include "extensions/browser/extension_system.h"
|
| #include "ui/app_list/app_list_switches.h"
|
|
|
| namespace {
|
| @@ -23,6 +27,65 @@ bool AllProfilesHaveSameAppList() {
|
| return SyncAppListHelper::GetInstance()->AllProfilesHaveSameAppList();
|
| }
|
|
|
| +// Returns true if sync items from |service1| match to sync items in |service2|.
|
| +bool SyncItemsMatch(const app_list::AppListSyncableService* service1,
|
| + const app_list::AppListSyncableService* service2) {
|
| + if (service1->sync_items().size() != service2->sync_items().size())
|
| + return false;
|
| +
|
| + for (const auto& it : service1->sync_items()) {
|
| + const app_list::AppListSyncableService::SyncItem* item1 = it.second.get();
|
| + const app_list::AppListSyncableService::SyncItem* item2 =
|
| + service2->GetSyncItem(it.first);
|
| + if (!item2)
|
| + return false;
|
| + if (item1->item_id != item2->item_id ||
|
| + item1->item_type != item2->item_type ||
|
| + item1->item_name != item2->item_name ||
|
| + item1->parent_id != item2->parent_id ||
|
| + !item1->item_ordinal.EqualsOrBothInvalid(item2->item_ordinal) ||
|
| + !item1->item_pin_ordinal.EqualsOrBothInvalid(item2->item_pin_ordinal)) {
|
| + return false;
|
| + }
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +class AppListSyncUpdateWaiter
|
| + : public StatusChangeChecker,
|
| + public app_list::AppListSyncableService::Observer {
|
| + public:
|
| + explicit AppListSyncUpdateWaiter(app_list::AppListSyncableService* service)
|
| + : service_(service) {
|
| + service_->AddObserverAndStart(this);
|
| + }
|
| +
|
| + ~AppListSyncUpdateWaiter() override {
|
| + service_->RemoveObserver(this);
|
| + }
|
| +
|
| + // StatusChangeChecker:
|
| + std::string GetDebugMessage() const override {
|
| + return "AwaitAppListSyncUpdated";
|
| + }
|
| +
|
| + bool IsExitConditionSatisfied() override {
|
| + return service_updated_;
|
| + }
|
| +
|
| + // app_list::AppListSyncableService::Observer:
|
| + void OnSyncModelUpdated() override {
|
| + service_updated_ = true;
|
| + StopWaiting();
|
| + }
|
| +
|
| + private:
|
| + app_list::AppListSyncableService* const service_;
|
| + bool service_updated_ = false;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(AppListSyncUpdateWaiter);
|
| +};
|
| +
|
| } // namespace
|
|
|
| class SingleClientAppListSyncTest : public SyncTest {
|
| @@ -73,3 +136,57 @@ IN_PROC_BROWSER_TEST_F(SingleClientAppListSyncTest, AppListSomeApps) {
|
| ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait());
|
| ASSERT_TRUE(AllProfilesHaveSameAppList());
|
| }
|
| +
|
| +IN_PROC_BROWSER_TEST_F(SingleClientAppListSyncTest, LocalStorage) {
|
| + ASSERT_TRUE(SetupSync());
|
| +
|
| + Profile* profile = GetProfile(0);
|
| + app_list::AppListSyncableService* service =
|
| + app_list::AppListSyncableServiceFactory::GetForProfile(profile);
|
| + browser_sync::ProfileSyncService* sync_service =
|
| + ProfileSyncServiceFactory::GetForProfile(profile);
|
| +
|
| + const size_t kNumApps = 5;
|
| + syncer::StringOrdinal pin_position =
|
| + syncer::StringOrdinal::CreateInitialOrdinal();
|
| + std::vector<std::string> app_ids;
|
| + for (int i = 0; i < static_cast<int>(kNumApps); ++i) {
|
| + app_ids.push_back(apps_helper::InstallApp(profile, i));
|
| + service->SetPinPosition(app_ids.back(), pin_position);
|
| + pin_position = pin_position.CreateAfter();
|
| + }
|
| + SyncAppListHelper::GetInstance()->MoveAppToFolder(
|
| + profile, 2, "folder1");
|
| + SyncAppListHelper::GetInstance()->MoveAppToFolder(
|
| + profile, 3, "folder2");
|
| +
|
| + app_list::AppListSyncableService compare_service(
|
| + profile, extensions::ExtensionSystem::Get(profile));
|
| +
|
| + // Make sure that that on start, when sync has not been started yet, model
|
| + // content is filled from local prefs and it matches latest state.
|
| + EXPECT_TRUE(SyncItemsMatch(service, &compare_service));
|
| +
|
| + ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait());
|
| +
|
| + // Disable app sync.
|
| + sync_service->OnUserChoseDatatypes(false, syncer::ModelTypeSet());
|
| +
|
| + // Change data when sync is off.
|
| + for (const auto& app_id : app_ids) {
|
| + service->SetPinPosition(app_id, pin_position);
|
| + pin_position = pin_position.CreateAfter();
|
| + }
|
| + SyncAppListHelper::GetInstance()->MoveAppFromFolder(
|
| + profile, 0, "folder1");
|
| + SyncAppListHelper::GetInstance()->MoveAppFromFolder(
|
| + profile, 0, "folder2");
|
| + SyncAppListHelper::GetInstance()->MoveApp(profile, 0, 1);
|
| +
|
| + EXPECT_FALSE(SyncItemsMatch(service, &compare_service));
|
| +
|
| + // Restore sync and sync data should override local changes.
|
| + sync_service->OnUserChoseDatatypes(true, syncer::ModelTypeSet());
|
| + EXPECT_TRUE(AppListSyncUpdateWaiter(service).Wait());
|
| + EXPECT_TRUE(SyncItemsMatch(service, &compare_service));
|
| +}
|
|
|