Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / webstore_private / webstore_private_apitest.cc
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.
4
5 #include <vector>
6
7 #include "base/callback_list.h"
8 #include "base/file_util.h"
9 #include "base/files/file_path.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/extensions/api/identity/identity_api.h"
15 #include "chrome/browser/extensions/api/management/management_api.h"
16 #include "chrome/browser/extensions/api/webstore_private/webstore_private_api.h"
17 #include "chrome/browser/extensions/extension_apitest.h"
18 #include "chrome/browser/extensions/extension_function_test_utils.h"
19 #include "chrome/browser/extensions/extension_install_prompt.h"
20 #include "chrome/browser/extensions/extension_install_ui.h"
21 #include "chrome/browser/extensions/extension_service.h"
22 #include "chrome/browser/extensions/webstore_installer.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
25 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
26 #include "chrome/browser/signin/fake_signin_manager.h"
27 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
28 #include "chrome/browser/signin/signin_manager_factory.h"
29 #include "chrome/browser/ui/browser.h"
30 #include "chrome/browser/ui/tabs/tab_strip_model.h"
31 #include "chrome/common/chrome_switches.h"
32 #include "chrome/test/base/ui_test_utils.h"
33 #include "components/keyed_service/content/browser_context_dependency_manager.h"
34 #include "components/signin/core/browser/signin_manager.h"
35 #include "components/signin/core/browser/test_signin_client.h"
36 #include "content/public/browser/gpu_data_manager.h"
37 #include "content/public/browser/notification_observer.h"
38 #include "content/public/browser/notification_registrar.h"
39 #include "content/public/test/browser_test_utils.h"
40 #include "extensions/browser/extension_system.h"
41 #include "gpu/config/gpu_feature_type.h"
42 #include "gpu/config/gpu_info.h"
43 #include "net/dns/mock_host_resolver.h"
44 #include "ui/gl/gl_switches.h"
45
46 using gpu::GpuFeatureType;
47
48 namespace utils = extension_function_test_utils;
49
50 namespace extensions {
51
52 namespace {
53
54 class WebstoreInstallListener : public WebstoreInstaller::Delegate {
55  public:
56   WebstoreInstallListener()
57       : received_failure_(false), received_success_(false), waiting_(false) {}
58
59   virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE {
60     received_success_ = true;
61     id_ = id;
62
63     if (waiting_) {
64       waiting_ = false;
65       base::MessageLoopForUI::current()->Quit();
66     }
67   }
68
69   virtual void OnExtensionInstallFailure(
70       const std::string& id,
71       const std::string& error,
72       WebstoreInstaller::FailureReason reason) OVERRIDE {
73     received_failure_ = true;
74     id_ = id;
75     error_ = error;
76
77     if (waiting_) {
78       waiting_ = false;
79       base::MessageLoopForUI::current()->Quit();
80     }
81   }
82
83   void Wait() {
84     if (received_success_ || received_failure_)
85       return;
86
87     waiting_ = true;
88     content::RunMessageLoop();
89   }
90   bool received_success() const { return received_success_; }
91   const std::string& id() const { return id_; }
92
93  private:
94   bool received_failure_;
95   bool received_success_;
96   bool waiting_;
97   std::string id_;
98   std::string error_;
99 };
100
101 }  // namespace
102
103 // A base class for tests below.
104 class ExtensionWebstorePrivateApiTest : public ExtensionApiTest {
105  public:
106   ExtensionWebstorePrivateApiTest()
107       : signin_manager_(NULL),
108         token_service_(NULL) {}
109   virtual ~ExtensionWebstorePrivateApiTest() {}
110
111   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
112     ExtensionApiTest::SetUpCommandLine(command_line);
113     command_line->AppendSwitchASCII(
114         switches::kAppsGalleryURL,
115         "http://www.example.com/files/extensions/api_test");
116   }
117
118   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
119     ExtensionApiTest::SetUpInProcessBrowserTestFixture();
120
121     // Start up the test server and get us ready for calling the install
122     // API functions.
123     host_resolver()->AddRule("www.example.com", "127.0.0.1");
124     ASSERT_TRUE(StartSpawnedTestServer());
125     ExtensionInstallUI::set_disable_failure_ui_for_tests();
126
127     will_create_browser_context_services_subscription_ =
128         BrowserContextDependencyManager::GetInstance()->
129             RegisterWillCreateBrowserContextServicesCallbackForTesting(
130                 base::Bind(
131                     &ExtensionWebstorePrivateApiTest::
132                         OnWillCreateBrowserContextServices,
133                     base::Unretained(this))).Pass();
134   }
135
136   void OnWillCreateBrowserContextServices(content::BrowserContext* context) {
137     // Replace the signin manager and token service with fakes. Do this ahead of
138     // creating the browser so that a bunch of classes don't register as
139     // observers and end up needing to unregister when the fake is substituted.
140     SigninManagerFactory::GetInstance()->SetTestingFactory(
141         context, &FakeSigninManagerBase::Build);
142     ProfileOAuth2TokenServiceFactory::GetInstance()->SetTestingFactory(
143         context, &BuildFakeProfileOAuth2TokenService);
144   }
145
146   virtual void SetUpOnMainThread() OVERRIDE {
147     ExtensionApiTest::SetUpOnMainThread();
148
149     ExtensionInstallPrompt::g_auto_confirm_for_tests =
150         ExtensionInstallPrompt::ACCEPT;
151
152     // Grab references to the fake signin manager and token service.
153     signin_manager_ =
154         static_cast<FakeSigninManagerForTesting*>(
155             SigninManagerFactory::GetInstance()->GetForProfile(profile()));
156     ASSERT_TRUE(signin_manager_);
157     token_service_ =
158         static_cast<FakeProfileOAuth2TokenService*>(
159             ProfileOAuth2TokenServiceFactory::GetInstance()->GetForProfile(
160                 profile()));
161     ASSERT_TRUE(token_service_);
162
163     ASSERT_TRUE(webstore_install_dir_.CreateUniqueTempDir());
164     webstore_install_dir_copy_ = webstore_install_dir_.path();
165     WebstoreInstaller::SetDownloadDirectoryForTests(
166         &webstore_install_dir_copy_);
167   }
168
169  protected:
170   // Returns a test server URL, but with host 'www.example.com' so it matches
171   // the web store app's extent that we set up via command line flags.
172   GURL DoGetTestServerURL(const std::string& path) {
173     GURL url = test_server()->GetURL(path);
174
175     // Replace the host with 'www.example.com' so it matches the web store
176     // app's extent.
177     GURL::Replacements replace_host;
178     std::string host_str("www.example.com");
179     replace_host.SetHostStr(host_str);
180
181     return url.ReplaceComponents(replace_host);
182   }
183
184   virtual GURL GetTestServerURL(const std::string& path) {
185     return DoGetTestServerURL(
186         std::string("files/extensions/api_test/webstore_private/") + path);
187   }
188
189   // Navigates to |page| and runs the Extension API test there. Any downloads
190   // of extensions will return the contents of |crx_file|.
191   bool RunInstallTest(const std::string& page, const std::string& crx_file) {
192     // Auto-confirm the uninstallation dialog.
193     ManagementUninstallFunction::SetAutoConfirmForTest(true);
194 #if defined(OS_WIN) && !defined(NDEBUG)
195     // See http://crbug.com/177163 for details.
196     return true;
197 #else
198     GURL crx_url = GetTestServerURL(crx_file);
199     CommandLine::ForCurrentProcess()->AppendSwitchASCII(
200         switches::kAppsGalleryUpdateURL, crx_url.spec());
201
202     GURL page_url = GetTestServerURL(page);
203     return RunPageTest(page_url.spec());
204 #endif
205   }
206
207   // Navigates to |page| and waits for the API call.
208   void StartSignInTest(const std::string& page) {
209     ui_test_utils::NavigateToURL(browser(), GetTestServerURL(page));
210
211     // Wait for the API to be called.  A simple way to wait for this is to run
212     // some other JavaScript in the page and wait for a round-trip back to the
213     // browser process.
214     bool result = false;
215     ASSERT_TRUE(
216         content::ExecuteScriptAndExtractBool(
217             GetWebContents(), "window.domAutomationController.send(true)",
218             &result));
219     ASSERT_TRUE(result);
220   }
221
222   content::WebContents* GetWebContents() {
223     return browser()->tab_strip_model()->GetActiveWebContents();
224   }
225
226   ExtensionService* service() {
227     return ExtensionSystem::Get(browser()->profile())->extension_service();
228   }
229
230   FakeSigninManagerForTesting* signin_manager_;
231   FakeProfileOAuth2TokenService* token_service_;
232
233  private:
234   scoped_ptr<base::CallbackList<void(content::BrowserContext*)>::Subscription>
235       will_create_browser_context_services_subscription_;
236
237   base::ScopedTempDir webstore_install_dir_;
238   // WebstoreInstaller needs a reference to a FilePath when setting the download
239   // directory for testing.
240   base::FilePath webstore_install_dir_copy_;
241 };
242
243 // Test cases for webstore origin frame blocking.
244 // TODO(mkwst): Disabled until new X-Frame-Options behavior rolls into
245 // Chromium, see crbug.com/226018.
246 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
247                        DISABLED_FrameWebstorePageBlocked) {
248   base::string16 expected_title = base::UTF8ToUTF16("PASS: about:blank");
249   base::string16 failure_title = base::UTF8ToUTF16("FAIL");
250   content::TitleWatcher watcher(GetWebContents(), expected_title);
251   watcher.AlsoWaitForTitle(failure_title);
252   GURL url = test_server()->GetURL(
253       "files/extensions/api_test/webstore_private/noframe.html");
254   ui_test_utils::NavigateToURL(browser(), url);
255   base::string16 final_title = watcher.WaitAndGetTitle();
256   EXPECT_EQ(expected_title, final_title);
257 }
258
259 // TODO(mkwst): Disabled until new X-Frame-Options behavior rolls into
260 // Chromium, see crbug.com/226018.
261 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
262                        DISABLED_FrameErrorPageBlocked) {
263   base::string16 expected_title = base::UTF8ToUTF16("PASS: about:blank");
264   base::string16 failure_title = base::UTF8ToUTF16("FAIL");
265   content::TitleWatcher watcher(GetWebContents(), expected_title);
266   watcher.AlsoWaitForTitle(failure_title);
267   GURL url = test_server()->GetURL(
268       "files/extensions/api_test/webstore_private/noframe2.html");
269   ui_test_utils::NavigateToURL(browser(), url);
270   base::string16 final_title = watcher.WaitAndGetTitle();
271   EXPECT_EQ(expected_title, final_title);
272 }
273
274 // Test cases where the user accepts the install confirmation dialog.
275 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, InstallAccepted) {
276   ASSERT_TRUE(RunInstallTest("accepted.html", "extension.crx"));
277 }
278
279 // Test having the default download directory missing.
280 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MissingDownloadDir) {
281   // Set a non-existent directory as the download path.
282   base::ScopedTempDir temp_dir;
283   EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
284   base::FilePath missing_directory = temp_dir.Take();
285   EXPECT_TRUE(base::DeleteFile(missing_directory, true));
286   WebstoreInstaller::SetDownloadDirectoryForTests(&missing_directory);
287
288   // Now run the install test, which should succeed.
289   ASSERT_TRUE(RunInstallTest("accepted.html", "extension.crx"));
290
291   // Cleanup.
292   if (base::DirectoryExists(missing_directory))
293     EXPECT_TRUE(base::DeleteFile(missing_directory, true));
294 }
295
296 // Tests passing a localized name.
297 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, InstallLocalized) {
298   ASSERT_TRUE(RunInstallTest("localized.html", "localized_extension.crx"));
299 }
300
301 // Now test the case where the user cancels the confirmation dialog.
302 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, InstallCancelled) {
303   ExtensionInstallPrompt::g_auto_confirm_for_tests =
304       ExtensionInstallPrompt::CANCEL;
305   ASSERT_TRUE(RunInstallTest("cancelled.html", "extension.crx"));
306 }
307
308 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, IncorrectManifest1) {
309   ASSERT_TRUE(RunInstallTest("incorrect_manifest1.html", "extension.crx"));
310 }
311
312 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, IncorrectManifest2) {
313   ASSERT_TRUE(RunInstallTest("incorrect_manifest2.html", "extension.crx"));
314 }
315
316 // Disabled: http://crbug.com/174399 and http://crbug.com/177163
317 #if defined(OS_WIN) && (defined(USE_AURA) || !defined(NDEBUG))
318 #define MAYBE_AppInstallBubble DISABLED_AppInstallBubble
319 #else
320 #define MAYBE_AppInstallBubble AppInstallBubble
321 #endif
322
323 // Tests that we can request an app installed bubble (instead of the default
324 // UI when an app is installed).
325 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
326                        MAYBE_AppInstallBubble) {
327   WebstoreInstallListener listener;
328   WebstorePrivateApi::SetWebstoreInstallerDelegateForTesting(&listener);
329   ASSERT_TRUE(RunInstallTest("app_install_bubble.html", "app.crx"));
330   listener.Wait();
331   ASSERT_TRUE(listener.received_success());
332   ASSERT_EQ("iladmdjkfniedhfhcfoefgojhgaiaccc", listener.id());
333 }
334
335 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, IsInIncognitoMode) {
336   GURL page_url = GetTestServerURL("incognito.html");
337   ASSERT_TRUE(
338       RunPageTest(page_url.spec(), ExtensionApiTest::kFlagUseIncognito));
339 }
340
341 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, IsNotInIncognitoMode) {
342   GURL page_url = GetTestServerURL("not_incognito.html");
343   ASSERT_TRUE(RunPageTest(page_url.spec()));
344 }
345
346 // Fails often on Windows dbg bots. http://crbug.com/177163.
347 #if defined(OS_WIN)
348 #define MAYBE_IconUrl DISABLED_IconUrl
349 #else
350 #define MAYBE_IconUrl IconUrl
351 #endif  // defined(OS_WIN)
352 // Tests using the iconUrl parameter to the install function.
353 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MAYBE_IconUrl) {
354   ASSERT_TRUE(RunInstallTest("icon_url.html", "extension.crx"));
355 }
356
357 // http://crbug.com/177163
358 #if defined(OS_WIN) && !defined(NDEBUG)
359 #define MAYBE_BeginInstall DISABLED_BeginInstall
360 #else
361 #define MAYBE_BeginInstall BeginInstall
362 #endif
363 // Tests that the Approvals are properly created in beginInstall.
364 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MAYBE_BeginInstall) {
365   std::string appId = "iladmdjkfniedhfhcfoefgojhgaiaccc";
366   std::string extensionId = "enfkhcelefdadlmkffamgdlgplcionje";
367   ASSERT_TRUE(RunInstallTest("begin_install.html", "extension.crx"));
368
369   scoped_ptr<WebstoreInstaller::Approval> approval =
370       WebstorePrivateApi::PopApprovalForTesting(browser()->profile(), appId);
371   EXPECT_EQ(appId, approval->extension_id);
372   EXPECT_TRUE(approval->use_app_installed_bubble);
373   EXPECT_FALSE(approval->skip_post_install_ui);
374   EXPECT_EQ("2", approval->authuser);
375   EXPECT_EQ(browser()->profile(), approval->profile);
376
377   approval = WebstorePrivateApi::PopApprovalForTesting(
378       browser()->profile(), extensionId);
379   EXPECT_EQ(extensionId, approval->extension_id);
380   EXPECT_FALSE(approval->use_app_installed_bubble);
381   EXPECT_FALSE(approval->skip_post_install_ui);
382   EXPECT_TRUE(approval->authuser.empty());
383   EXPECT_EQ(browser()->profile(), approval->profile);
384 }
385
386 // http://crbug.com/177163
387 #if defined(OS_WIN) && !defined(NDEBUG)
388 #define MAYBE_InstallTheme DISABLED_InstallTheme
389 #else
390 #define MAYBE_InstallTheme InstallTheme
391 #endif
392 // Tests that themes are installed without an install prompt.
393 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MAYBE_InstallTheme) {
394   WebstoreInstallListener listener;
395   WebstorePrivateApi::SetWebstoreInstallerDelegateForTesting(&listener);
396   ASSERT_TRUE(RunInstallTest("theme.html", "../../theme.crx"));
397   listener.Wait();
398   ASSERT_TRUE(listener.received_success());
399   ASSERT_EQ("iamefpfkojoapidjnbafmgkgncegbkad", listener.id());
400 }
401
402 // Tests that an error is properly reported when an empty crx is returned.
403 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, EmptyCrx) {
404   ASSERT_TRUE(RunInstallTest("empty.html", "empty.crx"));
405 }
406
407 class ExtensionWebstoreGetWebGLStatusTest : public InProcessBrowserTest {
408  protected:
409   void RunTest(bool webgl_allowed) {
410     // If Gpu access is disallowed then WebGL will not be available.
411     if (!content::GpuDataManager::GetInstance()->GpuAccessAllowed(NULL))
412       webgl_allowed = false;
413
414     static const char kEmptyArgs[] = "[]";
415     static const char kWebGLStatusAllowed[] = "webgl_allowed";
416     static const char kWebGLStatusBlocked[] = "webgl_blocked";
417     scoped_refptr<WebstorePrivateGetWebGLStatusFunction> function =
418         new WebstorePrivateGetWebGLStatusFunction();
419     scoped_ptr<base::Value> result(utils::RunFunctionAndReturnSingleResult(
420             function.get(), kEmptyArgs, browser()));
421     ASSERT_TRUE(result);
422     EXPECT_EQ(base::Value::TYPE_STRING, result->GetType());
423     std::string webgl_status;
424     EXPECT_TRUE(result->GetAsString(&webgl_status));
425     EXPECT_STREQ(webgl_allowed ? kWebGLStatusAllowed : kWebGLStatusBlocked,
426                  webgl_status.c_str());
427   }
428 };
429
430 // Tests getWebGLStatus function when WebGL is allowed.
431 IN_PROC_BROWSER_TEST_F(ExtensionWebstoreGetWebGLStatusTest, Allowed) {
432   bool webgl_allowed = true;
433   RunTest(webgl_allowed);
434 }
435
436 // Tests getWebGLStatus function when WebGL is blacklisted.
437 IN_PROC_BROWSER_TEST_F(ExtensionWebstoreGetWebGLStatusTest, Blocked) {
438   static const std::string json_blacklist =
439       "{\n"
440       "  \"name\": \"gpu blacklist\",\n"
441       "  \"version\": \"1.0\",\n"
442       "  \"entries\": [\n"
443       "    {\n"
444       "      \"id\": 1,\n"
445       "      \"features\": [\n"
446       "        \"webgl\"\n"
447       "      ]\n"
448       "    }\n"
449       "  ]\n"
450       "}";
451   gpu::GPUInfo gpu_info;
452   content::GpuDataManager::GetInstance()->InitializeForTesting(
453       json_blacklist, gpu_info);
454   EXPECT_TRUE(content::GpuDataManager::GetInstance()->IsFeatureBlacklisted(
455       gpu::GPU_FEATURE_TYPE_WEBGL));
456
457   bool webgl_allowed = false;
458   RunTest(webgl_allowed);
459 }
460
461 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
462                        SignIn_UserGestureRequired) {
463   GURL page_url = GetTestServerURL("sign_in_user_gesture_required.html");
464   ASSERT_TRUE(RunPageTest(page_url.spec()));
465 }
466
467 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
468                        SignIn_MissingContinueUrl) {
469   GURL page_url = GetTestServerURL("sign_in_missing_continue_url.html");
470   ASSERT_TRUE(RunPageTest(page_url.spec()));
471 }
472
473 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
474                        SignIn_InvalidContinueUrl) {
475   GURL page_url = GetTestServerURL("sign_in_invalid_continue_url.html");
476   ASSERT_TRUE(RunPageTest(page_url.spec()));
477 }
478
479 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
480                        SignIn_ContinueUrlOnDifferentOrigin) {
481   GURL page_url =
482       GetTestServerURL("sign_in_continue_url_on_different_origin.html");
483   ASSERT_TRUE(RunPageTest(page_url.spec()));
484 }
485
486 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
487                        SignIn_DisallowedInIncognito) {
488   // Make sure that the test is testing something more than the absence of a
489   // sign-in manager for this profile.
490   ASSERT_TRUE(SigninManagerFactory::GetForProfile(profile()));
491
492   GURL page_url =
493       GetTestServerURL("sign_in_disallowed_in_incognito.html");
494   ASSERT_TRUE(
495       RunPageTest(page_url.spec(), ExtensionApiTest::kFlagUseIncognito));
496 }
497
498 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
499                        SignIn_DisabledWhenWebBasedSigninIsEnabled) {
500   // Make sure that the test is testing something more than the absence of a
501   // sign-in manager for this profile.
502   ASSERT_TRUE(SigninManagerFactory::GetForProfile(profile()));
503
504   CommandLine::ForCurrentProcess()->AppendSwitch(
505       switches::kEnableWebBasedSignin);
506   GURL page_url = GetTestServerURL(
507       "sign_in_disabled_when_web_based_signin_is_enabled.html");
508   ASSERT_TRUE(RunPageTest(page_url.spec()));
509 }
510
511 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
512                        SignIn_AlreadySignedIn) {
513   signin_manager_->SetAuthenticatedUsername("user@example.com");
514   GURL page_url = GetTestServerURL("sign_in_already_signed_in.html");
515   ASSERT_TRUE(RunPageTest(page_url.spec()));
516 }
517
518 // The FakeSignInManager class is not implemented for ChromeOS, so there's no
519 // straightforward way to test these flows on that platform.
520 #if !defined(OS_CHROMEOS)
521 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
522                        SignIn_AuthInProgress_Fails) {
523   // Initiate an authentication that will be in progress when the sign-in API is
524   // called.
525   signin_manager_->set_auth_in_progress("user@example.com");
526
527   // Navigate to the page, which will cause the sign-in API to be called.
528   // Then, complete the authentication in a failed state.
529   ResultCatcher catcher;
530   StartSignInTest("sign_in_auth_in_progress_fails.html");
531   signin_manager_->FailSignin(GoogleServiceAuthError::AuthErrorNone());
532   ASSERT_TRUE(catcher.GetNextResult());
533 }
534
535 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
536                        SignIn_AuthInProgress_MergeSessionFails) {
537   // Initiate an authentication that will be in progress when the sign-in API is
538   // called.
539   signin_manager_->set_auth_in_progress("user@example.com");
540
541   // Navigate to the page, which will cause the sign-in API to be called.
542   // Then, complete the authentication in a successful state.
543   ResultCatcher catcher;
544   StartSignInTest("sign_in_auth_in_progress_merge_session_fails.html");
545   signin_manager_->CompletePendingSignin();
546   token_service_->IssueRefreshTokenForUser("user@example.com", "token");
547   signin_manager_->NotifyMergeSessionObservers(
548       GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE));
549   ASSERT_TRUE(catcher.GetNextResult());
550 }
551
552 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
553                        SignIn_AuthInProgress_Succeeds) {
554   // Initiate an authentication that will be in progress when the sign-in API is
555   // called.
556   signin_manager_->set_auth_in_progress("user@example.com");
557
558   // Navigate to the page, which will cause the sign-in API to be called.
559   // Then, complete the authentication in a successful state.
560   ResultCatcher catcher;
561   StartSignInTest("sign_in_auth_in_progress_succeeds.html");
562   signin_manager_->CompletePendingSignin();
563   token_service_->IssueRefreshTokenForUser("user@example.com", "token");
564   signin_manager_->NotifyMergeSessionObservers(
565       GoogleServiceAuthError::AuthErrorNone());
566   ASSERT_TRUE(catcher.GetNextResult());
567 }
568 #endif  // !defined (OS_CHROMEOS)
569
570 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
571                        SignIn_RedirectToSignIn) {
572   GURL signin_url(
573       "chrome://chrome-signin/?source=5&"
574       "continue=http%3A%2F%2Fwww.example.com%3A" +
575       base::IntToString(test_server()->host_port_pair().port()) +
576       "%2Fcontinue");
577   ui_test_utils::UrlLoadObserver observer(
578       signin_url,
579       content::Source<content::NavigationController>(
580           &GetWebContents()->GetController()));
581   StartSignInTest("sign_in_redirect_to_sign_in.html");
582   observer.Wait();
583
584   // TODO(isherman): Also test the redirect back to the continue URL once
585   // sign-in completes?
586 }
587
588 class EphemeralAppWebstorePrivateApiTest
589     : public ExtensionWebstorePrivateApiTest {
590  public:
591   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
592     ExtensionWebstorePrivateApiTest::SetUpInProcessBrowserTestFixture();
593
594     net::HostPortPair host_port = test_server()->host_port_pair();
595     std::string test_gallery_url = base::StringPrintf(
596         "http://www.example.com:%d/files/extensions/platform_apps/"
597         "ephemeral_launcher",
598         host_port.port());
599     CommandLine::ForCurrentProcess()->AppendSwitchASCII(
600         switches::kAppsGalleryURL, test_gallery_url);
601   }
602
603   virtual GURL GetTestServerURL(const std::string& path) OVERRIDE {
604     return DoGetTestServerURL(
605         std::string("files/extensions/platform_apps/ephemeral_launcher/") +
606         path);
607   }
608 };
609
610 // Run tests when the --enable-ephemeral-apps switch is not enabled.
611 IN_PROC_BROWSER_TEST_F(EphemeralAppWebstorePrivateApiTest,
612                        EphemeralAppsFeatureDisabled) {
613   ASSERT_TRUE(RunInstallTest("webstore_launch_disabled.html", "app.crx"));
614 }
615
616 // Run tests when the --enable-ephemeral-apps switch is enabled.
617 IN_PROC_BROWSER_TEST_F(EphemeralAppWebstorePrivateApiTest, LaunchEphemeralApp) {
618   CommandLine::ForCurrentProcess()->AppendSwitch(
619       switches::kEnableEphemeralApps);
620   ASSERT_TRUE(RunInstallTest("webstore_launch_app.html", "app.crx"));
621 }
622
623 }  // namespace extensions