Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: chrome/browser/extensions/api/storage/settings_apitest.cc

Issue 11826048: Revert 176015 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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/bind.h"
6 #include "base/json/json_writer.h"
7 #include "chrome/browser/extensions/api/storage/settings_frontend.h"
8 #include "chrome/browser/extensions/api/storage/settings_namespace.h"
9 #include "chrome/browser/extensions/api/storage/settings_sync_util.h"
10 #include "chrome/browser/extensions/extension_apitest.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/extension_test_message_listener.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/common/extensions/value_builder.h"
16 #include "chrome/test/base/ui_test_utils.h"
17 #include "sync/api/sync_change.h"
18 #include "sync/api/sync_change_processor.h"
19 #include "sync/api/sync_error_factory.h"
20 #include "sync/api/sync_error_factory_mock.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22
23 #if defined(ENABLE_CONFIGURATION_POLICY)
24 #include "chrome/browser/policy/browser_policy_connector.h"
25 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
26 #include "chrome/browser/policy/policy_bundle.h"
27 #include "chrome/browser/policy/policy_map.h"
28 #endif
29
30 namespace extensions {
31
32 using settings_namespace::FromString;
33 using settings_namespace::LOCAL;
34 using settings_namespace::MANAGED;
35 using settings_namespace::Namespace;
36 using settings_namespace::SYNC;
37 using settings_namespace::ToString;
38 using testing::Return;
39
40 namespace {
41
42 // TODO(kalman): test both EXTENSION_SETTINGS and APP_SETTINGS.
43 const syncer::ModelType kModelType = syncer::EXTENSION_SETTINGS;
44
45 // The managed_storage extension has a key defined in its manifest, so that
46 // its extension ID is well-known and the policy system can push policies for
47 // the extension.
48 const char kManagedStorageExtensionId[] = "kjmkgkdkpedkejedfhmfcenooemhbpbo";
49
50 class NoopSyncChangeProcessor : public syncer::SyncChangeProcessor {
51 public:
52 virtual syncer::SyncError ProcessSyncChanges(
53 const tracked_objects::Location& from_here,
54 const syncer::SyncChangeList& change_list) OVERRIDE {
55 return syncer::SyncError();
56 }
57
58 virtual ~NoopSyncChangeProcessor() {};
59 };
60
61 class SyncChangeProcessorDelegate : public syncer::SyncChangeProcessor {
62 public:
63 explicit SyncChangeProcessorDelegate(syncer::SyncChangeProcessor* recipient)
64 : recipient_(recipient) {
65 DCHECK(recipient_);
66 }
67 virtual ~SyncChangeProcessorDelegate() {}
68
69 // syncer::SyncChangeProcessor implementation.
70 virtual syncer::SyncError ProcessSyncChanges(
71 const tracked_objects::Location& from_here,
72 const syncer::SyncChangeList& change_list) OVERRIDE {
73 return recipient_->ProcessSyncChanges(from_here, change_list);
74 }
75
76 private:
77 // The recipient of all sync changes.
78 syncer::SyncChangeProcessor* recipient_;
79
80 DISALLOW_COPY_AND_ASSIGN(SyncChangeProcessorDelegate);
81 };
82
83 } // namespace
84
85 class ExtensionSettingsApiTest : public ExtensionApiTest {
86 protected:
87 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
88 ExtensionApiTest::SetUpInProcessBrowserTestFixture();
89
90 #if defined(ENABLE_CONFIGURATION_POLICY)
91 EXPECT_CALL(policy_provider_, IsInitializationComplete())
92 .WillRepeatedly(Return(true));
93 policy::BrowserPolicyConnector::SetPolicyProviderForTesting(
94 &policy_provider_);
95 #endif
96 }
97
98 void ReplyWhenSatisfied(
99 Namespace settings_namespace,
100 const std::string& normal_action,
101 const std::string& incognito_action) {
102 MaybeLoadAndReplyWhenSatisfied(
103 settings_namespace, normal_action, incognito_action, NULL, false);
104 }
105
106 const Extension* LoadAndReplyWhenSatisfied(
107 Namespace settings_namespace,
108 const std::string& normal_action,
109 const std::string& incognito_action,
110 const std::string& extension_dir) {
111 return MaybeLoadAndReplyWhenSatisfied(
112 settings_namespace,
113 normal_action,
114 incognito_action,
115 &extension_dir,
116 false);
117 }
118
119 void FinalReplyWhenSatisfied(
120 Namespace settings_namespace,
121 const std::string& normal_action,
122 const std::string& incognito_action) {
123 MaybeLoadAndReplyWhenSatisfied(
124 settings_namespace, normal_action, incognito_action, NULL, true);
125 }
126
127 void InitSync(syncer::SyncChangeProcessor* sync_processor) {
128 MessageLoop::current()->RunUntilIdle();
129 InitSyncWithSyncableService(
130 sync_processor,
131 browser()->profile()->GetExtensionService()->settings_frontend()->
132 GetBackendForSync(kModelType));
133 }
134
135 void SendChanges(const syncer::SyncChangeList& change_list) {
136 MessageLoop::current()->RunUntilIdle();
137 SendChangesToSyncableService(
138 change_list,
139 browser()->profile()->GetExtensionService()->settings_frontend()->
140 GetBackendForSync(kModelType));
141 }
142
143 #if defined(ENABLE_CONFIGURATION_POLICY)
144 void SetPolicies(const base::DictionaryValue& policies) {
145 scoped_ptr<policy::PolicyBundle> bundle(new policy::PolicyBundle());
146 policy::PolicyMap& policy_map = bundle->Get(
147 policy::POLICY_DOMAIN_EXTENSIONS, kManagedStorageExtensionId);
148 policy_map.LoadFrom(
149 &policies, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER);
150 policy_provider_.UpdatePolicy(bundle.Pass());
151 }
152 #endif
153
154 private:
155 const Extension* MaybeLoadAndReplyWhenSatisfied(
156 Namespace settings_namespace,
157 const std::string& normal_action,
158 const std::string& incognito_action,
159 // May be NULL to imply not loading the extension.
160 const std::string* extension_dir,
161 bool is_final_action) {
162 ExtensionTestMessageListener listener("waiting", true);
163 ExtensionTestMessageListener listener_incognito("waiting_incognito", true);
164
165 // Only load the extension after the listeners have been set up, to avoid
166 // initialisation race conditions.
167 const Extension* extension = NULL;
168 if (extension_dir) {
169 extension = LoadExtensionIncognito(
170 test_data_dir_.AppendASCII("settings").AppendASCII(*extension_dir));
171 EXPECT_TRUE(extension);
172 }
173
174 EXPECT_TRUE(listener.WaitUntilSatisfied());
175 EXPECT_TRUE(listener_incognito.WaitUntilSatisfied());
176
177 listener.Reply(
178 CreateMessage(settings_namespace, normal_action, is_final_action));
179 listener_incognito.Reply(
180 CreateMessage(settings_namespace, incognito_action, is_final_action));
181 return extension;
182 }
183
184 std::string CreateMessage(
185 Namespace settings_namespace,
186 const std::string& action,
187 bool is_final_action) {
188 scoped_ptr<DictionaryValue> message(new DictionaryValue());
189 message->SetString("namespace", ToString(settings_namespace));
190 message->SetString("action", action);
191 message->SetBoolean("isFinalAction", is_final_action);
192 std::string message_json;
193 base::JSONWriter::Write(message.get(), &message_json);
194 return message_json;
195 }
196
197 void InitSyncWithSyncableService(
198 syncer::SyncChangeProcessor* sync_processor,
199 syncer::SyncableService* settings_service) {
200 EXPECT_FALSE(settings_service->MergeDataAndStartSyncing(
201 kModelType,
202 syncer::SyncDataList(),
203 scoped_ptr<syncer::SyncChangeProcessor>(
204 new SyncChangeProcessorDelegate(sync_processor)),
205 scoped_ptr<syncer::SyncErrorFactory>(
206 new syncer::SyncErrorFactoryMock())).error().IsSet());
207 }
208
209 void SendChangesToSyncableService(
210 const syncer::SyncChangeList& change_list,
211 syncer::SyncableService* settings_service) {
212 EXPECT_FALSE(
213 settings_service->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
214 }
215
216 protected:
217 #if defined(ENABLE_CONFIGURATION_POLICY)
218 policy::MockConfigurationPolicyProvider policy_provider_;
219 #endif
220 };
221
222 IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, SimpleTest) {
223 ASSERT_TRUE(RunExtensionTest("settings/simple_test")) << message_;
224 }
225
226 // Structure of this test taken from IncognitoSplitMode.
227 // Note that only split-mode incognito is tested, because spanning mode
228 // incognito looks the same as normal mode when the only API activity comes
229 // from background pages.
230 IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, SplitModeIncognito) {
231 // We need 2 ResultCatchers because we'll be running the same test in both
232 // regular and incognito mode.
233 ResultCatcher catcher, catcher_incognito;
234 catcher.RestrictToProfile(browser()->profile());
235 catcher_incognito.RestrictToProfile(
236 browser()->profile()->GetOffTheRecordProfile());
237
238 LoadAndReplyWhenSatisfied(SYNC,
239 "assertEmpty", "assertEmpty", "split_incognito");
240 ReplyWhenSatisfied(SYNC, "noop", "setFoo");
241 ReplyWhenSatisfied(SYNC, "assertFoo", "assertFoo");
242 ReplyWhenSatisfied(SYNC, "clear", "noop");
243 ReplyWhenSatisfied(SYNC, "assertEmpty", "assertEmpty");
244 ReplyWhenSatisfied(SYNC, "setFoo", "noop");
245 ReplyWhenSatisfied(SYNC, "assertFoo", "assertFoo");
246 ReplyWhenSatisfied(SYNC, "noop", "removeFoo");
247 FinalReplyWhenSatisfied(SYNC, "assertEmpty", "assertEmpty");
248
249 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
250 EXPECT_TRUE(catcher_incognito.GetNextResult()) << catcher.message();
251 }
252
253 IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest,
254 OnChangedNotificationsBetweenBackgroundPages) {
255 // We need 2 ResultCatchers because we'll be running the same test in both
256 // regular and incognito mode.
257 ResultCatcher catcher, catcher_incognito;
258 catcher.RestrictToProfile(browser()->profile());
259 catcher_incognito.RestrictToProfile(
260 browser()->profile()->GetOffTheRecordProfile());
261
262 LoadAndReplyWhenSatisfied(SYNC,
263 "assertNoNotifications", "assertNoNotifications", "split_incognito");
264 ReplyWhenSatisfied(SYNC, "noop", "setFoo");
265 ReplyWhenSatisfied(SYNC,
266 "assertAddFooNotification", "assertAddFooNotification");
267 ReplyWhenSatisfied(SYNC, "clearNotifications", "clearNotifications");
268 ReplyWhenSatisfied(SYNC, "removeFoo", "noop");
269 FinalReplyWhenSatisfied(SYNC,
270 "assertDeleteFooNotification", "assertDeleteFooNotification");
271
272 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
273 EXPECT_TRUE(catcher_incognito.GetNextResult()) << catcher.message();
274 }
275
276 IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest,
277 SyncAndLocalAreasAreSeparate) {
278 // We need 2 ResultCatchers because we'll be running the same test in both
279 // regular and incognito mode.
280 ResultCatcher catcher, catcher_incognito;
281 catcher.RestrictToProfile(browser()->profile());
282 catcher_incognito.RestrictToProfile(
283 browser()->profile()->GetOffTheRecordProfile());
284
285 LoadAndReplyWhenSatisfied(SYNC,
286 "assertNoNotifications", "assertNoNotifications", "split_incognito");
287
288 ReplyWhenSatisfied(SYNC, "noop", "setFoo");
289 ReplyWhenSatisfied(SYNC, "assertFoo", "assertFoo");
290 ReplyWhenSatisfied(SYNC,
291 "assertAddFooNotification", "assertAddFooNotification");
292 ReplyWhenSatisfied(LOCAL, "assertEmpty", "assertEmpty");
293 ReplyWhenSatisfied(LOCAL, "assertNoNotifications", "assertNoNotifications");
294
295 ReplyWhenSatisfied(SYNC, "clearNotifications", "clearNotifications");
296
297 ReplyWhenSatisfied(LOCAL, "setFoo", "noop");
298 ReplyWhenSatisfied(LOCAL, "assertFoo", "assertFoo");
299 ReplyWhenSatisfied(LOCAL,
300 "assertAddFooNotification", "assertAddFooNotification");
301 ReplyWhenSatisfied(SYNC, "assertFoo", "assertFoo");
302 ReplyWhenSatisfied(SYNC, "assertNoNotifications", "assertNoNotifications");
303
304 ReplyWhenSatisfied(LOCAL, "clearNotifications", "clearNotifications");
305
306 ReplyWhenSatisfied(LOCAL, "noop", "removeFoo");
307 ReplyWhenSatisfied(LOCAL, "assertEmpty", "assertEmpty");
308 ReplyWhenSatisfied(LOCAL,
309 "assertDeleteFooNotification", "assertDeleteFooNotification");
310 ReplyWhenSatisfied(SYNC, "assertFoo", "assertFoo");
311 ReplyWhenSatisfied(SYNC, "assertNoNotifications", "assertNoNotifications");
312
313 ReplyWhenSatisfied(LOCAL, "clearNotifications", "clearNotifications");
314
315 ReplyWhenSatisfied(SYNC, "removeFoo", "noop");
316 ReplyWhenSatisfied(SYNC, "assertEmpty", "assertEmpty");
317 ReplyWhenSatisfied(SYNC,
318 "assertDeleteFooNotification", "assertDeleteFooNotification");
319 ReplyWhenSatisfied(LOCAL, "assertNoNotifications", "assertNoNotifications");
320 FinalReplyWhenSatisfied(LOCAL, "assertEmpty", "assertEmpty");
321
322 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
323 EXPECT_TRUE(catcher_incognito.GetNextResult()) << catcher.message();
324 }
325
326 // Disabled, see crbug.com/101110
327 IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest,
328 DISABLED_OnChangedNotificationsFromSync) {
329 // We need 2 ResultCatchers because we'll be running the same test in both
330 // regular and incognito mode.
331 ResultCatcher catcher, catcher_incognito;
332 catcher.RestrictToProfile(browser()->profile());
333 catcher_incognito.RestrictToProfile(
334 browser()->profile()->GetOffTheRecordProfile());
335
336 const Extension* extension =
337 LoadAndReplyWhenSatisfied(SYNC,
338 "assertNoNotifications", "assertNoNotifications", "split_incognito");
339 const std::string& extension_id = extension->id();
340
341 NoopSyncChangeProcessor sync_processor;
342 InitSync(&sync_processor);
343
344 // Set "foo" to "bar" via sync.
345 syncer::SyncChangeList sync_changes;
346 StringValue bar("bar");
347 sync_changes.push_back(settings_sync_util::CreateAdd(
348 extension_id, "foo", bar, kModelType));
349 SendChanges(sync_changes);
350
351 ReplyWhenSatisfied(SYNC,
352 "assertAddFooNotification", "assertAddFooNotification");
353 ReplyWhenSatisfied(SYNC, "clearNotifications", "clearNotifications");
354
355 // Remove "foo" via sync.
356 sync_changes.clear();
357 sync_changes.push_back(settings_sync_util::CreateDelete(
358 extension_id, "foo", kModelType));
359 SendChanges(sync_changes);
360
361 FinalReplyWhenSatisfied(SYNC,
362 "assertDeleteFooNotification", "assertDeleteFooNotification");
363
364 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
365 EXPECT_TRUE(catcher_incognito.GetNextResult()) << catcher.message();
366 }
367
368 // Disabled, see crbug.com/101110
369 //
370 // TODO: boring test, already done in the unit tests. What we really should be
371 // be testing is that the areas don't overlap.
372 IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest,
373 DISABLED_OnChangedNotificationsFromSyncNotSentToLocal) {
374 // We need 2 ResultCatchers because we'll be running the same test in both
375 // regular and incognito mode.
376 ResultCatcher catcher, catcher_incognito;
377 catcher.RestrictToProfile(browser()->profile());
378 catcher_incognito.RestrictToProfile(
379 browser()->profile()->GetOffTheRecordProfile());
380
381 const Extension* extension =
382 LoadAndReplyWhenSatisfied(LOCAL,
383 "assertNoNotifications", "assertNoNotifications", "split_incognito");
384 const std::string& extension_id = extension->id();
385
386 NoopSyncChangeProcessor sync_processor;
387 InitSync(&sync_processor);
388
389 // Set "foo" to "bar" via sync.
390 syncer::SyncChangeList sync_changes;
391 StringValue bar("bar");
392 sync_changes.push_back(settings_sync_util::CreateAdd(
393 extension_id, "foo", bar, kModelType));
394 SendChanges(sync_changes);
395
396 ReplyWhenSatisfied(LOCAL, "assertNoNotifications", "assertNoNotifications");
397
398 // Remove "foo" via sync.
399 sync_changes.clear();
400 sync_changes.push_back(settings_sync_util::CreateDelete(
401 extension_id, "foo", kModelType));
402 SendChanges(sync_changes);
403
404 FinalReplyWhenSatisfied(LOCAL,
405 "assertNoNotifications", "assertNoNotifications");
406
407 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
408 EXPECT_TRUE(catcher_incognito.GetNextResult()) << catcher.message();
409 }
410
411 IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, IsStorageEnabled) {
412 SettingsFrontend* frontend =
413 browser()->profile()->GetExtensionService()->settings_frontend();
414 EXPECT_TRUE(frontend->IsStorageEnabled(LOCAL));
415 EXPECT_TRUE(frontend->IsStorageEnabled(SYNC));
416
417 #if defined(ENABLE_CONFIGURATION_POLICY)
418 EXPECT_TRUE(frontend->IsStorageEnabled(MANAGED));
419 #else
420 EXPECT_FALSE(frontend->IsStorageEnabled(MANAGED));
421 #endif
422 }
423
424 #if defined(ENABLE_CONFIGURATION_POLICY)
425
426 IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, ManagedStorage) {
427 // Set policies for the test extension.
428 scoped_ptr<base::DictionaryValue> policy = extensions::DictionaryBuilder()
429 .Set("string-policy", "value")
430 .Set("int-policy", -123)
431 .Set("double-policy", 456e7)
432 .SetBoolean("boolean-policy", true)
433 .Set("list-policy", extensions::ListBuilder()
434 .Append("one")
435 .Append("two")
436 .Append("three"))
437 .Set("dict-policy", extensions::DictionaryBuilder()
438 .Set("list", extensions::ListBuilder()
439 .Append(extensions::DictionaryBuilder()
440 .Set("one", 1)
441 .Set("two", 2))
442 .Append(extensions::DictionaryBuilder()
443 .Set("three", 3))))
444 .Build();
445 SetPolicies(*policy);
446 // Now run the extension.
447 ASSERT_TRUE(RunExtensionTest("settings/managed_storage")) << message_;
448 }
449
450 IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, PRE_ManagedStorageEvents) {
451 ResultCatcher catcher;
452
453 // This test starts without any test extensions installed.
454 EXPECT_FALSE(GetSingleLoadedExtension());
455 message_.clear();
456
457 // Set policies for the test extension.
458 scoped_ptr<base::DictionaryValue> policy = extensions::DictionaryBuilder()
459 .Set("constant-policy", "aaa")
460 .Set("changes-policy", "bbb")
461 .Set("deleted-policy", "ccc")
462 .Build();
463 SetPolicies(*policy);
464
465 ExtensionTestMessageListener ready_listener("ready", false);
466 // Load the extension to install the event listener.
467 const Extension* extension = LoadExtension(
468 test_data_dir_.AppendASCII("settings/managed_storage_events"));
469 ASSERT_TRUE(extension);
470 // Wait until the extension sends the "ready" message.
471 ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
472
473 // Now change the policies and wait until the extension is done.
474 policy = extensions::DictionaryBuilder()
475 .Set("constant-policy", "aaa")
476 .Set("changes-policy", "ddd")
477 .Set("new-policy", "eee")
478 .Build();
479 SetPolicies(*policy);
480 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
481 }
482
483 // TODO(joaodasilva): This test times out on Vista. http://crbug.com/166261
484 #if !defined(OS_WIN)
485 IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, ManagedStorageEvents) {
486 // This test runs after PRE_ManagedStorageEvents without having deleted the
487 // profile, so the extension is still around. While the browser restarted the
488 // policy went back to the empty default, and so the extension should receive
489 // the corresponding change events.
490
491 ResultCatcher catcher;
492
493 // Verify that the test extension is still installed.
494 const Extension* extension = GetSingleLoadedExtension();
495 ASSERT_TRUE(extension);
496 EXPECT_EQ(kManagedStorageExtensionId, extension->id());
497
498 // Running the test again skips the onInstalled callback, and just triggers
499 // the onChanged notification.
500 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
501 }
502 #endif // !defined(OS_WIN)
503
504 #endif // defined(ENABLE_CONFIGURATION_POLICY)
505
506 IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, ManagedStorageDisabled) {
507 // Disable the 'managed' namespace. This is redundant when
508 // ENABLE_CONFIGURATION_POLICY is not defined.
509 SettingsFrontend* frontend =
510 browser()->profile()->GetExtensionService()->settings_frontend();
511 frontend->DisableStorageForTesting(MANAGED);
512 EXPECT_FALSE(frontend->IsStorageEnabled(MANAGED));
513 // Now run the extension.
514 ASSERT_TRUE(RunExtensionTest("settings/managed_storage_disabled"))
515 << message_;
516 }
517
518 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/storage/setting_sync_data.cc ('k') | chrome/browser/extensions/api/storage/settings_backend.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698