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