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