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