• 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 #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