OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/memory/ptr_util.h" | 6 #include "base/memory/ptr_util.h" |
7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
9 #include "base/values.h" | 9 #include "base/values.h" |
10 #include "content/public/child/v8_value_converter.h" | 10 #include "content/public/child/v8_value_converter.h" |
11 #include "extensions/renderer/api_binding.h" | 11 #include "extensions/renderer/api_binding.h" |
12 #include "extensions/renderer/api_binding_test_util.h" | 12 #include "extensions/renderer/api_binding_test_util.h" |
| 13 #include "extensions/renderer/api_event_handler.h" |
13 #include "extensions/renderer/api_request_handler.h" | 14 #include "extensions/renderer/api_request_handler.h" |
14 #include "gin/converter.h" | 15 #include "gin/converter.h" |
15 #include "gin/public/context_holder.h" | 16 #include "gin/public/context_holder.h" |
16 #include "gin/public/isolate_holder.h" | 17 #include "gin/public/isolate_holder.h" |
17 #include "gin/test/v8_test.h" | 18 #include "gin/test/v8_test.h" |
18 #include "gin/try_catch.h" | 19 #include "gin/try_catch.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
20 #include "v8/include/v8.h" | 21 #include "v8/include/v8.h" |
21 | 22 |
22 namespace extensions { | 23 namespace extensions { |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 } | 196 } |
196 | 197 |
197 arguments_.reset(); | 198 arguments_.reset(); |
198 } | 199 } |
199 | 200 |
200 TEST_F(APIBindingTest, Test) { | 201 TEST_F(APIBindingTest, Test) { |
201 std::unique_ptr<base::ListValue> functions = ListValueFromString(kFunctions); | 202 std::unique_ptr<base::ListValue> functions = ListValueFromString(kFunctions); |
202 ASSERT_TRUE(functions); | 203 ASSERT_TRUE(functions); |
203 ArgumentSpec::RefMap refs; | 204 ArgumentSpec::RefMap refs; |
204 APIBinding binding( | 205 APIBinding binding( |
205 "test", *functions, nullptr, | 206 "test", *functions, nullptr, nullptr, |
206 base::Bind(&APIBindingTest::OnFunctionCall, base::Unretained(this)), | 207 base::Bind(&APIBindingTest::OnFunctionCall, base::Unretained(this)), |
207 &refs); | 208 &refs); |
208 EXPECT_TRUE(refs.empty()); | 209 EXPECT_TRUE(refs.empty()); |
209 | 210 |
210 v8::Isolate* isolate = instance_->isolate(); | 211 v8::Isolate* isolate = instance_->isolate(); |
211 | 212 |
212 v8::HandleScope handle_scope(isolate); | 213 v8::HandleScope handle_scope(isolate); |
213 v8::Local<v8::Context> context = | 214 v8::Local<v8::Context> context = |
214 v8::Local<v8::Context>::New(isolate, context_); | 215 v8::Local<v8::Context>::New(isolate, context_); |
215 | 216 |
| 217 APIEventHandler event_handler( |
| 218 base::Bind(&RunFunctionOnGlobalAndIgnoreResult)); |
216 v8::Local<v8::Object> binding_object = | 219 v8::Local<v8::Object> binding_object = |
217 binding.CreateInstance(context, isolate, base::Bind(&AllowAllAPIs)); | 220 binding.CreateInstance(context, isolate, &event_handler, |
| 221 base::Bind(&AllowAllAPIs)); |
218 | 222 |
219 ExpectPass(binding_object, "obj.oneString('foo');", "['foo']"); | 223 ExpectPass(binding_object, "obj.oneString('foo');", "['foo']"); |
220 ExpectPass(binding_object, "obj.oneString('');", "['']"); | 224 ExpectPass(binding_object, "obj.oneString('');", "['']"); |
221 ExpectFailure(binding_object, "obj.oneString(1);", kError); | 225 ExpectFailure(binding_object, "obj.oneString(1);", kError); |
222 ExpectFailure(binding_object, "obj.oneString();", kError); | 226 ExpectFailure(binding_object, "obj.oneString();", kError); |
223 ExpectFailure(binding_object, "obj.oneString({});", kError); | 227 ExpectFailure(binding_object, "obj.oneString({});", kError); |
224 ExpectFailure(binding_object, "obj.oneString('foo', 'bar');", kError); | 228 ExpectFailure(binding_object, "obj.oneString('foo', 'bar');", kError); |
225 | 229 |
226 ExpectPass(binding_object, "obj.stringAndInt('foo', 42);", "['foo',42]"); | 230 ExpectPass(binding_object, "obj.stringAndInt('foo', 42);", "['foo',42]"); |
227 ExpectPass(binding_object, "obj.stringAndInt('foo', -1);", "['foo',-1]"); | 231 ExpectPass(binding_object, "obj.stringAndInt('foo', -1);", "['foo',-1]"); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 " }]" | 301 " }]" |
298 "}]"; | 302 "}]"; |
299 | 303 |
300 std::unique_ptr<base::ListValue> functions = | 304 std::unique_ptr<base::ListValue> functions = |
301 ListValueFromString(kRefFunctions); | 305 ListValueFromString(kRefFunctions); |
302 ASSERT_TRUE(functions); | 306 ASSERT_TRUE(functions); |
303 std::unique_ptr<base::ListValue> types = ListValueFromString(kTypes); | 307 std::unique_ptr<base::ListValue> types = ListValueFromString(kTypes); |
304 ASSERT_TRUE(types); | 308 ASSERT_TRUE(types); |
305 ArgumentSpec::RefMap refs; | 309 ArgumentSpec::RefMap refs; |
306 APIBinding binding( | 310 APIBinding binding( |
307 "test", *functions, types.get(), | 311 "test", *functions, types.get(), nullptr, |
308 base::Bind(&APIBindingTest::OnFunctionCall, base::Unretained(this)), | 312 base::Bind(&APIBindingTest::OnFunctionCall, base::Unretained(this)), |
309 &refs); | 313 &refs); |
310 EXPECT_EQ(2u, refs.size()); | 314 EXPECT_EQ(2u, refs.size()); |
311 EXPECT_TRUE(base::ContainsKey(refs, "refObj")); | 315 EXPECT_TRUE(base::ContainsKey(refs, "refObj")); |
312 EXPECT_TRUE(base::ContainsKey(refs, "refEnum")); | 316 EXPECT_TRUE(base::ContainsKey(refs, "refEnum")); |
313 | 317 |
314 v8::Isolate* isolate = instance_->isolate(); | 318 v8::Isolate* isolate = instance_->isolate(); |
315 | 319 |
316 v8::HandleScope handle_scope(isolate); | 320 v8::HandleScope handle_scope(isolate); |
317 v8::Local<v8::Context> context = | 321 v8::Local<v8::Context> context = |
318 v8::Local<v8::Context>::New(isolate, context_); | 322 v8::Local<v8::Context>::New(isolate, context_); |
319 | 323 |
| 324 APIEventHandler event_handler( |
| 325 base::Bind(&RunFunctionOnGlobalAndIgnoreResult)); |
320 v8::Local<v8::Object> binding_object = | 326 v8::Local<v8::Object> binding_object = |
321 binding.CreateInstance(context, isolate, base::Bind(&AllowAllAPIs)); | 327 binding.CreateInstance(context, isolate, &event_handler, |
| 328 base::Bind(&AllowAllAPIs)); |
322 | 329 |
323 ExpectPass(binding_object, "obj.takesRefObj({prop1: 'foo'})", | 330 ExpectPass(binding_object, "obj.takesRefObj({prop1: 'foo'})", |
324 "[{'prop1':'foo'}]"); | 331 "[{'prop1':'foo'}]"); |
325 ExpectPass(binding_object, "obj.takesRefObj({prop1: 'foo', prop2: 2})", | 332 ExpectPass(binding_object, "obj.takesRefObj({prop1: 'foo', prop2: 2})", |
326 "[{'prop1':'foo','prop2':2}]"); | 333 "[{'prop1':'foo','prop2':2}]"); |
327 ExpectFailure(binding_object, "obj.takesRefObj({prop1: 'foo', prop2: 'a'})", | 334 ExpectFailure(binding_object, "obj.takesRefObj({prop1: 'foo', prop2: 'a'})", |
328 kError); | 335 kError); |
329 ExpectPass(binding_object, "obj.takesRefEnum('alpha')", "['alpha']"); | 336 ExpectPass(binding_object, "obj.takesRefEnum('alpha')", "['alpha']"); |
330 ExpectPass(binding_object, "obj.takesRefEnum('beta')", "['beta']"); | 337 ExpectPass(binding_object, "obj.takesRefEnum('beta')", "['beta']"); |
331 ExpectFailure(binding_object, "obj.takesRefEnum('gamma')", kError); | 338 ExpectFailure(binding_object, "obj.takesRefEnum('gamma')", kError); |
(...skipping 12 matching lines...) Expand all Loading... |
344 " 'parameters': []" | 351 " 'parameters': []" |
345 "}, {" | 352 "}, {" |
346 " 'name': 'restrictedTwo'," | 353 " 'name': 'restrictedTwo'," |
347 " 'parameters': []" | 354 " 'parameters': []" |
348 "}]"; | 355 "}]"; |
349 std::unique_ptr<base::ListValue> functions = | 356 std::unique_ptr<base::ListValue> functions = |
350 ListValueFromString(kRestrictedFunctions); | 357 ListValueFromString(kRestrictedFunctions); |
351 ASSERT_TRUE(functions); | 358 ASSERT_TRUE(functions); |
352 ArgumentSpec::RefMap refs; | 359 ArgumentSpec::RefMap refs; |
353 APIBinding binding( | 360 APIBinding binding( |
354 "test", *functions, nullptr, | 361 "test", *functions, nullptr, nullptr, |
355 base::Bind(&APIBindingTest::OnFunctionCall, base::Unretained(this)), | 362 base::Bind(&APIBindingTest::OnFunctionCall, base::Unretained(this)), |
356 &refs); | 363 &refs); |
357 | 364 |
358 v8::Isolate* isolate = instance_->isolate(); | 365 v8::Isolate* isolate = instance_->isolate(); |
359 v8::HandleScope handle_scope(isolate); | 366 v8::HandleScope handle_scope(isolate); |
360 v8::Local<v8::Context> context = | 367 v8::Local<v8::Context> context = |
361 v8::Local<v8::Context>::New(isolate, context_); | 368 v8::Local<v8::Context>::New(isolate, context_); |
362 | 369 |
363 auto is_available = [](const std::string& name) { | 370 auto is_available = [](const std::string& name) { |
364 std::set<std::string> functions = {"test.allowedOne", "test.allowedTwo", | 371 std::set<std::string> functions = {"test.allowedOne", "test.allowedTwo", |
365 "test.restrictedOne", | 372 "test.restrictedOne", |
366 "test.restrictedTwo"}; | 373 "test.restrictedTwo"}; |
367 EXPECT_TRUE(functions.count(name)); | 374 EXPECT_TRUE(functions.count(name)); |
368 return name == "test.allowedOne" || name == "test.allowedTwo"; | 375 return name == "test.allowedOne" || name == "test.allowedTwo"; |
369 }; | 376 }; |
370 | 377 |
| 378 APIEventHandler event_handler( |
| 379 base::Bind(&RunFunctionOnGlobalAndIgnoreResult)); |
371 v8::Local<v8::Object> binding_object = | 380 v8::Local<v8::Object> binding_object = |
372 binding.CreateInstance(context, isolate, base::Bind(is_available)); | 381 binding.CreateInstance(context, isolate, &event_handler, |
| 382 base::Bind(is_available)); |
373 | 383 |
374 auto is_defined = [&binding_object, context](const std::string& name) { | 384 auto is_defined = [&binding_object, context](const std::string& name) { |
375 v8::Local<v8::Value> val = | 385 v8::Local<v8::Value> val = |
376 GetPropertyFromObject(binding_object, context, name); | 386 GetPropertyFromObject(binding_object, context, name); |
377 EXPECT_FALSE(val.IsEmpty()); | 387 EXPECT_FALSE(val.IsEmpty()); |
378 return !val->IsUndefined() && !val->IsNull(); | 388 return !val->IsUndefined() && !val->IsNull(); |
379 }; | 389 }; |
380 | 390 |
381 EXPECT_TRUE(is_defined("allowedOne")); | 391 EXPECT_TRUE(is_defined("allowedOne")); |
382 EXPECT_TRUE(is_defined("allowedTwo")); | 392 EXPECT_TRUE(is_defined("allowedTwo")); |
383 EXPECT_FALSE(is_defined("restrictedOne")); | 393 EXPECT_FALSE(is_defined("restrictedOne")); |
384 EXPECT_FALSE(is_defined("restrictedTwo")); | 394 EXPECT_FALSE(is_defined("restrictedTwo")); |
385 } | 395 } |
386 | 396 |
| 397 // Tests that events specified in the API are created as properties of the API |
| 398 // object. |
| 399 TEST_F(APIBindingTest, TestEventCreation) { |
| 400 const char kEvents[] = "[{'name': 'onFoo'}, {'name': 'onBar'}]"; |
| 401 std::unique_ptr<base::ListValue> events = ListValueFromString(kEvents); |
| 402 ASSERT_TRUE(events); |
| 403 std::unique_ptr<base::ListValue> functions = ListValueFromString(kFunctions); |
| 404 ASSERT_TRUE(functions); |
| 405 ArgumentSpec::RefMap refs; |
| 406 APIBinding binding( |
| 407 "test", *functions, nullptr, events.get(), |
| 408 base::Bind(&APIBindingTest::OnFunctionCall, base::Unretained(this)), |
| 409 &refs); |
| 410 |
| 411 v8::Isolate* isolate = instance_->isolate(); |
| 412 v8::HandleScope handle_scope(isolate); |
| 413 v8::Local<v8::Context> context = |
| 414 v8::Local<v8::Context>::New(isolate, context_); |
| 415 |
| 416 APIEventHandler event_handler( |
| 417 base::Bind(&RunFunctionOnGlobalAndIgnoreResult)); |
| 418 v8::Local<v8::Object> binding_object = |
| 419 binding.CreateInstance(context, isolate, &event_handler, |
| 420 base::Bind(&AllowAllAPIs)); |
| 421 |
| 422 // Event behavior is tested in the APIEventHandler unittests as well as the |
| 423 // APIBindingsSystem tests, so we really only need to check that the events |
| 424 // are being initialized on the object. |
| 425 v8::Maybe<bool> has_on_foo = |
| 426 binding_object->Has(context, gin::StringToV8(isolate, "onFoo")); |
| 427 EXPECT_TRUE(has_on_foo.IsJust()); |
| 428 EXPECT_TRUE(has_on_foo.FromJust()); |
| 429 |
| 430 v8::Maybe<bool> has_on_bar = |
| 431 binding_object->Has(context, gin::StringToV8(isolate, "onBar")); |
| 432 EXPECT_TRUE(has_on_bar.IsJust()); |
| 433 EXPECT_TRUE(has_on_bar.FromJust()); |
| 434 |
| 435 v8::Maybe<bool> has_on_baz = |
| 436 binding_object->Has(context, gin::StringToV8(isolate, "onBaz")); |
| 437 EXPECT_TRUE(has_on_baz.IsJust()); |
| 438 EXPECT_FALSE(has_on_baz.FromJust()); |
| 439 } |
| 440 |
387 } // namespace extensions | 441 } // namespace extensions |
OLD | NEW |