Home | History | Annotate | Download | only in common
      1 // Copyright 2013 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 "components/policy/core/common/forwarding_policy_provider.h"
      6 
      7 #include <string>
      8 
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/values.h"
     11 #include "components/policy/core/common/mock_configuration_policy_provider.h"
     12 #include "components/policy/core/common/policy_bundle.h"
     13 #include "components/policy/core/common/policy_map.h"
     14 #include "components/policy/core/common/policy_types.h"
     15 #include "components/policy/core/common/schema.h"
     16 #include "components/policy/core/common/schema_registry.h"
     17 #include "testing/gmock/include/gmock/gmock.h"
     18 #include "testing/gtest/include/gtest/gtest.h"
     19 
     20 using testing::_;
     21 using testing::Mock;
     22 using testing::Return;
     23 
     24 namespace policy {
     25 
     26 namespace {
     27 
     28 const char kTestSchema[] =
     29     "{"
     30     "  \"type\": \"object\","
     31     "  \"properties\": {"
     32     "    \"foo\": { \"type\": \"string\" }"
     33     "  }"
     34     "}";
     35 
     36 }  // namespace
     37 
     38 class ForwardingPolicyProviderTest : public testing::Test {
     39  protected:
     40   ForwardingPolicyProviderTest() : forwarding_provider_(&mock_provider_) {
     41     mock_provider_.Init();
     42     forwarding_provider_.Init(&schema_registry_);
     43     forwarding_provider_.AddObserver(&observer_);
     44   }
     45 
     46   virtual ~ForwardingPolicyProviderTest() {
     47     forwarding_provider_.RemoveObserver(&observer_);
     48     forwarding_provider_.Shutdown();
     49     mock_provider_.Shutdown();
     50   }
     51 
     52   Schema CreateTestSchema() {
     53     std::string error;
     54     Schema schema = Schema::Parse(kTestSchema, &error);
     55     if (!schema.valid())
     56       ADD_FAILURE() << error;
     57     return schema;
     58   }
     59 
     60   SchemaRegistry schema_registry_;
     61   MockConfigurationPolicyObserver observer_;
     62   MockConfigurationPolicyProvider mock_provider_;
     63   ForwardingPolicyProvider forwarding_provider_;
     64 };
     65 
     66 TEST_F(ForwardingPolicyProviderTest, Empty) {
     67   EXPECT_FALSE(schema_registry_.IsReady());
     68   EXPECT_FALSE(
     69       forwarding_provider_.IsInitializationComplete(POLICY_DOMAIN_EXTENSIONS));
     70 
     71   EXPECT_CALL(mock_provider_, IsInitializationComplete(POLICY_DOMAIN_CHROME))
     72       .WillOnce(Return(false));
     73   EXPECT_FALSE(
     74       forwarding_provider_.IsInitializationComplete(POLICY_DOMAIN_CHROME));
     75   Mock::VerifyAndClearExpectations(&mock_provider_);
     76 
     77   const PolicyBundle empty_bundle;
     78   EXPECT_TRUE(forwarding_provider_.policies().Equals(empty_bundle));
     79 }
     80 
     81 TEST_F(ForwardingPolicyProviderTest, ForwardsChromePolicy) {
     82   PolicyBundle bundle;
     83   const PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
     84   bundle.Get(chrome_ns).Set("policy",
     85                             POLICY_LEVEL_MANDATORY,
     86                             POLICY_SCOPE_USER,
     87                             new base::StringValue("value"),
     88                             NULL);
     89 
     90   EXPECT_CALL(observer_, OnUpdatePolicy(&forwarding_provider_));
     91   scoped_ptr<PolicyBundle> delegate_bundle(new PolicyBundle);
     92   delegate_bundle->CopyFrom(bundle);
     93   delegate_bundle->Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"))
     94       .Set("foo",
     95            POLICY_LEVEL_MANDATORY,
     96            POLICY_SCOPE_USER,
     97            new base::StringValue("not forwarded"),
     98            NULL);
     99   mock_provider_.UpdatePolicy(delegate_bundle.Pass());
    100   Mock::VerifyAndClearExpectations(&observer_);
    101 
    102   EXPECT_FALSE(
    103       forwarding_provider_.IsInitializationComplete(POLICY_DOMAIN_EXTENSIONS));
    104   EXPECT_TRUE(forwarding_provider_.policies().Equals(bundle));
    105 }
    106 
    107 TEST_F(ForwardingPolicyProviderTest, RefreshPolicies) {
    108   EXPECT_CALL(mock_provider_, RefreshPolicies());
    109   forwarding_provider_.RefreshPolicies();
    110   Mock::VerifyAndClearExpectations(&mock_provider_);
    111 }
    112 
    113 TEST_F(ForwardingPolicyProviderTest, SchemaReady) {
    114   EXPECT_CALL(observer_, OnUpdatePolicy(&forwarding_provider_));
    115   schema_registry_.SetReady(POLICY_DOMAIN_CHROME);
    116   schema_registry_.SetReady(POLICY_DOMAIN_EXTENSIONS);
    117   Mock::VerifyAndClearExpectations(&observer_);
    118 
    119   EXPECT_TRUE(forwarding_provider_.IsInitializationComplete(
    120       policy::POLICY_DOMAIN_EXTENSIONS));
    121 }
    122 
    123 TEST_F(ForwardingPolicyProviderTest, SchemaReadyWithComponents) {
    124   PolicyMap policy_map;
    125   policy_map.Set("foo",
    126                  POLICY_LEVEL_MANDATORY,
    127                  POLICY_SCOPE_USER,
    128                  new base::StringValue("omg"),
    129                  NULL);
    130   scoped_ptr<PolicyBundle> bundle(new PolicyBundle);
    131   bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, "")).CopyFrom(policy_map);
    132   bundle->Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"))
    133       .CopyFrom(policy_map);
    134   EXPECT_CALL(observer_, OnUpdatePolicy(&forwarding_provider_));
    135   mock_provider_.UpdatePolicy(bundle.Pass());
    136   Mock::VerifyAndClearExpectations(&observer_);
    137 
    138   EXPECT_CALL(mock_provider_, RefreshPolicies()).Times(0);
    139   schema_registry_.RegisterComponent(
    140       PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"), CreateTestSchema());
    141   schema_registry_.SetReady(POLICY_DOMAIN_EXTENSIONS);
    142   Mock::VerifyAndClearExpectations(&mock_provider_);
    143 
    144   EXPECT_CALL(mock_provider_, RefreshPolicies());
    145   schema_registry_.SetReady(POLICY_DOMAIN_CHROME);
    146   Mock::VerifyAndClearExpectations(&mock_provider_);
    147 
    148   EXPECT_FALSE(forwarding_provider_.IsInitializationComplete(
    149       policy::POLICY_DOMAIN_EXTENSIONS));
    150   PolicyBundle expected_bundle;
    151   expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, ""))
    152       .CopyFrom(policy_map);
    153   EXPECT_TRUE(forwarding_provider_.policies().Equals(expected_bundle));
    154 
    155   EXPECT_CALL(observer_, OnUpdatePolicy(&forwarding_provider_));
    156   forwarding_provider_.OnUpdatePolicy(&mock_provider_);
    157   Mock::VerifyAndClearExpectations(&observer_);
    158 
    159   EXPECT_TRUE(forwarding_provider_.IsInitializationComplete(
    160       policy::POLICY_DOMAIN_EXTENSIONS));
    161   expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"))
    162       .CopyFrom(policy_map);
    163   EXPECT_TRUE(forwarding_provider_.policies().Equals(expected_bundle));
    164 }
    165 
    166 TEST_F(ForwardingPolicyProviderTest, DelegateUpdates) {
    167   schema_registry_.RegisterComponent(
    168       PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"), CreateTestSchema());
    169   EXPECT_FALSE(schema_registry_.IsReady());
    170   EXPECT_FALSE(forwarding_provider_.IsInitializationComplete(
    171       policy::POLICY_DOMAIN_EXTENSIONS));
    172 
    173   PolicyMap policy_map;
    174   policy_map.Set("foo",
    175                  POLICY_LEVEL_MANDATORY,
    176                  POLICY_SCOPE_USER,
    177                  new base::StringValue("omg"),
    178                  NULL);
    179   // Chrome policy updates are forwarded even if the components aren't ready.
    180   EXPECT_CALL(observer_, OnUpdatePolicy(&forwarding_provider_));
    181   mock_provider_.UpdateChromePolicy(policy_map);
    182   Mock::VerifyAndClearExpectations(&observer_);
    183 
    184   EXPECT_CALL(mock_provider_, RefreshPolicies());
    185   schema_registry_.SetReady(POLICY_DOMAIN_CHROME);
    186   schema_registry_.SetReady(POLICY_DOMAIN_EXTENSIONS);
    187   EXPECT_TRUE(schema_registry_.IsReady());
    188   Mock::VerifyAndClearExpectations(&mock_provider_);
    189   EXPECT_FALSE(forwarding_provider_.IsInitializationComplete(
    190       policy::POLICY_DOMAIN_EXTENSIONS));
    191 
    192   // The forwarding provider becomes ready after this refresh completes, and
    193   // starts forwarding policy updates after that.
    194   EXPECT_CALL(observer_, OnUpdatePolicy(_));
    195   mock_provider_.UpdateChromePolicy(policy_map);
    196   Mock::VerifyAndClearExpectations(&observer_);
    197 
    198   EXPECT_TRUE(forwarding_provider_.IsInitializationComplete(
    199       policy::POLICY_DOMAIN_EXTENSIONS));
    200 
    201   // Keeps forwarding.
    202   EXPECT_CALL(observer_, OnUpdatePolicy(_));
    203   mock_provider_.UpdateChromePolicy(policy_map);
    204   Mock::VerifyAndClearExpectations(&observer_);
    205 }
    206 
    207 TEST_F(ForwardingPolicyProviderTest, RemoveAndAddComponent) {
    208   EXPECT_CALL(mock_provider_, RefreshPolicies());
    209   const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, "xyz");
    210   schema_registry_.SetReady(POLICY_DOMAIN_CHROME);
    211   schema_registry_.RegisterComponent(ns, CreateTestSchema());
    212   schema_registry_.SetReady(POLICY_DOMAIN_EXTENSIONS);
    213   Mock::VerifyAndClearExpectations(&mock_provider_);
    214 
    215   // Serve policy for |ns|.
    216   PolicyBundle platform_policy;
    217   platform_policy.Get(ns).Set("foo",
    218                               POLICY_LEVEL_MANDATORY,
    219                               POLICY_SCOPE_USER,
    220                               new base::StringValue("omg"),
    221                               NULL);
    222   scoped_ptr<PolicyBundle> copy(new PolicyBundle);
    223   copy->CopyFrom(platform_policy);
    224   EXPECT_CALL(observer_, OnUpdatePolicy(_));
    225   mock_provider_.UpdatePolicy(copy.Pass());
    226   Mock::VerifyAndClearExpectations(&observer_);
    227   EXPECT_TRUE(forwarding_provider_.policies().Equals(platform_policy));
    228 
    229   // Now remove that component.
    230   EXPECT_CALL(observer_, OnUpdatePolicy(_));
    231   schema_registry_.UnregisterComponent(ns);
    232   Mock::VerifyAndClearExpectations(&observer_);
    233   const PolicyBundle empty;
    234   EXPECT_TRUE(forwarding_provider_.policies().Equals(empty));
    235 
    236   // Adding it back should serve the current policies again, even though they
    237   // haven't changed on the platform provider.
    238   EXPECT_CALL(mock_provider_, RefreshPolicies());
    239   schema_registry_.RegisterComponent(ns, CreateTestSchema());
    240   Mock::VerifyAndClearExpectations(&mock_provider_);
    241 
    242   EXPECT_CALL(observer_, OnUpdatePolicy(_));
    243   copy.reset(new PolicyBundle);
    244   copy->CopyFrom(platform_policy);
    245   mock_provider_.UpdatePolicy(copy.Pass());
    246   Mock::VerifyAndClearExpectations(&observer_);
    247   EXPECT_TRUE(forwarding_provider_.policies().Equals(platform_policy));
    248 }
    249 
    250 }  // namespace policy
    251