// Copyright 2016 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/native_extension_bindings_system_test_base.h"

#include "base/macros.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind_test_util.h"
#include "components/crx_file/id_util.h"
#include "extensions/common/extension_api.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/extension_messages.h"
#include "extensions/common/manifest.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/value_builder.h"
#include "extensions/renderer/bindings/api_binding_test_util.h"
#include "extensions/renderer/bindings/api_invocation_errors.h"
#include "extensions/renderer/bindings/api_response_validator.h"
#include "extensions/renderer/bindings/test_js_runner.h"
#include "extensions/renderer/message_target.h"
#include "extensions/renderer/native_extension_bindings_system.h"
#include "extensions/renderer/script_context.h"

namespace extensions {

namespace {

// Returns true if the value specified by |property| exists in the given
// context.
bool PropertyExists(v8::Local<v8::Context> context,
                    base::StringPiece property) {
  v8::Local<v8::Value> value = V8ValueFromScriptSource(context, property);
  EXPECT_FALSE(value.IsEmpty());
  return !value->IsUndefined();
}

}  // namespace

TEST_F(NativeExtensionBindingsSystemUnittest, Basic) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("foo")
          .AddPermissions({"idle", "power", "webRequest"})
          .Build();
  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

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

  bindings_system()->UpdateBindingsForContext(script_context);

  // chrome.idle.queryState should exist.
  v8::Local<v8::Value> chrome =
      GetPropertyFromObject(context->Global(), context, "chrome");
  ASSERT_FALSE(chrome.IsEmpty());
  ASSERT_TRUE(chrome->IsObject());

  v8::Local<v8::Value> idle = GetPropertyFromObject(
      v8::Local<v8::Object>::Cast(chrome), context, "idle");
  ASSERT_FALSE(idle.IsEmpty());
  ASSERT_TRUE(idle->IsObject());

  v8::Local<v8::Object> idle_object = v8::Local<v8::Object>::Cast(idle);
  v8::Local<v8::Value> idle_query_state =
      GetPropertyFromObject(idle_object, context, "queryState");
  ASSERT_FALSE(idle_query_state.IsEmpty());

  EXPECT_EQ(ReplaceSingleQuotes(
                "{'ACTIVE':'active','IDLE':'idle','LOCKED':'locked'}"),
            GetStringPropertyFromObject(idle_object, context, "IdleState"));

  {
    // Try calling the function with an invalid invocation - an error should be
    // thrown.
    const char kCallIdleQueryStateInvalid[] =
        "(function() {\n"
        "  chrome.idle.queryState('foo', function(state) {\n"
        "    this.responseState = state;\n"
        "  });\n"
        "});";
    v8::Local<v8::Function> function =
        FunctionFromString(context, kCallIdleQueryStateInvalid);
    ASSERT_FALSE(function.IsEmpty());
    RunFunctionAndExpectError(
        function, context, 0, nullptr,
        "Uncaught TypeError: " +
            api_errors::InvocationError(
                "idle.queryState",
                "integer detectionIntervalInSeconds, function callback",
                api_errors::NoMatchingSignature()));
  }

  {
    // Call the function correctly.
    const char kCallIdleQueryState[] =
        "(function() {\n"
        "  chrome.idle.queryState(30, function(state) {\n"
        "    this.responseState = state;\n"
        "  });\n"
        "});";

    v8::Local<v8::Function> call_idle_query_state =
        FunctionFromString(context, kCallIdleQueryState);
    RunFunctionOnGlobal(call_idle_query_state, context, 0, nullptr);
  }

  // Validate the params that would be sent to the browser.
  EXPECT_EQ(extension->id(), last_params().extension_id);
  EXPECT_EQ("idle.queryState", last_params().name);
  EXPECT_EQ(extension->url(), last_params().source_url);
  EXPECT_TRUE(last_params().has_callback);
  EXPECT_TRUE(
      last_params().arguments.Equals(ListValueFromString("[30]").get()));

  // Respond and validate.
  bindings_system()->HandleResponse(last_params().request_id, true,
                                    *ListValueFromString("['active']"),
                                    std::string());

  std::unique_ptr<base::Value> result_value = GetBaseValuePropertyFromObject(
      context->Global(), context, "responseState");
  ASSERT_TRUE(result_value);
  EXPECT_EQ("\"active\"", ValueToString(*result_value));

  // Sanity-check that another API also exists as expected.
  v8::Local<v8::Value> power_api =
      V8ValueFromScriptSource(context, "chrome.power");
  ASSERT_FALSE(power_api.IsEmpty());
  ASSERT_TRUE(power_api->IsObject());
  v8::Local<v8::Value> request_keep_awake = GetPropertyFromObject(
      power_api.As<v8::Object>(), context, "requestKeepAwake");
  ASSERT_FALSE(request_keep_awake.IsEmpty());
  EXPECT_TRUE(request_keep_awake->IsFunction());

  // Test properties exposed on the API object itself.
  v8::Local<v8::Value> web_request =
      V8ValueFromScriptSource(context, "chrome.webRequest");
  ASSERT_FALSE(web_request.IsEmpty());
  ASSERT_TRUE(web_request->IsObject());
  EXPECT_EQ("20", GetStringPropertyFromObject(
                      web_request.As<v8::Object>(), context,
                      "MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES"));
}

TEST_F(NativeExtensionBindingsSystemUnittest, Events) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("foo").AddPermissions({"idle", "power"}).Build();
  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

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

  bindings_system()->UpdateBindingsForContext(script_context);

  {
    const char kAddStateChangedListeners[] =
        "(function() {\n"
        "  chrome.idle.onStateChanged.addListener(function() {\n"
        "    this.didThrow = true;\n"
        "    throw new Error('Error!!!');\n"
        "  });\n"
        "  chrome.idle.onStateChanged.addListener(function(newState) {\n"
        "    this.newState = newState;\n"
        "  });\n"
        "});";

    v8::Local<v8::Function> add_listeners =
        FunctionFromString(context, kAddStateChangedListeners);
    RunFunctionOnGlobal(add_listeners, context, 0, nullptr);
  }

  {
    TestJSRunner::AllowErrors allow_errors;
    bindings_system()->DispatchEventInContext(
        "idle.onStateChanged", ListValueFromString("['idle']").get(), nullptr,
        script_context);
  }

  EXPECT_EQ("\"idle\"", GetStringPropertyFromObject(context->Global(), context,
                                                    "newState"));
  EXPECT_EQ("true", GetStringPropertyFromObject(context->Global(), context,
                                                "didThrow"));
}

// Tests that referencing the same API multiple times returns the same object;
// i.e. chrome.foo === chrome.foo.
TEST_F(NativeExtensionBindingsSystemUnittest, APIObjectsAreEqual) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("foo").AddPermission("idle").Build();
  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

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

  bindings_system()->UpdateBindingsForContext(script_context);

  v8::Local<v8::Value> first_idle_object =
      V8ValueFromScriptSource(context, "chrome.idle");
  ASSERT_FALSE(first_idle_object.IsEmpty());
  EXPECT_TRUE(first_idle_object->IsObject());
  EXPECT_FALSE(first_idle_object->IsUndefined());
  v8::Local<v8::Value> second_idle_object =
      V8ValueFromScriptSource(context, "chrome.idle");
  EXPECT_TRUE(first_idle_object == second_idle_object);
}

// Tests that referencing APIs after the context data is disposed is safe (and
// returns undefined if not yet instantiated).
TEST_F(NativeExtensionBindingsSystemUnittest,
       ReferencingAPIAfterDisposingContext) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("foo").AddPermissions({"idle", "power"}).Build();

  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

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

  bindings_system()->UpdateBindingsForContext(script_context);

  v8::Local<v8::Value> first_idle_object =
      V8ValueFromScriptSource(context, "chrome.idle");
  ASSERT_FALSE(first_idle_object.IsEmpty());
  EXPECT_TRUE(first_idle_object->IsObject());

  DisposeContext(context);
  {
    // Despite disposal, the context has been kept alive via the Local above.
    v8::Context::Scope context_scope(context);

    // Check an API that was instantiated....
    v8::Local<v8::Value> second_idle_object =
        V8ValueFromScriptSource(context, "chrome.idle");
    EXPECT_EQ(first_idle_object, second_idle_object);
    // ... and also one that wasn't.
    v8::Local<v8::Value> power_object =
        V8ValueFromScriptSource(context, "chrome.power");
    ASSERT_FALSE(power_object.IsEmpty());
    EXPECT_TRUE(power_object->IsUndefined());
  }
}

// Tests that traditional custom bindings can be used with the native bindings
// system.
TEST_F(NativeExtensionBindingsSystemUnittest, TestBridgingToJSCustomBindings) {
  // Custom binding code. This basically utilizes the interface in binding.js in
  // order to test backwards compatibility.
  const char kCustomBinding[] =
      "apiBridge.registerCustomHook((api, extensionId, contextType) => {\n"
      "  api.apiFunctions.setHandleRequest('queryState',\n"
      "                                    (time, callback) => {\n"
      "    this.timeArg = time;\n"
      "    callback('active');\n"
      "  });\n"
      "  api.apiFunctions.setUpdateArgumentsPreValidate(\n"
      "      'setDetectionInterval', (interval) => {\n"
      "    this.intervalArg = interval;\n"
      "    return [50];\n"
      "  });\n"
      "  this.hookedExtensionId = extensionId;\n"
      "  this.hookedContextType = contextType;\n"
      "  api.compiledApi.hookedApiProperty = 'someProperty';\n"
      "});\n";

  source_map()->RegisterModule("idle", kCustomBinding);

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

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

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

  bindings_system()->UpdateBindingsForContext(script_context);

  {
    // Call the function correctly.
    const char kCallIdleQueryState[] =
        "(function() {\n"
        "  chrome.idle.queryState(30, function(state) {\n"
        "    this.responseState = state;\n"
        "  });\n"
        "});";

    v8::Local<v8::Function> call_idle_query_state =
        FunctionFromString(context, kCallIdleQueryState);
    RunFunctionOnGlobal(call_idle_query_state, context, 0, nullptr);
  }

  // To start, check that the properties we set when running the hooks are
  // correct. We do this after calling the function because the API objects (and
  // thus the hooks) are set up lazily.
  v8::Local<v8::Object> global = context->Global();
  EXPECT_EQ(base::StringPrintf("\"%s\"", extension->id().c_str()),
            GetStringPropertyFromObject(global, context, "hookedExtensionId"));
  EXPECT_EQ("\"BLESSED_EXTENSION\"",
            GetStringPropertyFromObject(global, context, "hookedContextType"));
  v8::Local<v8::Value> idle_api =
      V8ValueFromScriptSource(context, "chrome.idle");
  ASSERT_FALSE(idle_api.IsEmpty());
  ASSERT_TRUE(idle_api->IsObject());
  EXPECT_EQ("\"someProperty\"",
            GetStringPropertyFromObject(idle_api.As<v8::Object>(), context,
                                        "hookedApiProperty"));

  // Next, we need to check two pieces: first, that the custom handler was
  // called with the proper arguments....
  EXPECT_EQ("30", GetStringPropertyFromObject(global, context, "timeArg"));

  // ...and second, that the callback was called with the proper result.
  EXPECT_EQ("\"active\"",
            GetStringPropertyFromObject(global, context, "responseState"));

  // Test the updateArgumentsPreValidate hook.
  {
    // Call the function correctly.
    const char kCallIdleSetInterval[] =
        "(function() {\n"
        "  chrome.idle.setDetectionInterval(20);\n"
        "});";

    v8::Local<v8::Function> call_idle_set_interval =
        FunctionFromString(context, kCallIdleSetInterval);
    RunFunctionOnGlobal(call_idle_set_interval, context, 0, nullptr);
  }

  // Since we don't have a custom request handler, the hook should have only
  // updated the arguments. The request then should have gone to the browser
  // normally.
  EXPECT_EQ("20", GetStringPropertyFromObject(global, context, "intervalArg"));
  EXPECT_EQ(extension->id(), last_params().extension_id);
  EXPECT_EQ("idle.setDetectionInterval", last_params().name);
  EXPECT_EQ(extension->url(), last_params().source_url);
  EXPECT_FALSE(last_params().has_callback);
  EXPECT_TRUE(
      last_params().arguments.Equals(ListValueFromString("[50]").get()));
}

TEST_F(NativeExtensionBindingsSystemUnittest, TestSendRequestHook) {
  // Custom binding code. This basically utilizes the interface in binding.js in
  // order to test backwards compatibility.
  const char kCustomBinding[] =
      "apiBridge.registerCustomHook((api) => {\n"
      "  api.apiFunctions.setHandleRequest('queryState',\n"
      "                                    (time, callback) => {\n"
      "    bindingUtil.sendRequest('idle.queryState', [time, callback],\n"
      "                            undefined, undefined);\n"
      "  });\n"
      "});\n";

  source_map()->RegisterModule("idle", kCustomBinding);

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

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

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

  bindings_system()->UpdateBindingsForContext(script_context);

  {
    // Call the function correctly.
    const char kCallIdleQueryState[] =
        "(function() { chrome.idle.queryState(30, function() {}); });";

    v8::Local<v8::Function> call_idle_query_state =
        FunctionFromString(context, kCallIdleQueryState);
    RunFunctionOnGlobal(call_idle_query_state, context, 0, nullptr);
  }
  EXPECT_EQ(extension->id(), last_params().extension_id);
  EXPECT_EQ("idle.queryState", last_params().name);
  EXPECT_EQ(extension->url(), last_params().source_url);
  EXPECT_TRUE(last_params().has_callback);
  EXPECT_TRUE(
      last_params().arguments.Equals(ListValueFromString("[30]").get()));
}

// Tests that we can notify the browser as event listeners are added or removed.
// Note: the notification logic is tested more thoroughly in the APIEventHandler
// unittests.
TEST_F(NativeExtensionBindingsSystemUnittest, TestEventRegistration) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("foo").AddPermissions({"idle", "power"}).Build();

  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

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

  bindings_system()->UpdateBindingsForContext(script_context);

  // Add a new event listener. We should be notified of the change.
  const char kEventName[] = "idle.onStateChanged";
  v8::Local<v8::Function> listener =
      FunctionFromString(context, "(function() {})");
  const char kAddListener[] =
      "(function(listener) {\n"
      "  chrome.idle.onStateChanged.addListener(listener);\n"
      "});";
  v8::Local<v8::Function> add_listener =
      FunctionFromString(context, kAddListener);
  EXPECT_CALL(*ipc_message_sender(),
              SendAddUnfilteredEventListenerIPC(script_context, kEventName))
      .Times(1);
  v8::Local<v8::Value> argv[] = {listener};
  RunFunction(add_listener, context, base::size(argv), argv);
  ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender());
  EXPECT_TRUE(bindings_system()->HasEventListenerInContext(
      "idle.onStateChanged", script_context));

  // Remove the event listener. We should be notified again.
  const char kRemoveListener[] =
      "(function(listener) {\n"
      "  chrome.idle.onStateChanged.removeListener(listener);\n"
      "});";
  EXPECT_CALL(*ipc_message_sender(),
              SendRemoveUnfilteredEventListenerIPC(script_context, kEventName))
      .Times(1);
  v8::Local<v8::Function> remove_listener =
      FunctionFromString(context, kRemoveListener);
  RunFunction(remove_listener, context, base::size(argv), argv);
  ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender());
  EXPECT_FALSE(bindings_system()->HasEventListenerInContext(
      "idle.onStateChanged", script_context));
}

TEST_F(NativeExtensionBindingsSystemUnittest,
       TestPrefixedApiEventsAndAppBinding) {
  scoped_refptr<const Extension> app =
      ExtensionBuilder("foo", ExtensionBuilder::Type::PLATFORM_APP).Build();
  EXPECT_TRUE(app->is_platform_app());
  RegisterExtension(app);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

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

  bindings_system()->UpdateBindingsForContext(script_context);

  // The 'chrome.app' object should have 'runtime' and 'window' entries, but
  // not the internal 'currentWindowInternal' object.
  v8::Local<v8::Value> app_binding_keys =
      V8ValueFromScriptSource(context,
                              "JSON.stringify(Object.keys(chrome.app));");
  ASSERT_FALSE(app_binding_keys.IsEmpty());
  ASSERT_TRUE(app_binding_keys->IsString());
  EXPECT_EQ("[\"runtime\",\"window\"]",
            gin::V8ToString(isolate(), app_binding_keys));

  const char kUseAppRuntime[] =
      "(function() {\n"
      "  chrome.app.runtime.onLaunched.addListener(function() {});\n"
      "});";
  v8::Local<v8::Function> use_app_runtime =
      FunctionFromString(context, kUseAppRuntime);
  EXPECT_CALL(*ipc_message_sender(),
              SendAddUnfilteredEventListenerIPC(script_context,
                                                "app.runtime.onLaunched"))
      .Times(1);
  RunFunctionOnGlobal(use_app_runtime, context, 0, nullptr);
  ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender());
}

TEST_F(NativeExtensionBindingsSystemUnittest,
       TestPrefixedApiMethodsAndSystemBinding) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("foo").AddPermission("system.cpu").Build();
  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

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

  bindings_system()->UpdateBindingsForContext(script_context);

  // The system.cpu object should exist, but system.network should not (as the
  // extension didn't request permission to it).
  v8::Local<v8::Value> system_cpu =
      V8ValueFromScriptSource(context, "chrome.system.cpu");
  ASSERT_FALSE(system_cpu.IsEmpty());
  EXPECT_TRUE(system_cpu->IsObject());
  EXPECT_FALSE(system_cpu->IsUndefined());

  v8::Local<v8::Value> system_network =
      V8ValueFromScriptSource(context, "chrome.system.network");
  ASSERT_FALSE(system_network.IsEmpty());
  EXPECT_TRUE(system_network->IsUndefined());

  const char kUseSystemCpu[] =
      "(function() {\n"
      "  chrome.system.cpu.getInfo(function() {})\n"
      "});";
  v8::Local<v8::Function> use_system_cpu =
      FunctionFromString(context, kUseSystemCpu);
  RunFunctionOnGlobal(use_system_cpu, context, 0, nullptr);

  EXPECT_EQ(extension->id(), last_params().extension_id);
  EXPECT_EQ("system.cpu.getInfo", last_params().name);
  EXPECT_TRUE(last_params().has_callback);
}

TEST_F(NativeExtensionBindingsSystemUnittest, TestLastError) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("foo").AddPermissions({"idle", "power"}).Build();
  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

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

  bindings_system()->UpdateBindingsForContext(script_context);

  const char kCallFunction[] =
      "(function() {\n"
      "  chrome.idle.queryState(30, function(state) {\n"
      "    if (chrome.runtime.lastError)\n"
      "      this.lastErrorMessage = chrome.runtime.lastError.message;\n"
      "  });\n"
      "});";
  v8::Local<v8::Function> function = FunctionFromString(context, kCallFunction);
  ASSERT_FALSE(function.IsEmpty());
  RunFunctionOnGlobal(function, context, 0, nullptr);

  // Validate the params that would be sent to the browser.
  EXPECT_EQ(extension->id(), last_params().extension_id);
  EXPECT_EQ("idle.queryState", last_params().name);

  int first_request_id = last_params().request_id;
  // Respond with an error.
  bindings_system()->HandleResponse(last_params().request_id, false,
                                    base::ListValue(), "Some API Error");
  EXPECT_EQ("\"Some API Error\"",
            GetStringPropertyFromObject(context->Global(), context,
                                        "lastErrorMessage"));

  // Test responding with a failure, but no set error.
  RunFunctionOnGlobal(function, context, 0, nullptr);
  EXPECT_EQ(extension->id(), last_params().extension_id);
  EXPECT_EQ("idle.queryState", last_params().name);
  EXPECT_NE(first_request_id, last_params().request_id);

  bindings_system()->HandleResponse(last_params().request_id, false,
                                    base::ListValue(), std::string());
  EXPECT_EQ("\"Unknown error.\"",
            GetStringPropertyFromObject(context->Global(), context,
                                        "lastErrorMessage"));
}

TEST_F(NativeExtensionBindingsSystemUnittest, TestCustomProperties) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("storage extension").AddPermission("storage").Build();
  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

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

  bindings_system()->UpdateBindingsForContext(script_context);

  v8::Local<v8::Value> storage =
      V8ValueFromScriptSource(context, "chrome.storage");
  ASSERT_FALSE(storage.IsEmpty());
  ASSERT_TRUE(storage->IsObject());

  v8::Local<v8::Value> local =
      GetPropertyFromObject(storage.As<v8::Object>(), context, "local");
  ASSERT_FALSE(local.IsEmpty());
  ASSERT_TRUE(local->IsObject());

  v8::Local<v8::Object> local_object = local.As<v8::Object>();
  const std::vector<std::string> kKeys = {"get", "set", "remove", "clear",
                                          "getBytesInUse"};
  for (const auto& key : kKeys) {
    v8::Local<v8::String> v8_key = gin::StringToV8(isolate(), key);
    EXPECT_TRUE(local_object->HasOwnProperty(context, v8_key).FromJust())
        << key;
  }
}

// Ensure that different contexts have different API objects.
TEST_F(NativeExtensionBindingsSystemUnittest,
       CheckDifferentContextsHaveDifferentAPIObjects) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension").AddPermission("idle").Build();
  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context_a = MainContext();
  v8::Local<v8::Context> context_b = AddContext();

  ScriptContext* script_context_a = CreateScriptContext(
      context_a, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT);
  script_context_a->set_url(extension->url());
  bindings_system()->UpdateBindingsForContext(script_context_a);

  ScriptContext* script_context_b = CreateScriptContext(
      context_b, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT);
  script_context_b->set_url(extension->url());
  bindings_system()->UpdateBindingsForContext(script_context_b);

  auto check_properties_inequal = [](v8::Local<v8::Context> context_a,
                                     v8::Local<v8::Context> context_b,
                                     base::StringPiece property) {
    v8::Local<v8::Value> value_a = V8ValueFromScriptSource(context_a, property);
    v8::Local<v8::Value> value_b = V8ValueFromScriptSource(context_b, property);
    EXPECT_FALSE(value_a.IsEmpty()) << property;
    EXPECT_FALSE(value_b.IsEmpty()) << property;
    EXPECT_NE(value_a, value_b) << property;
  };

  check_properties_inequal(context_a, context_b, "chrome");
  check_properties_inequal(context_a, context_b, "chrome.idle");
  check_properties_inequal(context_a, context_b, "chrome.idle.onStateChanged");
}

// Tests that API methods and events that are conditionally available based on
// context are properly present or absent from the API object.
TEST_F(NativeExtensionBindingsSystemUnittest,
       CheckRestrictedFeaturesBasedOnContext) {
  scoped_refptr<const Extension> connectable_extension;
  {
    DictionaryBuilder manifest;
    manifest.Set("name", "connectable")
        .Set("manifest_version", 2)
        .Set("version", "0.1")
        .Set("description", "test extension");
    DictionaryBuilder connectable;
    connectable.Set("matches",
                    ListBuilder().Append("*://example.com/*").Build());
    manifest.Set("externally_connectable", connectable.Build());
    connectable_extension =
        ExtensionBuilder()
            .SetManifest(manifest.Build())
            .SetLocation(Manifest::INTERNAL)
            .SetID(crx_file::id_util::GenerateId("connectable"))
            .Build();
  }

  RegisterExtension(connectable_extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> blessed_context = MainContext();
  v8::Local<v8::Context> connectable_webpage_context = AddContext();
  v8::Local<v8::Context> nonconnectable_webpage_context = AddContext();

  // Create two contexts - a blessed extension context and a normal web page
  // context.
  ScriptContext* blessed_script_context =
      CreateScriptContext(blessed_context, connectable_extension.get(),
                          Feature::BLESSED_EXTENSION_CONTEXT);
  blessed_script_context->set_url(connectable_extension->url());
  bindings_system()->UpdateBindingsForContext(blessed_script_context);

  ScriptContext* connectable_webpage_script_context = CreateScriptContext(
      connectable_webpage_context, nullptr, Feature::WEB_PAGE_CONTEXT);
  connectable_webpage_script_context->set_url(GURL("http://example.com"));
  bindings_system()->UpdateBindingsForContext(
      connectable_webpage_script_context);

  ScriptContext* nonconnectable_webpage_script_context = CreateScriptContext(
      nonconnectable_webpage_context, nullptr, Feature::WEB_PAGE_CONTEXT);
  nonconnectable_webpage_script_context->set_url(GURL("http://notexample.com"));
  bindings_system()->UpdateBindingsForContext(
      nonconnectable_webpage_script_context);

  // Check that properties are correctly restricted. The blessed context should
  // have access to the whole runtime API, the connectable webpage should only
  // have access to sendMessage, and the nonconnectable webpage should not have
  // access to any of the API.
  const char kRuntime[] = "chrome.runtime";
  const char kSendMessage[] = "chrome.runtime.sendMessage";
  const char kGetUrl[] = "chrome.runtime.getURL";
  const char kOnMessage[] = "chrome.runtime.onMessage";
  ASSERT_TRUE(PropertyExists(blessed_context, kRuntime));
  EXPECT_TRUE(PropertyExists(blessed_context, kSendMessage));
  EXPECT_TRUE(PropertyExists(blessed_context, kGetUrl));
  EXPECT_TRUE(PropertyExists(blessed_context, kOnMessage));

  ASSERT_TRUE(PropertyExists(connectable_webpage_context, kRuntime));
  EXPECT_TRUE(PropertyExists(connectable_webpage_context, kSendMessage));
  EXPECT_FALSE(PropertyExists(connectable_webpage_context, kGetUrl));
  EXPECT_FALSE(PropertyExists(connectable_webpage_context, kOnMessage));

  EXPECT_FALSE(PropertyExists(nonconnectable_webpage_context, kRuntime));
}

// Tests behavior when script sets window.chrome to be various things.
TEST_F(NativeExtensionBindingsSystemUnittest, TestUsingOtherChromeObjects) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension").Build();
  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context_a = MainContext();
  v8::Local<v8::Context> context_b = AddContext();

  ScriptContext* script_context_a = CreateScriptContext(
      context_a, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT);
  script_context_a->set_url(extension->url());
  ScriptContext* script_context_b = CreateScriptContext(
      context_b, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT);
  script_context_b->set_url(extension->url());

  auto check_runtime = [this, context_a, context_b, script_context_a,
                        script_context_b](bool expect_b_has_runtime) {
    bindings_system()->UpdateBindingsForContext(script_context_a);
    bindings_system()->UpdateBindingsForContext(script_context_b);

    const char kRuntime[] = "chrome.runtime";
    // chrome.runtime should always exist in context a - we only mess with
    // context b.
    EXPECT_TRUE(PropertyExists(context_a, kRuntime));
    EXPECT_EQ(expect_b_has_runtime, PropertyExists(context_b, kRuntime));
  };

  // By default, runtime should exist in both contexts (since both have access
  // to the API).
  check_runtime(true);

  {
    v8::Context::Scope scope(context_a);
    v8::Local<v8::Object> fake_chrome = v8::Object::New(isolate());
    EXPECT_EQ(context_a, fake_chrome->CreationContext());
    context_b->Global()
        ->Set(context_b, gin::StringToSymbol(isolate(), "chrome"), fake_chrome)
        .ToChecked();
  }
  // context_b has a chrome object that was created in a different context
  // (context_a), so we shouldn't have used it. This can legitimately happen in
  // the case of a parent frame modifying a child frame's window.chrome.
  check_runtime(false);

  {
    v8::Context::Scope scope(context_b);
    v8::Local<v8::Object> fake_chrome = v8::Object::New(isolate());
    EXPECT_EQ(context_b, fake_chrome->CreationContext());
    context_b->Global()
        ->Set(context_b, gin::StringToSymbol(isolate(), "chrome"), fake_chrome)
        .ToChecked();
  }
  // When the chrome object is created in the same context (context_b), that
  // object will be used.
  check_runtime(true);

  {
    v8::Context::Scope scope(context_b);
    v8::Local<v8::Boolean> fake_chrome = v8::Boolean::New(isolate(), true);
    context_b->Global()
        ->Set(context_b, gin::StringToSymbol(isolate(), "chrome"), fake_chrome)
        .ToChecked();
  }
  // A non-object chrome shouldn't be used.
  check_runtime(false);
}

// Tests updating a context's bindings after adding or removing permissions.
TEST_F(NativeExtensionBindingsSystemUnittest, TestUpdatingPermissions) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension").AddPermission("idle").Build();

  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();
  ScriptContext* script_context = CreateScriptContext(
      context, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT);
  script_context->set_url(extension->url());
  bindings_system()->UpdateBindingsForContext(script_context);

  // To start, chrome.idle should be available.
  v8::Local<v8::Value> initial_idle =
      V8ValueFromScriptSource(context, "chrome.idle");
  ASSERT_FALSE(initial_idle.IsEmpty());
  EXPECT_TRUE(initial_idle->IsObject());

  {
    // chrome.power should not be defined.
    v8::Local<v8::Value> power =
        V8ValueFromScriptSource(context, "chrome.power");
    ASSERT_FALSE(power.IsEmpty());
    EXPECT_TRUE(power->IsUndefined());
  }

  // Remove all permissions (`idle`).
  extension->permissions_data()->SetPermissions(
      std::make_unique<PermissionSet>(), std::make_unique<PermissionSet>());

  bindings_system()->OnExtensionPermissionsUpdated(extension->id());
  bindings_system()->UpdateBindingsForContext(script_context);
  {
    // TODO(devlin): Neither the native nor JS bindings systems clear the
    // property on the chrome object when an API is no longer available. This
    // seems unexpected, but warrants further investigation before changing
    // behavior. It can be complicated by the fact that chrome.idle may not be
    // the same chrome.idle the system instantiated, or may have additional
    // properties.
    // v8::Local<v8::Value> idle =
    //     V8ValueFromScriptSource(context, "chrome.idle");
    // ASSERT_FALSE(idle.IsEmpty());
    // EXPECT_TRUE(idle->IsUndefined());

    // chrome.power should still be undefined.
    v8::Local<v8::Value> power =
        V8ValueFromScriptSource(context, "chrome.power");
    ASSERT_FALSE(power.IsEmpty());
    EXPECT_TRUE(power->IsUndefined());
  }

  v8::Local<v8::Function> run_idle = FunctionFromString(
      context, "(function(idle) { idle.queryState(30, function() {}); })");
  {
    // Trying to run a chrome.idle function should fail.
    v8::Local<v8::Value> args[] = {initial_idle};
    RunFunctionAndExpectError(
        run_idle, context, base::size(args), args,
        "Uncaught Error: 'idle.queryState' is not available in this context.");
    EXPECT_FALSE(has_last_params());
  }

  {
    // Add back the `idle` permission, and also add `power`.
    APIPermissionSet apis;
    apis.insert(APIPermission::kPower);
    apis.insert(APIPermission::kIdle);
    extension->permissions_data()->SetPermissions(
        std::make_unique<PermissionSet>(std::move(apis),
                                        ManifestPermissionSet(),
                                        URLPatternSet(), URLPatternSet()),
        std::make_unique<PermissionSet>());
    bindings_system()->OnExtensionPermissionsUpdated(extension->id());
    bindings_system()->UpdateBindingsForContext(script_context);
  }

  {
    // Both chrome.idle and chrome.power should be defined.
    v8::Local<v8::Value> idle = V8ValueFromScriptSource(context, "chrome.idle");
    ASSERT_FALSE(idle.IsEmpty());
    EXPECT_TRUE(idle->IsObject());

    v8::Local<v8::Value> power =
        V8ValueFromScriptSource(context, "chrome.power");
    ASSERT_FALSE(power.IsEmpty());
    EXPECT_TRUE(power->IsObject());
  }

  {
    // Trying to run a chrome.idle function should now succeed.
    v8::Local<v8::Value> args[] = {initial_idle};
    RunFunction(run_idle, context, base::size(args), args);
    EXPECT_EQ("idle.queryState", last_params().name);
  }
}

TEST_F(NativeExtensionBindingsSystemUnittest, UnmanagedEvents) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension").Build();

  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();
  ScriptContext* script_context = CreateScriptContext(
      context, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT);
  script_context->set_url(extension->url());

  bindings_system()->UpdateBindingsForContext(script_context);

  const char kAddListeners[] =
      "(function() {\n"
      "  chrome.runtime.onMessage.addListener(function() {});\n"
      "  chrome.runtime.onConnect.addListener(function() {});\n"
      "});";

  v8::Local<v8::Function> add_listeners =
      FunctionFromString(context, kAddListeners);
  RunFunctionOnGlobal(add_listeners, context, 0, nullptr);

  // We should have no notifications for event listeners added (since the
  // mock is a strict mock, this will fail if anything was called).
  ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender());
}

// Tests that a context having access to an aliased API (like networking.onc)
// does not allow for accessing the source API (networkingPrivate) directly.
TEST_F(NativeExtensionBindingsSystemUnittest,
       AccessToAliasSourceDoesntGiveAliasAccess) {
  const char kWhitelistedId[] = "pkedcjkdefgpdelpbcmbmeomcjbeemfm";
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension")
          .SetID(kWhitelistedId)
          .AddPermission("networkingPrivate")
          .Build();

  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();
  ScriptContext* script_context = CreateScriptContext(
      context, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT);

  bindings_system()->UpdateBindingsForContext(script_context);

  // The extension only has access to networkingPrivate, so networking.onc
  // (and chrome.networking in general) should be undefined.
  EXPECT_EQ("object",
            gin::V8ToString(isolate(),
                            V8ValueFromScriptSource(
                                context, "typeof chrome.networkingPrivate")));
  EXPECT_EQ(
      "undefined",
      gin::V8ToString(isolate(), V8ValueFromScriptSource(
                                     context, "typeof chrome.networking")));
}

// Tests that a context having access to the source for an aliased API does not
// allow for accessing the alias.
TEST_F(NativeExtensionBindingsSystemUnittest,
       AccessToAliasDoesntGiveAliasSourceAccess) {
  const char kWhitelistedId[] = "pkedcjkdefgpdelpbcmbmeomcjbeemfm";
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension")
          .SetID(kWhitelistedId)
          .AddPermission("networking.onc")
          .Build();
  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();
  ScriptContext* script_context = CreateScriptContext(
      context, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT);

  bindings_system()->UpdateBindingsForContext(script_context);

  // The extension only has access to networking.onc, so networkingPrivate
  // should be undefined.
  EXPECT_EQ("undefined",
            gin::V8ToString(isolate(),
                            V8ValueFromScriptSource(
                                context, "typeof chrome.networkingPrivate")));
  EXPECT_EQ(
      "object",
      gin::V8ToString(isolate(), V8ValueFromScriptSource(
                                     context, "typeof chrome.networking.onc")));
}

// Test that if an extension has access to both an alias and an alias source,
// the objects on the API are different.
TEST_F(NativeExtensionBindingsSystemUnittest, AliasedAPIsAreDifferentObjects) {
  const char kWhitelistedId[] = "pkedcjkdefgpdelpbcmbmeomcjbeemfm";
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension")
          .SetID(kWhitelistedId)
          .AddPermissions({"networkingPrivate", "networking.onc"})
          .Build();
  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();
  ScriptContext* script_context = CreateScriptContext(
      context, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT);

  bindings_system()->UpdateBindingsForContext(script_context);

  // Both APIs should be defined, since the extension has access to each.
  EXPECT_EQ("object",
            gin::V8ToString(isolate(),
                            V8ValueFromScriptSource(
                                context, "typeof chrome.networkingPrivate")));
  EXPECT_EQ(
      "object",
      gin::V8ToString(isolate(), V8ValueFromScriptSource(
                                     context, "typeof chrome.networking.onc")));

  // The APIs should not be equal.
  bool equal = true;
  EXPECT_TRUE(gin::ConvertFromV8(
      isolate(),
      V8ValueFromScriptSource(
          context, "chrome.networkingPrivate == chrome.networking.onc"),
      &equal));
  EXPECT_FALSE(equal);
}

// Tests that script can overwrite the value of an API.
TEST_F(NativeExtensionBindingsSystemUnittest, CanOverwriteAPIs) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension").Build();

  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();
  ScriptContext* script_context = CreateScriptContext(
      context, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT);
  script_context->set_url(extension->url());

  bindings_system()->UpdateBindingsForContext(script_context);

  v8::Local<v8::Function> overwrite_api =
      FunctionFromString(context, "(function() { chrome.runtime = 'bar'; })");
  RunFunction(overwrite_api, context, 0, nullptr);
  v8::Local<v8::Value> property =
      V8ValueFromScriptSource(context, "chrome.runtime");
  EXPECT_TRUE(property->IsString());
  EXPECT_EQ("bar", gin::V8ToString(isolate(), property));
}

// Tests that script can delete an API property.
TEST_F(NativeExtensionBindingsSystemUnittest, CanDeleteAPIs) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("extension").Build();

  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();
  ScriptContext* script_context = CreateScriptContext(
      context, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT);
  script_context->set_url(extension->url());

  bindings_system()->UpdateBindingsForContext(script_context);

  v8::Local<v8::Object> chrome =
      GetPropertyFromObject(context->Global(), context, "chrome")
          .As<v8::Object>();
  v8::Local<v8::String> runtime_key = gin::StringToSymbol(isolate(), "runtime");

  {
    v8::Maybe<bool> has_runtime = chrome->HasOwnProperty(context, runtime_key);
    ASSERT_TRUE(has_runtime.IsJust());
    EXPECT_TRUE(has_runtime.FromJust());
  }

  v8::Local<v8::Function> delete_api =
      FunctionFromString(context, "(function() { delete chrome.runtime; })");
  RunFunction(delete_api, context, 0, nullptr);

  {
    v8::Maybe<bool> has_runtime = chrome->HasOwnProperty(context, runtime_key);
    ASSERT_TRUE(has_runtime.IsJust());
    EXPECT_FALSE(has_runtime.FromJust());
  }

  v8::Local<v8::Value> property =
      V8ValueFromScriptSource(context, "chrome.runtime");
  EXPECT_TRUE(property->IsUndefined());
}

// Test that API initialization happens in the owning context.
TEST_F(NativeExtensionBindingsSystemUnittest, APIIsInitializedByOwningContext) {
  // Attach custom JS hooks.
  const char kCustomBinding[] =
      R"(this.apiBridge = apiBridge;
         apiBridge.registerCustomHook(() => {});)";
  source_map()->RegisterModule("idle", kCustomBinding);

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

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

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

  bindings_system()->UpdateBindingsForContext(script_context);

  {
    // Create a second, uninitialized context, which will trigger the
    // construction of chrome.idle in the first context.
    set_allow_unregistered_contexts(true);
    v8::Local<v8::Context> second_context = AddContext();

    v8::Local<v8::Function> get_idle = FunctionFromString(
        second_context, "(function(chrome) { chrome.idle; })");
    v8::Local<v8::Value> chrome =
        context->Global()
            ->Get(context, gin::StringToV8(isolate(), "chrome"))
            .ToLocalChecked();
    ASSERT_TRUE(chrome->IsObject());

    v8::Context::Scope context_scope(second_context);
    v8::Local<v8::Value> args[] = {chrome};
    RunFunction(get_idle, second_context, base::size(args), args);
  }

  // The apiBridge should have been created in the owning (original) context,
  // even though the initialization was triggered by the second context.
  v8::Local<v8::Value> api_bridge =
      context->Global()
          ->Get(context, gin::StringToV8(isolate(), "apiBridge"))
          .ToLocalChecked();
  ASSERT_TRUE(api_bridge->IsObject());
  EXPECT_EQ(context, api_bridge.As<v8::Object>()->CreationContext());
}

class ResponseValidationNativeExtensionBindingsSystemUnittest
    : public NativeExtensionBindingsSystemUnittest,
      public testing::WithParamInterface<bool> {
 public:
  ResponseValidationNativeExtensionBindingsSystemUnittest() = default;
  ~ResponseValidationNativeExtensionBindingsSystemUnittest() override = default;

  void SetUp() override {
    response_validation_override_ =
        binding::SetResponseValidationEnabledForTesting(GetParam());
    NativeExtensionBindingsSystemUnittest::SetUp();
  }

  void TearDown() override {
    NativeExtensionBindingsSystemUnittest::TearDown();
    response_validation_override_.reset();
  }

 private:
  std::unique_ptr<base::AutoReset<bool>> response_validation_override_;

  DISALLOW_COPY_AND_ASSIGN(
      ResponseValidationNativeExtensionBindingsSystemUnittest);
};

TEST_P(ResponseValidationNativeExtensionBindingsSystemUnittest,
       ResponseValidation) {
  // The APIResponseValidator should only be used if response validation is
  // enabled. Otherwise, it should be null.
  EXPECT_EQ(GetParam(), bindings_system()
                            ->api_system()
                            ->request_handler()
                            ->has_response_validator_for_testing());

  base::Optional<std::string> validation_failure_method_name;
  base::Optional<std::string> validation_failure_error;

  auto on_validation_failure =
      [&validation_failure_method_name, &validation_failure_error](
          const std::string& method_name, const std::string& error) {
        validation_failure_method_name = method_name;
        validation_failure_error = error;
      };
  APIResponseValidator::TestHandler test_validation_failure_handler(
      base::BindLambdaForTesting(on_validation_failure));

  scoped_refptr<const Extension> extension =
      ExtensionBuilder("foo")
          .AddPermissions({"idle", "power", "webRequest"})
          .Build();
  RegisterExtension(extension);

  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

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

  bindings_system()->UpdateBindingsForContext(script_context);

  const char kCallIdleQueryState[] =
      "(function() { chrome.idle.queryState(30, function() {}); })";

  v8::Local<v8::Function> call_idle_query_state =
      FunctionFromString(context, kCallIdleQueryState);
  RunFunctionOnGlobal(call_idle_query_state, context, 0, nullptr);

  EXPECT_FALSE(validation_failure_method_name);
  EXPECT_FALSE(validation_failure_error);

  // Respond with a valid value. Validation should not fail.
  ASSERT_TRUE(has_last_params());
  bindings_system()->HandleResponse(last_params().request_id, true,
                                    *ListValueFromString("['active']"),
                                    std::string());

  EXPECT_FALSE(validation_failure_method_name);
  EXPECT_FALSE(validation_failure_error);

  // Run the function again, and response with an invalid value.
  RunFunctionOnGlobal(call_idle_query_state, context, 0, nullptr);
  ASSERT_TRUE(has_last_params());
  bindings_system()->HandleResponse(last_params().request_id, true,
                                    *ListValueFromString("['bad enum']"),
                                    std::string());

  // Validation should fail iff response validation is enabled.
  if (GetParam()) {
    EXPECT_EQ("idle.queryState",
              validation_failure_method_name.value_or("no value"));
    EXPECT_EQ(api_errors::ArgumentError(
                  "newState",
                  api_errors::InvalidEnumValue({"active", "idle", "locked"})),
              validation_failure_error.value_or("no value"));
  } else {
    EXPECT_FALSE(validation_failure_method_name);
    EXPECT_FALSE(validation_failure_error);
  }
}

INSTANTIATE_TEST_SUITE_P(
    ,
    ResponseValidationNativeExtensionBindingsSystemUnittest,
    testing::Bool());

}  // namespace extensions
