• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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