Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / api / webstore_private / webstore_private_apitest.cc
bloba304a04359e995454331824a944406682b65df90
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <vector>
7 #include "base/files/file_path.h"
8 #include "base/files/file_util.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/extensions/api/webstore_private/webstore_private_api.h"
13 #include "chrome/browser/extensions/bundle_installer.h"
14 #include "chrome/browser/extensions/extension_apitest.h"
15 #include "chrome/browser/extensions/extension_function_test_utils.h"
16 #include "chrome/browser/extensions/extension_install_prompt.h"
17 #include "chrome/browser/extensions/extension_service.h"
18 #include "chrome/browser/extensions/webstore_installer.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/tabs/tab_strip_model.h"
22 #include "chrome/common/chrome_switches.h"
23 #include "chrome/test/base/ui_test_utils.h"
24 #include "content/public/browser/gpu_data_manager.h"
25 #include "content/public/browser/notification_observer.h"
26 #include "content/public/browser/notification_registrar.h"
27 #include "content/public/test/browser_test_utils.h"
28 #include "extensions/browser/api/management/management_api.h"
29 #include "extensions/browser/extension_dialog_auto_confirm.h"
30 #include "extensions/browser/extension_system.h"
31 #include "extensions/browser/install/extension_install_ui.h"
32 #include "gpu/config/gpu_feature_type.h"
33 #include "gpu/config/gpu_info.h"
34 #include "net/dns/mock_host_resolver.h"
35 #include "ui/app_list/app_list_switches.h"
36 #include "ui/gl/gl_switches.h"
38 using gpu::GpuFeatureType;
40 namespace utils = extension_function_test_utils;
42 namespace extensions {
44 namespace {
46 class WebstoreInstallListener : public WebstoreInstaller::Delegate {
47 public:
48 WebstoreInstallListener()
49 : received_failure_(false), received_success_(false), waiting_(false) {}
51 void OnExtensionInstallSuccess(const std::string& id) override {
52 received_success_ = true;
53 id_ = id;
55 if (waiting_) {
56 waiting_ = false;
57 base::MessageLoopForUI::current()->Quit();
61 void OnExtensionInstallFailure(
62 const std::string& id,
63 const std::string& error,
64 WebstoreInstaller::FailureReason reason) override {
65 received_failure_ = true;
66 id_ = id;
67 error_ = error;
69 if (waiting_) {
70 waiting_ = false;
71 base::MessageLoopForUI::current()->Quit();
75 void Wait() {
76 if (received_success_ || received_failure_)
77 return;
79 waiting_ = true;
80 content::RunMessageLoop();
82 bool received_success() const { return received_success_; }
83 const std::string& id() const { return id_; }
85 private:
86 bool received_failure_;
87 bool received_success_;
88 bool waiting_;
89 std::string id_;
90 std::string error_;
93 } // namespace
95 // A base class for tests below.
96 class ExtensionWebstorePrivateApiTest : public ExtensionApiTest {
97 public:
98 ExtensionWebstorePrivateApiTest() {}
99 ~ExtensionWebstorePrivateApiTest() override {}
101 void SetUpCommandLine(base::CommandLine* command_line) override {
102 ExtensionApiTest::SetUpCommandLine(command_line);
103 command_line->AppendSwitchASCII(
104 switches::kAppsGalleryURL,
105 "http://www.example.com/files/extensions/api_test");
108 void SetUpInProcessBrowserTestFixture() override {
109 ExtensionApiTest::SetUpInProcessBrowserTestFixture();
111 // Start up the test server and get us ready for calling the install
112 // API functions.
113 host_resolver()->AddRule("www.example.com", "127.0.0.1");
114 ASSERT_TRUE(StartSpawnedTestServer());
115 extensions::ExtensionInstallUI::set_disable_failure_ui_for_tests();
118 void SetUpOnMainThread() override {
119 ExtensionApiTest::SetUpOnMainThread();
121 auto_confirm_install_.reset(
122 new ScopedTestDialogAutoConfirm(ScopedTestDialogAutoConfirm::ACCEPT));
124 ASSERT_TRUE(webstore_install_dir_.CreateUniqueTempDir());
125 webstore_install_dir_copy_ = webstore_install_dir_.path();
126 WebstoreInstaller::SetDownloadDirectoryForTests(
127 &webstore_install_dir_copy_);
130 protected:
131 // Returns a test server URL, but with host 'www.example.com' so it matches
132 // the web store app's extent that we set up via command line flags.
133 GURL DoGetTestServerURL(const std::string& path) {
134 GURL url = test_server()->GetURL(path);
136 // Replace the host with 'www.example.com' so it matches the web store
137 // app's extent.
138 GURL::Replacements replace_host;
139 replace_host.SetHostStr("www.example.com");
141 return url.ReplaceComponents(replace_host);
144 virtual GURL GetTestServerURL(const std::string& path) {
145 return DoGetTestServerURL(
146 std::string("files/extensions/api_test/webstore_private/") + path);
149 // Navigates to |page| and runs the Extension API test there. Any downloads
150 // of extensions will return the contents of |crx_file|.
151 bool RunInstallTest(const std::string& page, const std::string& crx_file) {
152 #if defined(OS_WIN) && !defined(NDEBUG)
153 // See http://crbug.com/177163 for details.
154 return true;
155 #else
156 GURL crx_url = GetTestServerURL(crx_file);
157 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
158 switches::kAppsGalleryUpdateURL, crx_url.spec());
160 GURL page_url = GetTestServerURL(page);
161 return RunPageTest(page_url.spec());
162 #endif
165 content::WebContents* GetWebContents() {
166 return browser()->tab_strip_model()->GetActiveWebContents();
169 ExtensionService* service() {
170 return ExtensionSystem::Get(browser()->profile())->extension_service();
173 private:
174 base::ScopedTempDir webstore_install_dir_;
175 // WebstoreInstaller needs a reference to a FilePath when setting the download
176 // directory for testing.
177 base::FilePath webstore_install_dir_copy_;
179 scoped_ptr<ScopedTestDialogAutoConfirm> auto_confirm_install_;
181 DISALLOW_COPY_AND_ASSIGN(ExtensionWebstorePrivateApiTest);
184 // Test cases for webstore origin frame blocking.
185 // TODO(mkwst): Disabled until new X-Frame-Options behavior rolls into
186 // Chromium, see crbug.com/226018.
187 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
188 DISABLED_FrameWebstorePageBlocked) {
189 base::string16 expected_title = base::UTF8ToUTF16("PASS: about:blank");
190 base::string16 failure_title = base::UTF8ToUTF16("FAIL");
191 content::TitleWatcher watcher(GetWebContents(), expected_title);
192 watcher.AlsoWaitForTitle(failure_title);
193 GURL url = test_server()->GetURL(
194 "files/extensions/api_test/webstore_private/noframe.html");
195 ui_test_utils::NavigateToURL(browser(), url);
196 base::string16 final_title = watcher.WaitAndGetTitle();
197 EXPECT_EQ(expected_title, final_title);
200 // TODO(mkwst): Disabled until new X-Frame-Options behavior rolls into
201 // Chromium, see crbug.com/226018.
202 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
203 DISABLED_FrameErrorPageBlocked) {
204 base::string16 expected_title = base::UTF8ToUTF16("PASS: about:blank");
205 base::string16 failure_title = base::UTF8ToUTF16("FAIL");
206 content::TitleWatcher watcher(GetWebContents(), expected_title);
207 watcher.AlsoWaitForTitle(failure_title);
208 GURL url = test_server()->GetURL(
209 "files/extensions/api_test/webstore_private/noframe2.html");
210 ui_test_utils::NavigateToURL(browser(), url);
211 base::string16 final_title = watcher.WaitAndGetTitle();
212 EXPECT_EQ(expected_title, final_title);
215 // Test cases where the user accepts the install confirmation dialog.
216 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, InstallAccepted) {
217 ASSERT_TRUE(RunInstallTest("accepted.html", "extension.crx"));
220 // Test having the default download directory missing.
221 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MissingDownloadDir) {
222 // Set a non-existent directory as the download path.
223 base::ScopedTempDir temp_dir;
224 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
225 base::FilePath missing_directory = temp_dir.Take();
226 EXPECT_TRUE(base::DeleteFile(missing_directory, true));
227 WebstoreInstaller::SetDownloadDirectoryForTests(&missing_directory);
229 // Now run the install test, which should succeed.
230 ASSERT_TRUE(RunInstallTest("accepted.html", "extension.crx"));
232 // Cleanup.
233 if (base::DirectoryExists(missing_directory))
234 EXPECT_TRUE(base::DeleteFile(missing_directory, true));
237 // Tests passing a localized name.
238 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, InstallLocalized) {
239 ASSERT_TRUE(RunInstallTest("localized.html", "localized_extension.crx"));
242 // Now test the case where the user cancels the confirmation dialog.
243 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, InstallCancelled) {
244 ScopedTestDialogAutoConfirm auto_cancel(ScopedTestDialogAutoConfirm::CANCEL);
245 ASSERT_TRUE(RunInstallTest("cancelled.html", "extension.crx"));
248 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, IncorrectManifest1) {
249 ASSERT_TRUE(RunInstallTest("incorrect_manifest1.html", "extension.crx"));
252 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, IncorrectManifest2) {
253 ASSERT_TRUE(RunInstallTest("incorrect_manifest2.html", "extension.crx"));
256 // Disabled: http://crbug.com/174399 and http://crbug.com/177163
257 #if defined(OS_WIN) && (defined(USE_AURA) || !defined(NDEBUG))
258 #define MAYBE_AppInstallBubble DISABLED_AppInstallBubble
259 #else
260 #define MAYBE_AppInstallBubble AppInstallBubble
261 #endif
263 // Tests that we can request an app installed bubble (instead of the default
264 // UI when an app is installed).
265 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
266 MAYBE_AppInstallBubble) {
267 WebstoreInstallListener listener;
268 WebstorePrivateApi::SetWebstoreInstallerDelegateForTesting(&listener);
269 ASSERT_TRUE(RunInstallTest("app_install_bubble.html", "app.crx"));
270 listener.Wait();
271 ASSERT_TRUE(listener.received_success());
272 ASSERT_EQ("iladmdjkfniedhfhcfoefgojhgaiaccc", listener.id());
275 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, IsInIncognitoMode) {
276 GURL page_url = GetTestServerURL("incognito.html");
277 ASSERT_TRUE(
278 RunPageTest(page_url.spec(), ExtensionApiTest::kFlagUseIncognito));
281 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, IsNotInIncognitoMode) {
282 GURL page_url = GetTestServerURL("not_incognito.html");
283 ASSERT_TRUE(RunPageTest(page_url.spec()));
286 // Fails often on Windows dbg bots. http://crbug.com/177163.
287 #if defined(OS_WIN)
288 #define MAYBE_IconUrl DISABLED_IconUrl
289 #else
290 #define MAYBE_IconUrl IconUrl
291 #endif // defined(OS_WIN)
292 // Tests using the iconUrl parameter to the install function.
293 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MAYBE_IconUrl) {
294 ASSERT_TRUE(RunInstallTest("icon_url.html", "extension.crx"));
297 // http://crbug.com/177163
298 #if defined(OS_WIN) && !defined(NDEBUG)
299 #define MAYBE_BeginInstall DISABLED_BeginInstall
300 #else
301 #define MAYBE_BeginInstall BeginInstall
302 #endif
303 // Tests that the Approvals are properly created in beginInstall.
304 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MAYBE_BeginInstall) {
305 std::string appId = "iladmdjkfniedhfhcfoefgojhgaiaccc";
306 std::string extensionId = "enfkhcelefdadlmkffamgdlgplcionje";
307 ASSERT_TRUE(RunInstallTest("begin_install.html", "extension.crx"));
309 scoped_ptr<WebstoreInstaller::Approval> approval =
310 WebstorePrivateApi::PopApprovalForTesting(browser()->profile(), appId);
311 EXPECT_EQ(appId, approval->extension_id);
312 EXPECT_TRUE(approval->use_app_installed_bubble);
313 EXPECT_FALSE(approval->skip_post_install_ui);
314 EXPECT_EQ("2", approval->authuser);
315 EXPECT_EQ(browser()->profile(), approval->profile);
317 approval = WebstorePrivateApi::PopApprovalForTesting(
318 browser()->profile(), extensionId);
319 EXPECT_EQ(extensionId, approval->extension_id);
320 EXPECT_FALSE(approval->use_app_installed_bubble);
321 EXPECT_FALSE(approval->skip_post_install_ui);
322 EXPECT_TRUE(approval->authuser.empty());
323 EXPECT_EQ(browser()->profile(), approval->profile);
326 // http://crbug.com/177163
327 #if defined(OS_WIN) && !defined(NDEBUG)
328 #define MAYBE_InstallTheme DISABLED_InstallTheme
329 #else
330 #define MAYBE_InstallTheme InstallTheme
331 #endif
332 // Tests that themes are installed without an install prompt.
333 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MAYBE_InstallTheme) {
334 WebstoreInstallListener listener;
335 WebstorePrivateApi::SetWebstoreInstallerDelegateForTesting(&listener);
336 ASSERT_TRUE(RunInstallTest("theme.html", "../../theme.crx"));
337 listener.Wait();
338 ASSERT_TRUE(listener.received_success());
339 ASSERT_EQ("iamefpfkojoapidjnbafmgkgncegbkad", listener.id());
342 // Tests that an error is properly reported when an empty crx is returned.
343 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, EmptyCrx) {
344 ASSERT_TRUE(RunInstallTest("empty.html", "empty.crx"));
347 class ExtensionWebstoreGetWebGLStatusTest : public InProcessBrowserTest {
348 protected:
349 void RunTest(bool webgl_allowed) {
350 // If Gpu access is disallowed then WebGL will not be available.
351 if (!content::GpuDataManager::GetInstance()->GpuAccessAllowed(NULL))
352 webgl_allowed = false;
354 static const char kEmptyArgs[] = "[]";
355 static const char kWebGLStatusAllowed[] = "webgl_allowed";
356 static const char kWebGLStatusBlocked[] = "webgl_blocked";
357 scoped_refptr<WebstorePrivateGetWebGLStatusFunction> function =
358 new WebstorePrivateGetWebGLStatusFunction();
359 scoped_ptr<base::Value> result(utils::RunFunctionAndReturnSingleResult(
360 function.get(), kEmptyArgs, browser()));
361 ASSERT_TRUE(result);
362 EXPECT_EQ(base::Value::TYPE_STRING, result->GetType());
363 std::string webgl_status;
364 EXPECT_TRUE(result->GetAsString(&webgl_status));
365 EXPECT_STREQ(webgl_allowed ? kWebGLStatusAllowed : kWebGLStatusBlocked,
366 webgl_status.c_str());
370 // Tests getWebGLStatus function when WebGL is allowed.
371 IN_PROC_BROWSER_TEST_F(ExtensionWebstoreGetWebGLStatusTest, Allowed) {
372 bool webgl_allowed = true;
373 RunTest(webgl_allowed);
376 // Tests getWebGLStatus function when WebGL is blacklisted.
377 IN_PROC_BROWSER_TEST_F(ExtensionWebstoreGetWebGLStatusTest, Blocked) {
378 static const std::string json_blacklist =
379 "{\n"
380 " \"name\": \"gpu blacklist\",\n"
381 " \"version\": \"1.0\",\n"
382 " \"entries\": [\n"
383 " {\n"
384 " \"id\": 1,\n"
385 " \"features\": [\n"
386 " \"webgl\"\n"
387 " ]\n"
388 " }\n"
389 " ]\n"
390 "}";
391 gpu::GPUInfo gpu_info;
392 content::GpuDataManager::GetInstance()->InitializeForTesting(
393 json_blacklist, gpu_info);
394 EXPECT_TRUE(content::GpuDataManager::GetInstance()->IsFeatureBlacklisted(
395 gpu::GPU_FEATURE_TYPE_WEBGL));
397 bool webgl_allowed = false;
398 RunTest(webgl_allowed);
401 class EphemeralAppWebstorePrivateApiTest
402 : public ExtensionWebstorePrivateApiTest {
403 public:
404 void SetUpInProcessBrowserTestFixture() override {
405 ExtensionWebstorePrivateApiTest::SetUpInProcessBrowserTestFixture();
407 net::HostPortPair host_port = test_server()->host_port_pair();
408 std::string test_gallery_url = base::StringPrintf(
409 "http://www.example.com:%d/files/extensions/platform_apps/"
410 "ephemeral_launcher",
411 host_port.port());
412 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
413 switches::kAppsGalleryURL, test_gallery_url);
416 GURL GetTestServerURL(const std::string& path) override {
417 return DoGetTestServerURL(
418 std::string("files/extensions/platform_apps/ephemeral_launcher/") +
419 path);
423 // Run tests when the --enable-ephemeral-apps switch is not enabled.
424 IN_PROC_BROWSER_TEST_F(EphemeralAppWebstorePrivateApiTest,
425 EphemeralAppsFeatureDisabled) {
426 base::CommandLine::ForCurrentProcess()->AppendSwitch(
427 app_list::switches::kDisableExperimentalAppList);
428 ASSERT_TRUE(RunInstallTest("webstore_launch_disabled.html", "app.crx"));
431 // Run tests when the --enable-ephemeral-apps switch is enabled.
432 IN_PROC_BROWSER_TEST_F(EphemeralAppWebstorePrivateApiTest, LaunchEphemeralApp) {
433 base::CommandLine::ForCurrentProcess()->AppendSwitch(
434 switches::kEnableEphemeralAppsInWebstore);
435 base::CommandLine::ForCurrentProcess()->AppendSwitch(
436 app_list::switches::kEnableExperimentalAppList);
437 ASSERT_TRUE(RunInstallTest("webstore_launch_app.html", "app.crx"));
440 class BundleWebstorePrivateApiTest
441 : public ExtensionWebstorePrivateApiTest {
442 public:
443 void SetUpInProcessBrowserTestFixture() override {
444 ExtensionWebstorePrivateApiTest::SetUpInProcessBrowserTestFixture();
446 test_data_dir_ = test_data_dir_.AppendASCII("webstore_private/bundle");
448 // The test server needs to have already started, so setup the switch here
449 // rather than in SetUpCommandLine.
450 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
451 switches::kAppsGalleryDownloadURL,
452 GetTestServerURL("bundle/%s.crx").spec());
456 // Tests successfully installing a bundle of 2 apps and 2 extensions.
457 IN_PROC_BROWSER_TEST_F(BundleWebstorePrivateApiTest, InstallBundle) {
458 extensions::BundleInstaller::SetAutoApproveForTesting(true);
459 ASSERT_TRUE(RunPageTest(GetTestServerURL("install_bundle.html").spec()));
462 // Tests that bundles can be installed from incognito windows.
463 IN_PROC_BROWSER_TEST_F(BundleWebstorePrivateApiTest, InstallBundleIncognito) {
464 extensions::BundleInstaller::SetAutoApproveForTesting(true);
466 ASSERT_TRUE(RunPageTest(GetTestServerURL("install_bundle.html").spec(),
467 ExtensionApiTest::kFlagUseIncognito));
470 // Tests the user canceling the bundle install prompt.
471 IN_PROC_BROWSER_TEST_F(BundleWebstorePrivateApiTest, InstallBundleCancel) {
472 // We don't need to create the CRX files since we are aborting the install.
473 extensions::BundleInstaller::SetAutoApproveForTesting(false);
475 ASSERT_TRUE(
476 RunPageTest(GetTestServerURL("install_bundle_cancel.html").spec()));
479 // Tests partially installing a bundle (1 succeeds, 1 fails due to an invalid
480 // CRX, 1 fails due to the manifests not matching, and 1 fails due to a missing
481 // crx file).
482 IN_PROC_BROWSER_TEST_F(BundleWebstorePrivateApiTest, InstallBundleInvalid) {
483 extensions::BundleInstaller::SetAutoApproveForTesting(true);
485 ASSERT_TRUE(
486 RunPageTest(GetTestServerURL("install_bundle_invalid.html").spec()));
489 } // namespace extensions