two_client_app_list_sync_test.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/basictypes.h" 6#include "base/command_line.h" 7#include "chrome/browser/chrome_notification_types.h" 8#include "chrome/browser/extensions/extension_service.h" 9#include "chrome/browser/profiles/profile.h" 10#include "chrome/browser/sync/test/integration/apps_helper.h" 11#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" 12#include "chrome/browser/sync/test/integration/sync_app_list_helper.h" 13#include "chrome/browser/sync/test/integration/sync_integration_test_util.h" 14#include "chrome/browser/sync/test/integration/sync_test.h" 15#include "chrome/browser/ui/app_list/app_list_syncable_service.h" 16#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" 17#include "chrome/common/chrome_switches.h" 18#include "content/public/browser/notification_service.h" 19#include "content/public/test/test_utils.h" 20#include "extensions/browser/extension_prefs.h" 21#include "extensions/browser/extension_system.h" 22#include "ui/app_list/app_list_switches.h" 23 24using apps_helper::DisableApp; 25using apps_helper::EnableApp; 26using apps_helper::HasSameAppsAsVerifier; 27using apps_helper::IncognitoDisableApp; 28using apps_helper::IncognitoEnableApp; 29using apps_helper::InstallApp; 30using apps_helper::InstallAppsPendingForSync; 31using apps_helper::UninstallApp; 32using sync_integration_test_util::AwaitCommitActivityCompletion; 33 34namespace { 35 36const size_t kNumDefaultApps = 2; 37 38bool AllProfilesHaveSameAppListAsVerifier() { 39 return SyncAppListHelper::GetInstance()-> 40 AllProfilesHaveSameAppListAsVerifier(); 41} 42 43const app_list::AppListSyncableService::SyncItem* GetSyncItem( 44 Profile* profile, 45 const std::string& app_id) { 46 app_list::AppListSyncableService* service = 47 app_list::AppListSyncableServiceFactory::GetForProfile(profile); 48 return service->GetSyncItem(app_id); 49} 50 51} // namespace 52 53class TwoClientAppListSyncTest : public SyncTest { 54 public: 55 TwoClientAppListSyncTest() : SyncTest(TWO_CLIENT) {} 56 57 virtual ~TwoClientAppListSyncTest() {} 58 59 // SyncTest 60 virtual bool SetupClients() OVERRIDE { 61 if (!SyncTest::SetupClients()) 62 return false; 63 64 // Init SyncAppListHelper to ensure that the extension system is initialized 65 // for each Profile. 66 SyncAppListHelper::GetInstance(); 67 return true; 68 } 69 70 virtual bool SetupSync() OVERRIDE { 71 if (!SyncTest::SetupSync()) 72 return false; 73 WaitForExtensionServicesToLoad(); 74 return true; 75 } 76 77 private: 78 void WaitForExtensionServicesToLoad() { 79 for (int i = 0; i < num_clients(); ++i) 80 WaitForExtensionsServiceToLoadForProfile(GetProfile(i)); 81 WaitForExtensionsServiceToLoadForProfile(verifier()); 82 } 83 84 void WaitForExtensionsServiceToLoadForProfile(Profile* profile) { 85 ExtensionService* extension_service = 86 extensions::ExtensionSystem::Get(profile)->extension_service(); 87 if (extension_service && extension_service->is_ready()) 88 return; 89 content::WindowedNotificationObserver extensions_loaded_observer( 90 chrome::NOTIFICATION_EXTENSIONS_READY, 91 content::NotificationService::AllSources()); 92 extensions_loaded_observer.Wait(); 93 } 94 95 DISALLOW_COPY_AND_ASSIGN(TwoClientAppListSyncTest); 96}; 97 98IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncTest, StartWithNoApps) { 99 ASSERT_TRUE(SetupSync()); 100 101 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 102} 103 104IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncTest, StartWithSameApps) { 105 ASSERT_TRUE(SetupClients()); 106 107 const int kNumApps = 5; 108 for (int i = 0; i < kNumApps; ++i) { 109 InstallApp(GetProfile(0), i); 110 InstallApp(GetProfile(1), i); 111 InstallApp(verifier(), i); 112 } 113 114 ASSERT_TRUE(SetupSync()); 115 116 ASSERT_TRUE(AwaitQuiescence()); 117 118 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 119} 120 121// Install some apps on both clients, some on only one client, some on only the 122// other, and sync. Both clients should end up with all apps, and the app and 123// page ordinals should be identical. 124IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncTest, StartWithDifferentApps) { 125 ASSERT_TRUE(SetupClients()); 126 127 int i = 0; 128 129 const int kNumCommonApps = 5; 130 for (int j = 0; j < kNumCommonApps; ++i, ++j) { 131 InstallApp(GetProfile(0), i); 132 InstallApp(GetProfile(1), i); 133 InstallApp(verifier(), i); 134 } 135 136 const int kNumProfile0Apps = 10; 137 for (int j = 0; j < kNumProfile0Apps; ++i, ++j) { 138 std::string id = InstallApp(GetProfile(0), i); 139 InstallApp(verifier(), i); 140 SyncAppListHelper::GetInstance()->CopyOrdinalsToVerifier(GetProfile(0), id); 141 } 142 143 const int kNumProfile1Apps = 10; 144 for (int j = 0; j < kNumProfile1Apps; ++i, ++j) { 145 std::string id = InstallApp(GetProfile(1), i); 146 InstallApp(verifier(), i); 147 SyncAppListHelper::GetInstance()->CopyOrdinalsToVerifier(GetProfile(1), id); 148 } 149 150 ASSERT_TRUE(SetupSync()); 151 152 ASSERT_TRUE(AwaitQuiescence()); 153 154 InstallAppsPendingForSync(GetProfile(0)); 155 InstallAppsPendingForSync(GetProfile(1)); 156 157 // Verify the app lists, but ignore absolute position values, checking only 158 // relative positions (see note in app_list_syncable_service.h). 159 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 160} 161 162// Install some apps on both clients, then sync. Then install some apps on only 163// one client, some on only the other, and then sync again. Both clients should 164// end up with all apps, and the app and page ordinals should be identical. 165IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncTest, InstallDifferentApps) { 166 ASSERT_TRUE(SetupClients()); 167 168 int i = 0; 169 170 const int kNumCommonApps = 5; 171 for (int j = 0; j < kNumCommonApps; ++i, ++j) { 172 InstallApp(GetProfile(0), i); 173 InstallApp(GetProfile(1), i); 174 InstallApp(verifier(), i); 175 } 176 177 ASSERT_TRUE(SetupSync()); 178 179 ASSERT_TRUE(AwaitQuiescence()); 180 181 const int kNumProfile0Apps = 10; 182 for (int j = 0; j < kNumProfile0Apps; ++i, ++j) { 183 std::string id = InstallApp(GetProfile(0), i); 184 InstallApp(verifier(), i); 185 SyncAppListHelper::GetInstance()->CopyOrdinalsToVerifier(GetProfile(0), id); 186 } 187 188 const int kNumProfile1Apps = 10; 189 for (int j = 0; j < kNumProfile1Apps; ++i, ++j) { 190 std::string id = InstallApp(GetProfile(1), i); 191 InstallApp(verifier(), i); 192 SyncAppListHelper::GetInstance()->CopyOrdinalsToVerifier(GetProfile(1), id); 193 } 194 195 ASSERT_TRUE(AwaitQuiescence()); 196 197 InstallAppsPendingForSync(GetProfile(0)); 198 InstallAppsPendingForSync(GetProfile(1)); 199 200 // Verify the app lists, but ignore absolute position values, checking only 201 // relative positions (see note in app_list_syncable_service.h). 202 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 203} 204 205IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncTest, Install) { 206 ASSERT_TRUE(SetupSync()); 207 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 208 209 InstallApp(GetProfile(0), 0); 210 InstallApp(verifier(), 0); 211 ASSERT_TRUE(AwaitQuiescence()); 212 213 InstallAppsPendingForSync(GetProfile(0)); 214 InstallAppsPendingForSync(GetProfile(1)); 215 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 216} 217 218IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncTest, Uninstall) { 219 ASSERT_TRUE(SetupSync()); 220 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 221 222 InstallApp(GetProfile(0), 0); 223 InstallApp(verifier(), 0); 224 ASSERT_TRUE(AwaitQuiescence()); 225 226 InstallAppsPendingForSync(GetProfile(0)); 227 InstallAppsPendingForSync(GetProfile(1)); 228 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 229 230 UninstallApp(GetProfile(0), 0); 231 UninstallApp(verifier(), 0); 232 ASSERT_TRUE(AwaitQuiescence()); 233 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 234} 235 236// Install an app on one client, then sync. Then uninstall the app on the first 237// client and sync again. Now install a new app on the first client and sync. 238// Both client should only have the second app, with identical app and page 239// ordinals. 240IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncTest, UninstallThenInstall) { 241 ASSERT_TRUE(SetupSync()); 242 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 243 244 InstallApp(GetProfile(0), 0); 245 InstallApp(verifier(), 0); 246 ASSERT_TRUE(AwaitQuiescence()); 247 248 InstallAppsPendingForSync(GetProfile(0)); 249 InstallAppsPendingForSync(GetProfile(1)); 250 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 251 252 UninstallApp(GetProfile(0), 0); 253 UninstallApp(verifier(), 0); 254 ASSERT_TRUE(AwaitQuiescence()); 255 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 256 257 InstallApp(GetProfile(0), 1); 258 InstallApp(verifier(), 1); 259 ASSERT_TRUE(AwaitQuiescence()); 260 InstallAppsPendingForSync(GetProfile(0)); 261 InstallAppsPendingForSync(GetProfile(1)); 262 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 263} 264 265IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncTest, Merge) { 266 ASSERT_TRUE(SetupSync()); 267 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 268 269 InstallApp(GetProfile(0), 0); 270 InstallApp(GetProfile(1), 0); 271 ASSERT_TRUE(AwaitQuiescence()); 272 273 UninstallApp(GetProfile(0), 0); 274 InstallApp(GetProfile(0), 1); 275 InstallApp(verifier(), 1); 276 277 InstallApp(GetProfile(0), 2); 278 InstallApp(GetProfile(1), 2); 279 InstallApp(verifier(), 2); 280 281 InstallApp(GetProfile(1), 3); 282 InstallApp(verifier(), 3); 283 284 ASSERT_TRUE(AwaitQuiescence()); 285 InstallAppsPendingForSync(GetProfile(0)); 286 InstallAppsPendingForSync(GetProfile(1)); 287 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 288} 289 290IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncTest, UpdateEnableDisableApp) { 291 ASSERT_TRUE(SetupSync()); 292 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 293 294 InstallApp(GetProfile(0), 0); 295 InstallApp(GetProfile(1), 0); 296 InstallApp(verifier(), 0); 297 ASSERT_TRUE(AwaitQuiescence()); 298 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 299 300 DisableApp(GetProfile(0), 0); 301 DisableApp(verifier(), 0); 302 ASSERT_TRUE(HasSameAppsAsVerifier(0)); 303 ASSERT_FALSE(HasSameAppsAsVerifier(1)); 304 305 ASSERT_TRUE(AwaitQuiescence()); 306 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 307 308 EnableApp(GetProfile(1), 0); 309 EnableApp(verifier(), 0); 310 ASSERT_TRUE(HasSameAppsAsVerifier(1)); 311 ASSERT_FALSE(HasSameAppsAsVerifier(0)); 312 313 ASSERT_TRUE(AwaitQuiescence()); 314 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 315} 316 317IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncTest, UpdateIncognitoEnableDisable) { 318 ASSERT_TRUE(SetupSync()); 319 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 320 321 InstallApp(GetProfile(0), 0); 322 InstallApp(GetProfile(1), 0); 323 InstallApp(verifier(), 0); 324 ASSERT_TRUE(AwaitQuiescence()); 325 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 326 327 IncognitoEnableApp(GetProfile(0), 0); 328 IncognitoEnableApp(verifier(), 0); 329 ASSERT_TRUE(HasSameAppsAsVerifier(0)); 330 ASSERT_FALSE(HasSameAppsAsVerifier(1)); 331 332 ASSERT_TRUE(AwaitQuiescence()); 333 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 334 335 IncognitoDisableApp(GetProfile(1), 0); 336 IncognitoDisableApp(verifier(), 0); 337 ASSERT_TRUE(HasSameAppsAsVerifier(1)); 338 ASSERT_FALSE(HasSameAppsAsVerifier(0)); 339 340 ASSERT_TRUE(AwaitQuiescence()); 341 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 342} 343 344IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncTest, DisableApps) { 345 ASSERT_TRUE(SetupSync()); 346 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 347 348 ASSERT_TRUE(GetClient(1)->DisableSyncForDatatype(syncer::APP_LIST)); 349 InstallApp(GetProfile(0), 0); 350 InstallApp(verifier(), 0); 351 ASSERT_TRUE(AwaitCommitActivityCompletion(GetClient(0)->service())); 352 ASSERT_TRUE(HasSameAppsAsVerifier(0)); 353 ASSERT_FALSE(HasSameAppsAsVerifier(1)); 354 355 ASSERT_TRUE(GetClient(1)->EnableSyncForDatatype(syncer::APP_LIST)); 356 ASSERT_TRUE(AwaitQuiescence()); 357 358 InstallAppsPendingForSync(GetProfile(0)); 359 InstallAppsPendingForSync(GetProfile(1)); 360 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 361} 362 363// Disable sync for the second client and then install an app on the first 364// client, then enable sync on the second client. Both clients should have the 365// same app with identical app and page ordinals. 366IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncTest, DisableSync) { 367 ASSERT_TRUE(SetupSync()); 368 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 369 370 ASSERT_TRUE(GetClient(1)->DisableSyncForAllDatatypes()); 371 InstallApp(GetProfile(0), 0); 372 InstallApp(verifier(), 0); 373 ASSERT_TRUE(AwaitCommitActivityCompletion(GetClient(0)->service())); 374 ASSERT_TRUE(HasSameAppsAsVerifier(0)); 375 ASSERT_FALSE(HasSameAppsAsVerifier(1)); 376 377 ASSERT_TRUE(GetClient(1)->EnableSyncForAllDatatypes()); 378 ASSERT_TRUE(AwaitQuiescence()); 379 380 InstallAppsPendingForSync(GetProfile(0)); 381 InstallAppsPendingForSync(GetProfile(1)); 382 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 383} 384 385// Install some apps on both clients, then sync. Move an app on one client 386// and sync. Both clients should have the updated position for the app. 387IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncTest, Move) { 388 ASSERT_TRUE(SetupSync()); 389 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 390 391 const int kNumApps = 5; 392 for (int i = 0; i < kNumApps; ++i) { 393 InstallApp(GetProfile(0), i); 394 InstallApp(GetProfile(1), i); 395 InstallApp(verifier(), i); 396 } 397 ASSERT_TRUE(AwaitQuiescence()); 398 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 399 400 size_t first = kNumDefaultApps; 401 SyncAppListHelper::GetInstance()->MoveApp( 402 GetProfile(0), first + 1, first + 2); 403 SyncAppListHelper::GetInstance()->MoveApp( 404 verifier(), first + 1, first + 2); 405 406 ASSERT_TRUE(AwaitQuiescence()); 407 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 408} 409 410// Install a Default App on both clients, then sync. Remove the app on one 411// client and sync. Ensure that the app is removed on the other client and 412// that a REMOVE_DEFAULT_APP entry exists. 413IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncTest, RemoveDefault) { 414 ASSERT_TRUE(SetupClients()); 415 ASSERT_TRUE(SetupSync()); 416 417 // Install a non-default app. 418 InstallApp(GetProfile(0), 0); 419 InstallApp(GetProfile(1), 0); 420 InstallApp(verifier(), 0); 421 422 // Install a default app in Profile 0 only. 423 const int default_app_index = 1; 424 std::string default_app_id = InstallApp(GetProfile(0), default_app_index); 425 InstallApp(verifier(), default_app_index); 426 SyncAppListHelper::GetInstance()->CopyOrdinalsToVerifier( 427 GetProfile(0), default_app_id); 428 429 ASSERT_TRUE(AwaitQuiescence()); 430 InstallAppsPendingForSync(GetProfile(0)); 431 InstallAppsPendingForSync(GetProfile(1)); 432 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 433 434 // Flag Default app in Profile 1. 435 extensions::ExtensionPrefs::Get(GetProfile(1)) 436 ->UpdateExtensionPref(default_app_id, 437 "was_installed_by_default", 438 new base::FundamentalValue(true)); 439 440 // Remove the default app in Profile 0 and verifier, ensure it was removed 441 // in Profile 1. 442 UninstallApp(GetProfile(0), default_app_index); 443 UninstallApp(verifier(), default_app_index); 444 ASSERT_TRUE(AwaitQuiescence()); 445 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 446 447 // Ensure that a REMOVE_DEFAULT_APP SyncItem entry exists in Profile 1. 448 const app_list::AppListSyncableService::SyncItem* sync_item = 449 GetSyncItem(GetProfile(1), default_app_id); 450 ASSERT_TRUE(sync_item); 451 ASSERT_EQ(sync_pb::AppListSpecifics::TYPE_REMOVE_DEFAULT_APP, 452 sync_item->item_type); 453 454 // Re-Install the same app in Profile 0. 455 std::string app_id2 = InstallApp(GetProfile(0), default_app_index); 456 EXPECT_EQ(default_app_id, app_id2); 457 InstallApp(verifier(), default_app_index); 458 sync_item = GetSyncItem(GetProfile(0), app_id2); 459 EXPECT_EQ(sync_pb::AppListSpecifics::TYPE_APP, sync_item->item_type); 460 461 ASSERT_TRUE(AwaitQuiescence()); 462 InstallAppsPendingForSync(GetProfile(0)); 463 InstallAppsPendingForSync(GetProfile(1)); 464 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 465 466 // Ensure that the REMOVE_DEFAULT_APP SyncItem entry in Profile 1 is replaced 467 // with an APP entry after an install. 468 sync_item = GetSyncItem(GetProfile(1), app_id2); 469 ASSERT_TRUE(sync_item); 470 EXPECT_EQ(sync_pb::AppListSpecifics::TYPE_APP, sync_item->item_type); 471} 472 473class TwoClientAppListSyncFolderTest : public TwoClientAppListSyncTest { 474 public: 475 TwoClientAppListSyncFolderTest() {} 476 virtual ~TwoClientAppListSyncFolderTest() {} 477 478 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 479 TwoClientAppListSyncTest::SetUpCommandLine(command_line); 480 } 481 482 private: 483 DISALLOW_COPY_AND_ASSIGN(TwoClientAppListSyncFolderTest); 484}; 485 486// Install some apps on both clients, then sync. Move an app on one client 487// to a folder and sync. The app lists, including folders, should match. 488IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncFolderTest, MoveToFolder) { 489 ASSERT_TRUE(SetupSync()); 490 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 491 492 const int kNumApps = 5; 493 for (int i = 0; i < kNumApps; ++i) { 494 InstallApp(GetProfile(0), i); 495 InstallApp(GetProfile(1), i); 496 InstallApp(verifier(), i); 497 } 498 ASSERT_TRUE(AwaitQuiescence()); 499 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 500 501 size_t index = 2u; 502 std::string folder_id = "Folder 0"; 503 SyncAppListHelper::GetInstance()->MoveAppToFolder( 504 GetProfile(0), index, folder_id); 505 SyncAppListHelper::GetInstance()->MoveAppToFolder( 506 verifier(), index, folder_id); 507 508 ASSERT_TRUE(AwaitQuiescence()); 509 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 510} 511 512IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncFolderTest, FolderAddRemove) { 513 ASSERT_TRUE(SetupSync()); 514 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 515 516 const int kNumApps = 10; 517 for (int i = 0; i < kNumApps; ++i) { 518 InstallApp(GetProfile(0), i); 519 InstallApp(GetProfile(1), i); 520 InstallApp(verifier(), i); 521 } 522 ASSERT_TRUE(AwaitQuiescence()); 523 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 524 525 // Move a few apps to a folder. 526 const size_t kNumAppsToMove = 3; 527 std::string folder_id = "Folder 0"; 528 // The folder will be created at the end of the list; always move the 529 // first non default item in the list. 530 size_t item_index = kNumDefaultApps; 531 for (size_t i = 0; i < kNumAppsToMove; ++i) { 532 SyncAppListHelper::GetInstance()->MoveAppToFolder( 533 GetProfile(0), item_index, folder_id); 534 SyncAppListHelper::GetInstance()->MoveAppToFolder( 535 verifier(), item_index, folder_id); 536 } 537 ASSERT_TRUE(AwaitQuiescence()); 538 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 539 540 // Remove one app from the folder. 541 SyncAppListHelper::GetInstance()->MoveAppFromFolder( 542 GetProfile(0), 0, folder_id); 543 SyncAppListHelper::GetInstance()->MoveAppFromFolder( 544 verifier(), 0, folder_id); 545 546 ASSERT_TRUE(AwaitQuiescence()); 547 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 548 549 // Remove remaining apps from the folder (deletes folder). 550 for (size_t i = 1; i < kNumAppsToMove; ++i) { 551 SyncAppListHelper::GetInstance()->MoveAppFromFolder( 552 GetProfile(0), 0, folder_id); 553 SyncAppListHelper::GetInstance()->MoveAppFromFolder( 554 verifier(), 0, folder_id); 555 } 556 557 ASSERT_TRUE(AwaitQuiescence()); 558 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 559 560 // Move apps back to a (new) folder. 561 for (size_t i = 0; i < kNumAppsToMove; ++i) { 562 SyncAppListHelper::GetInstance()->MoveAppToFolder( 563 GetProfile(0), item_index, folder_id); 564 SyncAppListHelper::GetInstance()->MoveAppToFolder( 565 verifier(), item_index, folder_id); 566 } 567 568 ASSERT_TRUE(AwaitQuiescence()); 569 ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier()); 570} 571