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 #include "tests/ceftests/extensions/extension_test_handler.h"
6
7 #include "include/cef_request_context_handler.h"
8 #include "tests/ceftests/test_suite.h"
9 #include "tests/ceftests/test_util.h"
10
ExtensionTestHandler(RequestContextType request_context_type)11 ExtensionTestHandler::ExtensionTestHandler(
12 RequestContextType request_context_type)
13 : request_context_type_(request_context_type), create_main_browser_(true) {
14 // Verify supported flag combinations.
15 if (request_context_on_disk()) {
16 EXPECT_TRUE(request_context_is_custom());
17 }
18 if (request_context_load_with_handler()) {
19 EXPECT_FALSE(request_context_load_without_handler());
20 }
21 if (request_context_load_without_handler()) {
22 EXPECT_TRUE(request_context_with_handler());
23 EXPECT_FALSE(request_context_load_with_handler());
24 }
25 }
26
~ExtensionTestHandler()27 ExtensionTestHandler::~ExtensionTestHandler() {
28 if (!request_context_temp_dir_.IsEmpty()) {
29 // Temporary directory will be deleted on shutdown.
30 request_context_temp_dir_.Take();
31 }
32 }
33
RunTest()34 void ExtensionTestHandler::RunTest() {
35 if (create_main_browser_)
36 OnAddMainBrowserResources();
37
38 CefRefPtr<CefRequestContextHandler> rc_handler;
39 if (request_context_with_handler()) {
40 class Handler : public CefRequestContextHandler {
41 public:
42 explicit Handler(ExtensionTestHandler* test_handler)
43 : test_handler_(test_handler) {}
44
45 void OnRequestContextInitialized(
46 CefRefPtr<CefRequestContext> request_context) override {
47 if (test_handler_->create_main_browser()) {
48 // Load extensions after the RequestContext has been initialized by
49 // creation of the main browser.
50 test_handler_->OnLoadExtensions();
51 }
52 }
53
54 private:
55 ExtensionTestHandler* test_handler_;
56
57 IMPLEMENT_REFCOUNTING(Handler);
58 };
59 rc_handler = new Handler(this);
60 }
61
62 if (request_context_is_custom()) {
63 CefRequestContextSettings settings;
64
65 if (request_context_on_disk()) {
66 // Create a new temporary directory.
67 EXPECT_TRUE(request_context_temp_dir_.CreateUniqueTempDirUnderPath(
68 CefTestSuite::GetInstance()->root_cache_path()));
69 CefString(&settings.cache_path) = request_context_temp_dir_.GetPath();
70 }
71
72 request_context_ = CefRequestContext::CreateContext(settings, rc_handler);
73 } else {
74 request_context_ = CefRequestContext::CreateContext(
75 CefRequestContext::GetGlobalContext(), rc_handler);
76 }
77
78 if (request_context_load_with_handler()) {
79 class Handler : public CefRequestContextHandler {
80 public:
81 Handler() {}
82
83 private:
84 IMPLEMENT_REFCOUNTING(Handler);
85 };
86 loader_request_context_ =
87 CefRequestContext::CreateContext(request_context_, new Handler());
88 } else if (request_context_load_without_handler()) {
89 loader_request_context_ =
90 CefRequestContext::CreateContext(request_context_, nullptr);
91 } else {
92 loader_request_context_ = request_context_;
93 }
94
95 if (create_main_browser_) {
96 OnCreateMainBrowser();
97 } else {
98 // Creation of the extension browser will trigger initialization of the
99 // RequestContext, so just load the extensions now.
100 OnLoadExtensions();
101 }
102
103 // Time out the test after a reasonable period of time.
104 SetTestTimeout();
105 }
106
DestroyTest()107 void ExtensionTestHandler::DestroyTest() {
108 OnDestroyTest();
109 ReleaseRequestContexts();
110 RoutingTestHandler::DestroyTest();
111 }
112
OnAfterCreated(CefRefPtr<CefBrowser> browser)113 void ExtensionTestHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
114 RoutingTestHandler::OnAfterCreated(browser);
115
116 if (create_main_browser() && !request_context_with_handler() &&
117 GetBrowserId() == browser->GetIdentifier()) {
118 // When the RequestContext doesn't have a handler we won't get a
119 // notification for RequestContext initialization. Instead use main browser
120 // creation to indicate that the RequestContext has been initialized.
121 OnLoadExtensions();
122 }
123 }
124
OnExtensionLoadFailed(cef_errorcode_t result)125 void ExtensionTestHandler::OnExtensionLoadFailed(cef_errorcode_t result) {
126 EXPECT_TRUE(CefCurrentlyOn(TID_UI));
127 EXPECT_TRUE(false); // Not reached.
128 }
129
130 // CefMessageRouterBrowserSide::Handler methods:
OnQuery(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int64 query_id,const CefString & request,bool persistent,CefRefPtr<Callback> callback)131 bool ExtensionTestHandler::OnQuery(CefRefPtr<CefBrowser> browser,
132 CefRefPtr<CefFrame> frame,
133 int64 query_id,
134 const CefString& request,
135 bool persistent,
136 CefRefPtr<Callback> callback) {
137 if (OnMessage(browser, request))
138 return true;
139
140 EXPECT_FALSE(true) << "Unexpected message: " << request.ToString();
141 return false;
142 }
143
144 // static
CreateDefaultManifest(const std::vector<std::string> & api_permissions)145 CefRefPtr<CefDictionaryValue> ExtensionTestHandler::CreateDefaultManifest(
146 const std::vector<std::string>& api_permissions) {
147 CefRefPtr<CefDictionaryValue> manifest = CefDictionaryValue::Create();
148 manifest->SetString("name", "An extension");
149 manifest->SetString("description", "An extension description");
150 manifest->SetString("version", "1.0");
151 manifest->SetInt("manifest_version", 2);
152
153 CefRefPtr<CefListValue> permissions = CefListValue::Create();
154 permissions->SetSize(api_permissions.size() + 2);
155 size_t idx = 0;
156 for (; idx < api_permissions.size(); ++idx)
157 permissions->SetString(idx, api_permissions[idx]);
158
159 // Allow access to all http/https origins.
160 permissions->SetString(idx++, "http://*/*");
161 permissions->SetString(idx++, "https://*/*");
162
163 manifest->SetList("permissions", permissions);
164
165 return manifest;
166 }
167
168 // static
GetMessageJS(const std::string & message)169 std::string ExtensionTestHandler::GetMessageJS(const std::string& message) {
170 EXPECT_TRUE(!message.empty());
171 return "window.testQuery({request:'" + message + "'});";
172 }
173
174 // static
VerifyExtensionInContext(CefRefPtr<CefExtension> extension,CefRefPtr<CefRequestContext> context,bool has_access,bool is_loader)175 void ExtensionTestHandler::VerifyExtensionInContext(
176 CefRefPtr<CefExtension> extension,
177 CefRefPtr<CefRequestContext> context,
178 bool has_access,
179 bool is_loader) {
180 const CefString& extension_id = extension->GetIdentifier();
181 EXPECT_FALSE(extension_id.empty());
182
183 if (has_access) {
184 EXPECT_TRUE(context->DidLoadExtension(extension_id));
185 EXPECT_TRUE(context->HasExtension(extension_id));
186 } else {
187 EXPECT_FALSE(context->DidLoadExtension(extension_id));
188 EXPECT_FALSE(context->HasExtension(extension_id));
189 }
190
191 CefRefPtr<CefExtension> extension2 = context->GetExtension(extension_id);
192 if (has_access) {
193 EXPECT_TRUE(extension2);
194 EXPECT_TRUE(extension->IsSame(extension2));
195 TestDictionaryEqual(extension->GetManifest(), extension2->GetManifest());
196 } else {
197 EXPECT_FALSE(extension2);
198 }
199
200 std::vector<CefString> extension_ids;
201 EXPECT_TRUE(context->GetExtensions(extension_ids));
202
203 // Should be our test extension and possibly the builtin PDF extension if it
204 // has finished loading (our extension may load first if the call to
205 // LoadExtension initializes the request context).
206 bool has_extension = false;
207 for (size_t i = 0; i < extension_ids.size(); ++i) {
208 if (extension_ids[i] == extension_id) {
209 has_extension = true;
210 break;
211 }
212 }
213 if (has_access) {
214 EXPECT_TRUE(has_extension);
215 } else {
216 EXPECT_FALSE(has_extension);
217 }
218 }
219
LoadExtension(const std::string & extension_path,CefRefPtr<CefDictionaryValue> manifest)220 void ExtensionTestHandler::LoadExtension(
221 const std::string& extension_path,
222 CefRefPtr<CefDictionaryValue> manifest) {
223 EXPECT_TRUE(!extension_path.empty());
224 loader_request_context_->LoadExtension(extension_path, manifest, this);
225 }
226
UnloadExtension(CefRefPtr<CefExtension> extension)227 void ExtensionTestHandler::UnloadExtension(CefRefPtr<CefExtension> extension) {
228 EXPECT_TRUE(extension);
229 extension->Unload();
230 EXPECT_FALSE(extension->IsLoaded());
231 EXPECT_FALSE(extension->GetLoaderContext());
232 }
233
ReleaseRequestContexts()234 void ExtensionTestHandler::ReleaseRequestContexts() {
235 request_context_ = nullptr;
236 loader_request_context_ = nullptr;
237 }
238