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