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"
131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/crx_file/id_util.h"
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/api_test_utils.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/extension_function.h"
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/extension_function_dispatcher.h"
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension;
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::Manifest;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace keys = extensions::tabs_constants;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestFunctionDispatcherDelegate
31e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    : public extensions::ExtensionFunctionDispatcher::Delegate {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit TestFunctionDispatcherDelegate(Browser* browser) :
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_(browser) {}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TestFunctionDispatcherDelegate() {}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual extensions::WindowController* GetExtensionWindowController()
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const OVERRIDE {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return browser_->extension_window_controller();
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WebContents* GetAssociatedWebContents() const OVERRIDE {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* browser_;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extension_function_test_utils {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Value* ParseJSON(const std::string& data) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::JSONReader::Read(data);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::ListValue* ParseList(const std::string& data) {
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::Value* result = ParseJSON(data);
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::ListValue* list = NULL;
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  result->GetAsList(&list);
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return list;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::DictionaryValue* ParseDictionary(
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& data) {
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::Value* result = ParseJSON(data);
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::DictionaryValue* dict = NULL;
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  result->GetAsDictionary(&dict);
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return dict;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetBoolean(base::DictionaryValue* val, const std::string& key) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = false;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!val->GetBoolean(key, &result))
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ADD_FAILURE() << key << " does not exist or is not a boolean.";
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetInteger(base::DictionaryValue* val, const std::string& key) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = 0;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!val->GetInteger(key, &result))
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_FAILURE() << key << " does not exist or is not an integer.";
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetString(base::DictionaryValue* val, const std::string& key) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string result;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!val->GetString(key, &result))
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_FAILURE() << key << " does not exist or is not a string.";
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::DictionaryValue* ToDictionary(base::Value* val) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(val);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::Value::TYPE_DICTIONARY, val->GetType());
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<base::DictionaryValue*>(val);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::ListValue* ToList(base::Value* val) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(val);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::Value::TYPE_LIST, val->GetType());
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<base::ListValue*>(val);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Extension> CreateEmptyExtensionWithLocation(
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Manifest::Location location) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> test_extension_value(
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ParseDictionary("{\"name\": \"Test\", \"version\": \"1.0\"}"));
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CreateExtension(location, test_extension_value.get(), std::string());
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Extension> CreateExtension(
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::DictionaryValue* test_extension_value) {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CreateExtension(Manifest::INTERNAL, test_extension_value,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         std::string());
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Extension> CreateExtension(
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Manifest::Location location,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::DictionaryValue* test_extension_value,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& id_input) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath test_extension_path;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string id;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!id_input.empty())
12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    id = crx_file::id_util::GenerateId(id_input);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> extension(Extension::Create(
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_extension_path,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      location,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *test_extension_value,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Extension::NO_FLAGS,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      id,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &error));
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(error.empty()) << "Could not parse test extension " << error;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extension;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HasPrivacySensitiveFields(base::DictionaryValue* val) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string result;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (val->GetString(keys::kUrlKey, &result) ||
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      val->GetString(keys::kTitleKey, &result) ||
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      val->GetString(keys::kFaviconUrlKey, &result))
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const std::string& args,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      Browser* browser) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return RunFunctionAndReturnError(function, args, browser, NONE);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const std::string& args,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      Browser* browser,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      RunFunctionFlags flags) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<ExtensionFunction> function_owner(function);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Without a callback the function will not generate a result.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  function->set_has_callback(true);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunFunction(function, args, browser, flags);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(function->GetResultList()) << "Did not expect a result";
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return function->GetError();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Value* RunFunctionAndReturnSingleResult(
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UIThreadExtensionFunction* function,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& args,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return RunFunctionAndReturnSingleResult(function, args, browser, NONE);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Value* RunFunctionAndReturnSingleResult(
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UIThreadExtensionFunction* function,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& args,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunFunctionFlags flags) {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<ExtensionFunction> function_owner(function);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Without a callback the function will not generate a result.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  function->set_has_callback(true);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunFunction(function, args, browser, flags);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(function->GetError().empty()) << "Unexpected error: "
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << function->GetError();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::Value* single_result = NULL;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (function->GetResultList() != NULL &&
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      function->GetResultList()->Get(0, &single_result)) {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return single_result->DeepCopy();
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// This helps us be able to wait until an UIThreadExtensionFunction calls
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SendResponse.
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SendResponseDelegate
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public UIThreadExtensionFunction::DelegateForTests {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponseDelegate() : should_post_quit_(false) {}
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SendResponseDelegate() {}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_should_post_quit(bool should_quit) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    should_post_quit_ = should_quit;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool HasResponse() {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return response_.get() != NULL;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool GetResponse() {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(HasResponse());
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return *response_.get();
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnSendResponse(UIThreadExtensionFunction* function,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              bool success,
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              bool bad_message) OVERRIDE {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(bad_message);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(HasResponse());
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_.reset(new bool);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *response_ = success;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (should_post_quit_) {
22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::MessageLoopForUI::current()->Quit();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<bool> response_;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool should_post_quit_;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RunFunction(UIThreadExtensionFunction* function,
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const std::string& args,
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 Browser* browser,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 RunFunctionFlags flags) {
23303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<base::ListValue> parsed_args(ParseList(args));
23403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_TRUE(parsed_args.get())
23503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      << "Could not parse extension function arguments: " << args;
23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return RunFunction(function, parsed_args.Pass(), browser, flags);
23703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
23803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool RunFunction(UIThreadExtensionFunction* function,
24003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 scoped_ptr<base::ListValue> args,
24103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 Browser* browser,
24203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 RunFunctionFlags flags) {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestFunctionDispatcherDelegate dispatcher_delegate(browser);
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<extensions::ExtensionFunctionDispatcher> dispatcher(
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new extensions::ExtensionFunctionDispatcher(browser->profile(),
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                  &dispatcher_delegate));
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // TODO(yoz): The cast is a hack; these flags should be defined in
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // only one place.  See crbug.com/394840.
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return extensions::api_test_utils::RunFunction(
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      function,
25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      args.Pass(),
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      browser->profile(),
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      dispatcher.Pass(),
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      static_cast<extensions::api_test_utils::RunFunctionFlags>(flags));
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extension_function_test_utils
258