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