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/bindings/api_binding.h" | 10 #include "extensions/renderer/bindings/api_binding.h" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
73 bool AllowAllFeatures(v8::Local<v8::Context> context, const std::string& name) { | 73 bool AllowAllFeatures(v8::Local<v8::Context> context, const std::string& name) { |
74 return true; | 74 return true; |
75 } | 75 } |
76 | 76 |
77 void OnEventListenersChanged(const std::string& event_name, | 77 void OnEventListenersChanged(const std::string& event_name, |
78 binding::EventListenersChanged change, | 78 binding::EventListenersChanged change, |
79 const base::DictionaryValue* filter, | 79 const base::DictionaryValue* filter, |
80 bool was_manual, | 80 bool was_manual, |
81 v8::Local<v8::Context> context) {} | 81 v8::Local<v8::Context> context) {} |
82 | 82 |
83 void DoNothingWithSilentRequest( | |
84 v8::Local<v8::Context> context, | |
85 const std::string& call_name, | |
86 const std::vector<v8::Local<v8::Value>>& arguments) {} | |
87 | |
83 } // namespace | 88 } // namespace |
84 | 89 |
85 class APIBindingUnittest : public APIBindingTest { | 90 class APIBindingUnittest : public APIBindingTest { |
86 public: | 91 public: |
87 void OnFunctionCall(std::unique_ptr<APIRequestHandler::Request> request, | 92 void OnFunctionCall(std::unique_ptr<APIRequestHandler::Request> request, |
88 v8::Local<v8::Context> context) { | 93 v8::Local<v8::Context> context) { |
89 last_request_ = std::move(request); | 94 last_request_ = std::move(request); |
90 } | 95 } |
91 | 96 |
92 protected: | 97 protected: |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
143 void SetHooksDelegate( | 148 void SetHooksDelegate( |
144 std::unique_ptr<APIBindingHooksDelegate> hooks_delegate) { | 149 std::unique_ptr<APIBindingHooksDelegate> hooks_delegate) { |
145 binding_hooks_delegate_ = std::move(hooks_delegate); | 150 binding_hooks_delegate_ = std::move(hooks_delegate); |
146 ASSERT_TRUE(binding_hooks_delegate_); | 151 ASSERT_TRUE(binding_hooks_delegate_); |
147 } | 152 } |
148 | 153 |
149 void SetCreateCustomType(const APIBinding::CreateCustomType& callback) { | 154 void SetCreateCustomType(const APIBinding::CreateCustomType& callback) { |
150 create_custom_type_ = callback; | 155 create_custom_type_ = callback; |
151 } | 156 } |
152 | 157 |
158 void SetOnSilentRequest(const APIBinding::OnSilentRequest& callback) { | |
159 on_silent_request_ = callback; | |
160 } | |
161 | |
153 void SetAvailabilityCallback( | 162 void SetAvailabilityCallback( |
154 const BindingAccessChecker::AvailabilityCallback& callback) { | 163 const BindingAccessChecker::AvailabilityCallback& callback) { |
155 availability_callback_ = callback; | 164 availability_callback_ = callback; |
156 } | 165 } |
157 | 166 |
158 void InitializeBinding() { | 167 void InitializeBinding() { |
159 if (!binding_hooks_) { | 168 if (!binding_hooks_) { |
160 binding_hooks_ = base::MakeUnique<APIBindingHooks>( | 169 binding_hooks_ = base::MakeUnique<APIBindingHooks>( |
161 kBindingName, binding::RunJSFunctionSync()); | 170 kBindingName, binding::RunJSFunctionSync()); |
162 } | 171 } |
163 if (binding_hooks_delegate_) | 172 if (binding_hooks_delegate_) |
164 binding_hooks_->SetDelegate(std::move(binding_hooks_delegate_)); | 173 binding_hooks_->SetDelegate(std::move(binding_hooks_delegate_)); |
174 if (!on_silent_request_) | |
175 on_silent_request_ = base::Bind(&DoNothingWithSilentRequest); | |
165 if (!availability_callback_) | 176 if (!availability_callback_) |
166 availability_callback_ = base::Bind(&AllowAllFeatures); | 177 availability_callback_ = base::Bind(&AllowAllFeatures); |
167 event_handler_ = base::MakeUnique<APIEventHandler>( | 178 event_handler_ = base::MakeUnique<APIEventHandler>( |
168 base::Bind(&RunFunctionOnGlobalAndIgnoreResult), | 179 base::Bind(&RunFunctionOnGlobalAndIgnoreResult), |
169 base::Bind(&RunFunctionOnGlobalAndReturnHandle), | 180 base::Bind(&RunFunctionOnGlobalAndReturnHandle), |
170 base::Bind(&OnEventListenersChanged)); | 181 base::Bind(&OnEventListenersChanged)); |
171 access_checker_ = | 182 access_checker_ = |
172 base::MakeUnique<BindingAccessChecker>(availability_callback_); | 183 base::MakeUnique<BindingAccessChecker>(availability_callback_); |
173 binding_ = base::MakeUnique<APIBinding>( | 184 binding_ = base::MakeUnique<APIBinding>( |
174 kBindingName, binding_functions_.get(), binding_types_.get(), | 185 kBindingName, binding_functions_.get(), binding_types_.get(), |
175 binding_events_.get(), binding_properties_.get(), create_custom_type_, | 186 binding_events_.get(), binding_properties_.get(), create_custom_type_, |
176 std::move(binding_hooks_), &type_refs_, request_handler_.get(), | 187 on_silent_request_, std::move(binding_hooks_), &type_refs_, |
177 event_handler_.get(), access_checker_.get()); | 188 request_handler_.get(), event_handler_.get(), access_checker_.get()); |
178 EXPECT_EQ(!binding_types_.get(), type_refs_.empty()); | 189 EXPECT_EQ(!binding_types_.get(), type_refs_.empty()); |
179 } | 190 } |
180 | 191 |
181 void ExpectPass(v8::Local<v8::Object> object, | 192 void ExpectPass(v8::Local<v8::Object> object, |
182 const std::string& script_source, | 193 const std::string& script_source, |
183 const std::string& expected_json_arguments_single_quotes, | 194 const std::string& expected_json_arguments_single_quotes, |
184 bool expect_callback) { | 195 bool expect_callback) { |
185 ExpectPass(MainContext(), object, script_source, | 196 ExpectPass(MainContext(), object, script_source, |
186 expected_json_arguments_single_quotes, expect_callback); | 197 expected_json_arguments_single_quotes, expect_callback); |
187 } | 198 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
236 std::unique_ptr<BindingAccessChecker> access_checker_; | 247 std::unique_ptr<BindingAccessChecker> access_checker_; |
237 APITypeReferenceMap type_refs_; | 248 APITypeReferenceMap type_refs_; |
238 | 249 |
239 std::unique_ptr<base::ListValue> binding_functions_; | 250 std::unique_ptr<base::ListValue> binding_functions_; |
240 std::unique_ptr<base::ListValue> binding_events_; | 251 std::unique_ptr<base::ListValue> binding_events_; |
241 std::unique_ptr<base::ListValue> binding_types_; | 252 std::unique_ptr<base::ListValue> binding_types_; |
242 std::unique_ptr<base::DictionaryValue> binding_properties_; | 253 std::unique_ptr<base::DictionaryValue> binding_properties_; |
243 std::unique_ptr<APIBindingHooks> binding_hooks_; | 254 std::unique_ptr<APIBindingHooks> binding_hooks_; |
244 std::unique_ptr<APIBindingHooksDelegate> binding_hooks_delegate_; | 255 std::unique_ptr<APIBindingHooksDelegate> binding_hooks_delegate_; |
245 APIBinding::CreateCustomType create_custom_type_; | 256 APIBinding::CreateCustomType create_custom_type_; |
257 APIBinding::OnSilentRequest on_silent_request_; | |
246 BindingAccessChecker::AvailabilityCallback availability_callback_; | 258 BindingAccessChecker::AvailabilityCallback availability_callback_; |
247 | 259 |
248 DISALLOW_COPY_AND_ASSIGN(APIBindingUnittest); | 260 DISALLOW_COPY_AND_ASSIGN(APIBindingUnittest); |
249 }; | 261 }; |
250 | 262 |
251 void APIBindingUnittest::RunTest(v8::Local<v8::Context> context, | 263 void APIBindingUnittest::RunTest(v8::Local<v8::Context> context, |
252 v8::Local<v8::Object> object, | 264 v8::Local<v8::Object> object, |
253 const std::string& script_source, | 265 const std::string& script_source, |
254 bool should_pass, | 266 bool should_pass, |
255 const std::string& expected_json_arguments, | 267 const std::string& expected_json_arguments, |
(...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1272 v8::Local<v8::Object> binding_object = binding()->CreateInstance(context); | 1284 v8::Local<v8::Object> binding_object = binding()->CreateInstance(context); |
1273 | 1285 |
1274 // The extra property should be present on the binding object. | 1286 // The extra property should be present on the binding object. |
1275 EXPECT_EQ("42", GetStringPropertyFromObject(binding_object, context, | 1287 EXPECT_EQ("42", GetStringPropertyFromObject(binding_object, context, |
1276 "hookedProperty")); | 1288 "hookedProperty")); |
1277 // Sanity check: other values should still be there. | 1289 // Sanity check: other values should still be there. |
1278 EXPECT_EQ("function", | 1290 EXPECT_EQ("function", |
1279 GetStringPropertyFromObject(binding_object, context, "oneString")); | 1291 GetStringPropertyFromObject(binding_object, context, "oneString")); |
1280 } | 1292 } |
1281 | 1293 |
1294 // Test that running hooks returning different results correctly sends requests | |
1295 // or notifies of silent requests. | |
1296 TEST_F(APIBindingUnittest, TestSendingRequestsAndSilentRequestsWithHooks) { | |
1297 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. :)
| |
1298 "[{" | |
1299 " 'name': 'modifyArgs'," | |
1300 " 'parameters': []" | |
1301 "}, {" | |
1302 " 'name': 'invalidInvocation'," | |
1303 " 'parameters': []" | |
1304 "}, {" | |
1305 " 'name': 'throwException'," | |
1306 " 'parameters': []" | |
1307 "}, {" | |
1308 " 'name': 'dontHandle'," | |
1309 " 'parameters': []" | |
1310 "}, {" | |
1311 " 'name': 'handle'," | |
1312 " 'parameters': []" | |
1313 "}, {" | |
1314 " 'name': 'handleAndSendRequest'," | |
1315 " 'parameters': []" | |
1316 "}]"); | |
1317 | |
1318 using RequestResult = APIBindingHooks::RequestResult; | |
1319 | |
1320 auto basic_handler = [](RequestResult::ResultCode code, const APISignature*, | |
1321 v8::Local<v8::Context> context, | |
1322 std::vector<v8::Local<v8::Value>>* arguments, | |
1323 const APITypeReferenceMap& map) { | |
1324 return RequestResult(code); | |
1325 }; | |
1326 | |
1327 auto hooks = base::MakeUnique<APIBindingHooksTestDelegate>(); | |
1328 hooks->AddHandler( | |
1329 "test.modifyArgs", | |
1330 base::Bind(basic_handler, RequestResult::ARGUMENTS_UPDATED)); | |
1331 hooks->AddHandler( | |
1332 "test.invalidInvocation", | |
1333 base::Bind(basic_handler, RequestResult::INVALID_INVOCATION)); | |
1334 hooks->AddHandler("test.dontHandle", | |
1335 base::Bind(basic_handler, RequestResult::NOT_HANDLED)); | |
1336 hooks->AddHandler("test.handle", | |
1337 base::Bind(basic_handler, RequestResult::HANDLED)); | |
1338 hooks->AddHandler( | |
1339 "test.throwException", | |
1340 base::Bind([](const APISignature*, v8::Local<v8::Context> context, | |
1341 std::vector<v8::Local<v8::Value>>* arguments, | |
1342 const APITypeReferenceMap& map) { | |
1343 context->GetIsolate()->ThrowException( | |
1344 gin::StringToV8(context->GetIsolate(), "some error")); | |
1345 return RequestResult(RequestResult::THROWN); | |
1346 })); | |
1347 auto handle_and_send_request = | |
1348 [](APIRequestHandler* handler, const APISignature*, | |
1349 v8::Local<v8::Context> context, | |
1350 std::vector<v8::Local<v8::Value>>* arguments, | |
1351 const APITypeReferenceMap& map) { | |
1352 handler->StartRequest( | |
1353 context, "test.handleAndSendRequest", | |
1354 base::MakeUnique<base::ListValue>(), v8::Local<v8::Function>(), | |
1355 v8::Local<v8::Function>(), binding::RequestThread::UI); | |
1356 return RequestResult(RequestResult::HANDLED); | |
1357 }; | |
1358 hooks->AddHandler("test.handleAndSendRequest", | |
1359 base::Bind(handle_and_send_request, request_handler())); | |
1360 | |
1361 SetHooksDelegate(std::move(hooks)); | |
1362 | |
1363 auto on_silent_request = | |
1364 [](base::Optional<std::string>* name_out, v8::Local<v8::Context> context, | |
1365 const std::string& call_name, | |
1366 const std::vector<v8::Local<v8::Value>>& arguments) { | |
1367 *name_out = call_name; | |
1368 }; | |
1369 base::Optional<std::string> silent_request; | |
1370 SetOnSilentRequest(base::Bind(on_silent_request, &silent_request)); | |
1371 | |
1372 InitializeBinding(); | |
1373 | |
1374 v8::HandleScope handle_scope(isolate()); | |
1375 v8::Local<v8::Context> context = MainContext(); | |
1376 | |
1377 v8::Local<v8::Object> binding_object = binding()->CreateInstance(context); | |
1378 | |
1379 auto call_api_method = [binding_object, context](base::StringPiece name) { | |
1380 v8::Local<v8::Function> call = FunctionFromString( | |
1381 context, base::StringPrintf("(function(binding) { binding.%s(); })", | |
1382 name.data())); | |
1383 v8::Local<v8::Value> args[] = {binding_object}; | |
1384 // The throwException call will throw an exception; ignore it. | |
1385 ignore_result(call->Call(context, v8::Undefined(context->GetIsolate()), | |
1386 arraysize(args), args)); | |
1387 }; | |
1388 | |
1389 call_api_method("modifyArgs"); | |
1390 ASSERT_TRUE(last_request()); | |
1391 EXPECT_EQ("test.modifyArgs", last_request()->method_name); | |
1392 EXPECT_FALSE(silent_request); | |
1393 reset_last_request(); | |
1394 silent_request.reset(); | |
1395 | |
1396 call_api_method("invalidInvocation"); | |
1397 EXPECT_FALSE(last_request()); | |
1398 EXPECT_FALSE(silent_request); | |
1399 reset_last_request(); | |
1400 silent_request.reset(); | |
1401 | |
1402 call_api_method("throwException"); | |
1403 EXPECT_FALSE(last_request()); | |
1404 EXPECT_FALSE(silent_request); | |
1405 reset_last_request(); | |
1406 silent_request.reset(); | |
1407 | |
1408 call_api_method("dontHandle"); | |
1409 ASSERT_TRUE(last_request()); | |
1410 EXPECT_EQ("test.dontHandle", last_request()->method_name); | |
1411 EXPECT_FALSE(silent_request); | |
1412 reset_last_request(); | |
1413 silent_request.reset(); | |
1414 | |
1415 call_api_method("handle"); | |
1416 EXPECT_FALSE(last_request()); | |
1417 ASSERT_TRUE(silent_request); | |
1418 EXPECT_EQ("test.handle", *silent_request); | |
1419 reset_last_request(); | |
1420 silent_request.reset(); | |
1421 | |
1422 call_api_method("handleAndSendRequest"); | |
1423 ASSERT_TRUE(last_request()); | |
1424 EXPECT_EQ("test.handleAndSendRequest", last_request()->method_name); | |
1425 EXPECT_FALSE(silent_request); | |
1426 reset_last_request(); | |
1427 silent_request.reset(); | |
1428 } | |
1429 | |
1282 } // namespace extensions | 1430 } // namespace extensions |
OLD | NEW |