blob: f6c5b52195491eff6c73bf507c5963ecd013e579 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "extensions/renderer/send_message_tester.h"
#include "base/strings/stringprintf.h"
#include "extensions/renderer/bindings/api_binding_test_util.h"
#include "extensions/renderer/messaging_util.h"
#include "extensions/renderer/native_extension_bindings_system_test_base.h"
#include "extensions/renderer/script_context.h"
#include "ipc/ipc_message.h"
#include "v8/include/v8.h"
namespace extensions {
SendMessageTester::SendMessageTester(TestIPCMessageSender* ipc_sender,
ScriptContext* script_context,
int next_port_id,
const std::string& api_namespace)
: ipc_sender_(ipc_sender),
script_context_(script_context),
next_port_id_(next_port_id),
api_namespace_(api_namespace) {}
SendMessageTester::~SendMessageTester() {}
void SendMessageTester::TestSendMessage(const std::string& args,
const std::string& expected_message,
const MessageTarget& expected_target,
bool expected_include_tls_channel_id,
PortStatus expected_port_status) {
SCOPED_TRACE(base::StringPrintf("Send Message Args: `%s`", args.c_str()));
TestSendMessageOrRequest(args, expected_message, expected_target,
expected_include_tls_channel_id,
expected_port_status, SEND_MESSAGE);
}
void SendMessageTester::TestSendRequest(const std::string& args,
const std::string& expected_message,
const MessageTarget& expected_target,
PortStatus expected_port_status) {
SCOPED_TRACE(base::StringPrintf("Send Request Args: `%s`", args.c_str()));
TestSendMessageOrRequest(args, expected_message, expected_target, false,
expected_port_status, SEND_REQUEST);
}
void SendMessageTester::TestConnect(const std::string& args,
const std::string& expected_channel,
const MessageTarget& expected_target,
bool expected_include_tls_channel_id) {
SCOPED_TRACE(base::StringPrintf("Connect Args: `%s`", args.c_str()));
v8::Local<v8::Context> v8_context = script_context_->v8_context();
constexpr char kAddPortTemplate[] =
"(function() { return chrome.%s.connect(%s); })";
PortId expected_port_id(script_context_->context_id(), next_port_id_++, true);
EXPECT_CALL(*ipc_sender_,
SendOpenMessageChannel(script_context_, expected_port_id,
expected_target, expected_channel,
expected_include_tls_channel_id));
v8::Local<v8::Function> add_port = FunctionFromString(
v8_context, base::StringPrintf(kAddPortTemplate, api_namespace_.c_str(),
args.c_str()));
v8::Local<v8::Value> port = RunFunction(add_port, v8_context, 0, nullptr);
::testing::Mock::VerifyAndClearExpectations(ipc_sender_);
ASSERT_FALSE(port.IsEmpty());
ASSERT_TRUE(port->IsObject());
v8::Local<v8::Object> port_obj = port.As<v8::Object>();
EXPECT_EQ(base::StringPrintf(R"("%s")", expected_channel.c_str()),
GetStringPropertyFromObject(port_obj, v8_context, "name"));
}
void SendMessageTester::TestSendMessageOrRequest(
const std::string& args,
const std::string& expected_message,
const MessageTarget& expected_target,
bool expected_include_tls_channel_id,
PortStatus expected_port_status,
Method method) {
constexpr char kSendMessageTemplate[] = "(function() { chrome.%s.%s(%s); })";
std::string expected_channel;
const char* method_name = nullptr;
switch (method) {
case SEND_MESSAGE:
method_name = "sendMessage";
expected_channel = messaging_util::kSendMessageChannel;
break;
case SEND_REQUEST:
method_name = "sendRequest";
expected_channel = messaging_util::kSendRequestChannel;
break;
}
PortId expected_port_id(script_context_->context_id(), next_port_id_++, true);
EXPECT_CALL(*ipc_sender_,
SendOpenMessageChannel(script_context_, expected_port_id,
expected_target, expected_channel,
expected_include_tls_channel_id));
Message message(expected_message, false);
EXPECT_CALL(*ipc_sender_, SendPostMessageToPort(MSG_ROUTING_NONE,
expected_port_id, message));
if (expected_port_status == CLOSED) {
EXPECT_CALL(*ipc_sender_,
SendCloseMessagePort(MSG_ROUTING_NONE, expected_port_id, true));
}
v8::Local<v8::Context> v8_context = script_context_->v8_context();
v8::Local<v8::Function> send_message = FunctionFromString(
v8_context,
base::StringPrintf(kSendMessageTemplate, api_namespace_.c_str(),
method_name, args.c_str()));
RunFunction(send_message, v8_context, 0, nullptr);
::testing::Mock::VerifyAndClearExpectations(ipc_sender_);
}
} // namespace extensions