|  | // Copyright 2014 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. | 
|  |  | 
|  | #ifndef EXTENSIONS_BROWSER_API_TEST_UTILS_H_ | 
|  | #define EXTENSIONS_BROWSER_API_TEST_UTILS_H_ | 
|  |  | 
|  | #include <memory> | 
|  | #include <string> | 
|  |  | 
|  | #include "base/memory/ref_counted.h" | 
|  | #include "base/run_loop.h" | 
|  | #include "extensions/browser/extension_function.h" | 
|  | #include "extensions/common/manifest.h" | 
|  |  | 
|  | namespace base { | 
|  | class DictionaryValue; | 
|  | class ListValue; | 
|  | class Value; | 
|  | } | 
|  |  | 
|  | namespace content { | 
|  | class BrowserContext; | 
|  | } | 
|  |  | 
|  | namespace extensions { | 
|  | class Extension; | 
|  | class ExtensionFunctionDispatcher; | 
|  |  | 
|  | // TODO(yoz): crbug.com/394840: Remove duplicate functionality in | 
|  | // chrome/browser/extensions/extension_function_test_utils.h. | 
|  | // | 
|  | // TODO(ckehoe): Accept args as std::unique_ptr<base::Value>, | 
|  | // and migrate existing users to the new API. | 
|  | namespace api_test_utils { | 
|  |  | 
|  | // A helper class to handle waiting for a function response. | 
|  | class SendResponseHelper { | 
|  | public: | 
|  | explicit SendResponseHelper(UIThreadExtensionFunction* function); | 
|  | ~SendResponseHelper(); | 
|  |  | 
|  | bool has_response() { return response_.get() != nullptr; } | 
|  |  | 
|  | // Asserts a response has been posted (has_response()) and returns the value. | 
|  | bool GetResponse(); | 
|  |  | 
|  | // Waits until a response is posted. | 
|  | void WaitForResponse(); | 
|  |  | 
|  | private: | 
|  | // Response handler. | 
|  | void OnResponse(ExtensionFunction::ResponseType response, | 
|  | const base::ListValue& results, | 
|  | const std::string& error, | 
|  | functions::HistogramValue histogram_value); | 
|  |  | 
|  | base::RunLoop run_loop_; | 
|  | std::unique_ptr<bool> response_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(SendResponseHelper); | 
|  | }; | 
|  |  | 
|  | enum RunFunctionFlags { NONE = 0, INCLUDE_INCOGNITO = 1 << 0 }; | 
|  |  | 
|  | // Parse JSON and return as the specified type, or NULL if the JSON is invalid | 
|  | // or not the specified type. | 
|  | std::unique_ptr<base::DictionaryValue> ParseDictionary(const std::string& data); | 
|  |  | 
|  | // Get |key| from |val| as the specified type. If |key| does not exist, or is | 
|  | // not of the specified type, adds a failure to the current test and returns | 
|  | // false, 0, empty string, etc. | 
|  | bool GetBoolean(const base::DictionaryValue* val, const std::string& key); | 
|  | int GetInteger(const base::DictionaryValue* val, const std::string& key); | 
|  | std::string GetString(const base::DictionaryValue* val, const std::string& key); | 
|  |  | 
|  | // Creates an extension instance with a specified extension value that can be | 
|  | // attached to an ExtensionFunction before running. | 
|  | scoped_refptr<extensions::Extension> CreateExtension( | 
|  | base::DictionaryValue* test_extension_value); | 
|  |  | 
|  | scoped_refptr<extensions::Extension> CreateExtension( | 
|  | extensions::Manifest::Location location, | 
|  | base::DictionaryValue* test_extension_value, | 
|  | const std::string& id_input); | 
|  |  | 
|  | // Creates an extension instance with a specified location that can be attached | 
|  | // to an ExtensionFunction before running. | 
|  | scoped_refptr<extensions::Extension> CreateEmptyExtensionWithLocation( | 
|  | extensions::Manifest::Location location); | 
|  |  | 
|  | // Run |function| with |args| and return the result. Adds an error to the | 
|  | // current test if |function| returns an error. Takes ownership of | 
|  | // |function|. The caller takes ownership of the result. | 
|  | std::unique_ptr<base::Value> RunFunctionWithDelegateAndReturnSingleResult( | 
|  | scoped_refptr<UIThreadExtensionFunction> function, | 
|  | const std::string& args, | 
|  | content::BrowserContext* context, | 
|  | std::unique_ptr<ExtensionFunctionDispatcher> dispatcher); | 
|  | std::unique_ptr<base::Value> RunFunctionWithDelegateAndReturnSingleResult( | 
|  | scoped_refptr<UIThreadExtensionFunction> function, | 
|  | const std::string& args, | 
|  | content::BrowserContext* context, | 
|  | std::unique_ptr<ExtensionFunctionDispatcher> dispatcher, | 
|  | RunFunctionFlags flags); | 
|  | std::unique_ptr<base::Value> RunFunctionWithDelegateAndReturnSingleResult( | 
|  | scoped_refptr<UIThreadExtensionFunction> function, | 
|  | std::unique_ptr<base::ListValue> args, | 
|  | content::BrowserContext* context, | 
|  | std::unique_ptr<ExtensionFunctionDispatcher> dispatcher, | 
|  | RunFunctionFlags flags); | 
|  |  | 
|  | // RunFunctionWithDelegateAndReturnSingleResult, except with a NULL | 
|  | // implementation of the Delegate. | 
|  | std::unique_ptr<base::Value> RunFunctionAndReturnSingleResult( | 
|  | UIThreadExtensionFunction* function, | 
|  | const std::string& args, | 
|  | content::BrowserContext* context); | 
|  | std::unique_ptr<base::Value> RunFunctionAndReturnSingleResult( | 
|  | UIThreadExtensionFunction* function, | 
|  | const std::string& args, | 
|  | content::BrowserContext* context, | 
|  | RunFunctionFlags flags); | 
|  |  | 
|  | // Run |function| with |args| and return the resulting error. Adds an error to | 
|  | // the current test if |function| returns a result. Takes ownership of | 
|  | // |function|. | 
|  | std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, | 
|  | const std::string& args, | 
|  | content::BrowserContext* context, | 
|  | RunFunctionFlags flags); | 
|  | std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, | 
|  | const std::string& args, | 
|  | content::BrowserContext* context); | 
|  |  | 
|  | // Create and run |function| with |args|. Works with both synchronous and async | 
|  | // functions. Ownership of |function| remains with the caller. | 
|  | // | 
|  | // TODO(aa): It would be nice if |args| could be validated against the schema | 
|  | // that |function| expects. That way, we know that we are testing something | 
|  | // close to what the bindings would actually send. | 
|  | // | 
|  | // TODO(aa): I'm concerned that this style won't scale to all the bits and bobs | 
|  | // we're going to need to frob for all the different extension functions. But | 
|  | // we can refactor when we see what is needed. | 
|  | bool RunFunction(UIThreadExtensionFunction* function, | 
|  | const std::string& args, | 
|  | content::BrowserContext* context); | 
|  | bool RunFunction(UIThreadExtensionFunction* function, | 
|  | const std::string& args, | 
|  | content::BrowserContext* context, | 
|  | std::unique_ptr<ExtensionFunctionDispatcher> dispatcher, | 
|  | RunFunctionFlags flags); | 
|  | bool RunFunction(UIThreadExtensionFunction* function, | 
|  | std::unique_ptr<base::ListValue> args, | 
|  | content::BrowserContext* context, | 
|  | std::unique_ptr<ExtensionFunctionDispatcher> dispatcher, | 
|  | RunFunctionFlags flags); | 
|  |  | 
|  | }  // namespace api_test_utils | 
|  | }  // namespace extensions | 
|  |  | 
|  | #endif  // EXTENSIONS_BROWSER_API_TEST_UTILS_H_ |