| 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 "extensions/renderer/api_binding.h" | 10 #include "extensions/renderer/api_binding.h" |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 last_request_.reset(); | 306 last_request_.reset(); |
| 307 } | 307 } |
| 308 | 308 |
| 309 TEST_F(APIBindingUnittest, TestEmptyAPI) { | 309 TEST_F(APIBindingUnittest, TestEmptyAPI) { |
| 310 InitializeBinding(); | 310 InitializeBinding(); |
| 311 | 311 |
| 312 v8::HandleScope handle_scope(isolate()); | 312 v8::HandleScope handle_scope(isolate()); |
| 313 v8::Local<v8::Context> context = MainContext(); | 313 v8::Local<v8::Context> context = MainContext(); |
| 314 | 314 |
| 315 v8::Local<v8::Object> binding_object = | 315 v8::Local<v8::Object> binding_object = |
| 316 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 316 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 317 EXPECT_EQ( | 317 EXPECT_EQ( |
| 318 0u, | 318 0u, |
| 319 binding_object->GetOwnPropertyNames(context).ToLocalChecked()->Length()); | 319 binding_object->GetOwnPropertyNames(context).ToLocalChecked()->Length()); |
| 320 } | 320 } |
| 321 | 321 |
| 322 TEST_F(APIBindingUnittest, Test) { | 322 TEST_F(APIBindingUnittest, Test) { |
| 323 // TODO(devlin): Move this test to an api_signature_unittest file? It really | 323 // TODO(devlin): Move this test to an api_signature_unittest file? It really |
| 324 // only tests parsing. | 324 // only tests parsing. |
| 325 SetFunctions(kFunctions); | 325 SetFunctions(kFunctions); |
| 326 InitializeBinding(); | 326 InitializeBinding(); |
| 327 | 327 |
| 328 v8::HandleScope handle_scope(isolate()); | 328 v8::HandleScope handle_scope(isolate()); |
| 329 v8::Local<v8::Context> context = MainContext(); | 329 v8::Local<v8::Context> context = MainContext(); |
| 330 | 330 |
| 331 v8::Local<v8::Object> binding_object = | 331 v8::Local<v8::Object> binding_object = |
| 332 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 332 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 333 | 333 |
| 334 ExpectPass(binding_object, "obj.oneString('foo');", "['foo']", false); | 334 ExpectPass(binding_object, "obj.oneString('foo');", "['foo']", false); |
| 335 ExpectPass(binding_object, "obj.oneString('');", "['']", false); | 335 ExpectPass(binding_object, "obj.oneString('');", "['']", false); |
| 336 ExpectFailure(binding_object, "obj.oneString(1);", kError); | 336 ExpectFailure(binding_object, "obj.oneString(1);", kError); |
| 337 ExpectFailure(binding_object, "obj.oneString();", kError); | 337 ExpectFailure(binding_object, "obj.oneString();", kError); |
| 338 ExpectFailure(binding_object, "obj.oneString({});", kError); | 338 ExpectFailure(binding_object, "obj.oneString({});", kError); |
| 339 ExpectFailure(binding_object, "obj.oneString('foo', 'bar');", kError); | 339 ExpectFailure(binding_object, "obj.oneString('foo', 'bar');", kError); |
| 340 | 340 |
| 341 ExpectPass(binding_object, "obj.stringAndInt('foo', 42);", "['foo',42]", | 341 ExpectPass(binding_object, "obj.stringAndInt('foo', 42);", "['foo',42]", |
| 342 false); | 342 false); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 " 'enum': [{'name': 'omega'}]" | 416 " 'enum': [{'name': 'omega'}]" |
| 417 "}]"; | 417 "}]"; |
| 418 | 418 |
| 419 SetTypes(kTypes); | 419 SetTypes(kTypes); |
| 420 InitializeBinding(); | 420 InitializeBinding(); |
| 421 | 421 |
| 422 v8::HandleScope handle_scope(isolate()); | 422 v8::HandleScope handle_scope(isolate()); |
| 423 v8::Local<v8::Context> context = MainContext(); | 423 v8::Local<v8::Context> context = MainContext(); |
| 424 | 424 |
| 425 v8::Local<v8::Object> binding_object = | 425 v8::Local<v8::Object> binding_object = |
| 426 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 426 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 427 | 427 |
| 428 const char kExpected[] = | 428 const char kExpected[] = |
| 429 "{'ALPHA':'alpha','CAMEL_CASE':'camelCase','HYPHEN_ATED':'Hyphen-ated'," | 429 "{'ALPHA':'alpha','CAMEL_CASE':'camelCase','HYPHEN_ATED':'Hyphen-ated'," |
| 430 "'NUMS123':'nums123','SCREAMING':'SCREAMING','_42NUMS':'42nums'}"; | 430 "'NUMS123':'nums123','SCREAMING':'SCREAMING','_42NUMS':'42nums'}"; |
| 431 EXPECT_EQ(ReplaceSingleQuotes(kExpected), | 431 EXPECT_EQ(ReplaceSingleQuotes(kExpected), |
| 432 GetStringPropertyFromObject(binding_object, context, "first")); | 432 GetStringPropertyFromObject(binding_object, context, "first")); |
| 433 EXPECT_EQ(ReplaceSingleQuotes("{'OMEGA':'omega'}"), | 433 EXPECT_EQ(ReplaceSingleQuotes("{'OMEGA':'omega'}"), |
| 434 GetStringPropertyFromObject(binding_object, context, "last")); | 434 GetStringPropertyFromObject(binding_object, context, "last")); |
| 435 } | 435 } |
| 436 | 436 |
| 437 // Test that empty enum entries are (unfortunately) allowed. | 437 // Test that empty enum entries are (unfortunately) allowed. |
| 438 TEST_F(APIBindingUnittest, EnumWithEmptyEntry) { | 438 TEST_F(APIBindingUnittest, EnumWithEmptyEntry) { |
| 439 const char kTypes[] = | 439 const char kTypes[] = |
| 440 "[{" | 440 "[{" |
| 441 " 'id': 'enumWithEmpty'," | 441 " 'id': 'enumWithEmpty'," |
| 442 " 'type': 'string'," | 442 " 'type': 'string'," |
| 443 " 'enum': [{'name': ''}, {'name': 'other'}]" | 443 " 'enum': [{'name': ''}, {'name': 'other'}]" |
| 444 "}]"; | 444 "}]"; |
| 445 | 445 |
| 446 SetTypes(kTypes); | 446 SetTypes(kTypes); |
| 447 InitializeBinding(); | 447 InitializeBinding(); |
| 448 | 448 |
| 449 v8::HandleScope handle_scope(isolate()); | 449 v8::HandleScope handle_scope(isolate()); |
| 450 v8::Local<v8::Context> context = MainContext(); | 450 v8::Local<v8::Context> context = MainContext(); |
| 451 | 451 |
| 452 v8::Local<v8::Object> binding_object = | 452 v8::Local<v8::Object> binding_object = |
| 453 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 453 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 454 | 454 |
| 455 EXPECT_EQ( | 455 EXPECT_EQ( |
| 456 "{\"\":\"\",\"OTHER\":\"other\"}", | 456 "{\"\":\"\",\"OTHER\":\"other\"}", |
| 457 GetStringPropertyFromObject(binding_object, context, "enumWithEmpty")); | 457 GetStringPropertyFromObject(binding_object, context, "enumWithEmpty")); |
| 458 } | 458 } |
| 459 | 459 |
| 460 TEST_F(APIBindingUnittest, TypeRefsTest) { | 460 TEST_F(APIBindingUnittest, TypeRefsTest) { |
| 461 const char kTypes[] = | 461 const char kTypes[] = |
| 462 "[{" | 462 "[{" |
| 463 " 'id': 'refObj'," | 463 " 'id': 'refObj'," |
| (...skipping 26 matching lines...) Expand all Loading... |
| 490 SetTypes(kTypes); | 490 SetTypes(kTypes); |
| 491 InitializeBinding(); | 491 InitializeBinding(); |
| 492 EXPECT_EQ(2u, type_refs().size()); | 492 EXPECT_EQ(2u, type_refs().size()); |
| 493 EXPECT_TRUE(type_refs().GetSpec("refObj")); | 493 EXPECT_TRUE(type_refs().GetSpec("refObj")); |
| 494 EXPECT_TRUE(type_refs().GetSpec("refEnum")); | 494 EXPECT_TRUE(type_refs().GetSpec("refEnum")); |
| 495 | 495 |
| 496 v8::HandleScope handle_scope(isolate()); | 496 v8::HandleScope handle_scope(isolate()); |
| 497 v8::Local<v8::Context> context = MainContext(); | 497 v8::Local<v8::Context> context = MainContext(); |
| 498 | 498 |
| 499 v8::Local<v8::Object> binding_object = | 499 v8::Local<v8::Object> binding_object = |
| 500 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 500 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 501 | 501 |
| 502 ExpectPass(binding_object, "obj.takesRefObj({prop1: 'foo'})", | 502 ExpectPass(binding_object, "obj.takesRefObj({prop1: 'foo'})", |
| 503 "[{'prop1':'foo'}]", false); | 503 "[{'prop1':'foo'}]", false); |
| 504 ExpectPass(binding_object, "obj.takesRefObj({prop1: 'foo', prop2: 2})", | 504 ExpectPass(binding_object, "obj.takesRefObj({prop1: 'foo', prop2: 2})", |
| 505 "[{'prop1':'foo','prop2':2}]", false); | 505 "[{'prop1':'foo','prop2':2}]", false); |
| 506 ExpectFailure(binding_object, "obj.takesRefObj({prop1: 'foo', prop2: 'a'})", | 506 ExpectFailure(binding_object, "obj.takesRefObj({prop1: 'foo', prop2: 'a'})", |
| 507 kError); | 507 kError); |
| 508 ExpectPass(binding_object, "obj.takesRefEnum('alpha')", "['alpha']", false); | 508 ExpectPass(binding_object, "obj.takesRefEnum('alpha')", "['alpha']", false); |
| 509 ExpectPass(binding_object, "obj.takesRefEnum('beta')", "['beta']", false); | 509 ExpectPass(binding_object, "obj.takesRefEnum('beta')", "['beta']", false); |
| 510 ExpectPass(binding_object, "obj.takesRefEnum(obj.refEnum.BETA)", "['beta']", | 510 ExpectPass(binding_object, "obj.takesRefEnum(obj.refEnum.BETA)", "['beta']", |
| (...skipping 28 matching lines...) Expand all Loading... |
| 539 auto is_available = [](const std::string& name) { | 539 auto is_available = [](const std::string& name) { |
| 540 std::set<std::string> allowed = {"test.allowedOne", "test.allowedTwo", | 540 std::set<std::string> allowed = {"test.allowedOne", "test.allowedTwo", |
| 541 "test.allowedEvent"}; | 541 "test.allowedEvent"}; |
| 542 std::set<std::string> restricted = { | 542 std::set<std::string> restricted = { |
| 543 "test.restrictedOne", "test.restrictedTwo", "test.restrictedEvent"}; | 543 "test.restrictedOne", "test.restrictedTwo", "test.restrictedEvent"}; |
| 544 EXPECT_TRUE(allowed.count(name) || restricted.count(name)) << name; | 544 EXPECT_TRUE(allowed.count(name) || restricted.count(name)) << name; |
| 545 return allowed.count(name) != 0; | 545 return allowed.count(name) != 0; |
| 546 }; | 546 }; |
| 547 | 547 |
| 548 v8::Local<v8::Object> binding_object = | 548 v8::Local<v8::Object> binding_object = |
| 549 binding()->CreateInstance(context, isolate(), base::Bind(is_available)); | 549 binding()->CreateInstance(context, base::Bind(is_available)); |
| 550 | 550 |
| 551 auto is_defined = [&binding_object, context](const std::string& name) { | 551 auto is_defined = [&binding_object, context](const std::string& name) { |
| 552 v8::Local<v8::Value> val = | 552 v8::Local<v8::Value> val = |
| 553 GetPropertyFromObject(binding_object, context, name); | 553 GetPropertyFromObject(binding_object, context, name); |
| 554 EXPECT_FALSE(val.IsEmpty()); | 554 EXPECT_FALSE(val.IsEmpty()); |
| 555 return !val->IsUndefined() && !val->IsNull(); | 555 return !val->IsUndefined() && !val->IsNull(); |
| 556 }; | 556 }; |
| 557 | 557 |
| 558 EXPECT_TRUE(is_defined("allowedOne")); | 558 EXPECT_TRUE(is_defined("allowedOne")); |
| 559 EXPECT_TRUE(is_defined("allowedTwo")); | 559 EXPECT_TRUE(is_defined("allowedTwo")); |
| 560 EXPECT_TRUE(is_defined("allowedEvent")); | 560 EXPECT_TRUE(is_defined("allowedEvent")); |
| 561 EXPECT_FALSE(is_defined("restrictedOne")); | 561 EXPECT_FALSE(is_defined("restrictedOne")); |
| 562 EXPECT_FALSE(is_defined("restrictedTwo")); | 562 EXPECT_FALSE(is_defined("restrictedTwo")); |
| 563 EXPECT_FALSE(is_defined("restrictedEvent")); | 563 EXPECT_FALSE(is_defined("restrictedEvent")); |
| 564 } | 564 } |
| 565 | 565 |
| 566 // Tests that events specified in the API are created as properties of the API | 566 // Tests that events specified in the API are created as properties of the API |
| 567 // object. | 567 // object. |
| 568 TEST_F(APIBindingUnittest, TestEventCreation) { | 568 TEST_F(APIBindingUnittest, TestEventCreation) { |
| 569 SetEvents("[{'name': 'onFoo'}, {'name': 'onBar'}]"); | 569 SetEvents("[{'name': 'onFoo'}, {'name': 'onBar'}]"); |
| 570 SetFunctions(kFunctions); | 570 SetFunctions(kFunctions); |
| 571 InitializeBinding(); | 571 InitializeBinding(); |
| 572 | 572 |
| 573 v8::HandleScope handle_scope(isolate()); | 573 v8::HandleScope handle_scope(isolate()); |
| 574 v8::Local<v8::Context> context = MainContext(); | 574 v8::Local<v8::Context> context = MainContext(); |
| 575 | 575 |
| 576 v8::Local<v8::Object> binding_object = | 576 v8::Local<v8::Object> binding_object = |
| 577 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 577 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 578 | 578 |
| 579 // Event behavior is tested in the APIEventHandler unittests as well as the | 579 // Event behavior is tested in the APIEventHandler unittests as well as the |
| 580 // APIBindingsSystem tests, so we really only need to check that the events | 580 // APIBindingsSystem tests, so we really only need to check that the events |
| 581 // are being initialized on the object. | 581 // are being initialized on the object. |
| 582 v8::Maybe<bool> has_on_foo = | 582 v8::Maybe<bool> has_on_foo = |
| 583 binding_object->Has(context, gin::StringToV8(isolate(), "onFoo")); | 583 binding_object->Has(context, gin::StringToV8(isolate(), "onFoo")); |
| 584 EXPECT_TRUE(has_on_foo.IsJust()); | 584 EXPECT_TRUE(has_on_foo.IsJust()); |
| 585 EXPECT_TRUE(has_on_foo.FromJust()); | 585 EXPECT_TRUE(has_on_foo.FromJust()); |
| 586 | 586 |
| 587 v8::Maybe<bool> has_on_bar = | 587 v8::Maybe<bool> has_on_bar = |
| (...skipping 17 matching lines...) Expand all Loading... |
| 605 " 'subprop1': { 'value': 'some value', 'type': 'string' }," | 605 " 'subprop1': { 'value': 'some value', 'type': 'string' }," |
| 606 " 'subprop2': { 'value': true, 'type': 'boolean' }" | 606 " 'subprop2': { 'value': true, 'type': 'boolean' }" |
| 607 " }" | 607 " }" |
| 608 " }" | 608 " }" |
| 609 "}"); | 609 "}"); |
| 610 InitializeBinding(); | 610 InitializeBinding(); |
| 611 | 611 |
| 612 v8::HandleScope handle_scope(isolate()); | 612 v8::HandleScope handle_scope(isolate()); |
| 613 v8::Local<v8::Context> context = MainContext(); | 613 v8::Local<v8::Context> context = MainContext(); |
| 614 v8::Local<v8::Object> binding_object = | 614 v8::Local<v8::Object> binding_object = |
| 615 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 615 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 616 EXPECT_EQ("17", | 616 EXPECT_EQ("17", |
| 617 GetStringPropertyFromObject(binding_object, context, "prop1")); | 617 GetStringPropertyFromObject(binding_object, context, "prop1")); |
| 618 EXPECT_EQ(R"({"subprop1":"some value","subprop2":true})", | 618 EXPECT_EQ(R"({"subprop1":"some value","subprop2":true})", |
| 619 GetStringPropertyFromObject(binding_object, context, "prop2")); | 619 GetStringPropertyFromObject(binding_object, context, "prop2")); |
| 620 } | 620 } |
| 621 | 621 |
| 622 TEST_F(APIBindingUnittest, TestRefProperties) { | 622 TEST_F(APIBindingUnittest, TestRefProperties) { |
| 623 SetProperties( | 623 SetProperties( |
| 624 "{" | 624 "{" |
| 625 " 'alpha': {" | 625 " 'alpha': {" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 return result; | 657 return result; |
| 658 }; | 658 }; |
| 659 | 659 |
| 660 SetCreateCustomType(base::Bind(create_custom_type)); | 660 SetCreateCustomType(base::Bind(create_custom_type)); |
| 661 | 661 |
| 662 InitializeBinding(); | 662 InitializeBinding(); |
| 663 | 663 |
| 664 v8::HandleScope handle_scope(isolate()); | 664 v8::HandleScope handle_scope(isolate()); |
| 665 v8::Local<v8::Context> context = MainContext(); | 665 v8::Local<v8::Context> context = MainContext(); |
| 666 v8::Local<v8::Object> binding_object = | 666 v8::Local<v8::Object> binding_object = |
| 667 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 667 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 668 EXPECT_EQ(R"({"alphaProp":"alphaVal"})", | 668 EXPECT_EQ(R"({"alphaProp":"alphaVal"})", |
| 669 GetStringPropertyFromObject(binding_object, context, "alpha")); | 669 GetStringPropertyFromObject(binding_object, context, "alpha")); |
| 670 EXPECT_EQ( | 670 EXPECT_EQ( |
| 671 R"({"betaProp":"betaVal"})", | 671 R"({"betaProp":"betaVal"})", |
| 672 GetStringPropertyFromObject(binding_object, context, "beta")); | 672 GetStringPropertyFromObject(binding_object, context, "beta")); |
| 673 } | 673 } |
| 674 | 674 |
| 675 TEST_F(APIBindingUnittest, TestDisposedContext) { | 675 TEST_F(APIBindingUnittest, TestDisposedContext) { |
| 676 SetFunctions(kFunctions); | 676 SetFunctions(kFunctions); |
| 677 InitializeBinding(); | 677 InitializeBinding(); |
| 678 | 678 |
| 679 v8::HandleScope handle_scope(isolate()); | 679 v8::HandleScope handle_scope(isolate()); |
| 680 v8::Local<v8::Context> context = MainContext(); | 680 v8::Local<v8::Context> context = MainContext(); |
| 681 | 681 |
| 682 v8::Local<v8::Object> binding_object = | 682 v8::Local<v8::Object> binding_object = |
| 683 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 683 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 684 | 684 |
| 685 v8::Local<v8::Function> func = | 685 v8::Local<v8::Function> func = |
| 686 FunctionFromString(context, "(function(obj) { obj.oneString('foo'); })"); | 686 FunctionFromString(context, "(function(obj) { obj.oneString('foo'); })"); |
| 687 v8::Local<v8::Value> argv[] = {binding_object}; | 687 v8::Local<v8::Value> argv[] = {binding_object}; |
| 688 DisposeContext(context); | 688 DisposeContext(context); |
| 689 RunFunction(func, context, arraysize(argv), argv); | 689 RunFunction(func, context, arraysize(argv), argv); |
| 690 EXPECT_FALSE(HandlerWasInvoked()); | 690 EXPECT_FALSE(HandlerWasInvoked()); |
| 691 // This test passes if this does not crash, even under AddressSanitizer | 691 // This test passes if this does not crash, even under AddressSanitizer |
| 692 // builds. | 692 // builds. |
| 693 } | 693 } |
| 694 | 694 |
| 695 TEST_F(APIBindingUnittest, MultipleContexts) { | 695 TEST_F(APIBindingUnittest, MultipleContexts) { |
| 696 v8::HandleScope handle_scope(isolate()); | 696 v8::HandleScope handle_scope(isolate()); |
| 697 v8::Local<v8::Context> context_a = MainContext(); | 697 v8::Local<v8::Context> context_a = MainContext(); |
| 698 v8::Local<v8::Context> context_b = AddContext(); | 698 v8::Local<v8::Context> context_b = AddContext(); |
| 699 | 699 |
| 700 SetFunctions(kFunctions); | 700 SetFunctions(kFunctions); |
| 701 InitializeBinding(); | 701 InitializeBinding(); |
| 702 | 702 |
| 703 v8::Local<v8::Object> binding_object_a = binding()->CreateInstance( | 703 v8::Local<v8::Object> binding_object_a = |
| 704 context_a, isolate(), base::Bind(&AllowAllAPIs)); | 704 binding()->CreateInstance(context_a, base::Bind(&AllowAllAPIs)); |
| 705 v8::Local<v8::Object> binding_object_b = binding()->CreateInstance( | 705 v8::Local<v8::Object> binding_object_b = |
| 706 context_b, isolate(), base::Bind(&AllowAllAPIs)); | 706 binding()->CreateInstance(context_b, base::Bind(&AllowAllAPIs)); |
| 707 | 707 |
| 708 ExpectPass(context_a, binding_object_a, "obj.oneString('foo');", "['foo']", | 708 ExpectPass(context_a, binding_object_a, "obj.oneString('foo');", "['foo']", |
| 709 false); | 709 false); |
| 710 ExpectPass(context_b, binding_object_b, "obj.oneString('foo');", "['foo']", | 710 ExpectPass(context_b, binding_object_b, "obj.oneString('foo');", "['foo']", |
| 711 false); | 711 false); |
| 712 DisposeContext(context_a); | 712 DisposeContext(context_a); |
| 713 ExpectPass(context_b, binding_object_b, "obj.oneString('foo');", "['foo']", | 713 ExpectPass(context_b, binding_object_b, "obj.oneString('foo');", "['foo']", |
| 714 false); | 714 false); |
| 715 } | 715 } |
| 716 | 716 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 737 }; | 737 }; |
| 738 hooks->AddHandler("test.oneString", base::Bind(hook, &did_call)); | 738 hooks->AddHandler("test.oneString", base::Bind(hook, &did_call)); |
| 739 SetHooksDelegate(std::move(hooks)); | 739 SetHooksDelegate(std::move(hooks)); |
| 740 | 740 |
| 741 InitializeBinding(); | 741 InitializeBinding(); |
| 742 | 742 |
| 743 v8::HandleScope handle_scope(isolate()); | 743 v8::HandleScope handle_scope(isolate()); |
| 744 v8::Local<v8::Context> context = MainContext(); | 744 v8::Local<v8::Context> context = MainContext(); |
| 745 | 745 |
| 746 v8::Local<v8::Object> binding_object = | 746 v8::Local<v8::Object> binding_object = |
| 747 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 747 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 748 | 748 |
| 749 // First try calling the oneString() method, which has a custom hook | 749 // First try calling the oneString() method, which has a custom hook |
| 750 // installed. | 750 // installed. |
| 751 v8::Local<v8::Function> func = | 751 v8::Local<v8::Function> func = |
| 752 FunctionFromString(context, "(function(obj) { obj.oneString('foo'); })"); | 752 FunctionFromString(context, "(function(obj) { obj.oneString('foo'); })"); |
| 753 v8::Local<v8::Value> args[] = {binding_object}; | 753 v8::Local<v8::Value> args[] = {binding_object}; |
| 754 RunFunction(func, context, 1, args); | 754 RunFunction(func, context, 1, args); |
| 755 EXPECT_TRUE(did_call); | 755 EXPECT_TRUE(did_call); |
| 756 | 756 |
| 757 // Other methods, like stringAndInt(), should behave normally. | 757 // Other methods, like stringAndInt(), should behave normally. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 778 FunctionFromString(context, kRegisterHook); | 778 FunctionFromString(context, kRegisterHook); |
| 779 v8::Local<v8::Value> args[] = {js_hooks}; | 779 v8::Local<v8::Value> args[] = {js_hooks}; |
| 780 RunFunctionOnGlobal(function, context, arraysize(args), args); | 780 RunFunctionOnGlobal(function, context, arraysize(args), args); |
| 781 } | 781 } |
| 782 | 782 |
| 783 SetFunctions(kFunctions); | 783 SetFunctions(kFunctions); |
| 784 SetHooks(std::move(hooks)); | 784 SetHooks(std::move(hooks)); |
| 785 InitializeBinding(); | 785 InitializeBinding(); |
| 786 | 786 |
| 787 v8::Local<v8::Object> binding_object = | 787 v8::Local<v8::Object> binding_object = |
| 788 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 788 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 789 | 789 |
| 790 // First try calling with an invalid invocation. An error should be raised and | 790 // First try calling with an invalid invocation. An error should be raised and |
| 791 // the hook should never have been called, since the arguments didn't match. | 791 // the hook should never have been called, since the arguments didn't match. |
| 792 ExpectFailure(binding_object, "obj.oneString(1);", kError); | 792 ExpectFailure(binding_object, "obj.oneString(1);", kError); |
| 793 v8::Local<v8::Value> property = | 793 v8::Local<v8::Value> property = |
| 794 GetPropertyFromObject(context->Global(), context, "requestArguments"); | 794 GetPropertyFromObject(context->Global(), context, "requestArguments"); |
| 795 ASSERT_FALSE(property.IsEmpty()); | 795 ASSERT_FALSE(property.IsEmpty()); |
| 796 EXPECT_TRUE(property->IsUndefined()); | 796 EXPECT_TRUE(property->IsUndefined()); |
| 797 | 797 |
| 798 // Try calling the oneString() method with valid arguments. The hook should | 798 // Try calling the oneString() method with valid arguments. The hook should |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 v8::Local<v8::Object> js_hooks = hooks->GetJSHookInterface(context); | 830 v8::Local<v8::Object> js_hooks = hooks->GetJSHookInterface(context); |
| 831 v8::Local<v8::Function> function = FunctionFromString(context, kRegisterHook); | 831 v8::Local<v8::Function> function = FunctionFromString(context, kRegisterHook); |
| 832 v8::Local<v8::Value> args[] = {js_hooks}; | 832 v8::Local<v8::Value> args[] = {js_hooks}; |
| 833 RunFunctionOnGlobal(function, context, arraysize(args), args); | 833 RunFunctionOnGlobal(function, context, arraysize(args), args); |
| 834 | 834 |
| 835 SetHooks(std::move(hooks)); | 835 SetHooks(std::move(hooks)); |
| 836 SetFunctions(kFunctions); | 836 SetFunctions(kFunctions); |
| 837 InitializeBinding(); | 837 InitializeBinding(); |
| 838 | 838 |
| 839 v8::Local<v8::Object> binding_object = | 839 v8::Local<v8::Object> binding_object = |
| 840 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 840 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 841 | 841 |
| 842 // Call the method with a hook. Since the hook updates arguments before | 842 // Call the method with a hook. Since the hook updates arguments before |
| 843 // validation, we should be able to pass in invalid arguments and still | 843 // validation, we should be able to pass in invalid arguments and still |
| 844 // have the hook called. | 844 // have the hook called. |
| 845 ExpectFailure(binding_object, "obj.oneString(false);", kError); | 845 ExpectFailure(binding_object, "obj.oneString(false);", kError); |
| 846 EXPECT_EQ("[false]", GetStringPropertyFromObject( | 846 EXPECT_EQ("[false]", GetStringPropertyFromObject( |
| 847 context->Global(), context, "requestArguments")); | 847 context->Global(), context, "requestArguments")); |
| 848 | 848 |
| 849 ExpectPass(binding_object, "obj.oneString(true);", "['hooked']", false); | 849 ExpectPass(binding_object, "obj.oneString(true);", "['hooked']", false); |
| 850 EXPECT_EQ("[true]", GetStringPropertyFromObject( | 850 EXPECT_EQ("[true]", GetStringPropertyFromObject( |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 888 FunctionFromString(context, kRegisterHook); | 888 FunctionFromString(context, kRegisterHook); |
| 889 v8::Local<v8::Value> args[] = {js_hooks}; | 889 v8::Local<v8::Value> args[] = {js_hooks}; |
| 890 RunFunctionOnGlobal(function, context, arraysize(args), args); | 890 RunFunctionOnGlobal(function, context, arraysize(args), args); |
| 891 } | 891 } |
| 892 | 892 |
| 893 SetHooks(std::move(hooks)); | 893 SetHooks(std::move(hooks)); |
| 894 SetFunctions(kFunctions); | 894 SetFunctions(kFunctions); |
| 895 InitializeBinding(); | 895 InitializeBinding(); |
| 896 | 896 |
| 897 v8::Local<v8::Object> binding_object = | 897 v8::Local<v8::Object> binding_object = |
| 898 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 898 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 899 | 899 |
| 900 v8::Local<v8::Function> function = | 900 v8::Local<v8::Function> function = |
| 901 FunctionFromString(context, | 901 FunctionFromString(context, |
| 902 "(function(obj) { return obj.oneString('ping'); })"); | 902 "(function(obj) { return obj.oneString('ping'); })"); |
| 903 v8::Local<v8::Value> args[] = {binding_object}; | 903 v8::Local<v8::Value> args[] = {binding_object}; |
| 904 RunFunctionAndExpectError(function, context, v8::Undefined(isolate()), | 904 RunFunctionAndExpectError(function, context, v8::Undefined(isolate()), |
| 905 arraysize(args), args, | 905 arraysize(args), args, |
| 906 "Uncaught Error: Custom Hook Error"); | 906 "Uncaught Error: Custom Hook Error"); |
| 907 | 907 |
| 908 // Other methods, like stringAndInt(), should behave normally. | 908 // Other methods, like stringAndInt(), should behave normally. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 930 FunctionFromString(context, kRegisterHook); | 930 FunctionFromString(context, kRegisterHook); |
| 931 v8::Local<v8::Value> args[] = {js_hooks}; | 931 v8::Local<v8::Value> args[] = {js_hooks}; |
| 932 RunFunctionOnGlobal(function, context, arraysize(args), args); | 932 RunFunctionOnGlobal(function, context, arraysize(args), args); |
| 933 } | 933 } |
| 934 | 934 |
| 935 SetHooks(std::move(hooks)); | 935 SetHooks(std::move(hooks)); |
| 936 SetFunctions(kFunctions); | 936 SetFunctions(kFunctions); |
| 937 InitializeBinding(); | 937 InitializeBinding(); |
| 938 | 938 |
| 939 v8::Local<v8::Object> binding_object = | 939 v8::Local<v8::Object> binding_object = |
| 940 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 940 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 941 | 941 |
| 942 v8::Local<v8::Function> function = | 942 v8::Local<v8::Function> function = |
| 943 FunctionFromString(context, | 943 FunctionFromString(context, |
| 944 "(function(obj) { return obj.oneString('ping'); })"); | 944 "(function(obj) { return obj.oneString('ping'); })"); |
| 945 v8::Local<v8::Value> args[] = {binding_object}; | 945 v8::Local<v8::Value> args[] = {binding_object}; |
| 946 v8::Local<v8::Value> result = | 946 v8::Local<v8::Value> result = |
| 947 RunFunction(function, context, arraysize(args), args); | 947 RunFunction(function, context, arraysize(args), args); |
| 948 ASSERT_FALSE(result.IsEmpty()); | 948 ASSERT_FALSE(result.IsEmpty()); |
| 949 std::unique_ptr<base::Value> json_result = V8ToBaseValue(result, context); | 949 std::unique_ptr<base::Value> json_result = V8ToBaseValue(result, context); |
| 950 ASSERT_TRUE(json_result); | 950 ASSERT_TRUE(json_result); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 991 FunctionFromString(context, kRegisterHook); | 991 FunctionFromString(context, kRegisterHook); |
| 992 v8::Local<v8::Value> args[] = {js_hooks}; | 992 v8::Local<v8::Value> args[] = {js_hooks}; |
| 993 RunFunctionOnGlobal(function, context, arraysize(args), args); | 993 RunFunctionOnGlobal(function, context, arraysize(args), args); |
| 994 } | 994 } |
| 995 | 995 |
| 996 SetHooks(std::move(hooks)); | 996 SetHooks(std::move(hooks)); |
| 997 SetFunctions(kFunctions); | 997 SetFunctions(kFunctions); |
| 998 InitializeBinding(); | 998 InitializeBinding(); |
| 999 | 999 |
| 1000 v8::Local<v8::Object> binding_object = | 1000 v8::Local<v8::Object> binding_object = |
| 1001 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 1001 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 1002 | 1002 |
| 1003 v8::Local<v8::Function> function = | 1003 v8::Local<v8::Function> function = |
| 1004 FunctionFromString(context, | 1004 FunctionFromString(context, |
| 1005 "(function(obj) { return obj.oneString('ping'); })"); | 1005 "(function(obj) { return obj.oneString('ping'); })"); |
| 1006 v8::Local<v8::Value> args[] = {binding_object}; | 1006 v8::Local<v8::Value> args[] = {binding_object}; |
| 1007 RunFunctionAndExpectError(function, context, v8::Undefined(isolate()), | 1007 RunFunctionAndExpectError(function, context, v8::Undefined(isolate()), |
| 1008 arraysize(args), args, | 1008 arraysize(args), args, |
| 1009 "Uncaught Error: Custom Hook Error"); | 1009 "Uncaught Error: Custom Hook Error"); |
| 1010 } | 1010 } |
| 1011 | 1011 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1041 gin::StringToV8(context->GetIsolate(), arg_value + " pong"); | 1041 gin::StringToV8(context->GetIsolate(), arg_value + " pong"); |
| 1042 return result; | 1042 return result; |
| 1043 }; | 1043 }; |
| 1044 hooks->AddHandler("test.oneString", base::Bind(hook, &did_call)); | 1044 hooks->AddHandler("test.oneString", base::Bind(hook, &did_call)); |
| 1045 | 1045 |
| 1046 SetHooksDelegate(std::move(hooks)); | 1046 SetHooksDelegate(std::move(hooks)); |
| 1047 SetFunctions(kFunctions); | 1047 SetFunctions(kFunctions); |
| 1048 InitializeBinding(); | 1048 InitializeBinding(); |
| 1049 | 1049 |
| 1050 v8::Local<v8::Object> binding_object = | 1050 v8::Local<v8::Object> binding_object = |
| 1051 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 1051 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 1052 | 1052 |
| 1053 { | 1053 { |
| 1054 // Test an invocation that we expect to throw an exception. | 1054 // Test an invocation that we expect to throw an exception. |
| 1055 v8::Local<v8::Function> function = | 1055 v8::Local<v8::Function> function = |
| 1056 FunctionFromString( | 1056 FunctionFromString( |
| 1057 context, "(function(obj) { return obj.oneString('throw'); })"); | 1057 context, "(function(obj) { return obj.oneString('throw'); })"); |
| 1058 v8::Local<v8::Value> args[] = {binding_object}; | 1058 v8::Local<v8::Value> args[] = {binding_object}; |
| 1059 RunFunctionAndExpectError(function, context, v8::Undefined(isolate()), | 1059 RunFunctionAndExpectError(function, context, v8::Undefined(isolate()), |
| 1060 arraysize(args), args, | 1060 arraysize(args), args, |
| 1061 "Uncaught Error: Custom Hook Error"); | 1061 "Uncaught Error: Custom Hook Error"); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1097 FunctionFromString(context, kRegisterHook); | 1097 FunctionFromString(context, kRegisterHook); |
| 1098 v8::Local<v8::Value> args[] = {js_hooks}; | 1098 v8::Local<v8::Value> args[] = {js_hooks}; |
| 1099 RunFunctionOnGlobal(function, context, arraysize(args), args); | 1099 RunFunctionOnGlobal(function, context, arraysize(args), args); |
| 1100 } | 1100 } |
| 1101 | 1101 |
| 1102 SetHooks(std::move(hooks)); | 1102 SetHooks(std::move(hooks)); |
| 1103 SetFunctions(kFunctions); | 1103 SetFunctions(kFunctions); |
| 1104 InitializeBinding(); | 1104 InitializeBinding(); |
| 1105 | 1105 |
| 1106 v8::Local<v8::Object> binding_object = | 1106 v8::Local<v8::Object> binding_object = |
| 1107 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 1107 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 1108 | 1108 |
| 1109 // Try calling the method with an invalid signature. Since it's invalid, we | 1109 // Try calling the method with an invalid signature. Since it's invalid, we |
| 1110 // should never enter the hook. | 1110 // should never enter the hook. |
| 1111 ExpectFailure(binding_object, "obj.oneString(false);", kError); | 1111 ExpectFailure(binding_object, "obj.oneString(false);", kError); |
| 1112 EXPECT_EQ("undefined", GetStringPropertyFromObject( | 1112 EXPECT_EQ("undefined", GetStringPropertyFromObject( |
| 1113 context->Global(), context, "requestArguments")); | 1113 context->Global(), context, "requestArguments")); |
| 1114 | 1114 |
| 1115 // Call the method with a valid signature. The hook should be entered and | 1115 // Call the method with a valid signature. The hook should be entered and |
| 1116 // manipulate the arguments. | 1116 // manipulate the arguments. |
| 1117 ExpectPass(binding_object, "obj.oneString('ping');", "['pong']", false); | 1117 ExpectPass(binding_object, "obj.oneString('ping');", "['pong']", false); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1145 FunctionFromString(context, kRegisterHook); | 1145 FunctionFromString(context, kRegisterHook); |
| 1146 v8::Local<v8::Value> args[] = {js_hooks}; | 1146 v8::Local<v8::Value> args[] = {js_hooks}; |
| 1147 RunFunctionOnGlobal(function, context, arraysize(args), args); | 1147 RunFunctionOnGlobal(function, context, arraysize(args), args); |
| 1148 } | 1148 } |
| 1149 | 1149 |
| 1150 SetHooks(std::move(hooks)); | 1150 SetHooks(std::move(hooks)); |
| 1151 SetFunctions(kFunctions); | 1151 SetFunctions(kFunctions); |
| 1152 InitializeBinding(); | 1152 InitializeBinding(); |
| 1153 | 1153 |
| 1154 v8::Local<v8::Object> binding_object = | 1154 v8::Local<v8::Object> binding_object = |
| 1155 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 1155 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 1156 | 1156 |
| 1157 // Call the method with a valid signature. The hook should be entered and | 1157 // Call the method with a valid signature. The hook should be entered and |
| 1158 // manipulate the arguments. | 1158 // manipulate the arguments. |
| 1159 ExpectPass(binding_object, "obj.oneString('ping');", "[{}]", false); | 1159 ExpectPass(binding_object, "obj.oneString('ping');", "[{}]", false); |
| 1160 } | 1160 } |
| 1161 | 1161 |
| 1162 // Test that user gestures are properly recorded when calling APIs. | 1162 // Test that user gestures are properly recorded when calling APIs. |
| 1163 TEST_F(APIBindingUnittest, TestUserGestures) { | 1163 TEST_F(APIBindingUnittest, TestUserGestures) { |
| 1164 SetFunctions(kFunctions); | 1164 SetFunctions(kFunctions); |
| 1165 InitializeBinding(); | 1165 InitializeBinding(); |
| 1166 | 1166 |
| 1167 v8::HandleScope handle_scope(isolate()); | 1167 v8::HandleScope handle_scope(isolate()); |
| 1168 v8::Local<v8::Context> context = MainContext(); | 1168 v8::Local<v8::Context> context = MainContext(); |
| 1169 | 1169 |
| 1170 v8::Local<v8::Object> binding_object = | 1170 v8::Local<v8::Object> binding_object = |
| 1171 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 1171 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
| 1172 | 1172 |
| 1173 v8::Local<v8::Function> function = | 1173 v8::Local<v8::Function> function = |
| 1174 FunctionFromString(context, "(function(obj) { obj.oneString('foo');})"); | 1174 FunctionFromString(context, "(function(obj) { obj.oneString('foo');})"); |
| 1175 ASSERT_FALSE(function.IsEmpty()); | 1175 ASSERT_FALSE(function.IsEmpty()); |
| 1176 | 1176 |
| 1177 v8::Local<v8::Value> argv[] = {binding_object}; | 1177 v8::Local<v8::Value> argv[] = {binding_object}; |
| 1178 RunFunction(function, context, arraysize(argv), argv); | 1178 RunFunction(function, context, arraysize(argv), argv); |
| 1179 ASSERT_TRUE(last_request()); | 1179 ASSERT_TRUE(last_request()); |
| 1180 EXPECT_FALSE(last_request()->has_user_gesture); | 1180 EXPECT_FALSE(last_request()->has_user_gesture); |
| 1181 reset_last_request(); | 1181 reset_last_request(); |
| 1182 | 1182 |
| 1183 blink::WebScopedUserGesture user_gesture(nullptr); | 1183 blink::WebScopedUserGesture user_gesture(nullptr); |
| 1184 RunFunction(function, context, arraysize(argv), argv); | 1184 RunFunction(function, context, arraysize(argv), argv); |
| 1185 ASSERT_TRUE(last_request()); | 1185 ASSERT_TRUE(last_request()); |
| 1186 EXPECT_TRUE(last_request()->has_user_gesture); | 1186 EXPECT_TRUE(last_request()->has_user_gesture); |
| 1187 | 1187 |
| 1188 reset_last_request(); | 1188 reset_last_request(); |
| 1189 } | 1189 } |
| 1190 | 1190 |
| 1191 } // namespace extensions | 1191 } // namespace extensions |
| OLD | NEW |