// Copyright 2018 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/storage_area.h"

#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "extensions/common/extension_builder.h"
#include "extensions/renderer/bindings/api_binding_test_util.h"
#include "extensions/renderer/bindings/api_binding_util.h"
#include "extensions/renderer/bindings/api_invocation_errors.h"
#include "extensions/renderer/native_extension_bindings_system.h"
#include "extensions/renderer/native_extension_bindings_system_test_base.h"
#include "extensions/renderer/script_context.h"

namespace extensions {

using StorageAreaTest = NativeExtensionBindingsSystemUnittest;

// Test that trying to use StorageArea.get without a StorageArea `this` fails
// (with a helpful error message).
TEST_F(StorageAreaTest, TestUnboundedUse) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("foo").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_get =
      V8ValueFromScriptSource(context, "chrome.storage.local.get");
  ASSERT_TRUE(storage_get->IsFunction());

  constexpr char kRunStorageGet[] =
      "(function(get) { get('foo', function() {}); })";
  v8::Local<v8::Function> run_storage_get =
      FunctionFromString(context, kRunStorageGet);
  v8::Local<v8::Value> args[] = {storage_get};
  RunFunctionAndExpectError(
      run_storage_get, context, base::size(args), args,
      "Uncaught TypeError: Illegal invocation: Function must be called on "
      "an object of type StorageArea");
}

TEST_F(StorageAreaTest, TestUseAfterInvalidation) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("foo").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.local");
  ASSERT_TRUE(storage->IsObject());

  constexpr char kRunStorageGet[] =
      "(function(storage) { storage.get('foo', function() {}); })";
  v8::Local<v8::Function> run_storage_get =
      FunctionFromString(context, kRunStorageGet);
  v8::Local<v8::Value> args[] = {storage};
  RunFunction(run_storage_get, context, base::size(args), args);

  DisposeContext(context);

  EXPECT_FALSE(binding::IsContextValid(context));
  RunFunctionAndExpectError(run_storage_get, context, base::size(args), args,
                            "Uncaught Error: Extension context invalidated.");
}

TEST_F(StorageAreaTest, InvalidInvocationError) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("foo").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.local");
  ASSERT_TRUE(storage->IsObject());

  constexpr char kRunStorageGet[] =
      "(function(storage) { storage.get(1, function() {}); })";
  v8::Local<v8::Function> run_storage_get =
      FunctionFromString(context, kRunStorageGet);
  v8::Local<v8::Value> args[] = {storage};
  RunFunctionAndExpectError(
      run_storage_get, context, base::size(args), args,
      "Uncaught TypeError: " +
          api_errors::InvocationError(
              "storage.get",
              "optional [string|array|object] keys, function callback",
              "No matching signature."));
}

TEST_F(StorageAreaTest, HasOnChanged) {
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("foo").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);

  const char* kStorages[] = {"sync", "local", "managed"};
  for (size_t i = 0; i < base::size(kStorages); ++i) {
    const std::string kRegisterListener = base::StringPrintf(
        R"((function() {
             chrome.storage.%s.onChanged.addListener(
                function(change) {
                  this.change = change;
              });
        }))",
        kStorages[i]);
    v8::Local<v8::Function> add_listener =
        FunctionFromString(context, kRegisterListener);
    RunFunctionOnGlobal(add_listener, context, 0, nullptr);

    bindings_system()->DispatchEventInContext(
        base::StringPrintf("storage.%s.onChanged", kStorages[i]).c_str(),
        ListValueFromString("['foo']").get(), nullptr, script_context);

    EXPECT_EQ("\"foo\"", GetStringPropertyFromObject(context->Global(), context,
                                                     "change"));
  }
}

}  // namespace extensions
