1 // Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights 2 // reserved. Use of this source code is governed by a BSD-style license that 3 // can be found in the LICENSE file. 4 5 #ifndef CEF_TESTS_CEFTESTS_EXTENSIONS_EXTENSION_TEST_HANDLER_H_ 6 #define CEF_TESTS_CEFTESTS_EXTENSIONS_EXTENSION_TEST_HANDLER_H_ 7 #pragma once 8 9 #include <vector> 10 11 #include "include/cef_extension_handler.h" 12 #include "include/cef_values.h" 13 #include "include/wrapper/cef_scoped_temp_dir.h" 14 #include "tests/ceftests/routing_test_handler.h" 15 #include "tests/gtest/include/gtest/gtest.h" 16 17 class ExtensionTestHandler : public RoutingTestHandler, 18 public CefExtensionHandler { 19 public: 20 // All tests must be able to run with all RequestContext combinations. See the 21 // EXTENSION_TEST_GROUP_* macros below. 22 enum RequestContextType { 23 // If set create a custom context. Otherwise, use the global context. 24 RC_TYPE_FLAG_CUSTOM = 1 << 0, 25 26 // If set store data on disk. Otherwise, store data in memory. 27 // Requires RC_TYPE_FLAG_CUSTOM. 28 RC_TYPE_FLAG_ON_DISK = 1 << 1, 29 30 // If set use a handler. Otherwise, don't. 31 RC_TYPE_FLAG_WITH_HANDLER = 1 << 2, 32 33 // If set load extensions with a different context that shares the same 34 // storage but specifies a different handler. 35 // Excludes RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER. 36 RC_TYPE_FLAG_LOAD_WITH_HANDLER = 1 << 3, 37 38 // If set load extensions with a different context that shares the same 39 // storage but doesn't specify a handler. 40 // Requires RC_TYPE_FLAG_WITH_HANDLER. 41 // Excludes RC_TYPE_FLAG_LOAD_WITH_HANDLER. 42 RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER = 1 << 4, 43 }; 44 45 explicit ExtensionTestHandler(RequestContextType request_context_type); 46 virtual ~ExtensionTestHandler(); 47 48 // TestHandler methods: 49 void RunTest() override; 50 void DestroyTest() override; 51 void OnAfterCreated(CefRefPtr<CefBrowser> browser) override; 52 53 // CefExtensionHandler methods: 54 void OnExtensionLoadFailed(cef_errorcode_t result) override; 55 56 // CefMessageRouterBrowserSide::Handler methods: 57 bool OnQuery(CefRefPtr<CefBrowser> browser, 58 CefRefPtr<CefFrame> frame, 59 int64 query_id, 60 const CefString& request, 61 bool persistent, 62 CefRefPtr<Callback> callback) override; 63 request_context()64 CefRefPtr<CefRequestContext> request_context() const { 65 return request_context_; 66 } loader_request_context()67 CefRefPtr<CefRequestContext> loader_request_context() const { 68 return loader_request_context_; 69 } 70 request_context_is_custom()71 bool request_context_is_custom() const { 72 return !!(request_context_type_ & RC_TYPE_FLAG_CUSTOM); 73 } request_context_on_disk()74 bool request_context_on_disk() const { 75 return !!(request_context_type_ & RC_TYPE_FLAG_ON_DISK); 76 } request_context_with_handler()77 bool request_context_with_handler() const { 78 return !!(request_context_type_ & RC_TYPE_FLAG_WITH_HANDLER); 79 } request_context_load_with_handler()80 bool request_context_load_with_handler() const { 81 return !!(request_context_type_ & RC_TYPE_FLAG_LOAD_WITH_HANDLER); 82 } request_context_load_without_handler()83 bool request_context_load_without_handler() const { 84 return !!(request_context_type_ & RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER); 85 } request_context_same_loader()86 bool request_context_same_loader() const { 87 return !(request_context_load_with_handler() || 88 request_context_load_without_handler()); 89 } 90 91 protected: 92 // Returns the default extension manifest. 93 typedef std::vector<std::string> ApiPermissionsList; 94 static CefRefPtr<CefDictionaryValue> CreateDefaultManifest( 95 const ApiPermissionsList& api_permissions); 96 97 // Returns the JS code that, when executed, will deliver |message| to the 98 // OnMessage callback. 99 static std::string GetMessageJS(const std::string& message); 100 101 // Run checks on the state of |extension| in |context|. If |has_access| is 102 // true then |context| is expected to have access to |extension|. If 103 // |is_loader| is true then |context| is expected to have loaded |extension|. 104 static void VerifyExtensionInContext(CefRefPtr<CefExtension> extension, 105 CefRefPtr<CefRequestContext> context, 106 bool has_access, 107 bool is_loader); 108 109 // Helper for loading/unloading an extension. 110 void LoadExtension(const std::string& extension_path, 111 CefRefPtr<CefDictionaryValue> manifest); 112 void UnloadExtension(CefRefPtr<CefExtension> extension); 113 114 // Release request contexts. This is normally called from DestroyTest(). 115 void ReleaseRequestContexts(); 116 set_create_main_browser(bool val)117 void set_create_main_browser(bool val) { create_main_browser_ = val; } create_main_browser()118 bool create_main_browser() const { return create_main_browser_; } 119 120 // Called when its time to add resources for the main browser if 121 // |create_main_browser_| is true. OnAddMainBrowserResources()122 virtual void OnAddMainBrowserResources() {} 123 // Called when its time to create the main browser if 124 // |create_main_browser_| is true. OnCreateMainBrowser()125 virtual void OnCreateMainBrowser() {} 126 127 // Called when its time to load extensions. 128 virtual void OnLoadExtensions() = 0; 129 130 // Called when |browser| receives |message|. Return true if the message is 131 // handled. The JS code that sends messages is created by GetMessageJS(). 132 virtual bool OnMessage(CefRefPtr<CefBrowser> browser, 133 const std::string& message) = 0; 134 135 // Called to perform verification on test destruction. 136 virtual void OnDestroyTest() = 0; 137 138 private: 139 const RequestContextType request_context_type_; 140 CefScopedTempDir request_context_temp_dir_; 141 142 // Context used when creating browsers. 143 CefRefPtr<CefRequestContext> request_context_; 144 145 // Context used when loading extensions. 146 CefRefPtr<CefRequestContext> loader_request_context_; 147 148 // If true expect creation of a main browser. Default is true. 149 bool create_main_browser_; 150 151 DISALLOW_COPY_AND_ASSIGN(ExtensionTestHandler); 152 }; 153 154 // Helper for implementing an extension test. 155 #define EXTENSION_TEST(name, test_class, rc_type) \ 156 TEST(ExtensionTest, name) { \ 157 CefRefPtr<test_class> handler = new test_class( \ 158 static_cast<ExtensionTestHandler::RequestContextType>(rc_type)); \ 159 handler->ExecuteTest(); \ 160 ReleaseAndWaitForDestructor(handler); \ 161 } 162 163 // Helper for implementing extension tests that include all RequestContext 164 // combinations. When two or more extension tests significantly overlap in 165 // tested functionality the first test should use the ALL macro and the others 166 // should use the MINIMAL macro. 167 #define EXTENSION_TEST_GROUP_ALL(name, test_class) \ 168 EXTENSION_TEST(name##RCGlobal, test_class, 0) \ 169 EXTENSION_TEST(name##RCGlobalLoadWithHandler, test_class, \ 170 ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \ 171 EXTENSION_TEST(name##RCGlobalWithHandler, test_class, \ 172 ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER) \ 173 EXTENSION_TEST(name##RCGlobalWithHandlerLoadWithHandler, test_class, \ 174 ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \ 175 ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \ 176 EXTENSION_TEST(name##RCGlobalWithHandlerLoadWithoutHandler, test_class, \ 177 ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \ 178 ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER) \ 179 EXTENSION_TEST(name##RCCustomInMemory, test_class, \ 180 ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM) \ 181 EXTENSION_TEST(name##RCCustomInMemoryLoadWithHandler, test_class, \ 182 ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ 183 ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \ 184 EXTENSION_TEST(name##RCCustomInMemoryWithHandler, test_class, \ 185 ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ 186 ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER) \ 187 EXTENSION_TEST(name##RCCustomInMemoryWithHandlerLoadWithHandler, test_class, \ 188 ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ 189 ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \ 190 ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \ 191 EXTENSION_TEST(name##RCCustomInMemoryWithHandlerLoadWithoutHandler, \ 192 test_class, \ 193 ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ 194 ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \ 195 ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER) \ 196 EXTENSION_TEST(name##RCCustomOnDisk, test_class, \ 197 ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ 198 ExtensionTestHandler::RC_TYPE_FLAG_ON_DISK) \ 199 EXTENSION_TEST(name##RCCustomOnDiskLoadWithHandler, test_class, \ 200 ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ 201 ExtensionTestHandler::RC_TYPE_FLAG_ON_DISK | \ 202 ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \ 203 EXTENSION_TEST(name##RCCustomOnDiskWithHandler, test_class, \ 204 ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ 205 ExtensionTestHandler::RC_TYPE_FLAG_ON_DISK | \ 206 ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER) \ 207 EXTENSION_TEST(name##RCCustomOnDiskWithHandlerLoadWithHandler, test_class, \ 208 ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ 209 ExtensionTestHandler::RC_TYPE_FLAG_ON_DISK | \ 210 ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \ 211 ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITH_HANDLER) \ 212 EXTENSION_TEST(name##RCCustomOnDiskWithHandlerLoadWithoutHandler, \ 213 test_class, \ 214 ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ 215 ExtensionTestHandler::RC_TYPE_FLAG_ON_DISK | \ 216 ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER | \ 217 ExtensionTestHandler::RC_TYPE_FLAG_LOAD_WITHOUT_HANDLER) 218 219 #define EXTENSION_TEST_GROUP_MINIMAL_GLOBAL(name, test_class) \ 220 EXTENSION_TEST(name##RCGlobal, test_class, 0) \ 221 EXTENSION_TEST(name##RCGlobalWithHandler, test_class, \ 222 ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER) 223 224 #define EXTENSION_TEST_GROUP_MINIMAL_CUSTOM(name, test_class) \ 225 EXTENSION_TEST(name##RCCustomInMemory, test_class, \ 226 ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM) \ 227 EXTENSION_TEST(name##RCCustomInMemoryWithHandler, test_class, \ 228 ExtensionTestHandler::RC_TYPE_FLAG_CUSTOM | \ 229 ExtensionTestHandler::RC_TYPE_FLAG_WITH_HANDLER) 230 231 // Helper for implementing extension tests that include a minimal set of 232 // RequestContext combinations. This mostly just verifies that the test runs 233 // and doesn't leak state information in the context. 234 #define EXTENSION_TEST_GROUP_MINIMAL(name, test_class) \ 235 EXTENSION_TEST_GROUP_MINIMAL_GLOBAL(name, test_class) \ 236 EXTENSION_TEST_GROUP_MINIMAL_CUSTOM(name, test_class) 237 238 #endif // CEF_TESTS_CEFTESTS_EXTENSIONS_EXTENSION_TEST_HANDLER_H_ 239