| 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/guid.h" | |
| 7 #include "base/json/json_reader.h" | |
| 8 #include "base/json/json_writer.h" | |
| 9 #include "base/strings/string_util.h" | |
| 10 #include "base/values.h" | 6 #include "base/values.h" |
| 11 #include "content/public/child/v8_value_converter.h" | 7 #include "extensions/renderer/api_binding_test.h" |
| 12 #include "extensions/renderer/api_binding_test_util.h" | 8 #include "extensions/renderer/api_binding_test_util.h" |
| 13 #include "extensions/renderer/api_request_handler.h" | 9 #include "extensions/renderer/api_request_handler.h" |
| 14 #include "gin/converter.h" | |
| 15 #include "gin/public/context_holder.h" | 10 #include "gin/public/context_holder.h" |
| 16 #include "gin/public/isolate_holder.h" | 11 #include "gin/public/isolate_holder.h" |
| 17 #include "gin/test/v8_test.h" | |
| 18 #include "gin/try_catch.h" | |
| 19 #include "testing/gmock/include/gmock/gmock.h" | 12 #include "testing/gmock/include/gmock/gmock.h" |
| 20 | 13 |
| 21 namespace extensions { | 14 namespace extensions { |
| 22 | 15 |
| 23 namespace { | 16 namespace { |
| 24 | 17 |
| 25 const char kEchoArgs[] = | 18 const char kEchoArgs[] = |
| 26 "(function() { this.result = Array.from(arguments); })"; | 19 "(function() { this.result = Array.from(arguments); })"; |
| 27 | 20 |
| 28 } // namespace | 21 } // namespace |
| 29 | 22 |
| 30 class APIRequestHandlerTest : public gin::V8Test { | 23 class APIRequestHandlerTest : public APIBindingTest { |
| 31 public: | 24 public: |
| 32 // Runs the given |function|. | 25 // Runs the given |function|. |
| 33 void RunJS(v8::Local<v8::Function> function, | 26 void RunJS(v8::Local<v8::Function> function, |
| 34 v8::Local<v8::Context> context, | 27 v8::Local<v8::Context> context, |
| 35 int argc, | 28 int argc, |
| 36 v8::Local<v8::Value> argv[]) { | 29 v8::Local<v8::Value> argv[]) { |
| 37 RunFunctionOnGlobal(function, context, argc, argv); | 30 RunFunctionOnGlobal(function, context, argc, argv); |
| 38 did_run_js_ = true; | 31 did_run_js_ = true; |
| 39 } | 32 } |
| 40 | 33 |
| 41 protected: | 34 protected: |
| 42 APIRequestHandlerTest() {} | 35 APIRequestHandlerTest() {} |
| 43 ~APIRequestHandlerTest() override {} | 36 ~APIRequestHandlerTest() override {} |
| 44 | 37 |
| 45 bool did_run_js() const { return did_run_js_; } | 38 bool did_run_js() const { return did_run_js_; } |
| 46 | 39 |
| 47 private: | 40 private: |
| 48 bool did_run_js_ = false; | 41 bool did_run_js_ = false; |
| 49 | 42 |
| 50 DISALLOW_COPY_AND_ASSIGN(APIRequestHandlerTest); | 43 DISALLOW_COPY_AND_ASSIGN(APIRequestHandlerTest); |
| 51 }; | 44 }; |
| 52 | 45 |
| 53 // Tests adding a request to the request handler, and then triggering the | 46 // Tests adding a request to the request handler, and then triggering the |
| 54 // response. | 47 // response. |
| 55 TEST_F(APIRequestHandlerTest, AddRequestAndCompleteRequestTest) { | 48 TEST_F(APIRequestHandlerTest, AddRequestAndCompleteRequestTest) { |
| 56 v8::Isolate* isolate = instance_->isolate(); | 49 v8::HandleScope handle_scope(isolate()); |
| 57 v8::HandleScope handle_scope(instance_->isolate()); | 50 v8::Local<v8::Context> context = ContextLocal(); |
| 58 v8::Local<v8::Context> context = | |
| 59 v8::Local<v8::Context>::New(instance_->isolate(), context_); | |
| 60 | 51 |
| 61 APIRequestHandler request_handler( | 52 APIRequestHandler request_handler( |
| 62 base::Bind(&APIRequestHandlerTest::RunJS, base::Unretained(this))); | 53 base::Bind(&APIRequestHandlerTest::RunJS, base::Unretained(this))); |
| 63 | 54 |
| 64 EXPECT_TRUE(request_handler.GetPendingRequestIdsForTesting().empty()); | 55 EXPECT_TRUE(request_handler.GetPendingRequestIdsForTesting().empty()); |
| 65 | 56 |
| 66 v8::Local<v8::Function> function = FunctionFromString(context, kEchoArgs); | 57 v8::Local<v8::Function> function = FunctionFromString(context, kEchoArgs); |
| 67 ASSERT_FALSE(function.IsEmpty()); | 58 ASSERT_FALSE(function.IsEmpty()); |
| 68 | 59 |
| 69 int request_id = | 60 int request_id = |
| 70 request_handler.AddPendingRequest(isolate, function, context); | 61 request_handler.AddPendingRequest(isolate(), function, context); |
| 71 EXPECT_THAT(request_handler.GetPendingRequestIdsForTesting(), | 62 EXPECT_THAT(request_handler.GetPendingRequestIdsForTesting(), |
| 72 testing::UnorderedElementsAre(request_id)); | 63 testing::UnorderedElementsAre(request_id)); |
| 73 | 64 |
| 74 const char kArguments[] = "['foo',1,{'prop1':'bar'}]"; | 65 const char kArguments[] = "['foo',1,{'prop1':'bar'}]"; |
| 75 std::unique_ptr<base::ListValue> response_arguments = | 66 std::unique_ptr<base::ListValue> response_arguments = |
| 76 ListValueFromString(kArguments); | 67 ListValueFromString(kArguments); |
| 77 ASSERT_TRUE(response_arguments); | 68 ASSERT_TRUE(response_arguments); |
| 78 request_handler.CompleteRequest(request_id, *response_arguments); | 69 request_handler.CompleteRequest(request_id, *response_arguments); |
| 79 | 70 |
| 80 EXPECT_TRUE(did_run_js()); | 71 EXPECT_TRUE(did_run_js()); |
| 81 EXPECT_EQ(ReplaceSingleQuotes(kArguments), | 72 EXPECT_EQ(ReplaceSingleQuotes(kArguments), |
| 82 GetStringPropertyFromObject(context->Global(), context, "result")); | 73 GetStringPropertyFromObject(context->Global(), context, "result")); |
| 83 | 74 |
| 84 EXPECT_TRUE(request_handler.GetPendingRequestIdsForTesting().empty()); | 75 EXPECT_TRUE(request_handler.GetPendingRequestIdsForTesting().empty()); |
| 85 } | 76 } |
| 86 | 77 |
| 87 // Tests that trying to run non-existent or invalided requests is a no-op. | 78 // Tests that trying to run non-existent or invalided requests is a no-op. |
| 88 TEST_F(APIRequestHandlerTest, InvalidRequestsTest) { | 79 TEST_F(APIRequestHandlerTest, InvalidRequestsTest) { |
| 89 v8::Isolate* isolate = instance_->isolate(); | 80 v8::HandleScope handle_scope(isolate()); |
| 90 v8::HandleScope handle_scope(instance_->isolate()); | 81 v8::Local<v8::Context> context = ContextLocal(); |
| 91 v8::Local<v8::Context> context = | |
| 92 v8::Local<v8::Context>::New(instance_->isolate(), context_); | |
| 93 | 82 |
| 94 APIRequestHandler request_handler( | 83 APIRequestHandler request_handler( |
| 95 base::Bind(&APIRequestHandlerTest::RunJS, base::Unretained(this))); | 84 base::Bind(&APIRequestHandlerTest::RunJS, base::Unretained(this))); |
| 96 | 85 |
| 97 v8::Local<v8::Function> function = FunctionFromString(context, kEchoArgs); | 86 v8::Local<v8::Function> function = FunctionFromString(context, kEchoArgs); |
| 98 ASSERT_FALSE(function.IsEmpty()); | 87 ASSERT_FALSE(function.IsEmpty()); |
| 99 | 88 |
| 100 int request_id = | 89 int request_id = |
| 101 request_handler.AddPendingRequest(isolate, function, context); | 90 request_handler.AddPendingRequest(isolate(), function, context); |
| 102 EXPECT_THAT(request_handler.GetPendingRequestIdsForTesting(), | 91 EXPECT_THAT(request_handler.GetPendingRequestIdsForTesting(), |
| 103 testing::UnorderedElementsAre(request_id)); | 92 testing::UnorderedElementsAre(request_id)); |
| 104 | 93 |
| 105 std::unique_ptr<base::ListValue> response_arguments = | 94 std::unique_ptr<base::ListValue> response_arguments = |
| 106 ListValueFromString("['foo']"); | 95 ListValueFromString("['foo']"); |
| 107 ASSERT_TRUE(response_arguments); | 96 ASSERT_TRUE(response_arguments); |
| 108 | 97 |
| 109 // Try running with a non-existent request id. | 98 // Try running with a non-existent request id. |
| 110 int fake_request_id = 42; | 99 int fake_request_id = 42; |
| 111 request_handler.CompleteRequest(fake_request_id, *response_arguments); | 100 request_handler.CompleteRequest(fake_request_id, *response_arguments); |
| 112 EXPECT_FALSE(did_run_js()); | 101 EXPECT_FALSE(did_run_js()); |
| 113 | 102 |
| 114 // Try running with a request from an invalidated context. | 103 // Try running with a request from an invalidated context. |
| 115 request_handler.InvalidateContext(context); | 104 request_handler.InvalidateContext(context); |
| 116 request_handler.CompleteRequest(request_id, *response_arguments); | 105 request_handler.CompleteRequest(request_id, *response_arguments); |
| 117 EXPECT_FALSE(did_run_js()); | 106 EXPECT_FALSE(did_run_js()); |
| 118 } | 107 } |
| 119 | 108 |
| 120 TEST_F(APIRequestHandlerTest, MultipleRequestsAndContexts) { | 109 TEST_F(APIRequestHandlerTest, MultipleRequestsAndContexts) { |
| 121 v8::Isolate* isolate = instance_->isolate(); | 110 v8::HandleScope handle_scope(isolate()); |
| 122 v8::HandleScope handle_scope(instance_->isolate()); | 111 v8::Local<v8::Context> context_a = ContextLocal(); |
| 123 v8::Local<v8::Context> context_a = | 112 v8::Local<v8::Context> context_b = v8::Context::New(isolate()); |
| 124 v8::Local<v8::Context>::New(isolate, context_); | 113 gin::ContextHolder holder_b(isolate()); |
| 125 v8::Local<v8::Context> context_b = v8::Context::New(isolate); | 114 holder_b.SetContext(context_b); |
| 126 | 115 |
| 127 APIRequestHandler request_handler( | 116 APIRequestHandler request_handler( |
| 128 base::Bind(&APIRequestHandlerTest::RunJS, base::Unretained(this))); | 117 base::Bind(&APIRequestHandlerTest::RunJS, base::Unretained(this))); |
| 129 | 118 |
| 130 // By having both different arguments and different behaviors in the | 119 // By having both different arguments and different behaviors in the |
| 131 // callbacks, we can easily verify that the right function is called in the | 120 // callbacks, we can easily verify that the right function is called in the |
| 132 // right context. | 121 // right context. |
| 133 v8::Local<v8::Function> function_a = FunctionFromString( | 122 v8::Local<v8::Function> function_a = FunctionFromString( |
| 134 context_a, "(function(res) { this.result = res + 'alpha'; })"); | 123 context_a, "(function(res) { this.result = res + 'alpha'; })"); |
| 135 v8::Local<v8::Function> function_b = FunctionFromString( | 124 v8::Local<v8::Function> function_b = FunctionFromString( |
| 136 context_b, "(function(res) { this.result = res + 'beta'; })"); | 125 context_b, "(function(res) { this.result = res + 'beta'; })"); |
| 137 | 126 |
| 138 int request_a = | 127 int request_a = |
| 139 request_handler.AddPendingRequest(isolate, function_a, context_a); | 128 request_handler.AddPendingRequest(isolate(), function_a, context_a); |
| 140 int request_b = | 129 int request_b = |
| 141 request_handler.AddPendingRequest(isolate, function_b, context_b); | 130 request_handler.AddPendingRequest(isolate(), function_b, context_b); |
| 142 | 131 |
| 143 EXPECT_THAT(request_handler.GetPendingRequestIdsForTesting(), | 132 EXPECT_THAT(request_handler.GetPendingRequestIdsForTesting(), |
| 144 testing::UnorderedElementsAre(request_a, request_b)); | 133 testing::UnorderedElementsAre(request_a, request_b)); |
| 145 | 134 |
| 146 std::unique_ptr<base::ListValue> response_a = | 135 std::unique_ptr<base::ListValue> response_a = |
| 147 ListValueFromString("['response_a:']"); | 136 ListValueFromString("['response_a:']"); |
| 148 ASSERT_TRUE(response_a); | 137 ASSERT_TRUE(response_a); |
| 149 | 138 |
| 150 request_handler.CompleteRequest(request_a, *response_a); | 139 request_handler.CompleteRequest(request_a, *response_a); |
| 151 EXPECT_TRUE(did_run_js()); | 140 EXPECT_TRUE(did_run_js()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 162 | 151 |
| 163 request_handler.CompleteRequest(request_b, *response_b); | 152 request_handler.CompleteRequest(request_b, *response_b); |
| 164 EXPECT_TRUE(request_handler.GetPendingRequestIdsForTesting().empty()); | 153 EXPECT_TRUE(request_handler.GetPendingRequestIdsForTesting().empty()); |
| 165 | 154 |
| 166 EXPECT_EQ( | 155 EXPECT_EQ( |
| 167 ReplaceSingleQuotes("'response_b:beta'"), | 156 ReplaceSingleQuotes("'response_b:beta'"), |
| 168 GetStringPropertyFromObject(context_b->Global(), context_b, "result")); | 157 GetStringPropertyFromObject(context_b->Global(), context_b, "result")); |
| 169 } | 158 } |
| 170 | 159 |
| 171 } // namespace extensions | 160 } // namespace extensions |
| OLD | NEW |