Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Unified Diff: extensions/renderer/api_binding_unittest.cc

Issue 2598123002: [Extensions Bindings] Add support for updateArgumentsPreValidate (Closed)
Patch Set: rebase Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « extensions/renderer/api_binding_types.h ('k') | extensions/renderer/api_bindings_system.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: extensions/renderer/api_binding_unittest.cc
diff --git a/extensions/renderer/api_binding_unittest.cc b/extensions/renderer/api_binding_unittest.cc
index 2eeaf2a49be97a20c89386e3040ec2c635338f48..d526b7d1f16a568098c6a20590e20bdfe6121d04 100644
--- a/extensions/renderer/api_binding_unittest.cc
+++ b/extensions/renderer/api_binding_unittest.cc
@@ -194,7 +194,7 @@ TEST_F(APIBindingUnittest, TestEmptyAPI) {
APIBinding binding(
"empty", nullptr, nullptr, nullptr,
base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)),
- base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs);
+ base::MakeUnique<APIBindingHooks>(binding::RunJSFunctionSync()), &refs);
EXPECT_TRUE(refs.empty());
v8::HandleScope handle_scope(isolate());
@@ -216,7 +216,7 @@ TEST_F(APIBindingUnittest, Test) {
APIBinding binding(
"test", functions.get(), nullptr, nullptr,
base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)),
- base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs);
+ base::MakeUnique<APIBindingHooks>(binding::RunJSFunctionSync()), &refs);
EXPECT_TRUE(refs.empty());
v8::HandleScope handle_scope(isolate());
@@ -317,7 +317,7 @@ TEST_F(APIBindingUnittest, TypeRefsTest) {
APIBinding binding(
"test", functions.get(), types.get(), nullptr,
base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)),
- base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs);
+ base::MakeUnique<APIBindingHooks>(binding::RunJSFunctionSync()), &refs);
EXPECT_EQ(2u, refs.size());
EXPECT_TRUE(base::ContainsKey(refs, "refObj"));
EXPECT_TRUE(base::ContainsKey(refs, "refEnum"));
@@ -363,7 +363,7 @@ TEST_F(APIBindingUnittest, RestrictedAPIs) {
APIBinding binding(
"test", functions.get(), nullptr, nullptr,
base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)),
- base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs);
+ base::MakeUnique<APIBindingHooks>(binding::RunJSFunctionSync()), &refs);
v8::HandleScope handle_scope(isolate());
v8::Local<v8::Context> context = ContextLocal();
@@ -406,7 +406,7 @@ TEST_F(APIBindingUnittest, TestEventCreation) {
APIBinding binding(
"test", functions.get(), nullptr, events.get(),
base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)),
- base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs);
+ base::MakeUnique<APIBindingHooks>(binding::RunJSFunctionSync()), &refs);
v8::HandleScope handle_scope(isolate());
v8::Local<v8::Context> context = ContextLocal();
@@ -442,7 +442,7 @@ TEST_F(APIBindingUnittest, TestDisposedContext) {
APIBinding binding(
"test", functions.get(), nullptr, nullptr,
base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)),
- base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs);
+ base::MakeUnique<APIBindingHooks>(binding::RunJSFunctionSync()), &refs);
EXPECT_TRUE(refs.empty());
v8::HandleScope handle_scope(isolate());
@@ -471,16 +471,18 @@ TEST_F(APIBindingUnittest, TestCustomHooks) {
// Register a hook for the test.oneString method.
auto hooks = base::MakeUnique<APIBindingHooks>(
- base::Bind(&RunFunctionOnGlobalAndIgnoreResult));
+ base::Bind(&RunFunctionOnGlobalAndReturnHandle));
bool did_call = false;
auto hook = [](bool* did_call, const APISignature* signature,
- gin::Arguments* arguments,
+ v8::Local<v8::Context> context,
+ std::vector<v8::Local<v8::Value>>* arguments,
const ArgumentSpec::RefMap& ref_map) {
*did_call = true;
- EXPECT_EQ(1, arguments->Length());
- std::string argument;
- EXPECT_TRUE(arguments->GetNext(&argument));
- EXPECT_EQ("foo", argument);
+ if (arguments->size() != 1u) {
+ EXPECT_EQ(1u, arguments->size());
+ return APIBindingHooks::RequestResult::HANDLED;
+ }
+ EXPECT_EQ("foo", gin::V8ToString(arguments->at(0)));
return APIBindingHooks::RequestResult::HANDLED;
};
hooks->RegisterHandleRequest("test.oneString", base::Bind(hook, &did_call));
@@ -514,7 +516,7 @@ TEST_F(APIBindingUnittest, TestCustomHooks) {
TEST_F(APIBindingUnittest, TestJSCustomHook) {
// Register a hook for the test.oneString method.
auto hooks = base::MakeUnique<APIBindingHooks>(
- base::Bind(&RunFunctionOnGlobalAndIgnoreResult));
+ base::Bind(&RunFunctionOnGlobalAndReturnHandle));
v8::HandleScope handle_scope(isolate());
v8::Local<v8::Context> context = ContextLocal();
@@ -572,4 +574,121 @@ TEST_F(APIBindingUnittest, TestJSCustomHook) {
ExpectPass(binding_object, "obj.stringAndInt('foo', 42);", "['foo',42]");
}
+// Tests the updateArgumentsPreValidate hook.
+TEST_F(APIBindingUnittest, TestUpdateArgumentsPreValidate) {
+ // Register a hook for the test.oneString method.
+ auto hooks = base::MakeUnique<APIBindingHooks>(
+ base::Bind(&RunFunctionOnGlobalAndReturnHandle));
+
+ v8::HandleScope handle_scope(isolate());
+ v8::Local<v8::Context> context = ContextLocal();
+ const char kRegisterHook[] =
+ "(function(hooks) {\n"
+ " hooks.setUpdateArgumentsPreValidate('oneString', function() {\n"
+ " this.requestArguments = Array.from(arguments);\n"
+ " if (this.requestArguments[0] === true)\n"
+ " return ['hooked']\n"
+ " return this.requestArguments\n"
+ " });\n"
+ "})";
+ v8::Local<v8::String> source_string =
+ gin::StringToV8(isolate(), kRegisterHook);
+ v8::Local<v8::String> source_name =
+ gin::StringToV8(isolate(), "custom_hook");
+ hooks->RegisterJsSource(
+ v8::Global<v8::String>(isolate(), source_string),
+ v8::Global<v8::String>(isolate(), source_name));
+
+ std::unique_ptr<base::ListValue> functions = ListValueFromString(kFunctions);
+ ASSERT_TRUE(functions);
+ ArgumentSpec::RefMap refs;
+
+ APIBinding binding(
+ "test", functions.get(), nullptr, nullptr,
+ base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)),
+ std::move(hooks), &refs);
+ EXPECT_TRUE(refs.empty());
+
+ APIEventHandler event_handler(
+ base::Bind(&RunFunctionOnGlobalAndIgnoreResult));
+ v8::Local<v8::Object> binding_object = binding.CreateInstance(
+ context, isolate(), &event_handler, base::Bind(&AllowAllAPIs));
+
+ // Call the method with a hook. Since the hook updates arguments before
+ // validation, we should be able to pass in invalid arguments and still
+ // have the hook called.
+ ExpectFailure(binding_object, "obj.oneString(false);", kError);
+ EXPECT_EQ("[false]", GetStringPropertyFromObject(
+ context->Global(), context, "requestArguments"));
+
+ ExpectPass(binding_object, "obj.oneString(true);", "['hooked']");
+ EXPECT_EQ("[true]", GetStringPropertyFromObject(
+ context->Global(), context, "requestArguments"));
+
+ // Other methods, like stringAndInt(), should behave normally.
+ ExpectPass(binding_object, "obj.stringAndInt('foo', 42);", "['foo',42]");
+}
+
+// Tests the updateArgumentsPreValidate hook.
+TEST_F(APIBindingUnittest, TestThrowInUpdateArgumentsPreValidate) {
+ auto run_js_and_allow_error = [](v8::Local<v8::Function> function,
+ v8::Local<v8::Context> context,
+ int argc,
+ v8::Local<v8::Value> argv[]) {
+ v8::MaybeLocal<v8::Value> maybe_result =
+ function->Call(context, context->Global(), argc, argv);
+ v8::Global<v8::Value> result;
+ v8::Local<v8::Value> local;
+ if (maybe_result.ToLocal(&local))
+ result.Reset(context->GetIsolate(), local);
+ return result;
+ };
+
+ // Register a hook for the test.oneString method.
+ auto hooks = base::MakeUnique<APIBindingHooks>(
+ base::Bind(run_js_and_allow_error));
+
+ v8::HandleScope handle_scope(isolate());
+ v8::Local<v8::Context> context = ContextLocal();
+ const char kRegisterHook[] =
+ "(function(hooks) {\n"
+ " hooks.setUpdateArgumentsPreValidate('oneString', function() {\n"
+ " throw new Error('Custom Hook Error');\n"
+ " });\n"
+ "})";
+ v8::Local<v8::String> source_string =
+ gin::StringToV8(isolate(), kRegisterHook);
+ v8::Local<v8::String> source_name =
+ gin::StringToV8(isolate(), "custom_hook");
+ hooks->RegisterJsSource(
+ v8::Global<v8::String>(isolate(), source_string),
+ v8::Global<v8::String>(isolate(), source_name));
+
+ std::unique_ptr<base::ListValue> functions = ListValueFromString(kFunctions);
+ ASSERT_TRUE(functions);
+ ArgumentSpec::RefMap refs;
+
+ APIBinding binding(
+ "test", functions.get(), nullptr, nullptr,
+ base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)),
+ std::move(hooks), &refs);
+ EXPECT_TRUE(refs.empty());
+
+ APIEventHandler event_handler(
+ base::Bind(&RunFunctionOnGlobalAndIgnoreResult));
+ v8::Local<v8::Object> binding_object = binding.CreateInstance(
+ context, isolate(), &event_handler, base::Bind(&AllowAllAPIs));
+
+ v8::Local<v8::Function> function =
+ FunctionFromString(context,
+ "(function(obj) { return obj.oneString('ping'); })");
+ v8::Local<v8::Value> args[] = {binding_object};
+ RunFunctionAndExpectError(function, context, v8::Undefined(isolate()),
+ arraysize(args), args,
+ "Uncaught Error: Custom Hook Error");
+
+ // Other methods, like stringAndInt(), should behave normally.
+ ExpectPass(binding_object, "obj.stringAndInt('foo', 42);", "['foo',42]");
+}
+
} // namespace extensions
« no previous file with comments | « extensions/renderer/api_binding_types.h ('k') | extensions/renderer/api_bindings_system.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698