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