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

Side by Side Diff: extensions/renderer/bindings/api_binding_unittest.cc

Issue 2962093002: [Extensions Bindings] Add activity logging of custom handling (Closed)
Patch Set: . Created 3 years, 5 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 unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698