Chromium Code Reviews| 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..b79d9933ff1fe9caf7bdcab6be947f151d0310c8 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,6 +6,8 @@ |
| #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/sync_app_list_helper.h" |
| #include "chrome/browser/sync/test/integration/sync_test.h" |
| @@ -13,6 +15,7 @@ |
| #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 +26,59 @@ bool AllProfilesHaveSameAppList() { |
| return SyncAppListHelper::GetInstance()->AllProfilesHaveSameAppList(); |
| } |
| +// Returns true if sync items from |service1| match to sync items in |service2|. |
| +bool AreSyncItemsMatch(const app_list::AppListSyncableService* service1, |
| + const app_list::AppListSyncableService* service2) { |
|
stevenjb
2016/10/21 20:03:10
Ah.
nit: Just 'SyncItemsMatch' is better, otherwi
khmel
2016/10/24 17:28:39
Sure! Sorry for confusion
|
| + 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 app_list::AppListSyncableService::Observer { |
| + public: |
| + explicit AppListSyncUpdateWaiter(app_list::AppListSyncableService* service) |
| + : service_(service) { |
| + service_->AddObserverAndStart(this); |
| + } |
| + |
| + ~AppListSyncUpdateWaiter() override { |
| + service_->RemoveObserver(this); |
| + } |
| + |
| + // app_list::AppListSyncableService::Observer: |
| + void OnSyncModelUpdated() override { |
| + model_updated_callback_.Run(); |
| + } |
| + |
| + void WaitForUpdate() { |
| + base::RunLoop run_loop; |
| + model_updated_callback_ = run_loop.QuitClosure(); |
| + run_loop.Run(); |
| + } |
| + private: |
| + app_list::AppListSyncableService* service_; |
| + base::Closure model_updated_callback_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(AppListSyncUpdateWaiter); |
| +}; |
| + |
| } // namespace |
| class SingleClientAppListSyncTest : public SyncTest { |
| @@ -73,3 +129,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(AreSyncItemsMatch(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(AreSyncItemsMatch(service, &compare_service)); |
| + |
| + // Restore sync and sync data should override local changes. |
| + sync_service->OnUserChoseDatatypes(true, syncer::ModelTypeSet()); |
| + AppListSyncUpdateWaiter(service).WaitForUpdate(); |
| + EXPECT_TRUE(AreSyncItemsMatch(service, &compare_service)); |
| +} |