two_client_apps_sync_test.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1// Copyright (c) 2012 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 "chrome/browser/extensions/extension_service.h"
7#include "chrome/browser/extensions/launch_util.h"
8#include "chrome/browser/profiles/profile.h"
9#include "chrome/browser/sync/test/integration/apps_helper.h"
10#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
11#include "chrome/browser/sync/test/integration/sync_app_helper.h"
12#include "chrome/browser/sync/test/integration/sync_test.h"
13#include "chrome/common/extensions/extension_constants.h"
14#include "extensions/browser/app_sorting.h"
15#include "extensions/browser/extension_prefs.h"
16#include "sync/api/string_ordinal.h"
17
18using apps_helper::AllProfilesHaveSameAppsAsVerifier;
19using apps_helper::CopyNTPOrdinals;
20using apps_helper::DisableApp;
21using apps_helper::EnableApp;
22using apps_helper::FixNTPOrdinalCollisions;
23using apps_helper::GetAppLaunchOrdinalForApp;
24using apps_helper::HasSameAppsAsVerifier;
25using apps_helper::IncognitoDisableApp;
26using apps_helper::IncognitoEnableApp;
27using apps_helper::InstallApp;
28using apps_helper::InstallAppsPendingForSync;
29using apps_helper::InstallPlatformApp;
30using apps_helper::SetAppLaunchOrdinalForApp;
31using apps_helper::SetPageOrdinalForApp;
32using apps_helper::UninstallApp;
33
34class TwoClientAppsSyncTest : public SyncTest {
35 public:
36  TwoClientAppsSyncTest() : SyncTest(TWO_CLIENT) {}
37
38  virtual ~TwoClientAppsSyncTest() {}
39
40 private:
41  DISALLOW_COPY_AND_ASSIGN(TwoClientAppsSyncTest);
42};
43
44IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, StartWithNoApps) {
45  ASSERT_TRUE(SetupSync());
46
47  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
48}
49
50IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, StartWithSameApps) {
51  ASSERT_TRUE(SetupClients());
52
53  const int kNumApps = 5;
54  for (int i = 0; i < kNumApps; ++i) {
55    InstallApp(GetProfile(0), i);
56    InstallApp(GetProfile(1), i);
57    InstallApp(verifier(), i);
58  }
59
60  ASSERT_TRUE(SetupSync());
61
62  ASSERT_TRUE(AwaitQuiescence());
63
64  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
65}
66
67// Install some apps on both clients, some on only one client, some on only the
68// other, and sync.  Both clients should end up with all apps, and the app and
69// page ordinals should be identical.
70IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, StartWithDifferentApps) {
71  ASSERT_TRUE(SetupClients());
72
73  int i = 0;
74
75  const int kNumCommonApps = 5;
76  for (int j = 0; j < kNumCommonApps; ++i, ++j) {
77    InstallApp(GetProfile(0), i);
78    InstallApp(GetProfile(1), i);
79    InstallApp(verifier(), i);
80  }
81
82  const int kNumProfile0Apps = 10;
83  for (int j = 0; j < kNumProfile0Apps; ++i, ++j) {
84    InstallApp(GetProfile(0), i);
85    InstallApp(verifier(), i);
86    CopyNTPOrdinals(GetProfile(0), verifier(), i);
87  }
88
89  const int kNumProfile1Apps = 10;
90  for (int j = 0; j < kNumProfile1Apps; ++i, ++j) {
91    InstallApp(GetProfile(1), i);
92    InstallApp(verifier(), i);
93    CopyNTPOrdinals(GetProfile(1), verifier(), i);
94  }
95
96  const int kNumPlatformApps = 5;
97  for (int j = 0; j < kNumPlatformApps; ++i, ++j) {
98    InstallPlatformApp(GetProfile(1), i);
99    InstallPlatformApp(verifier(), i);
100    CopyNTPOrdinals(GetProfile(1), verifier(), i);
101  }
102
103  FixNTPOrdinalCollisions(verifier());
104
105  ASSERT_TRUE(SetupSync());
106
107  ASSERT_TRUE(AwaitQuiescence());
108
109  InstallAppsPendingForSync(GetProfile(0));
110  InstallAppsPendingForSync(GetProfile(1));
111
112  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
113}
114
115// Install some apps on both clients, then sync.  Then install some apps on only
116// one client, some on only the other, and then sync again.  Both clients should
117// end up with all apps, and the app and page ordinals should be identical.
118IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, InstallDifferentApps) {
119  ASSERT_TRUE(SetupClients());
120
121  int i = 0;
122
123  const int kNumCommonApps = 5;
124  for (int j = 0; j < kNumCommonApps; ++i, ++j) {
125    InstallApp(GetProfile(0), i);
126    InstallApp(GetProfile(1), i);
127    InstallApp(verifier(), i);
128  }
129
130  ASSERT_TRUE(SetupSync());
131
132  ASSERT_TRUE(AwaitQuiescence());
133
134  const int kNumProfile0Apps = 10;
135  for (int j = 0; j < kNumProfile0Apps; ++i, ++j) {
136    InstallApp(GetProfile(0), i);
137    InstallApp(verifier(), i);
138    CopyNTPOrdinals(GetProfile(0), verifier(), i);
139  }
140
141  const int kNumProfile1Apps = 10;
142  for (int j = 0; j < kNumProfile1Apps; ++i, ++j) {
143    InstallApp(GetProfile(1), i);
144    InstallApp(verifier(), i);
145    CopyNTPOrdinals(GetProfile(1), verifier(), i);
146  }
147
148  FixNTPOrdinalCollisions(verifier());
149
150  ASSERT_TRUE(AwaitQuiescence());
151
152  InstallAppsPendingForSync(GetProfile(0));
153  InstallAppsPendingForSync(GetProfile(1));
154
155  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
156}
157
158// TCM ID - 3711279.
159IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, Add) {
160  ASSERT_TRUE(SetupSync());
161  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
162
163  InstallApp(GetProfile(0), 0);
164  InstallApp(verifier(), 0);
165  ASSERT_TRUE(AwaitQuiescence());
166
167  InstallAppsPendingForSync(GetProfile(0));
168  InstallAppsPendingForSync(GetProfile(1));
169  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
170}
171
172// TCM ID - 3706267.
173IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, Uninstall) {
174  ASSERT_TRUE(SetupSync());
175  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
176
177  InstallApp(GetProfile(0), 0);
178  InstallApp(verifier(), 0);
179  ASSERT_TRUE(AwaitQuiescence());
180
181  InstallAppsPendingForSync(GetProfile(0));
182  InstallAppsPendingForSync(GetProfile(1));
183  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
184
185  UninstallApp(GetProfile(0), 0);
186  UninstallApp(verifier(), 0);
187  ASSERT_TRUE(AwaitQuiescence());
188  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
189}
190
191// Install an app on one client, then sync. Then uninstall the app on the first
192// client and sync again. Now install a new app on the first client and sync.
193// Both client should only have the second app, with identical app and page
194// ordinals.
195IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UninstallThenInstall) {
196  ASSERT_TRUE(SetupSync());
197  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
198
199  InstallApp(GetProfile(0), 0);
200  InstallApp(verifier(), 0);
201  ASSERT_TRUE(AwaitQuiescence());
202
203  InstallAppsPendingForSync(GetProfile(0));
204  InstallAppsPendingForSync(GetProfile(1));
205  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
206
207  UninstallApp(GetProfile(0), 0);
208  UninstallApp(verifier(), 0);
209  ASSERT_TRUE(AwaitQuiescence());
210  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
211
212  InstallApp(GetProfile(0), 1);
213  InstallApp(verifier(), 1);
214  ASSERT_TRUE(AwaitQuiescence());
215  InstallAppsPendingForSync(GetProfile(0));
216  InstallAppsPendingForSync(GetProfile(1));
217  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
218}
219
220// TCM ID - 3699295.
221// Flaky: http://crbug.com/226055
222IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, DISABLED_Merge) {
223  ASSERT_TRUE(SetupSync());
224  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
225
226  InstallApp(GetProfile(0), 0);
227  InstallApp(GetProfile(1), 0);
228  ASSERT_TRUE(AwaitQuiescence());
229
230  UninstallApp(GetProfile(0), 0);
231  InstallApp(GetProfile(0), 1);
232  InstallApp(verifier(), 1);
233
234  InstallApp(GetProfile(0), 2);
235  InstallApp(GetProfile(1), 2);
236  InstallApp(verifier(), 2);
237
238  InstallApp(GetProfile(1), 3);
239  InstallApp(verifier(), 3);
240
241  ASSERT_TRUE(AwaitQuiescence());
242  InstallAppsPendingForSync(GetProfile(0));
243  InstallAppsPendingForSync(GetProfile(1));
244  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
245}
246
247// TCM ID - 7723126.
248IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UpdateEnableDisableApp) {
249  ASSERT_TRUE(SetupSync());
250  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
251
252  InstallApp(GetProfile(0), 0);
253  InstallApp(GetProfile(1), 0);
254  InstallApp(verifier(), 0);
255  ASSERT_TRUE(AwaitQuiescence());
256  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
257
258  DisableApp(GetProfile(0), 0);
259  DisableApp(verifier(), 0);
260  ASSERT_TRUE(HasSameAppsAsVerifier(0));
261  ASSERT_FALSE(HasSameAppsAsVerifier(1));
262
263  ASSERT_TRUE(AwaitQuiescence());
264  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
265
266  EnableApp(GetProfile(1), 0);
267  EnableApp(verifier(), 0);
268  ASSERT_TRUE(HasSameAppsAsVerifier(1));
269  ASSERT_FALSE(HasSameAppsAsVerifier(0));
270
271  ASSERT_TRUE(AwaitQuiescence());
272  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
273}
274
275// TCM ID - 7706637.
276IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UpdateIncognitoEnableDisable) {
277  ASSERT_TRUE(SetupSync());
278  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
279
280  InstallApp(GetProfile(0), 0);
281  InstallApp(GetProfile(1), 0);
282  InstallApp(verifier(), 0);
283  ASSERT_TRUE(AwaitQuiescence());
284  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
285
286  IncognitoEnableApp(GetProfile(0), 0);
287  IncognitoEnableApp(verifier(), 0);
288  ASSERT_TRUE(HasSameAppsAsVerifier(0));
289  ASSERT_FALSE(HasSameAppsAsVerifier(1));
290
291  ASSERT_TRUE(AwaitQuiescence());
292  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
293
294  IncognitoDisableApp(GetProfile(1), 0);
295  IncognitoDisableApp(verifier(), 0);
296  ASSERT_TRUE(HasSameAppsAsVerifier(1));
297  ASSERT_FALSE(HasSameAppsAsVerifier(0));
298
299  ASSERT_TRUE(AwaitQuiescence());
300  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
301}
302
303// TCM ID - 3718276.
304IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, DisableApps) {
305  ASSERT_TRUE(SetupSync());
306  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
307
308  ASSERT_TRUE(GetClient(1)->DisableSyncForDatatype(syncer::APPS));
309  InstallApp(GetProfile(0), 0);
310  InstallApp(verifier(), 0);
311  ASSERT_TRUE(GetClient(0)->AwaitCommitActivityCompletion());
312  ASSERT_TRUE(HasSameAppsAsVerifier(0));
313  ASSERT_FALSE(HasSameAppsAsVerifier(1));
314
315  ASSERT_TRUE(GetClient(1)->EnableSyncForDatatype(syncer::APPS));
316  ASSERT_TRUE(AwaitQuiescence());
317
318  InstallAppsPendingForSync(GetProfile(0));
319  InstallAppsPendingForSync(GetProfile(1));
320  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
321}
322
323// Disable sync for the second client and then install an app on the first
324// client, then enable sync on the second client. Both clients should have the
325// same app with identical app and page ordinals.
326// TCM ID - 3720303.
327IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, DisableSync) {
328  ASSERT_TRUE(SetupSync());
329  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
330
331  ASSERT_TRUE(GetClient(1)->DisableSyncForAllDatatypes());
332  InstallApp(GetProfile(0), 0);
333  InstallApp(verifier(), 0);
334  ASSERT_TRUE(GetClient(0)->AwaitCommitActivityCompletion());
335  ASSERT_TRUE(HasSameAppsAsVerifier(0));
336  ASSERT_FALSE(HasSameAppsAsVerifier(1));
337
338  ASSERT_TRUE(GetClient(1)->EnableSyncForAllDatatypes());
339  ASSERT_TRUE(AwaitQuiescence());
340
341  InstallAppsPendingForSync(GetProfile(0));
342  InstallAppsPendingForSync(GetProfile(1));
343  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
344}
345
346// Install the same app on both clients, then sync. Change the page ordinal on
347// one client and sync. Both clients should have the updated page ordinal for
348// the app.
349IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UpdatePageOrdinal) {
350  ASSERT_TRUE(SetupSync());
351  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
352
353  syncer::StringOrdinal initial_page =
354      syncer::StringOrdinal::CreateInitialOrdinal();
355  InstallApp(GetProfile(0), 0);
356  InstallApp(GetProfile(1), 0);
357  InstallApp(verifier(), 0);
358  ASSERT_TRUE(AwaitQuiescence());
359  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
360
361  syncer::StringOrdinal second_page = initial_page.CreateAfter();
362  SetPageOrdinalForApp(GetProfile(0), 0, second_page);
363  SetPageOrdinalForApp(verifier(), 0, second_page);
364  ASSERT_TRUE(AwaitQuiescence());
365  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
366}
367
368// Install the same app on both clients, then sync. Change the app launch
369// ordinal on one client and sync. Both clients should have the updated app
370// launch ordinal for the app.
371IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UpdateAppLaunchOrdinal) {
372  ASSERT_TRUE(SetupSync());
373  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
374
375  InstallApp(GetProfile(0), 0);
376  InstallApp(GetProfile(1), 0);
377  InstallApp(verifier(), 0);
378  ASSERT_TRUE(AwaitQuiescence());
379  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
380
381  syncer::StringOrdinal initial_position =
382      GetAppLaunchOrdinalForApp(GetProfile(0), 0);
383
384  syncer::StringOrdinal second_position = initial_position.CreateAfter();
385  SetAppLaunchOrdinalForApp(GetProfile(0), 0, second_position);
386  SetAppLaunchOrdinalForApp(verifier(), 0, second_position);
387  ASSERT_TRUE(AwaitQuiescence());
388  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
389}
390
391// Adjust the CWS location within a page on the first client and sync. Adjust
392// which page the CWS appears on and sync. Both clients should have the same
393// page and app launch ordinal values for the CWS.
394IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UpdateCWSOrdinals) {
395  ASSERT_TRUE(SetupSync());
396  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
397
398  // Change the app launch ordinal.
399  syncer::StringOrdinal cws_app_launch_ordinal =
400      extensions::ExtensionPrefs::Get(GetProfile(0))
401          ->app_sorting()
402          ->GetAppLaunchOrdinal(extension_misc::kWebStoreAppId);
403  extensions::ExtensionPrefs::Get(GetProfile(0))
404      ->app_sorting()
405      ->SetAppLaunchOrdinal(extension_misc::kWebStoreAppId,
406                            cws_app_launch_ordinal.CreateAfter());
407  extensions::ExtensionPrefs::Get(verifier())
408      ->app_sorting()
409      ->SetAppLaunchOrdinal(extension_misc::kWebStoreAppId,
410                            cws_app_launch_ordinal.CreateAfter());
411  ASSERT_TRUE(AwaitQuiescence());
412  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
413
414  // Change the page ordinal.
415  syncer::StringOrdinal cws_page_ordinal =
416      extensions::ExtensionPrefs::Get(GetProfile(1))
417          ->app_sorting()
418          ->GetPageOrdinal(extension_misc::kWebStoreAppId);
419  extensions::ExtensionPrefs::Get(GetProfile(1))->app_sorting()->SetPageOrdinal(
420      extension_misc::kWebStoreAppId, cws_page_ordinal.CreateAfter());
421  extensions::ExtensionPrefs::Get(verifier())->app_sorting()->SetPageOrdinal(
422      extension_misc::kWebStoreAppId, cws_page_ordinal.CreateAfter());
423  ASSERT_TRUE(AwaitQuiescence());
424  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
425}
426
427// Adjust the launch type on the first client and sync. Both clients should
428// have the same launch type values for the CWS.
429IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UpdateLaunchType) {
430  ASSERT_TRUE(SetupSync());
431  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
432
433  // Change the launch type to window.
434  extensions::SetLaunchType(GetProfile(1)->GetExtensionService(),
435                            extension_misc::kWebStoreAppId,
436                            extensions::LAUNCH_TYPE_WINDOW);
437  extensions::SetLaunchType(verifier()->GetExtensionService(),
438                            extension_misc::kWebStoreAppId,
439                            extensions::LAUNCH_TYPE_WINDOW);
440  ASSERT_TRUE(AwaitQuiescence());
441  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
442
443  // Change the launch type to regular tab.
444  extensions::SetLaunchType(GetProfile(1)->GetExtensionService(),
445                            extension_misc::kWebStoreAppId,
446                            extensions::LAUNCH_TYPE_REGULAR);
447  ASSERT_FALSE(HasSameAppsAsVerifier(1));
448  extensions::SetLaunchType(verifier()->GetExtensionService(),
449                            extension_misc::kWebStoreAppId,
450                            extensions::LAUNCH_TYPE_REGULAR);
451  ASSERT_TRUE(AwaitQuiescence());
452  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
453}
454
455IN_PROC_BROWSER_TEST_F(TwoClientAppsSyncTest, UnexpectedLaunchType) {
456  ASSERT_TRUE(SetupSync());
457  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
458
459  extensions::SetLaunchType(GetProfile(1)->GetExtensionService(),
460                            extension_misc::kWebStoreAppId,
461                            extensions::LAUNCH_TYPE_REGULAR);
462  extensions::SetLaunchType(verifier()->GetExtensionService(),
463                            extension_misc::kWebStoreAppId,
464                            extensions::LAUNCH_TYPE_REGULAR);
465  ASSERT_TRUE(AwaitQuiescence());
466  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
467
468  const extensions::Extension* extension =
469      GetProfile(1)->GetExtensionService()->
470          GetInstalledExtension(extension_misc::kWebStoreAppId);
471  ASSERT_TRUE(extension);
472
473  ExtensionSyncService* extension_sync_service =
474      ExtensionSyncService::Get(GetProfile(1));
475
476  extensions::AppSyncData original_data(
477      extension_sync_service->GetAppSyncData(*extension));
478
479  // Create an invalid launch type and ensure it doesn't get down-synced. This
480  // simulates the case of a future launch type being added which old versions
481  // don't yet understand.
482  extensions::AppSyncData invalid_launch_type_data(
483      *extension,
484      original_data.extension_sync_data().enabled(),
485      original_data.extension_sync_data().incognito_enabled(),
486      original_data.app_launch_ordinal(),
487      original_data.page_ordinal(),
488      extensions::NUM_LAUNCH_TYPES);
489  extension_sync_service->ProcessAppSyncData(invalid_launch_type_data);
490
491  // The launch type should remain the same.
492  ASSERT_TRUE(AwaitQuiescence());
493  ASSERT_TRUE(AllProfilesHaveSameAppsAsVerifier());
494}
495
496// TODO(akalin): Add tests exercising:
497//   - Offline installation/uninstallation behavior
498//   - App-specific properties
499