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 20using testing::_; 21using testing::Mock; 22using testing::Return; 23 24namespace policy { 25 26namespace { 27 28const char kTestSchema[] = 29 "{" 30 " \"type\": \"object\"," 31 " \"properties\": {" 32 " \"foo\": { \"type\": \"string\" }" 33 " }" 34 "}"; 35 36} // namespace 37 38class 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 66TEST_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 81TEST_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 107TEST_F(ForwardingPolicyProviderTest, RefreshPolicies) { 108 EXPECT_CALL(mock_provider_, RefreshPolicies()); 109 forwarding_provider_.RefreshPolicies(); 110 Mock::VerifyAndClearExpectations(&mock_provider_); 111} 112 113TEST_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 123TEST_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 166TEST_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 207TEST_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