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/macros.h"
6 #include "base/strings/stringprintf.h"
7 #include "chrome/browser/profiles/profile.h"
8 #include "chrome/browser/sync/test/integration/apps_helper.h"
9 #include "chrome/browser/sync/test/integration/extension_settings_helper.h"
10 #include "chrome/browser/sync/test/integration/extensions_helper.h"
11 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
12 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
13 #include "chrome/browser/sync/test/integration/sync_test.h"
14 #include "content/public/test/browser_test.h"
15 
16 #if defined(OS_CHROMEOS)
17 #include "chrome/browser/sync/test/integration/os_sync_test.h"
18 #include "chromeos/constants/chromeos_features.h"
19 #endif
20 
21 namespace {
22 
23 using apps_helper::InstallHostedAppForAllProfiles;
24 using extension_settings_helper::AllExtensionSettingsSameAsVerifier;
25 using extension_settings_helper::SetExtensionSettings;
26 using extension_settings_helper::SetExtensionSettingsForAllProfiles;
27 using extensions_helper::InstallExtensionForAllProfiles;
28 using sync_datatype_helper::test;
29 
30 // Generic mutations done after the initial setup of all tests. Note that
31 // unfortuately we can't test existing configurations of the sync server since
32 // the tests don't support that.
MutateSomeSettings(int seed,const std::string & extension0,const std::string & extension1,const std::string & extension2)33 void MutateSomeSettings(
34     int seed,  // used to modify the mutation values, not keys.
35     const std::string& extension0,
36     const std::string& extension1,
37     const std::string& extension2) {
38   {
39     // Write to extension0 from profile 0 but not profile 1.
40     base::DictionaryValue settings;
41     settings.SetString("asdf", base::StringPrintf("asdfasdf-%d", seed));
42     SetExtensionSettings(test()->verifier(),    extension0, settings);
43     SetExtensionSettings(test()->GetProfile(0), extension0, settings);
44   }
45   {
46     // Write the same data to extension1 from both profiles.
47     base::DictionaryValue settings;
48     settings.SetString("asdf", base::StringPrintf("asdfasdf-%d", seed));
49     settings.SetString("qwer", base::StringPrintf("qwerqwer-%d", seed));
50     SetExtensionSettingsForAllProfiles(extension1, settings);
51   }
52   {
53     // Write different data to extension2 from each profile.
54     base::DictionaryValue settings0;
55     settings0.SetString("zxcv", base::StringPrintf("zxcvzxcv-%d", seed));
56     SetExtensionSettings(test()->verifier(),    extension2, settings0);
57     SetExtensionSettings(test()->GetProfile(0), extension2, settings0);
58 
59     base::DictionaryValue settings1;
60     settings1.SetString("1324", base::StringPrintf("12341234-%d", seed));
61     settings1.SetString("5687", base::StringPrintf("56785678-%d", seed));
62     SetExtensionSettings(test()->verifier(),    extension2, settings1);
63     SetExtensionSettings(test()->GetProfile(1), extension2, settings1);
64   }
65 }
66 
67 class TwoClientExtensionSettingsAndAppSettingsSyncTest : public SyncTest {
68  public:
TwoClientExtensionSettingsAndAppSettingsSyncTest()69   TwoClientExtensionSettingsAndAppSettingsSyncTest() : SyncTest(TWO_CLIENT) {}
70   ~TwoClientExtensionSettingsAndAppSettingsSyncTest() override = default;
71 
UseVerifier()72   bool UseVerifier() override {
73     // TODO(crbug.com/1137735): rewrite tests to not use verifier.
74     return true;
75   }
76 };
77 
78 // For three independent extensions:
79 //
80 // Set up each extension with the same (but not necessarily empty) settings for
81 // all profiles, start syncing, add some new settings, sync, mutate those
82 // settings, sync.
StartWithSameSettingsTest(const std::string & extension0,const std::string & extension1,const std::string & extension2)83 testing::AssertionResult StartWithSameSettingsTest(
84     const std::string& extension0,
85     const std::string& extension1,
86     const std::string& extension2) {
87   {
88     // Leave extension0 empty.
89   }
90   {
91     base::DictionaryValue settings;
92     settings.SetString("foo", "bar");
93     SetExtensionSettingsForAllProfiles(extension1, settings);
94   }
95   {
96     base::DictionaryValue settings;
97     settings.SetString("foo", "bar");
98     settings.SetString("baz", "qux");
99     SetExtensionSettingsForAllProfiles(extension2, settings);
100   }
101 
102   if (!test()->SetupSync())
103     return testing::AssertionFailure();
104   if (!test()->AwaitQuiescence())
105     return testing::AssertionFailure();
106   if (!AllExtensionSettingsSameAsVerifier())
107     return testing::AssertionFailure();
108 
109   MutateSomeSettings(0, extension0, extension1, extension2);
110   if (!test()->AwaitQuiescence())
111     return testing::AssertionFailure();
112   if (!AllExtensionSettingsSameAsVerifier())
113     return testing::AssertionFailure();
114 
115   MutateSomeSettings(1, extension0, extension1, extension2);
116   if (!test()->AwaitQuiescence())
117     return testing::AssertionFailure();
118   if (!AllExtensionSettingsSameAsVerifier())
119     return testing::AssertionFailure();
120 
121   return testing::AssertionSuccess();
122 }
123 
124 // For three independent extensions:
125 //
126 // Set up each extension with different settings for each profile, start
127 // syncing, add some settings, sync, mutate those settings, sync, have a no-op
128 // (non-)change to those settings, sync, mutate again, sync.
StartWithDifferentSettingsTest(const std::string & extension0,const std::string & extension1,const std::string & extension2)129 testing::AssertionResult StartWithDifferentSettingsTest(
130     const std::string& extension0,
131     const std::string& extension1,
132     const std::string& extension2) {
133   {
134     // Leave extension0 empty again for no particular reason other than it's
135     // the only remaining unique combination given the other 2 tests have
136     // (empty, nonempty) and (nonempty, nonempty) configurations. We can't test
137     // (nonempty, nonempty) because the merging will provide unpredictable
138     // results, so test (empty, empty).
139   }
140   {
141     base::DictionaryValue settings;
142     settings.SetString("foo", "bar");
143     SetExtensionSettings(test()->verifier(), extension1, settings);
144     SetExtensionSettings(test()->GetProfile(0), extension1, settings);
145   }
146   {
147     base::DictionaryValue settings;
148     settings.SetString("foo", "bar");
149     settings.SetString("baz", "qux");
150     SetExtensionSettings(test()->verifier(), extension2, settings);
151     SetExtensionSettings(test()->GetProfile(1), extension2, settings);
152   }
153 
154   if (!test()->SetupSync())
155     return testing::AssertionFailure();
156   if (!test()->AwaitQuiescence())
157     return testing::AssertionFailure();
158   if (!AllExtensionSettingsSameAsVerifier())
159     return testing::AssertionFailure();
160 
161   MutateSomeSettings(2, extension0, extension1, extension2);
162   if (!test()->AwaitQuiescence())
163     return testing::AssertionFailure();
164   if (!AllExtensionSettingsSameAsVerifier())
165     return testing::AssertionFailure();
166 
167   MutateSomeSettings(3, extension0, extension1, extension2);
168   if (!test()->AwaitQuiescence())
169     return testing::AssertionFailure();
170   if (!AllExtensionSettingsSameAsVerifier())
171     return testing::AssertionFailure();
172 
173   // Test a round of no-ops once, for sanity. Ideally we'd want to assert that
174   // this causes no sync activity, but that sounds tricky.
175   MutateSomeSettings(3, extension0, extension1, extension2);
176   if (!test()->AwaitQuiescence())
177     return testing::AssertionFailure();
178   if (!AllExtensionSettingsSameAsVerifier())
179     return testing::AssertionFailure();
180 
181   MutateSomeSettings(4, extension0, extension1, extension2);
182   if (!test()->AwaitQuiescence())
183     return testing::AssertionFailure();
184   if (!AllExtensionSettingsSameAsVerifier())
185     return testing::AssertionFailure();
186 
187   return testing::AssertionSuccess();
188 }
189 
IN_PROC_BROWSER_TEST_F(TwoClientExtensionSettingsAndAppSettingsSyncTest,ExtensionsStartWithSameSettings)190 IN_PROC_BROWSER_TEST_F(TwoClientExtensionSettingsAndAppSettingsSyncTest,
191                        ExtensionsStartWithSameSettings) {
192   ASSERT_TRUE(SetupClients());
193   ASSERT_PRED3(StartWithSameSettingsTest, InstallExtensionForAllProfiles(0),
194                InstallExtensionForAllProfiles(1),
195                InstallExtensionForAllProfiles(2));
196 }
197 
IN_PROC_BROWSER_TEST_F(TwoClientExtensionSettingsAndAppSettingsSyncTest,AppsStartWithSameSettings)198 IN_PROC_BROWSER_TEST_F(TwoClientExtensionSettingsAndAppSettingsSyncTest,
199                        AppsStartWithSameSettings) {
200   ASSERT_TRUE(SetupClients());
201   ASSERT_PRED3(StartWithSameSettingsTest, InstallHostedAppForAllProfiles(0),
202                InstallHostedAppForAllProfiles(1),
203                InstallHostedAppForAllProfiles(2));
204 }
205 
IN_PROC_BROWSER_TEST_F(TwoClientExtensionSettingsAndAppSettingsSyncTest,ExtensionsStartWithDifferentSettings)206 IN_PROC_BROWSER_TEST_F(TwoClientExtensionSettingsAndAppSettingsSyncTest,
207                        ExtensionsStartWithDifferentSettings) {
208   ASSERT_TRUE(SetupClients());
209   ASSERT_PRED3(
210       StartWithDifferentSettingsTest, InstallExtensionForAllProfiles(0),
211       InstallExtensionForAllProfiles(1), InstallExtensionForAllProfiles(2));
212 }
213 
IN_PROC_BROWSER_TEST_F(TwoClientExtensionSettingsAndAppSettingsSyncTest,AppsStartWithDifferentSettings)214 IN_PROC_BROWSER_TEST_F(TwoClientExtensionSettingsAndAppSettingsSyncTest,
215                        AppsStartWithDifferentSettings) {
216   ASSERT_TRUE(SetupClients());
217   ASSERT_PRED3(
218       StartWithDifferentSettingsTest, InstallHostedAppForAllProfiles(0),
219       InstallHostedAppForAllProfiles(1), InstallHostedAppForAllProfiles(2));
220 }
221 
222 #if defined(OS_CHROMEOS)
223 // Tests for SplitSettingsSync, which uses a different ModelTypeController for
224 // syncer::APP_SETTINGS.
225 class TwoClientAppSettingsOsSyncTest : public OsSyncTest {
226  public:
TwoClientAppSettingsOsSyncTest()227   TwoClientAppSettingsOsSyncTest() : OsSyncTest(TWO_CLIENT) {}
228   ~TwoClientAppSettingsOsSyncTest() override = default;
229 
UseVerifier()230   bool UseVerifier() override {
231     // TODO(crbug.com/1137735): rewrite tests to not use verifier.
232     return true;
233   }
234 };
235 
IN_PROC_BROWSER_TEST_F(TwoClientAppSettingsOsSyncTest,AppsStartWithSameSettings)236 IN_PROC_BROWSER_TEST_F(TwoClientAppSettingsOsSyncTest,
237                        AppsStartWithSameSettings) {
238   ASSERT_TRUE(chromeos::features::IsSplitSettingsSyncEnabled());
239   ASSERT_TRUE(SetupClients());
240   ASSERT_PRED3(StartWithSameSettingsTest, InstallHostedAppForAllProfiles(0),
241                InstallHostedAppForAllProfiles(1),
242                InstallHostedAppForAllProfiles(2));
243 }
244 
IN_PROC_BROWSER_TEST_F(TwoClientAppSettingsOsSyncTest,AppsStartWithDifferentSettings)245 IN_PROC_BROWSER_TEST_F(TwoClientAppSettingsOsSyncTest,
246                        AppsStartWithDifferentSettings) {
247   ASSERT_TRUE(chromeos::features::IsSplitSettingsSyncEnabled());
248   ASSERT_TRUE(SetupClients());
249   ASSERT_PRED3(
250       StartWithDifferentSettingsTest, InstallHostedAppForAllProfiles(0),
251       InstallHostedAppForAllProfiles(1), InstallHostedAppForAllProfiles(2));
252 }
253 #endif  // defined(OS_CHROMEOS)
254 
255 }  // namespace
256