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