extension_function_test_utils.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_function_test_utils.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_reader.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/tabs/tabs_constants.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_function.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_function_dispatcher.h"
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/id_util.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::Manifest;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace keys = extensions::tabs_constants;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestFunctionDispatcherDelegate
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public ExtensionFunctionDispatcher::Delegate {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit TestFunctionDispatcherDelegate(Browser* browser) :
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_(browser) {}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TestFunctionDispatcherDelegate() {}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual extensions::WindowController* GetExtensionWindowController()
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const OVERRIDE {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return browser_->extension_window_controller();
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WebContents* GetAssociatedWebContents() const OVERRIDE {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* browser_;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extension_function_test_utils {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Value* ParseJSON(const std::string& data) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::JSONReader::Read(data);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::ListValue* ParseList(const std::string& data) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> result(ParseJSON(data));
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result.get() && result->IsType(base::Value::TYPE_LIST))
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<base::ListValue*>(result.release());
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::DictionaryValue* ParseDictionary(
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& data) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> result(ParseJSON(data));
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result.get() && result->IsType(base::Value::TYPE_DICTIONARY))
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<base::DictionaryValue*>(result.release());
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetBoolean(base::DictionaryValue* val, const std::string& key) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = false;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!val->GetBoolean(key, &result))
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ADD_FAILURE() << key << " does not exist or is not a boolean.";
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetInteger(base::DictionaryValue* val, const std::string& key) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = 0;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!val->GetInteger(key, &result))
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_FAILURE() << key << " does not exist or is not an integer.";
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetString(base::DictionaryValue* val, const std::string& key) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string result;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!val->GetString(key, &result))
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_FAILURE() << key << " does not exist or is not a string.";
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::DictionaryValue* ToDictionary(base::Value* val) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(val);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::Value::TYPE_DICTIONARY, val->GetType());
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<base::DictionaryValue*>(val);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::ListValue* ToList(base::Value* val) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(val);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::Value::TYPE_LIST, val->GetType());
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<base::ListValue*>(val);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Extension> CreateEmptyExtension() {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CreateEmptyExtensionWithLocation(Manifest::INTERNAL);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Extension> CreateEmptyExtensionWithLocation(
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Manifest::Location location) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> test_extension_value(
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ParseDictionary("{\"name\": \"Test\", \"version\": \"1.0\"}"));
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CreateExtension(location, test_extension_value.get(), std::string());
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Extension> CreateEmptyExtension(
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& id_input) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> test_extension_value(
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ParseDictionary("{\"name\": \"Test\", \"version\": \"1.0\"}"));
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CreateExtension(Manifest::INTERNAL, test_extension_value.get(),
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         id_input);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Extension> CreateExtension(
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::DictionaryValue* test_extension_value) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CreateExtension(Manifest::INTERNAL, test_extension_value,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         std::string());
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Extension> CreateExtension(
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Manifest::Location location,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::DictionaryValue* test_extension_value,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& id_input) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath test_extension_path;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string id;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!id_input.empty())
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    id = extensions::id_util::GenerateId(id_input);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> extension(Extension::Create(
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_extension_path,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      location,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *test_extension_value,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Extension::NO_FLAGS,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      id,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &error));
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(error.empty()) << "Could not parse test extension " << error;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extension;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HasPrivacySensitiveFields(base::DictionaryValue* val) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string result;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (val->GetString(keys::kUrlKey, &result) ||
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      val->GetString(keys::kTitleKey, &result) ||
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      val->GetString(keys::kFaviconUrlKey, &result))
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const std::string& args,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      Browser* browser) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return RunFunctionAndReturnError(function, args, browser, NONE);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const std::string& args,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      Browser* browser,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      RunFunctionFlags flags) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<ExtensionFunction> function_owner(function);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Without a callback the function will not generate a result.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  function->set_has_callback(true);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunFunction(function, args, browser, flags);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(function->GetResultList()) << "Did not expect a result";
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return function->GetError();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Value* RunFunctionAndReturnSingleResult(
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UIThreadExtensionFunction* function,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& args,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser) {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return RunFunctionAndReturnSingleResult(function, args, browser, NONE);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Value* RunFunctionAndReturnSingleResult(
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UIThreadExtensionFunction* function,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& args,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunFunctionFlags flags) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<ExtensionFunction> function_owner(function);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Without a callback the function will not generate a result.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  function->set_has_callback(true);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunFunction(function, args, browser, flags);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(function->GetError().empty()) << "Unexpected error: "
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << function->GetError();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::Value* single_result = NULL;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (function->GetResultList() != NULL &&
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      function->GetResultList()->Get(0, &single_result)) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return single_result->DeepCopy();
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// This helps us be able to wait until an UIThreadExtensionFunction calls
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SendResponse.
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SendResponseDelegate
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public UIThreadExtensionFunction::DelegateForTests {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponseDelegate() : should_post_quit_(false) {}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SendResponseDelegate() {}
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_should_post_quit(bool should_quit) {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    should_post_quit_ = should_quit;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool HasResponse() {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return response_.get() != NULL;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool GetResponse() {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(HasResponse());
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return *response_.get();
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnSendResponse(UIThreadExtensionFunction* function,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              bool success,
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              bool bad_message) OVERRIDE {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(bad_message);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(HasResponse());
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_.reset(new bool);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *response_ = success;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (should_post_quit_) {
23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::MessageLoopForUI::current()->Quit();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<bool> response_;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool should_post_quit_;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RunFunction(UIThreadExtensionFunction* function,
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const std::string& args,
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 Browser* browser,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 RunFunctionFlags flags) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponseDelegate response_delegate;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  function->set_test_delegate(&response_delegate);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::ListValue> parsed_args(ParseList(args));
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parsed_args.get()) <<
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Could not parse extension function arguments: " << args;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  function->SetArgs(parsed_args.get());
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestFunctionDispatcherDelegate dispatcher_delegate(browser);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionFunctionDispatcher dispatcher(
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser->profile(), &dispatcher_delegate);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  function->set_dispatcher(dispatcher.AsWeakPtr());
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  function->set_context(browser->profile());
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  function->set_include_incognito(flags & INCLUDE_INCOGNITO);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  function->Run();
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the RunImpl of |function| didn't already call SendResponse, run the
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // message loop until they do.
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!response_delegate.HasResponse()) {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_delegate.set_should_post_quit(true);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RunMessageLoop();
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response_delegate.HasResponse());
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return response_delegate.GetResponse();
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extension_function_test_utils
274