OLD | NEW |
| (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/extension_apitest.h" | |
8 #include "chrome/browser/extensions/extension_service.h" | |
9 #include "chrome/browser/extensions/extension_test_message_listener.h" | |
10 #include "chrome/browser/extensions/settings/settings_frontend.h" | |
11 #include "chrome/browser/extensions/settings/settings_namespace.h" | |
12 #include "chrome/browser/extensions/settings/settings_sync_util.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 IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, ManagedStorageEvents) { | |
484 // This test runs after PRE_ManagedStorageEvents without having deleted the | |
485 // profile, so the extension is still around. While the browser restarted the | |
486 // policy went back to the empty default, and so the extension should receive | |
487 // the corresponding change events. | |
488 | |
489 ResultCatcher catcher; | |
490 | |
491 // Verify that the test extension is still installed. | |
492 const Extension* extension = GetSingleLoadedExtension(); | |
493 ASSERT_TRUE(extension); | |
494 EXPECT_EQ(kManagedStorageExtensionId, extension->id()); | |
495 | |
496 // Running the test again skips the onInstalled callback, and just triggers | |
497 // the onChanged notification. | |
498 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); | |
499 } | |
500 | |
501 #endif // defined(ENABLE_CONFIGURATION_POLICY) | |
502 | |
503 IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, ManagedStorageDisabled) { | |
504 // Disable the 'managed' namespace. This is redundant when | |
505 // ENABLE_CONFIGURATION_POLICY is not defined. | |
506 SettingsFrontend* frontend = | |
507 browser()->profile()->GetExtensionService()->settings_frontend(); | |
508 frontend->DisableStorageForTesting(MANAGED); | |
509 EXPECT_FALSE(frontend->IsStorageEnabled(MANAGED)); | |
510 // Now run the extension. | |
511 ASSERT_TRUE(RunExtensionTest("settings/managed_storage_disabled")) | |
512 << message_; | |
513 } | |
514 | |
515 } // namespace extensions | |
OLD | NEW |