Chromium Code Reviews| Index: extensions/renderer/bindings/api_binding_unittest.cc |
| diff --git a/extensions/renderer/bindings/api_binding_unittest.cc b/extensions/renderer/bindings/api_binding_unittest.cc |
| index 9f43d1aa5b47efda7a9c325969b8ecebefdc6cb6..e51d882430b872c1c7a94ee18290fc84f61ba751 100644 |
| --- a/extensions/renderer/bindings/api_binding_unittest.cc |
| +++ b/extensions/renderer/bindings/api_binding_unittest.cc |
| @@ -80,6 +80,11 @@ void OnEventListenersChanged(const std::string& event_name, |
| bool was_manual, |
| v8::Local<v8::Context> context) {} |
| +void DoNothingWithSilentRequest( |
| + v8::Local<v8::Context> context, |
| + const std::string& call_name, |
| + const std::vector<v8::Local<v8::Value>>& arguments) {} |
| + |
| } // namespace |
| class APIBindingUnittest : public APIBindingTest { |
| @@ -150,6 +155,10 @@ class APIBindingUnittest : public APIBindingTest { |
| create_custom_type_ = callback; |
| } |
| + void SetOnSilentRequest(const APIBinding::OnSilentRequest& callback) { |
| + on_silent_request_ = callback; |
| + } |
| + |
| void SetAvailabilityCallback( |
| const BindingAccessChecker::AvailabilityCallback& callback) { |
| availability_callback_ = callback; |
| @@ -162,6 +171,8 @@ class APIBindingUnittest : public APIBindingTest { |
| } |
| if (binding_hooks_delegate_) |
| binding_hooks_->SetDelegate(std::move(binding_hooks_delegate_)); |
| + if (!on_silent_request_) |
| + on_silent_request_ = base::Bind(&DoNothingWithSilentRequest); |
| if (!availability_callback_) |
| availability_callback_ = base::Bind(&AllowAllFeatures); |
| event_handler_ = base::MakeUnique<APIEventHandler>( |
| @@ -173,8 +184,8 @@ class APIBindingUnittest : public APIBindingTest { |
| binding_ = base::MakeUnique<APIBinding>( |
| kBindingName, binding_functions_.get(), binding_types_.get(), |
| binding_events_.get(), binding_properties_.get(), create_custom_type_, |
| - std::move(binding_hooks_), &type_refs_, request_handler_.get(), |
| - event_handler_.get(), access_checker_.get()); |
| + on_silent_request_, std::move(binding_hooks_), &type_refs_, |
| + request_handler_.get(), event_handler_.get(), access_checker_.get()); |
| EXPECT_EQ(!binding_types_.get(), type_refs_.empty()); |
| } |
| @@ -243,6 +254,7 @@ class APIBindingUnittest : public APIBindingTest { |
| std::unique_ptr<APIBindingHooks> binding_hooks_; |
| std::unique_ptr<APIBindingHooksDelegate> binding_hooks_delegate_; |
| APIBinding::CreateCustomType create_custom_type_; |
| + APIBinding::OnSilentRequest on_silent_request_; |
| BindingAccessChecker::AvailabilityCallback availability_callback_; |
| DISALLOW_COPY_AND_ASSIGN(APIBindingUnittest); |
| @@ -1279,4 +1291,140 @@ TEST_F(APIBindingUnittest, HooksTemplateInitializer) { |
| GetStringPropertyFromObject(binding_object, context, "oneString")); |
| } |
| +// Test that running hooks returning different results correctly sends requests |
| +// or notifies of silent requests. |
| +TEST_F(APIBindingUnittest, TestSendingRequestsAndSilentRequestsWithHooks) { |
| + SetFunctions( |
|
jbroman
2017/06/30 19:05:48
This seems to be missing any unit tests which have
Devlin
2017/07/06 17:09:57
Fair enough. Added one with real parameters. :)
|
| + "[{" |
| + " 'name': 'modifyArgs'," |
| + " 'parameters': []" |
| + "}, {" |
| + " 'name': 'invalidInvocation'," |
| + " 'parameters': []" |
| + "}, {" |
| + " 'name': 'throwException'," |
| + " 'parameters': []" |
| + "}, {" |
| + " 'name': 'dontHandle'," |
| + " 'parameters': []" |
| + "}, {" |
| + " 'name': 'handle'," |
| + " 'parameters': []" |
| + "}, {" |
| + " 'name': 'handleAndSendRequest'," |
| + " 'parameters': []" |
| + "}]"); |
| + |
| + using RequestResult = APIBindingHooks::RequestResult; |
| + |
| + auto basic_handler = [](RequestResult::ResultCode code, const APISignature*, |
| + v8::Local<v8::Context> context, |
| + std::vector<v8::Local<v8::Value>>* arguments, |
| + const APITypeReferenceMap& map) { |
| + return RequestResult(code); |
| + }; |
| + |
| + auto hooks = base::MakeUnique<APIBindingHooksTestDelegate>(); |
| + hooks->AddHandler( |
| + "test.modifyArgs", |
| + base::Bind(basic_handler, RequestResult::ARGUMENTS_UPDATED)); |
| + hooks->AddHandler( |
| + "test.invalidInvocation", |
| + base::Bind(basic_handler, RequestResult::INVALID_INVOCATION)); |
| + hooks->AddHandler("test.dontHandle", |
| + base::Bind(basic_handler, RequestResult::NOT_HANDLED)); |
| + hooks->AddHandler("test.handle", |
| + base::Bind(basic_handler, RequestResult::HANDLED)); |
| + hooks->AddHandler( |
| + "test.throwException", |
| + base::Bind([](const APISignature*, v8::Local<v8::Context> context, |
| + std::vector<v8::Local<v8::Value>>* arguments, |
| + const APITypeReferenceMap& map) { |
| + context->GetIsolate()->ThrowException( |
| + gin::StringToV8(context->GetIsolate(), "some error")); |
| + return RequestResult(RequestResult::THROWN); |
| + })); |
| + auto handle_and_send_request = |
| + [](APIRequestHandler* handler, const APISignature*, |
| + v8::Local<v8::Context> context, |
| + std::vector<v8::Local<v8::Value>>* arguments, |
| + const APITypeReferenceMap& map) { |
| + handler->StartRequest( |
| + context, "test.handleAndSendRequest", |
| + base::MakeUnique<base::ListValue>(), v8::Local<v8::Function>(), |
| + v8::Local<v8::Function>(), binding::RequestThread::UI); |
| + return RequestResult(RequestResult::HANDLED); |
| + }; |
| + hooks->AddHandler("test.handleAndSendRequest", |
| + base::Bind(handle_and_send_request, request_handler())); |
| + |
| + SetHooksDelegate(std::move(hooks)); |
| + |
| + auto on_silent_request = |
| + [](base::Optional<std::string>* name_out, v8::Local<v8::Context> context, |
| + const std::string& call_name, |
| + const std::vector<v8::Local<v8::Value>>& arguments) { |
| + *name_out = call_name; |
| + }; |
| + base::Optional<std::string> silent_request; |
| + SetOnSilentRequest(base::Bind(on_silent_request, &silent_request)); |
| + |
| + InitializeBinding(); |
| + |
| + v8::HandleScope handle_scope(isolate()); |
| + v8::Local<v8::Context> context = MainContext(); |
| + |
| + v8::Local<v8::Object> binding_object = binding()->CreateInstance(context); |
| + |
| + auto call_api_method = [binding_object, context](base::StringPiece name) { |
| + v8::Local<v8::Function> call = FunctionFromString( |
| + context, base::StringPrintf("(function(binding) { binding.%s(); })", |
| + name.data())); |
| + v8::Local<v8::Value> args[] = {binding_object}; |
| + // The throwException call will throw an exception; ignore it. |
| + ignore_result(call->Call(context, v8::Undefined(context->GetIsolate()), |
| + arraysize(args), args)); |
| + }; |
| + |
| + call_api_method("modifyArgs"); |
| + ASSERT_TRUE(last_request()); |
| + EXPECT_EQ("test.modifyArgs", last_request()->method_name); |
| + EXPECT_FALSE(silent_request); |
| + reset_last_request(); |
| + silent_request.reset(); |
| + |
| + call_api_method("invalidInvocation"); |
| + EXPECT_FALSE(last_request()); |
| + EXPECT_FALSE(silent_request); |
| + reset_last_request(); |
| + silent_request.reset(); |
| + |
| + call_api_method("throwException"); |
| + EXPECT_FALSE(last_request()); |
| + EXPECT_FALSE(silent_request); |
| + reset_last_request(); |
| + silent_request.reset(); |
| + |
| + call_api_method("dontHandle"); |
| + ASSERT_TRUE(last_request()); |
| + EXPECT_EQ("test.dontHandle", last_request()->method_name); |
| + EXPECT_FALSE(silent_request); |
| + reset_last_request(); |
| + silent_request.reset(); |
| + |
| + call_api_method("handle"); |
| + EXPECT_FALSE(last_request()); |
| + ASSERT_TRUE(silent_request); |
| + EXPECT_EQ("test.handle", *silent_request); |
| + reset_last_request(); |
| + silent_request.reset(); |
| + |
| + call_api_method("handleAndSendRequest"); |
| + ASSERT_TRUE(last_request()); |
| + EXPECT_EQ("test.handleAndSendRequest", last_request()->method_name); |
| + EXPECT_FALSE(silent_request); |
| + reset_last_request(); |
| + silent_request.reset(); |
| +} |
| + |
| } // namespace extensions |