| // Copyright (c) 2017 The Chromium Embedded Framework 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 CEF_TESTS_UNITTESTS_EXTENSIONS_EXTENSION_TEST_HANDLER_H_ |
| #define CEF_TESTS_UNITTESTS_EXTENSIONS_EXTENSION_TEST_HANDLER_H_ |
| #pragma once |
| |
| #include <vector> |
| |
| #include "include/cef_extension_handler.h" |
| #include "include/cef_values.h" |
| #include "include/wrapper/cef_scoped_temp_dir.h" |
| #include "tests/ceftests/routing_test_handler.h" |
| #include "tests/gtest/include/gtest/gtest.h" |
| |
| class ExtensionTestHandler : public RoutingTestHandler, |
| public CefExtensionHandler { |
| public: |
| // All tests must be able to run with all RequestContext combinations. See the |
| // EXTENSION_TEST_GROUP_* macros below. |
| enum RequestContextType { |
| // If set create a custom context. Otherwise, use the global context. |
| RC_TYPE_FLAG_CUSTOM = 1 << 0, |
| |
| // If set store data on disk. Otherwise, store data in memory. |
| // Requires RC_TYPE_FLAG_CUSTOM. |
| RC_TYPE_FLAG_ON_DISK = 1 << 1, |
| |
| // If set use a handler. Otherwise, don't. |
| RC_TYPE_FLAG_WITH_HANDLER = 1 << 2, |
| |
| // If set load extensions with a different context that shares the same |
| // storage but specifies a different handler. |
| // Excludes RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER. |
| RC_TYPE_FLAG_LOAD_WITH_HANDLER = 1 << 3, |
| |
| // If set load extensions with a different context that shares the same |
| // storage but doesn't specify a handler. |
| // Requires RC_TYPE_FLAG_WITH_HANDLER. |
| // Excludes RC_TYPE_FLAG_LOAD_WITH_HANDLER. |
| RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER = 1 << 4, |
| }; |
| |
| explicit ExtensionTestHandler(RequestContextType request_context_type); |
| virtual ~ExtensionTestHandler(); |
| |
| // TestHandler methods: |
| void RunTest() override; |
| void DestroyTest() override; |
| void OnAfterCreated(CefRefPtr<CefBrowser> browser) override; |
| |
| // CefExtensionHandler methods: |
| void OnExtensionLoadFailed(cef_errorcode_t result) override; |
| |
| // CefMessageRouterBrowserSide::Handler methods: |
| bool OnQuery(CefRefPtr<CefBrowser> browser, |
| CefRefPtr<CefFrame> frame, |
| int64 query_id, |
| const CefString& request, |
| bool persistent, |
| CefRefPtr<Callback> callback) override; |
| |
| CefRefPtr<CefRequestContext> request_context() const { |
| return request_context_; |
| } |
| CefRefPtr<CefRequestContext> loader_request_context() const { |
| return loader_request_context_; |
| } |
| |
| bool request_context_is_custom() const { |
| return !!(request_context_type_ & RC_TYPE_FLAG_CUSTOM); |
| } |
| bool request_context_on_disk() const { |
| return !!(request_context_type_ & RC_TYPE_FLAG_ON_DISK); |
| } |
| bool request_context_with_handler() const { |
| return !!(request_context_type_ & RC_TYPE_FLAG_WITH_HANDLER); |
| } |
| bool request_context_load_with_handler() const { |
| return !!(request_context_type_ & RC_TYPE_FLAG_LOAD_WITH_HANDLER); |
| } |
| bool request_context_load_without_handler() const { |
| return !!(request_context_type_ & RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER); |
| } |
| bool request_context_same_loader() const { |
| return !(request_context_load_with_handler() || |
| request_context_load_without_handler()); |
| } |
| |
| protected: |
| // Returns the default extension manifest. |
| typedef std::vector<std::string> ApiPermissionsList; |
| static CefRefPtr<CefDictionaryValue> CreateDefaultManifest( |
| const ApiPermissionsList& api_permissions); |
| |
| // Returns the JS code that, when executed, will deliver |message| to the |
| // OnMessage callback. |
| static std::string GetMessageJS(const std::string& message); |
| |
| // Run checks on the state of |extension| in |context|. If |has_access| is |
| // true then |context| is expected to have access to |extension|. If |
| // |is_loader| is true then |context| is expected to have loaded |extension|. |
| static void VerifyExtensionInContext(CefRefPtr<CefExtension> extension, |
| CefRefPtr<CefRequestContext> context, |
| bool has_access, |
| bool is_loader); |
| |
| // Helper for loading/unloading an extension. |
| void LoadExtension(const std::string& extension_path, |
| CefRefPtr<CefDictionaryValue> manifest); |
| void UnloadExtension(CefRefPtr<CefExtension> extension); |
| |
| // Release request contexts. This is normally called from DestroyTest(). |
| void ReleaseRequestContexts(); |
| |
| void set_create_main_browser(bool val) { create_main_browser_ = val; } |
| bool create_main_browser() const { return create_main_browser_; } |
| |
| // Called when its time to add resources for the main browser if |
| // |create_main_browser_| is true. |
| virtual void OnAddMainBrowserResources() {} |
| // Called when its time to create the main browser if |
| // |create_main_browser_| is true. |
| virtual void OnCreateMainBrowser() {} |
| |
| // Called when its time to load extensions. |
| virtual void OnLoadExtensions() = 0; |
| |
| // Called when |browser| receives |message|. Return true if the message is |
| // handled. The JS code that sends messages is created by GetMessageJS(). |
| virtual bool OnMessage(CefRefPtr<CefBrowser> browser, |
| const std::string& message) = 0; |
| |
| // Called to perform verification on test destruction. |
| virtual void OnDestroyTest() = 0; |
| |
| private: |
| const RequestContextType request_context_type_; |
| CefScopedTempDir request_context_temp_dir_; |
| |
| // Context used when creating browsers. |
| CefRefPtr<CefRequestContext> request_context_; |
| |
| // Context used when loading extensions. |
| CefRefPtr<CefRequestContext> loader_request_context_; |
| |
| // If true expect creation of a main browser. Default is true. |
| bool create_main_browser_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ExtensionTestHandler); |
| }; |
| |
| // Helper for implementing an extension test. |
| #define EXTENSION_TEST(name, test_class, rc_type) \ |
| TEST(ExtensionTest, name) { \ |
| CefRefPtr<test_class> handler = new test_class( \ |
| static_cast<ExtensionTestHandler::RequestContextType>(rc_type)); \ |
| handler->ExecuteTest(); \ |
| ReleaseAndWaitForDestructor(handler); \ |
| } |
| |
| // Helper for implementing extension tests that include all RequestContext |
| // combinations. When two or more extension tests significantly overlap in |
| // tested functionality the first test should use the ALL macro and the others |
| // should use the MINIMAL macro. |
| #define EXTENSION_TEST_GROUP_ALL(name, test_class) \ |
| EXTENSION_TEST(name##RCGlobal, test_class, 0) \ |
| EXTENSION_TEST(name##RCGlobalLoadWithHandler, test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \ |
| EXTENSION_TEST(name##RCGlobalWithHandler, test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER) \ |
| EXTENSION_TEST(name##RCGlobalWithHandlerLoadWithHandler, test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \ |
| EXTENSION_TEST(name##RCGlobalWithHandlerLoadWithoutHandler, test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER) \ |
| EXTENSION_TEST(name##RCCustomInMemory, test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM) \ |
| EXTENSION_TEST(name##RCCustomInMemoryLoadWithHandler, test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \ |
| EXTENSION_TEST(name##RCCustomInMemoryWithHandler, test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER) \ |
| EXTENSION_TEST(name##RCCustomInMemoryWithHandlerLoadWithHandler, test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \ |
| EXTENSION_TEST(name##RCCustomInMemoryWithHandlerLoadWithoutHandler, \ |
| test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER) \ |
| EXTENSION_TEST(name##RCCustomOnDisk, test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_ON_DISK) \ |
| EXTENSION_TEST(name##RCCustomOnDiskLoadWithHandler, test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_ON_DISK | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \ |
| EXTENSION_TEST(name##RCCustomOnDiskWithHandler, test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_ON_DISK | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER) \ |
| EXTENSION_TEST(name##RCCustomOnDiskWithHandlerLoadWithHandler, test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_ON_DISK | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \ |
| EXTENSION_TEST(name##RCCustomOnDiskWithHandlerLoadWithoutHandler, \ |
| test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_ON_DISK | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER) |
| |
| #define EXTENSION_TEST_GROUP_MINIMAL_GLOBAL(name, test_class) \ |
| EXTENSION_TEST(name##RCGlobal, test_class, 0) \ |
| EXTENSION_TEST(name##RCGlobalWithHandler, test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER) |
| |
| #define EXTENSION_TEST_GROUP_MINIMAL_CUSTOM(name, test_class) \ |
| EXTENSION_TEST(name##RCCustomInMemory, test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM) \ |
| EXTENSION_TEST(name##RCCustomInMemoryWithHandler, test_class, \ |
| ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ |
| ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER) |
| |
| // Helper for implementing extension tests that include a minimal set of |
| // RequestContext combinations. This mostly just verifies that the test runs |
| // and doesn't leak state information in the context. |
| #define EXTENSION_TEST_GROUP_MINIMAL(name, test_class) \ |
| EXTENSION_TEST_GROUP_MINIMAL_GLOBAL(name, test_class) \ |
| EXTENSION_TEST_GROUP_MINIMAL_CUSTOM(name, test_class) |
| |
| #endif // CEF_TESTS_UNITTESTS_EXTENSIONS_EXTENSION_TEST_HANDLER_H_ |