two_client_app_list_sync_test.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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
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_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
103IN_PROC_BROWSER_TEST_F(TwoClientAppListSyncTest, StartWithNoApps) {
104  ASSERT_TRUE(SetupSync());
105
106  ASSERT_TRUE(AllProfilesHaveSameAppListAsVerifier());
107}
108
109IN_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.
129IN_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.
170IN_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
210IN_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
223IN_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.
245IN_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
270IN_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
295IN_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
322IN_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
349IN_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.
371IN_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.
392IN_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.
418IN_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
480class 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.
503IN_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
527IN_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)
588