Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / policy / core / common / schema_registry_unittest.cc
blob9d5fbd4f6db0fae5c7544426b24b408a4275bd2e
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.
5 #include "components/policy/core/common/schema_registry.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "components/policy/core/common/policy_namespace.h"
9 #include "components/policy/core/common/schema.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 using ::testing::Mock;
14 using ::testing::_;
16 namespace policy {
18 namespace {
20 const char kTestSchema[] =
21 "{"
22 " \"type\": \"object\","
23 " \"properties\": {"
24 " \"string\": { \"type\": \"string\" },"
25 " \"integer\": { \"type\": \"integer\" },"
26 " \"boolean\": { \"type\": \"boolean\" },"
27 " \"null\": { \"type\": \"null\" },"
28 " \"double\": { \"type\": \"number\" },"
29 " \"list\": {"
30 " \"type\": \"array\","
31 " \"items\": { \"type\": \"string\" }"
32 " },"
33 " \"object\": {"
34 " \"type\": \"object\","
35 " \"properties\": {"
36 " \"a\": { \"type\": \"string\" },"
37 " \"b\": { \"type\": \"integer\" }"
38 " }"
39 " }"
40 " }"
41 "}";
43 class MockSchemaRegistryObserver : public SchemaRegistry::Observer {
44 public:
45 MockSchemaRegistryObserver() {}
46 virtual ~MockSchemaRegistryObserver() {}
48 MOCK_METHOD1(OnSchemaRegistryUpdated, void(bool));
49 MOCK_METHOD0(OnSchemaRegistryReady, void());
52 bool SchemaMapEquals(const scoped_refptr<SchemaMap>& schema_map1,
53 const scoped_refptr<SchemaMap>& schema_map2) {
54 PolicyNamespaceList added;
55 PolicyNamespaceList removed;
56 schema_map1->GetChanges(schema_map2, &removed, &added);
57 return added.empty() && removed.empty();
60 } // namespace
62 TEST(SchemaRegistryTest, Notifications) {
63 std::string error;
64 Schema schema = Schema::Parse(kTestSchema, &error);
65 ASSERT_TRUE(schema.valid()) << error;
67 MockSchemaRegistryObserver observer;
68 SchemaRegistry registry;
69 registry.AddObserver(&observer);
71 ASSERT_TRUE(registry.schema_map().get());
72 EXPECT_FALSE(registry.schema_map()->GetSchema(
73 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc")));
75 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true));
76 registry.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"),
77 schema);
78 Mock::VerifyAndClearExpectations(&observer);
80 // Re-register also triggers notifications, because the Schema might have
81 // changed.
82 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true));
83 registry.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"),
84 schema);
85 Mock::VerifyAndClearExpectations(&observer);
87 EXPECT_TRUE(registry.schema_map()->GetSchema(
88 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc")));
90 EXPECT_CALL(observer, OnSchemaRegistryUpdated(false));
91 registry.UnregisterComponent(
92 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"));
93 Mock::VerifyAndClearExpectations(&observer);
95 EXPECT_FALSE(registry.schema_map()->GetSchema(
96 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc")));
98 // Registering multiple components at once issues only one notification.
99 ComponentMap components;
100 components["abc"] = schema;
101 components["def"] = schema;
102 components["xyz"] = schema;
103 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true));
104 registry.RegisterComponents(POLICY_DOMAIN_EXTENSIONS, components);
105 Mock::VerifyAndClearExpectations(&observer);
107 registry.RemoveObserver(&observer);
110 TEST(SchemaRegistryTest, IsReady) {
111 SchemaRegistry registry;
112 MockSchemaRegistryObserver observer;
113 registry.AddObserver(&observer);
115 EXPECT_FALSE(registry.IsReady());
116 #if defined(ENABLE_EXTENSIONS)
117 EXPECT_CALL(observer, OnSchemaRegistryReady()).Times(0);
118 registry.SetReady(POLICY_DOMAIN_EXTENSIONS);
119 Mock::VerifyAndClearExpectations(&observer);
120 EXPECT_FALSE(registry.IsReady());
121 #endif
122 EXPECT_CALL(observer, OnSchemaRegistryReady());
123 registry.SetReady(POLICY_DOMAIN_CHROME);
124 Mock::VerifyAndClearExpectations(&observer);
125 EXPECT_TRUE(registry.IsReady());
126 EXPECT_CALL(observer, OnSchemaRegistryReady()).Times(0);
127 registry.SetReady(POLICY_DOMAIN_CHROME);
128 Mock::VerifyAndClearExpectations(&observer);
129 EXPECT_TRUE(registry.IsReady());
131 CombinedSchemaRegistry combined;
132 EXPECT_TRUE(combined.IsReady());
134 registry.RemoveObserver(&observer);
137 TEST(SchemaRegistryTest, Combined) {
138 std::string error;
139 Schema schema = Schema::Parse(kTestSchema, &error);
140 ASSERT_TRUE(schema.valid()) << error;
142 MockSchemaRegistryObserver observer;
143 scoped_ptr<SchemaRegistry> registry1(new SchemaRegistry);
144 scoped_ptr<SchemaRegistry> registry2(new SchemaRegistry);
145 CombinedSchemaRegistry combined;
146 combined.AddObserver(&observer);
148 EXPECT_CALL(observer, OnSchemaRegistryUpdated(_)).Times(0);
149 registry1->RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"),
150 schema);
151 Mock::VerifyAndClearExpectations(&observer);
153 // Starting to track a registry issues notifications when it comes with new
154 // schemas.
155 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true));
156 combined.Track(registry1.get());
157 Mock::VerifyAndClearExpectations(&observer);
159 // Adding a new empty registry does not trigger notifications.
160 EXPECT_CALL(observer, OnSchemaRegistryUpdated(_)).Times(0);
161 combined.Track(registry2.get());
162 Mock::VerifyAndClearExpectations(&observer);
164 // Adding the same component to the combined registry itself triggers
165 // notifications.
166 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true));
167 combined.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"),
168 schema);
169 Mock::VerifyAndClearExpectations(&observer);
171 // Adding components to the sub-registries triggers notifications.
172 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true));
173 registry2->RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def"),
174 schema);
175 Mock::VerifyAndClearExpectations(&observer);
177 // If the same component is published in 2 sub-registries then the combined
178 // registry publishes one of them.
179 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true));
180 registry1->RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def"),
181 schema);
182 Mock::VerifyAndClearExpectations(&observer);
184 ASSERT_EQ(1u, combined.schema_map()->GetDomains().size());
185 ASSERT_TRUE(combined.schema_map()->GetComponents(POLICY_DOMAIN_EXTENSIONS));
186 ASSERT_EQ(
188 combined.schema_map()->GetComponents(POLICY_DOMAIN_EXTENSIONS)->size());
189 EXPECT_TRUE(combined.schema_map()->GetSchema(
190 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc")));
191 EXPECT_TRUE(combined.schema_map()->GetSchema(
192 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def")));
193 EXPECT_FALSE(combined.schema_map()->GetSchema(
194 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz")));
196 EXPECT_CALL(observer, OnSchemaRegistryUpdated(false));
197 registry1->UnregisterComponent(
198 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"));
199 Mock::VerifyAndClearExpectations(&observer);
200 // Still registered at the combined registry.
201 EXPECT_TRUE(combined.schema_map()->GetSchema(
202 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc")));
204 EXPECT_CALL(observer, OnSchemaRegistryUpdated(false));
205 combined.UnregisterComponent(
206 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"));
207 Mock::VerifyAndClearExpectations(&observer);
208 // Now it's gone.
209 EXPECT_FALSE(combined.schema_map()->GetSchema(
210 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc")));
212 EXPECT_CALL(observer, OnSchemaRegistryUpdated(false));
213 registry1->UnregisterComponent(
214 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def"));
215 Mock::VerifyAndClearExpectations(&observer);
216 // Still registered at registry2.
217 EXPECT_TRUE(combined.schema_map()->GetSchema(
218 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def")));
220 EXPECT_CALL(observer, OnSchemaRegistryUpdated(false));
221 registry2->UnregisterComponent(
222 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def"));
223 Mock::VerifyAndClearExpectations(&observer);
224 // Now it's gone.
225 EXPECT_FALSE(combined.schema_map()->GetSchema(
226 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def")));
228 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true)).Times(2);
229 registry1->RegisterComponent(PolicyNamespace(POLICY_DOMAIN_CHROME, ""),
230 schema);
231 registry2->RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "hij"),
232 schema);
233 Mock::VerifyAndClearExpectations(&observer);
235 // Untracking |registry1| doesn't trigger an update notification, because it
236 // doesn't contain any components.
237 EXPECT_CALL(observer, OnSchemaRegistryUpdated(_)).Times(0);
238 registry1.reset();
239 Mock::VerifyAndClearExpectations(&observer);
241 EXPECT_CALL(observer, OnSchemaRegistryUpdated(false));
242 registry2.reset();
243 Mock::VerifyAndClearExpectations(&observer);
245 combined.RemoveObserver(&observer);
248 TEST(SchemaRegistryTest, ForwardingSchemaRegistry) {
249 scoped_ptr<SchemaRegistry> registry(new SchemaRegistry);
250 ForwardingSchemaRegistry forwarding(registry.get());
251 MockSchemaRegistryObserver observer;
252 forwarding.AddObserver(&observer);
254 EXPECT_FALSE(registry->IsReady());
255 EXPECT_FALSE(forwarding.IsReady());
256 // They always have the same SchemaMap.
257 EXPECT_TRUE(SchemaMapEquals(registry->schema_map(), forwarding.schema_map()));
259 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true));
260 registry->RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"),
261 Schema());
262 Mock::VerifyAndClearExpectations(&observer);
263 EXPECT_TRUE(SchemaMapEquals(registry->schema_map(), forwarding.schema_map()));
265 EXPECT_CALL(observer, OnSchemaRegistryUpdated(false));
266 registry->UnregisterComponent(
267 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"));
268 Mock::VerifyAndClearExpectations(&observer);
269 EXPECT_TRUE(SchemaMapEquals(registry->schema_map(), forwarding.schema_map()));
271 // No notifications expected for these calls.
272 EXPECT_FALSE(registry->IsReady());
273 EXPECT_FALSE(forwarding.IsReady());
275 registry->SetReady(POLICY_DOMAIN_EXTENSIONS);
276 EXPECT_FALSE(registry->IsReady());
277 EXPECT_FALSE(forwarding.IsReady());
279 registry->SetReady(POLICY_DOMAIN_CHROME);
280 EXPECT_TRUE(registry->IsReady());
281 // The ForwardingSchemaRegistry becomes ready independently of the wrapped
282 // registry.
283 EXPECT_FALSE(forwarding.IsReady());
285 EXPECT_TRUE(SchemaMapEquals(registry->schema_map(), forwarding.schema_map()));
286 Mock::VerifyAndClearExpectations(&observer);
288 forwarding.SetReady(POLICY_DOMAIN_EXTENSIONS);
289 EXPECT_FALSE(forwarding.IsReady());
290 Mock::VerifyAndClearExpectations(&observer);
292 EXPECT_CALL(observer, OnSchemaRegistryReady());
293 forwarding.SetReady(POLICY_DOMAIN_CHROME);
294 EXPECT_TRUE(forwarding.IsReady());
295 Mock::VerifyAndClearExpectations(&observer);
297 // Keep the same SchemaMap when the original registry is gone.
298 // No notifications are expected in this case either.
299 scoped_refptr<SchemaMap> schema_map = registry->schema_map();
300 registry.reset();
301 EXPECT_TRUE(SchemaMapEquals(schema_map, forwarding.schema_map()));
302 Mock::VerifyAndClearExpectations(&observer);
304 forwarding.RemoveObserver(&observer);
307 } // namespace policy