OLD | NEW |
| (Empty) |
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 "chrome/browser/policy/schema_registry.h" | |
6 | |
7 #include "components/policy/core/common/policy_namespace.h" | |
8 #include "components/policy/core/common/schema.h" | |
9 #include "testing/gmock/include/gmock/gmock.h" | |
10 #include "testing/gtest/include/gtest/gtest.h" | |
11 | |
12 using ::testing::Mock; | |
13 using ::testing::_; | |
14 | |
15 namespace policy { | |
16 | |
17 namespace { | |
18 | |
19 const char kTestSchema[] = | |
20 "{" | |
21 " \"type\": \"object\"," | |
22 " \"properties\": {" | |
23 " \"string\": { \"type\": \"string\" }," | |
24 " \"integer\": { \"type\": \"integer\" }," | |
25 " \"boolean\": { \"type\": \"boolean\" }," | |
26 " \"null\": { \"type\": \"null\" }," | |
27 " \"double\": { \"type\": \"number\" }," | |
28 " \"list\": {" | |
29 " \"type\": \"array\"," | |
30 " \"items\": { \"type\": \"string\" }" | |
31 " }," | |
32 " \"object\": {" | |
33 " \"type\": \"object\"," | |
34 " \"properties\": {" | |
35 " \"a\": { \"type\": \"string\" }," | |
36 " \"b\": { \"type\": \"integer\" }" | |
37 " }" | |
38 " }" | |
39 " }" | |
40 "}"; | |
41 | |
42 class MockSchemaRegistryObserver : public SchemaRegistry::Observer { | |
43 public: | |
44 MockSchemaRegistryObserver() {} | |
45 virtual ~MockSchemaRegistryObserver() {} | |
46 | |
47 MOCK_METHOD1(OnSchemaRegistryUpdated, void(bool)); | |
48 MOCK_METHOD0(OnSchemaRegistryReady, void()); | |
49 }; | |
50 | |
51 } // namespace | |
52 | |
53 TEST(SchemaRegistryTest, Notifications) { | |
54 std::string error; | |
55 Schema schema = Schema::Parse(kTestSchema, &error); | |
56 ASSERT_TRUE(schema.valid()) << error; | |
57 | |
58 MockSchemaRegistryObserver observer; | |
59 SchemaRegistry registry; | |
60 EXPECT_FALSE(registry.HasObservers()); | |
61 registry.AddObserver(&observer); | |
62 EXPECT_TRUE(registry.HasObservers()); | |
63 | |
64 ASSERT_TRUE(registry.schema_map()); | |
65 EXPECT_FALSE(registry.schema_map()->GetSchema( | |
66 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"))); | |
67 | |
68 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true)); | |
69 registry.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"), | |
70 schema); | |
71 Mock::VerifyAndClearExpectations(&observer); | |
72 | |
73 // Re-register also triggers notifications, because the Schema might have | |
74 // changed. | |
75 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true)); | |
76 registry.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"), | |
77 schema); | |
78 Mock::VerifyAndClearExpectations(&observer); | |
79 | |
80 EXPECT_TRUE(registry.schema_map()->GetSchema( | |
81 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"))); | |
82 | |
83 EXPECT_CALL(observer, OnSchemaRegistryUpdated(false)); | |
84 registry.UnregisterComponent( | |
85 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc")); | |
86 Mock::VerifyAndClearExpectations(&observer); | |
87 | |
88 EXPECT_FALSE(registry.schema_map()->GetSchema( | |
89 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"))); | |
90 | |
91 // Registering multiple components at once issues only one notification. | |
92 ComponentMap components; | |
93 components["abc"] = schema; | |
94 components["def"] = schema; | |
95 components["xyz"] = schema; | |
96 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true)); | |
97 registry.RegisterComponents(POLICY_DOMAIN_EXTENSIONS, components); | |
98 Mock::VerifyAndClearExpectations(&observer); | |
99 | |
100 registry.RemoveObserver(&observer); | |
101 EXPECT_FALSE(registry.HasObservers()); | |
102 } | |
103 | |
104 TEST(SchemaRegistryTest, IsReady) { | |
105 SchemaRegistry registry; | |
106 MockSchemaRegistryObserver observer; | |
107 registry.AddObserver(&observer); | |
108 | |
109 EXPECT_FALSE(registry.IsReady()); | |
110 #if defined(ENABLE_EXTENSIONS) | |
111 EXPECT_CALL(observer, OnSchemaRegistryReady()).Times(0); | |
112 registry.SetReady(POLICY_DOMAIN_EXTENSIONS); | |
113 Mock::VerifyAndClearExpectations(&observer); | |
114 EXPECT_FALSE(registry.IsReady()); | |
115 #endif | |
116 EXPECT_CALL(observer, OnSchemaRegistryReady()); | |
117 registry.SetReady(POLICY_DOMAIN_CHROME); | |
118 Mock::VerifyAndClearExpectations(&observer); | |
119 EXPECT_TRUE(registry.IsReady()); | |
120 EXPECT_CALL(observer, OnSchemaRegistryReady()).Times(0); | |
121 registry.SetReady(POLICY_DOMAIN_CHROME); | |
122 Mock::VerifyAndClearExpectations(&observer); | |
123 EXPECT_TRUE(registry.IsReady()); | |
124 | |
125 CombinedSchemaRegistry combined; | |
126 EXPECT_TRUE(combined.IsReady()); | |
127 | |
128 registry.RemoveObserver(&observer); | |
129 } | |
130 | |
131 TEST(SchemaRegistryTest, Combined) { | |
132 std::string error; | |
133 Schema schema = Schema::Parse(kTestSchema, &error); | |
134 ASSERT_TRUE(schema.valid()) << error; | |
135 | |
136 MockSchemaRegistryObserver observer; | |
137 SchemaRegistry registry1; | |
138 SchemaRegistry registry2; | |
139 CombinedSchemaRegistry combined; | |
140 combined.AddObserver(&observer); | |
141 | |
142 EXPECT_CALL(observer, OnSchemaRegistryUpdated(_)).Times(0); | |
143 registry1.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"), | |
144 schema); | |
145 Mock::VerifyAndClearExpectations(&observer); | |
146 | |
147 // Starting to track a registry issues notifications when it comes with new | |
148 // schemas. | |
149 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true)); | |
150 combined.Track(®istry1); | |
151 Mock::VerifyAndClearExpectations(&observer); | |
152 | |
153 // Adding a new empty registry does not trigger notifications. | |
154 EXPECT_CALL(observer, OnSchemaRegistryUpdated(_)).Times(0); | |
155 combined.Track(®istry2); | |
156 Mock::VerifyAndClearExpectations(&observer); | |
157 | |
158 // Adding the same component to the combined registry itself triggers | |
159 // notifications. | |
160 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true)); | |
161 combined.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"), | |
162 schema); | |
163 Mock::VerifyAndClearExpectations(&observer); | |
164 | |
165 // Adding components to the sub-registries triggers notifications. | |
166 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true)); | |
167 registry2.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def"), | |
168 schema); | |
169 Mock::VerifyAndClearExpectations(&observer); | |
170 | |
171 // If the same component is published in 2 sub-registries then the combined | |
172 // registry publishes one of them. | |
173 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true)); | |
174 registry1.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def"), | |
175 schema); | |
176 Mock::VerifyAndClearExpectations(&observer); | |
177 | |
178 ASSERT_EQ(1u, combined.schema_map()->GetDomains().size()); | |
179 ASSERT_TRUE(combined.schema_map()->GetComponents(POLICY_DOMAIN_EXTENSIONS)); | |
180 ASSERT_EQ( | |
181 2u, | |
182 combined.schema_map()->GetComponents(POLICY_DOMAIN_EXTENSIONS)->size()); | |
183 EXPECT_TRUE(combined.schema_map()->GetSchema( | |
184 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"))); | |
185 EXPECT_TRUE(combined.schema_map()->GetSchema( | |
186 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def"))); | |
187 EXPECT_FALSE(combined.schema_map()->GetSchema( | |
188 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"))); | |
189 | |
190 EXPECT_CALL(observer, OnSchemaRegistryUpdated(false)); | |
191 registry1.UnregisterComponent( | |
192 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc")); | |
193 Mock::VerifyAndClearExpectations(&observer); | |
194 // Still registered at the combined registry. | |
195 EXPECT_TRUE(combined.schema_map()->GetSchema( | |
196 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"))); | |
197 | |
198 EXPECT_CALL(observer, OnSchemaRegistryUpdated(false)); | |
199 combined.UnregisterComponent( | |
200 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc")); | |
201 Mock::VerifyAndClearExpectations(&observer); | |
202 // Now it's gone. | |
203 EXPECT_FALSE(combined.schema_map()->GetSchema( | |
204 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"))); | |
205 | |
206 EXPECT_CALL(observer, OnSchemaRegistryUpdated(false)); | |
207 registry1.UnregisterComponent( | |
208 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def")); | |
209 Mock::VerifyAndClearExpectations(&observer); | |
210 // Still registered at registry2. | |
211 EXPECT_TRUE(combined.schema_map()->GetSchema( | |
212 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def"))); | |
213 | |
214 EXPECT_CALL(observer, OnSchemaRegistryUpdated(false)); | |
215 registry2.UnregisterComponent( | |
216 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def")); | |
217 Mock::VerifyAndClearExpectations(&observer); | |
218 // Now it's gone. | |
219 EXPECT_FALSE(combined.schema_map()->GetSchema( | |
220 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "def"))); | |
221 | |
222 EXPECT_CALL(observer, OnSchemaRegistryUpdated(true)).Times(2); | |
223 registry1.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_CHROME, ""), | |
224 schema); | |
225 registry2.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "hij"), | |
226 schema); | |
227 Mock::VerifyAndClearExpectations(&observer); | |
228 | |
229 // Untracking |registry1| doesn't trigger an update nofitication, because it | |
230 // doesn't contain any components. | |
231 EXPECT_CALL(observer, OnSchemaRegistryUpdated(_)).Times(0); | |
232 combined.Untrack(®istry1); | |
233 Mock::VerifyAndClearExpectations(&observer); | |
234 | |
235 EXPECT_CALL(observer, OnSchemaRegistryUpdated(false)); | |
236 combined.Untrack(®istry2); | |
237 Mock::VerifyAndClearExpectations(&observer); | |
238 | |
239 combined.RemoveObserver(&observer); | |
240 } | |
241 | |
242 } // namespace policy | |
OLD | NEW |