// 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/messaging_util.h"

#include <memory>

#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "extensions/common/api/messaging/message.h"
#include "extensions/common/extension_builder.h"
#include "extensions/renderer/bindings/api_binding_test.h"
#include "extensions/renderer/bindings/api_binding_test_util.h"
#include "extensions/renderer/native_extension_bindings_system_test_base.h"
#include "extensions/renderer/script_context.h"
#include "gin/converter.h"
#include "v8/include/v8.h"

namespace extensions {

using MessagingUtilTest = APIBindingTest;

TEST_F(MessagingUtilTest, TestMaximumMessageSize) {
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

  constexpr char kMessageTooLongError[] =
      "Message length exceeded maximum allowed length.";

  {
    v8::Local<v8::Value> long_message =
        V8ValueFromScriptSource(context, "'a'.repeat(1024 *1024 * 65)");
    std::string error;
    std::unique_ptr<Message> message =
        messaging_util::MessageFromV8(context, long_message, &error);
    EXPECT_FALSE(message);
    EXPECT_EQ(kMessageTooLongError, error);
  }

  {
    v8::Local<v8::Value> long_json_message = V8ValueFromScriptSource(
        context, "(JSON.stringify('a'.repeat(1024 *1024 * 65)))");
    ASSERT_TRUE(long_json_message->IsString());
    std::string error;
    std::unique_ptr<Message> message = messaging_util::MessageFromV8(
        context, long_json_message.As<v8::String>(), &error);
    EXPECT_FALSE(message);
    EXPECT_EQ(kMessageTooLongError, error);
  }
}

TEST_F(MessagingUtilTest, TestParseMessageOptionsFrameId) {
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

  struct {
    int expected_frame_id;
    const char* string_options;
  } test_cases[] = {
      {messaging_util::kNoFrameId, "({})"},
      {messaging_util::kNoFrameId, "({frameId: undefined})"},
      // Note: we don't test null here, because the argument parsing code
      // ensures we would never pass undefined to ParseMessageOptions (and
      // there's a DCHECK to validate it). The null case is tested in the tabs'
      // API hooks delegate test.
      {0, "({frameId: 0})"},
      {2, "({frameId: 2})"},
  };

  for (const auto& test_case : test_cases) {
    SCOPED_TRACE(test_case.string_options);
    v8::Local<v8::Value> value =
        V8ValueFromScriptSource(context, test_case.string_options);
    ASSERT_FALSE(value.IsEmpty());
    ASSERT_TRUE(value->IsObject());
    messaging_util::MessageOptions options =
        messaging_util::ParseMessageOptions(context, value.As<v8::Object>(),
                                            messaging_util::PARSE_FRAME_ID);
    EXPECT_EQ(test_case.expected_frame_id, options.frame_id);
  }
}

using MessagingUtilWithSystemTest = NativeExtensionBindingsSystemUnittest;

TEST_F(MessagingUtilWithSystemTest, TestGetTargetIdFromExtensionContext) {
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

  scoped_refptr<const Extension> extension = ExtensionBuilder("foo").Build();
  RegisterExtension(extension);

  ScriptContext* script_context = CreateScriptContext(
      context, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT);
  script_context->set_url(extension->url());

  std::string other_id(32, 'a');
  struct {
    v8::Local<v8::Value> passed_id;
    base::StringPiece expected_id;
    bool should_pass;
  } test_cases[] = {
      // If the extension ID is not provided, the bindings use the calling
      // extension's.
      {v8::Null(isolate()), extension->id(), true},
      // We treat the empty string to be the same as null, even though it's
      // somewhat unfortunate.
      // See https://crbug.com/823577.
      {gin::StringToV8(isolate(), ""), extension->id(), true},
      {gin::StringToV8(isolate(), extension->id()), extension->id(), true},
      {gin::StringToV8(isolate(), other_id), other_id, true},
      {gin::StringToV8(isolate(), "invalid id"), base::StringPiece(), false},
  };

  for (size_t i = 0; i < base::size(test_cases); ++i) {
    SCOPED_TRACE(base::StringPrintf("Test Case: %d", static_cast<int>(i)));
    const auto& test_case = test_cases[i];
    std::string target;
    std::string error;
    EXPECT_EQ(test_case.should_pass,
              messaging_util::GetTargetExtensionId(
                  script_context, test_case.passed_id, "runtime.sendMessage",
                  &target, &error));
    EXPECT_EQ(test_case.expected_id, target);
    EXPECT_EQ(test_case.should_pass, error.empty()) << error;
  }
}

TEST_F(MessagingUtilWithSystemTest, TestGetTargetIdFromWebContext) {
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

  ScriptContext* script_context =
      CreateScriptContext(context, nullptr, Feature::WEB_PAGE_CONTEXT);
  script_context->set_url(GURL("https://example.com"));

  std::string other_id(32, 'a');
  struct {
    v8::Local<v8::Value> passed_id;
    base::StringPiece expected_id;
    bool should_pass;
  } test_cases[] = {
      // A web page should always have to specify the extension id.
      {gin::StringToV8(isolate(), other_id), other_id, true},
      {v8::Null(isolate()), base::StringPiece(), false},
      {gin::StringToV8(isolate(), ""), base::StringPiece(), false},
      {gin::StringToV8(isolate(), "invalid id"), base::StringPiece(), false},
  };

  for (size_t i = 0; i < base::size(test_cases); ++i) {
    SCOPED_TRACE(base::StringPrintf("Test Case: %d", static_cast<int>(i)));
    const auto& test_case = test_cases[i];
    std::string target;
    std::string error;
    EXPECT_EQ(test_case.should_pass,
              messaging_util::GetTargetExtensionId(
                  script_context, test_case.passed_id, "runtime.sendMessage",
                  &target, &error));
    EXPECT_EQ(test_case.expected_id, target);
    EXPECT_EQ(test_case.should_pass, error.empty()) << error;
  }
}

}  // namespace extensions
