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