send_message_tester.cc 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "extensions/renderer/send_message_tester.h"
  5. #include "base/strings/stringprintf.h"
  6. #include "extensions/common/api/messaging/serialization_format.h"
  7. #include "extensions/renderer/bindings/api_binding_test_util.h"
  8. #include "extensions/renderer/messaging_util.h"
  9. #include "extensions/renderer/native_extension_bindings_system_test_base.h"
  10. #include "extensions/renderer/script_context.h"
  11. #include "ipc/ipc_message.h"
  12. #include "v8/include/v8.h"
  13. namespace extensions {
  14. SendMessageTester::SendMessageTester(TestIPCMessageSender* ipc_sender,
  15. ScriptContext* script_context,
  16. int next_port_id,
  17. const std::string& api_namespace)
  18. : ipc_sender_(ipc_sender),
  19. script_context_(script_context),
  20. next_port_id_(next_port_id),
  21. api_namespace_(api_namespace) {}
  22. SendMessageTester::~SendMessageTester() {}
  23. v8::Local<v8::Value> SendMessageTester::TestSendMessage(
  24. const std::string& args,
  25. const std::string& expected_message,
  26. const MessageTarget& expected_target,
  27. PortStatus expected_port_status) {
  28. SCOPED_TRACE(base::StringPrintf("Send Message Args: `%s`", args.c_str()));
  29. v8::Local<v8::Value> output;
  30. TestSendMessageOrRequest(args, expected_message, expected_target,
  31. expected_port_status, SEND_MESSAGE, output);
  32. return output;
  33. }
  34. v8::Local<v8::Value> SendMessageTester::TestSendRequest(
  35. const std::string& args,
  36. const std::string& expected_message,
  37. const MessageTarget& expected_target,
  38. PortStatus expected_port_status) {
  39. SCOPED_TRACE(base::StringPrintf("Send Request Args: `%s`", args.c_str()));
  40. v8::Local<v8::Value> output;
  41. TestSendMessageOrRequest(args, expected_message, expected_target,
  42. expected_port_status, SEND_REQUEST, output);
  43. return output;
  44. }
  45. v8::Local<v8::Value> SendMessageTester::TestSendNativeMessage(
  46. const std::string& args,
  47. const std::string& expected_message,
  48. const std::string& expected_application_name) {
  49. SCOPED_TRACE(
  50. base::StringPrintf("Send Native Message Args: `%s`", args.c_str()));
  51. // Note: we don't close the native message ports immediately, See comment in
  52. // OneTimeMessageSender.
  53. PortStatus expected_port_status = OPEN;
  54. MessageTarget expected_target(
  55. MessageTarget::ForNativeApp(expected_application_name));
  56. v8::Local<v8::Value> output;
  57. TestSendMessageOrRequest(args, expected_message, expected_target,
  58. expected_port_status, SEND_NATIVE_MESSAGE, output);
  59. return output;
  60. }
  61. void SendMessageTester::TestConnect(const std::string& args,
  62. const std::string& expected_channel,
  63. const MessageTarget& expected_target) {
  64. SCOPED_TRACE(base::StringPrintf("Connect Args: `%s`", args.c_str()));
  65. v8::Local<v8::Context> v8_context = script_context_->v8_context();
  66. constexpr char kAddPortTemplate[] =
  67. "(function() { return chrome.%s.connect(%s); })";
  68. PortId expected_port_id(script_context_->context_id(), next_port_id_++, true,
  69. SerializationFormat::kJson);
  70. EXPECT_CALL(*ipc_sender_,
  71. SendOpenMessageChannel(script_context_, expected_port_id,
  72. expected_target, expected_channel));
  73. v8::Local<v8::Function> add_port = FunctionFromString(
  74. v8_context, base::StringPrintf(kAddPortTemplate, api_namespace_.c_str(),
  75. args.c_str()));
  76. v8::Local<v8::Value> port = RunFunction(add_port, v8_context, 0, nullptr);
  77. ::testing::Mock::VerifyAndClearExpectations(ipc_sender_);
  78. ASSERT_FALSE(port.IsEmpty());
  79. ASSERT_TRUE(port->IsObject());
  80. v8::Local<v8::Object> port_obj = port.As<v8::Object>();
  81. EXPECT_EQ(base::StringPrintf(R"("%s")", expected_channel.c_str()),
  82. GetStringPropertyFromObject(port_obj, v8_context, "name"));
  83. }
  84. void SendMessageTester::TestSendMessageOrRequest(
  85. const std::string& args,
  86. const std::string& expected_message,
  87. const MessageTarget& expected_target,
  88. PortStatus expected_port_status,
  89. Method method,
  90. v8::Local<v8::Value>& out_value) {
  91. constexpr char kSendMessageTemplate[] =
  92. "(function() { return chrome.%s.%s(%s); })";
  93. std::string expected_channel;
  94. const char* method_name = nullptr;
  95. switch (method) {
  96. case SEND_MESSAGE:
  97. method_name = "sendMessage";
  98. expected_channel = messaging_util::kSendMessageChannel;
  99. break;
  100. case SEND_REQUEST:
  101. method_name = "sendRequest";
  102. expected_channel = messaging_util::kSendRequestChannel;
  103. break;
  104. case SEND_NATIVE_MESSAGE:
  105. method_name = "sendNativeMessage";
  106. // sendNativeMessage doesn't have name channels so we don't need to change
  107. // expected_channel from an empty string.
  108. break;
  109. }
  110. PortId expected_port_id(script_context_->context_id(), next_port_id_++, true,
  111. SerializationFormat::kJson);
  112. EXPECT_CALL(*ipc_sender_,
  113. SendOpenMessageChannel(script_context_, expected_port_id,
  114. expected_target, expected_channel));
  115. Message message(expected_message, SerializationFormat::kJson, false);
  116. EXPECT_CALL(*ipc_sender_, SendPostMessageToPort(expected_port_id, message));
  117. if (expected_port_status == CLOSED) {
  118. EXPECT_CALL(*ipc_sender_,
  119. SendCloseMessagePort(MSG_ROUTING_NONE, expected_port_id, true));
  120. }
  121. v8::Local<v8::Context> v8_context = script_context_->v8_context();
  122. v8::Local<v8::Function> send_message = FunctionFromString(
  123. v8_context,
  124. base::StringPrintf(kSendMessageTemplate, api_namespace_.c_str(),
  125. method_name, args.c_str()));
  126. out_value = RunFunction(send_message, v8_context, 0, nullptr);
  127. ::testing::Mock::VerifyAndClearExpectations(ipc_sender_);
  128. }
  129. } // namespace extensions