| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/bind.h" |
| #include "base/json/json_writer.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/run_loop.h" |
| #include "base/values.h" |
| #include "chrome/browser/extensions/api/storage/settings_sync_util.h" |
| #include "chrome/browser/extensions/extension_apitest.h" |
| #include "chrome/browser/extensions/extension_system_factory.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "extensions/browser/api/storage/settings_namespace.h" |
| #include "extensions/browser/api/storage/storage_frontend.h" |
| #include "extensions/browser/extension_system.h" |
| #include "extensions/common/value_builder.h" |
| #include "extensions/test/extension_test_message_listener.h" |
| #include "extensions/test/result_catcher.h" |
| #include "sync/api/fake_sync_change_processor.h" |
| #include "sync/api/sync_change.h" |
| #include "sync/api/sync_change_processor.h" |
| #include "sync/api/sync_change_processor_wrapper_for_test.h" |
| #include "sync/api/sync_error_factory.h" |
| #include "sync/api/sync_error_factory_mock.h" |
| #include "sync/api/syncable_service.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| |
| #if defined(ENABLE_CONFIGURATION_POLICY) |
| #include "chrome/browser/policy/schema_registry_service.h" |
| #include "chrome/browser/policy/schema_registry_service_factory.h" |
| #include "components/policy/core/browser/browser_policy_connector.h" |
| #include "components/policy/core/common/mock_configuration_policy_provider.h" |
| #include "components/policy/core/common/policy_bundle.h" |
| #include "components/policy/core/common/policy_map.h" |
| #include "components/policy/core/common/policy_namespace.h" |
| #include "components/policy/core/common/schema.h" |
| #include "components/policy/core/common/schema_map.h" |
| #include "components/policy/core/common/schema_registry.h" |
| #endif |
| |
| namespace extensions { |
| |
| using settings_namespace::LOCAL; |
| using settings_namespace::MANAGED; |
| using settings_namespace::Namespace; |
| using settings_namespace::SYNC; |
| using settings_namespace::ToString; |
| using testing::Mock; |
| using testing::Return; |
| using testing::_; |
| |
| namespace { |
| |
| // TODO(kalman): test both EXTENSION_SETTINGS and APP_SETTINGS. |
| const syncer::ModelType kModelType = syncer::EXTENSION_SETTINGS; |
| |
| // The managed_storage extension has a key defined in its manifest, so that |
| // its extension ID is well-known and the policy system can push policies for |
| // the extension. |
| const char kManagedStorageExtensionId[] = "kjmkgkdkpedkejedfhmfcenooemhbpbo"; |
| |
| class MockSchemaRegistryObserver : public policy::SchemaRegistry::Observer { |
| public: |
| MockSchemaRegistryObserver() {} |
| virtual ~MockSchemaRegistryObserver() {} |
| |
| MOCK_METHOD1(OnSchemaRegistryUpdated, void(bool)); |
| MOCK_METHOD0(OnSchemaRegistryReady, void()); |
| }; |
| |
| } // namespace |
| |
| class ExtensionSettingsApiTest : public ExtensionApiTest { |
| protected: |
| void SetUpInProcessBrowserTestFixture() override { |
| ExtensionApiTest::SetUpInProcessBrowserTestFixture(); |
| |
| #if defined(ENABLE_CONFIGURATION_POLICY) |
| EXPECT_CALL(policy_provider_, IsInitializationComplete(_)) |
| .WillRepeatedly(Return(true)); |
| policy_provider_.SetAutoRefresh(); |
| policy::BrowserPolicyConnector::SetPolicyProviderForTesting( |
| &policy_provider_); |
| #endif |
| } |
| |
| void ReplyWhenSatisfied( |
| Namespace settings_namespace, |
| const std::string& normal_action, |
| const std::string& incognito_action) { |
| MaybeLoadAndReplyWhenSatisfied( |
| settings_namespace, normal_action, incognito_action, NULL, false); |
| } |
| |
| const Extension* LoadAndReplyWhenSatisfied( |
| Namespace settings_namespace, |
| const std::string& normal_action, |
| const std::string& incognito_action, |
| const std::string& extension_dir) { |
| return MaybeLoadAndReplyWhenSatisfied( |
| settings_namespace, |
| normal_action, |
| incognito_action, |
| &extension_dir, |
| false); |
| } |
| |
| void FinalReplyWhenSatisfied( |
| Namespace settings_namespace, |
| const std::string& normal_action, |
| const std::string& incognito_action) { |
| MaybeLoadAndReplyWhenSatisfied( |
| settings_namespace, normal_action, incognito_action, NULL, true); |
| } |
| |
| syncer::SyncableService* GetSyncableService() { |
| return settings_sync_util::GetSyncableService(browser()->profile(), |
| kModelType); |
| } |
| |
| void InitSync(syncer::SyncChangeProcessor* sync_processor) { |
| base::MessageLoop::current()->RunUntilIdle(); |
| InitSyncWithSyncableService(sync_processor, GetSyncableService()); |
| } |
| |
| void SendChanges(const syncer::SyncChangeList& change_list) { |
| base::MessageLoop::current()->RunUntilIdle(); |
| SendChangesToSyncableService(change_list, GetSyncableService()); |
| } |
| |
| #if defined(ENABLE_CONFIGURATION_POLICY) |
| void SetPolicies(const base::DictionaryValue& policies) { |
| scoped_ptr<policy::PolicyBundle> bundle(new policy::PolicyBundle()); |
| policy::PolicyMap& policy_map = bundle->Get(policy::PolicyNamespace( |
| policy::POLICY_DOMAIN_EXTENSIONS, kManagedStorageExtensionId)); |
| policy_map.LoadFrom( |
| &policies, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER); |
| policy_provider_.UpdatePolicy(bundle.Pass()); |
| } |
| #endif |
| |
| private: |
| const Extension* MaybeLoadAndReplyWhenSatisfied( |
| Namespace settings_namespace, |
| const std::string& normal_action, |
| const std::string& incognito_action, |
| // May be NULL to imply not loading the extension. |
| const std::string* extension_dir, |
| bool is_final_action) { |
| ExtensionTestMessageListener listener("waiting", true); |
| ExtensionTestMessageListener listener_incognito("waiting_incognito", true); |
| |
| // Only load the extension after the listeners have been set up, to avoid |
| // initialisation race conditions. |
| const Extension* extension = NULL; |
| if (extension_dir) { |
| extension = LoadExtensionIncognito( |
| test_data_dir_.AppendASCII("settings").AppendASCII(*extension_dir)); |
| EXPECT_TRUE(extension); |
| } |
| |
| EXPECT_TRUE(listener.WaitUntilSatisfied()); |
| EXPECT_TRUE(listener_incognito.WaitUntilSatisfied()); |
| |
| listener.Reply( |
| CreateMessage(settings_namespace, normal_action, is_final_action)); |
| listener_incognito.Reply( |
| CreateMessage(settings_namespace, incognito_action, is_final_action)); |
| return extension; |
| } |
| |
| std::string CreateMessage( |
| Namespace settings_namespace, |
| const std::string& action, |
| bool is_final_action) { |
| scoped_ptr<base::DictionaryValue> message(new base::DictionaryValue()); |
| message->SetString("namespace", ToString(settings_namespace)); |
| message->SetString("action", action); |
| message->SetBoolean("isFinalAction", is_final_action); |
| std::string message_json; |
| base::JSONWriter::Write(message.get(), &message_json); |
| return message_json; |
| } |
| |
| void InitSyncWithSyncableService( |
| syncer::SyncChangeProcessor* sync_processor, |
| syncer::SyncableService* settings_service) { |
| EXPECT_FALSE( |
| settings_service->MergeDataAndStartSyncing( |
| kModelType, |
| syncer::SyncDataList(), |
| scoped_ptr<syncer::SyncChangeProcessor>( |
| new syncer::SyncChangeProcessorWrapperForTest( |
| sync_processor)), |
| scoped_ptr<syncer::SyncErrorFactory>( |
| new syncer::SyncErrorFactoryMock())) |
| .error() |
| .IsSet()); |
| } |
| |
| void SendChangesToSyncableService( |
| const syncer::SyncChangeList& change_list, |
| syncer::SyncableService* settings_service) { |
| EXPECT_FALSE( |
| settings_service->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); |
| } |
| |
| protected: |
| #if defined(ENABLE_CONFIGURATION_POLICY) |
| policy::MockConfigurationPolicyProvider policy_provider_; |
| #endif |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, SimpleTest) { |
| ASSERT_TRUE(RunExtensionTest("settings/simple_test")) << message_; |
| } |
| |
| // Structure of this test taken from IncognitoSplitMode. |
| // Note that only split-mode incognito is tested, because spanning mode |
| // incognito looks the same as normal mode when the only API activity comes |
| // from background pages. |
| IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, SplitModeIncognito) { |
| // We need 2 ResultCatchers because we'll be running the same test in both |
| // regular and incognito mode. |
| ResultCatcher catcher, catcher_incognito; |
| catcher.RestrictToBrowserContext(browser()->profile()); |
| catcher_incognito.RestrictToBrowserContext( |
| browser()->profile()->GetOffTheRecordProfile()); |
| |
| LoadAndReplyWhenSatisfied(SYNC, |
| "assertEmpty", "assertEmpty", "split_incognito"); |
| ReplyWhenSatisfied(SYNC, "noop", "setFoo"); |
| ReplyWhenSatisfied(SYNC, "assertFoo", "assertFoo"); |
| ReplyWhenSatisfied(SYNC, "clear", "noop"); |
| ReplyWhenSatisfied(SYNC, "assertEmpty", "assertEmpty"); |
| ReplyWhenSatisfied(SYNC, "setFoo", "noop"); |
| ReplyWhenSatisfied(SYNC, "assertFoo", "assertFoo"); |
| ReplyWhenSatisfied(SYNC, "noop", "removeFoo"); |
| FinalReplyWhenSatisfied(SYNC, "assertEmpty", "assertEmpty"); |
| |
| EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); |
| EXPECT_TRUE(catcher_incognito.GetNextResult()) << catcher.message(); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, |
| OnChangedNotificationsBetweenBackgroundPages) { |
| // We need 2 ResultCatchers because we'll be running the same test in both |
| // regular and incognito mode. |
| ResultCatcher catcher, catcher_incognito; |
| catcher.RestrictToBrowserContext(browser()->profile()); |
| catcher_incognito.RestrictToBrowserContext( |
| browser()->profile()->GetOffTheRecordProfile()); |
| |
| LoadAndReplyWhenSatisfied(SYNC, |
| "assertNoNotifications", "assertNoNotifications", "split_incognito"); |
| ReplyWhenSatisfied(SYNC, "noop", "setFoo"); |
| ReplyWhenSatisfied(SYNC, |
| "assertAddFooNotification", "assertAddFooNotification"); |
| ReplyWhenSatisfied(SYNC, "clearNotifications", "clearNotifications"); |
| ReplyWhenSatisfied(SYNC, "removeFoo", "noop"); |
| FinalReplyWhenSatisfied(SYNC, |
| "assertDeleteFooNotification", "assertDeleteFooNotification"); |
| |
| EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); |
| EXPECT_TRUE(catcher_incognito.GetNextResult()) << catcher.message(); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, |
| SyncAndLocalAreasAreSeparate) { |
| // We need 2 ResultCatchers because we'll be running the same test in both |
| // regular and incognito mode. |
| ResultCatcher catcher, catcher_incognito; |
| catcher.RestrictToBrowserContext(browser()->profile()); |
| catcher_incognito.RestrictToBrowserContext( |
| browser()->profile()->GetOffTheRecordProfile()); |
| |
| LoadAndReplyWhenSatisfied(SYNC, |
| "assertNoNotifications", "assertNoNotifications", "split_incognito"); |
| |
| ReplyWhenSatisfied(SYNC, "noop", "setFoo"); |
| ReplyWhenSatisfied(SYNC, "assertFoo", "assertFoo"); |
| ReplyWhenSatisfied(SYNC, |
| "assertAddFooNotification", "assertAddFooNotification"); |
| ReplyWhenSatisfied(LOCAL, "assertEmpty", "assertEmpty"); |
| ReplyWhenSatisfied(LOCAL, "assertNoNotifications", "assertNoNotifications"); |
| |
| ReplyWhenSatisfied(SYNC, "clearNotifications", "clearNotifications"); |
| |
| ReplyWhenSatisfied(LOCAL, "setFoo", "noop"); |
| ReplyWhenSatisfied(LOCAL, "assertFoo", "assertFoo"); |
| ReplyWhenSatisfied(LOCAL, |
| "assertAddFooNotification", "assertAddFooNotification"); |
| ReplyWhenSatisfied(SYNC, "assertFoo", "assertFoo"); |
| ReplyWhenSatisfied(SYNC, "assertNoNotifications", "assertNoNotifications"); |
| |
| ReplyWhenSatisfied(LOCAL, "clearNotifications", "clearNotifications"); |
| |
| ReplyWhenSatisfied(LOCAL, "noop", "removeFoo"); |
| ReplyWhenSatisfied(LOCAL, "assertEmpty", "assertEmpty"); |
| ReplyWhenSatisfied(LOCAL, |
| "assertDeleteFooNotification", "assertDeleteFooNotification"); |
| ReplyWhenSatisfied(SYNC, "assertFoo", "assertFoo"); |
| ReplyWhenSatisfied(SYNC, "assertNoNotifications", "assertNoNotifications"); |
| |
| ReplyWhenSatisfied(LOCAL, "clearNotifications", "clearNotifications"); |
| |
| ReplyWhenSatisfied(SYNC, "removeFoo", "noop"); |
| ReplyWhenSatisfied(SYNC, "assertEmpty", "assertEmpty"); |
| ReplyWhenSatisfied(SYNC, |
| "assertDeleteFooNotification", "assertDeleteFooNotification"); |
| ReplyWhenSatisfied(LOCAL, "assertNoNotifications", "assertNoNotifications"); |
| FinalReplyWhenSatisfied(LOCAL, "assertEmpty", "assertEmpty"); |
| |
| EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); |
| EXPECT_TRUE(catcher_incognito.GetNextResult()) << catcher.message(); |
| } |
| |
| // Disabled, see crbug.com/101110 |
| IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, |
| DISABLED_OnChangedNotificationsFromSync) { |
| // We need 2 ResultCatchers because we'll be running the same test in both |
| // regular and incognito mode. |
| ResultCatcher catcher, catcher_incognito; |
| catcher.RestrictToBrowserContext(browser()->profile()); |
| catcher_incognito.RestrictToBrowserContext( |
| browser()->profile()->GetOffTheRecordProfile()); |
| |
| const Extension* extension = |
| LoadAndReplyWhenSatisfied(SYNC, |
| "assertNoNotifications", "assertNoNotifications", "split_incognito"); |
| const std::string& extension_id = extension->id(); |
| |
| syncer::FakeSyncChangeProcessor sync_processor; |
| InitSync(&sync_processor); |
| |
| // Set "foo" to "bar" via sync. |
| syncer::SyncChangeList sync_changes; |
| base::StringValue bar("bar"); |
| sync_changes.push_back(settings_sync_util::CreateAdd( |
| extension_id, "foo", bar, kModelType)); |
| SendChanges(sync_changes); |
| |
| ReplyWhenSatisfied(SYNC, |
| "assertAddFooNotification", "assertAddFooNotification"); |
| ReplyWhenSatisfied(SYNC, "clearNotifications", "clearNotifications"); |
| |
| // Remove "foo" via sync. |
| sync_changes.clear(); |
| sync_changes.push_back(settings_sync_util::CreateDelete( |
| extension_id, "foo", kModelType)); |
| SendChanges(sync_changes); |
| |
| FinalReplyWhenSatisfied(SYNC, |
| "assertDeleteFooNotification", "assertDeleteFooNotification"); |
| |
| EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); |
| EXPECT_TRUE(catcher_incognito.GetNextResult()) << catcher.message(); |
| } |
| |
| // Disabled, see crbug.com/101110 |
| // |
| // TODO: boring test, already done in the unit tests. What we really should be |
| // be testing is that the areas don't overlap. |
| IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, |
| DISABLED_OnChangedNotificationsFromSyncNotSentToLocal) { |
| // We need 2 ResultCatchers because we'll be running the same test in both |
| // regular and incognito mode. |
| ResultCatcher catcher, catcher_incognito; |
| catcher.RestrictToBrowserContext(browser()->profile()); |
| catcher_incognito.RestrictToBrowserContext( |
| browser()->profile()->GetOffTheRecordProfile()); |
| |
| const Extension* extension = |
| LoadAndReplyWhenSatisfied(LOCAL, |
| "assertNoNotifications", "assertNoNotifications", "split_incognito"); |
| const std::string& extension_id = extension->id(); |
| |
| syncer::FakeSyncChangeProcessor sync_processor; |
| InitSync(&sync_processor); |
| |
| // Set "foo" to "bar" via sync. |
| syncer::SyncChangeList sync_changes; |
| base::StringValue bar("bar"); |
| sync_changes.push_back(settings_sync_util::CreateAdd( |
| extension_id, "foo", bar, kModelType)); |
| SendChanges(sync_changes); |
| |
| ReplyWhenSatisfied(LOCAL, "assertNoNotifications", "assertNoNotifications"); |
| |
| // Remove "foo" via sync. |
| sync_changes.clear(); |
| sync_changes.push_back(settings_sync_util::CreateDelete( |
| extension_id, "foo", kModelType)); |
| SendChanges(sync_changes); |
| |
| FinalReplyWhenSatisfied(LOCAL, |
| "assertNoNotifications", "assertNoNotifications"); |
| |
| EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); |
| EXPECT_TRUE(catcher_incognito.GetNextResult()) << catcher.message(); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, IsStorageEnabled) { |
| StorageFrontend* frontend = StorageFrontend::Get(browser()->profile()); |
| EXPECT_TRUE(frontend->IsStorageEnabled(LOCAL)); |
| EXPECT_TRUE(frontend->IsStorageEnabled(SYNC)); |
| |
| #if defined(ENABLE_CONFIGURATION_POLICY) |
| EXPECT_TRUE(frontend->IsStorageEnabled(MANAGED)); |
| #else |
| EXPECT_FALSE(frontend->IsStorageEnabled(MANAGED)); |
| #endif |
| } |
| |
| #if defined(ENABLE_CONFIGURATION_POLICY) |
| |
| IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, ExtensionsSchemas) { |
| // Verifies that the Schemas for the extensions domain are created on startup. |
| Profile* profile = browser()->profile(); |
| ExtensionSystem* extension_system = ExtensionSystem::Get(profile); |
| if (!extension_system->ready().is_signaled()) { |
| // Wait until the extension system is ready. |
| base::RunLoop run_loop; |
| extension_system->ready().Post(FROM_HERE, run_loop.QuitClosure()); |
| run_loop.Run(); |
| ASSERT_TRUE(extension_system->ready().is_signaled()); |
| } |
| |
| // This test starts without any test extensions installed. |
| EXPECT_FALSE(GetSingleLoadedExtension()); |
| message_.clear(); |
| |
| policy::SchemaRegistry* registry = |
| policy::SchemaRegistryServiceFactory::GetForContext(profile)->registry(); |
| ASSERT_TRUE(registry); |
| EXPECT_FALSE(registry->schema_map()->GetSchema(policy::PolicyNamespace( |
| policy::POLICY_DOMAIN_EXTENSIONS, kManagedStorageExtensionId))); |
| |
| MockSchemaRegistryObserver observer; |
| registry->AddObserver(&observer); |
| |
| // Install a managed extension. |
| EXPECT_CALL(observer, OnSchemaRegistryUpdated(true)); |
| const Extension* extension = |
| LoadExtension(test_data_dir_.AppendASCII("settings/managed_storage")); |
| ASSERT_TRUE(extension); |
| Mock::VerifyAndClearExpectations(&observer); |
| registry->RemoveObserver(&observer); |
| |
| // Verify that its schema has been published, and verify its contents. |
| const policy::Schema* schema = |
| registry->schema_map()->GetSchema(policy::PolicyNamespace( |
| policy::POLICY_DOMAIN_EXTENSIONS, kManagedStorageExtensionId)); |
| ASSERT_TRUE(schema); |
| |
| ASSERT_TRUE(schema->valid()); |
| ASSERT_EQ(base::Value::TYPE_DICTIONARY, schema->type()); |
| ASSERT_TRUE(schema->GetKnownProperty("string-policy").valid()); |
| EXPECT_EQ(base::Value::TYPE_STRING, |
| schema->GetKnownProperty("string-policy").type()); |
| ASSERT_TRUE(schema->GetKnownProperty("int-policy").valid()); |
| EXPECT_EQ(base::Value::TYPE_INTEGER, |
| schema->GetKnownProperty("int-policy").type()); |
| ASSERT_TRUE(schema->GetKnownProperty("double-policy").valid()); |
| EXPECT_EQ(base::Value::TYPE_DOUBLE, |
| schema->GetKnownProperty("double-policy").type()); |
| ASSERT_TRUE(schema->GetKnownProperty("boolean-policy").valid()); |
| EXPECT_EQ(base::Value::TYPE_BOOLEAN, |
| schema->GetKnownProperty("boolean-policy").type()); |
| |
| policy::Schema list = schema->GetKnownProperty("list-policy"); |
| ASSERT_TRUE(list.valid()); |
| ASSERT_EQ(base::Value::TYPE_LIST, list.type()); |
| ASSERT_TRUE(list.GetItems().valid()); |
| EXPECT_EQ(base::Value::TYPE_STRING, list.GetItems().type()); |
| |
| policy::Schema dict = schema->GetKnownProperty("dict-policy"); |
| ASSERT_TRUE(dict.valid()); |
| ASSERT_EQ(base::Value::TYPE_DICTIONARY, dict.type()); |
| list = dict.GetKnownProperty("list"); |
| ASSERT_TRUE(list.valid()); |
| ASSERT_EQ(base::Value::TYPE_LIST, list.type()); |
| dict = list.GetItems(); |
| ASSERT_TRUE(dict.valid()); |
| ASSERT_EQ(base::Value::TYPE_DICTIONARY, dict.type()); |
| ASSERT_TRUE(dict.GetProperty("anything").valid()); |
| EXPECT_EQ(base::Value::TYPE_INTEGER, dict.GetProperty("anything").type()); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, ManagedStorage) { |
| // Set policies for the test extension. |
| scoped_ptr<base::DictionaryValue> policy = extensions::DictionaryBuilder() |
| .Set("string-policy", "value") |
| .Set("int-policy", -123) |
| .Set("double-policy", 456e7) |
| .SetBoolean("boolean-policy", true) |
| .Set("list-policy", extensions::ListBuilder() |
| .Append("one") |
| .Append("two") |
| .Append("three")) |
| .Set("dict-policy", extensions::DictionaryBuilder() |
| .Set("list", extensions::ListBuilder() |
| .Append(extensions::DictionaryBuilder() |
| .Set("one", 1) |
| .Set("two", 2)) |
| .Append(extensions::DictionaryBuilder() |
| .Set("three", 3)))) |
| .Build(); |
| SetPolicies(*policy); |
| // Now run the extension. |
| ASSERT_TRUE(RunExtensionTest("settings/managed_storage")) << message_; |
| } |
| |
| IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, |
| DISABLED_PRE_ManagedStorageEvents) { |
| ResultCatcher catcher; |
| |
| // This test starts without any test extensions installed. |
| EXPECT_FALSE(GetSingleLoadedExtension()); |
| message_.clear(); |
| |
| // Set policies for the test extension. |
| scoped_ptr<base::DictionaryValue> policy = extensions::DictionaryBuilder() |
| .Set("constant-policy", "aaa") |
| .Set("changes-policy", "bbb") |
| .Set("deleted-policy", "ccc") |
| .Build(); |
| SetPolicies(*policy); |
| |
| ExtensionTestMessageListener ready_listener("ready", false); |
| // Load the extension to install the event listener. |
| const Extension* extension = LoadExtension( |
| test_data_dir_.AppendASCII("settings/managed_storage_events")); |
| ASSERT_TRUE(extension); |
| // Wait until the extension sends the "ready" message. |
| ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); |
| |
| // Now change the policies and wait until the extension is done. |
| policy = extensions::DictionaryBuilder() |
| .Set("constant-policy", "aaa") |
| .Set("changes-policy", "ddd") |
| .Set("new-policy", "eee") |
| .Build(); |
| SetPolicies(*policy); |
| EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); |
| } |
| |
| IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, |
| DISABLED_ManagedStorageEvents) { |
| // This test runs after PRE_ManagedStorageEvents without having deleted the |
| // profile, so the extension is still around. While the browser restarted the |
| // policy went back to the empty default, and so the extension should receive |
| // the corresponding change events. |
| |
| ResultCatcher catcher; |
| |
| // Verify that the test extension is still installed. |
| const Extension* extension = GetSingleLoadedExtension(); |
| ASSERT_TRUE(extension); |
| EXPECT_EQ(kManagedStorageExtensionId, extension->id()); |
| |
| // Running the test again skips the onInstalled callback, and just triggers |
| // the onChanged notification. |
| EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); |
| } |
| |
| #endif // defined(ENABLE_CONFIGURATION_POLICY) |
| |
| IN_PROC_BROWSER_TEST_F(ExtensionSettingsApiTest, ManagedStorageDisabled) { |
| // Disable the 'managed' namespace. This is redundant when |
| // ENABLE_CONFIGURATION_POLICY is not defined. |
| StorageFrontend* frontend = StorageFrontend::Get(browser()->profile()); |
| frontend->DisableStorageForTesting(MANAGED); |
| EXPECT_FALSE(frontend->IsStorageEnabled(MANAGED)); |
| // Now run the extension. |
| ASSERT_TRUE(RunExtensionTest("settings/managed_storage_disabled")) |
| << message_; |
| } |
| |
| } // namespace extensions |