Upstream version 7.36.149.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 "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
162  protected:
163   // Returns a test server URL, but with host 'www.example.com' so it matches
164   // the web store app's extent that we set up via command line flags.
165   virtual GURL GetTestServerURL(const std::string& path) {
166     GURL url = test_server()->GetURL(
167         std::string("files/extensions/api_test/webstore_private/") + path);
168
169     // Replace the host with 'www.example.com' so it matches the web store
170     // app's extent.
171     GURL::Replacements replace_host;
172     std::string host_str("www.example.com");
173     replace_host.SetHostStr(host_str);
174
175     return url.ReplaceComponents(replace_host);
176   }
177
178   // Navigates to |page| and runs the Extension API test there. Any downloads
179   // of extensions will return the contents of |crx_file|.
180   bool RunInstallTest(const std::string& page, const std::string& crx_file) {
181     // Auto-confirm the uninstallation dialog.
182     ManagementUninstallFunction::SetAutoConfirmForTest(true);
183 #if defined(OS_WIN) && !defined(NDEBUG)
184     // See http://crbug.com/177163 for details.
185     return true;
186 #else
187     GURL crx_url = GetTestServerURL(crx_file);
188     CommandLine::ForCurrentProcess()->AppendSwitchASCII(
189         switches::kAppsGalleryUpdateURL, crx_url.spec());
190
191     GURL page_url = GetTestServerURL(page);
192     return RunPageTest(page_url.spec());
193 #endif
194   }
195
196   // Navigates to |page| and waits for the API call.
197   void StartSignInTest(const std::string& page) {
198     ui_test_utils::NavigateToURL(browser(), GetTestServerURL(page));
199
200     // Wait for the API to be called.  A simple way to wait for this is to run
201     // some other JavaScript in the page and wait for a round-trip back to the
202     // browser process.
203     bool result = false;
204     ASSERT_TRUE(
205         content::ExecuteScriptAndExtractBool(
206             GetWebContents(), "window.domAutomationController.send(true)",
207             &result));
208     ASSERT_TRUE(result);
209   }
210
211   content::WebContents* GetWebContents() {
212     return browser()->tab_strip_model()->GetActiveWebContents();
213   }
214
215   ExtensionService* service() {
216     return browser()->profile()->GetExtensionService();
217   }
218
219   FakeSigninManagerForTesting* signin_manager_;
220   FakeProfileOAuth2TokenService* token_service_;
221
222  private:
223   scoped_ptr<base::CallbackList<void(content::BrowserContext*)>::Subscription>
224       will_create_browser_context_services_subscription_;
225
226 };
227
228 // Test cases for webstore origin frame blocking.
229 // TODO(mkwst): Disabled until new X-Frame-Options behavior rolls into
230 // Chromium, see crbug.com/226018.
231 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
232                        DISABLED_FrameWebstorePageBlocked) {
233   base::string16 expected_title = base::UTF8ToUTF16("PASS: about:blank");
234   base::string16 failure_title = base::UTF8ToUTF16("FAIL");
235   content::TitleWatcher watcher(GetWebContents(), expected_title);
236   watcher.AlsoWaitForTitle(failure_title);
237   GURL url = test_server()->GetURL(
238       "files/extensions/api_test/webstore_private/noframe.html");
239   ui_test_utils::NavigateToURL(browser(), url);
240   base::string16 final_title = watcher.WaitAndGetTitle();
241   EXPECT_EQ(expected_title, final_title);
242 }
243
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_FrameErrorPageBlocked) {
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/noframe2.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 // Test cases where the user accepts the install confirmation dialog.
260 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, InstallAccepted) {
261   ASSERT_TRUE(RunInstallTest("accepted.html", "extension.crx"));
262 }
263
264 // Test having the default download directory missing.
265  IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MissingDownloadDir) {
266   // Set a non-existent directory as the download path.
267   base::ScopedTempDir temp_dir;
268   EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
269   base::FilePath missing_directory = temp_dir.Take();
270   EXPECT_TRUE(base::DeleteFile(missing_directory, true));
271   WebstoreInstaller::SetDownloadDirectoryForTests(&missing_directory);
272
273   // Now run the install test, which should succeed.
274   ASSERT_TRUE(RunInstallTest("accepted.html", "extension.crx"));
275
276   // Cleanup.
277   if (base::DirectoryExists(missing_directory))
278     EXPECT_TRUE(base::DeleteFile(missing_directory, true));
279 }
280
281 // Tests passing a localized name.
282 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, InstallLocalized) {
283   ASSERT_TRUE(RunInstallTest("localized.html", "localized_extension.crx"));
284 }
285
286 // Now test the case where the user cancels the confirmation dialog.
287 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, InstallCancelled) {
288   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
289       switches::kAppsGalleryInstallAutoConfirmForTests, "cancel");
290   ASSERT_TRUE(RunInstallTest("cancelled.html", "extension.crx"));
291 }
292
293 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, IncorrectManifest1) {
294   ASSERT_TRUE(RunInstallTest("incorrect_manifest1.html", "extension.crx"));
295 }
296
297 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, IncorrectManifest2) {
298   ASSERT_TRUE(RunInstallTest("incorrect_manifest2.html", "extension.crx"));
299 }
300
301 // Disabled: http://crbug.com/174399 and http://crbug.com/177163
302 #if defined(OS_WIN) && (defined(USE_AURA) || !defined(NDEBUG))
303 #define MAYBE_AppInstallBubble DISABLED_AppInstallBubble
304 #else
305 #define MAYBE_AppInstallBubble AppInstallBubble
306 #endif
307
308 // Tests that we can request an app installed bubble (instead of the default
309 // UI when an app is installed).
310 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
311                        MAYBE_AppInstallBubble) {
312   WebstoreInstallListener listener;
313   WebstorePrivateApi::SetWebstoreInstallerDelegateForTesting(&listener);
314   ASSERT_TRUE(RunInstallTest("app_install_bubble.html", "app.crx"));
315   listener.Wait();
316   ASSERT_TRUE(listener.received_success());
317   ASSERT_EQ("iladmdjkfniedhfhcfoefgojhgaiaccc", listener.id());
318 }
319
320 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, IsInIncognitoMode) {
321   GURL page_url = GetTestServerURL("incognito.html");
322   ASSERT_TRUE(
323       RunPageTest(page_url.spec(), ExtensionApiTest::kFlagUseIncognito));
324 }
325
326 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, IsNotInIncognitoMode) {
327   GURL page_url = GetTestServerURL("not_incognito.html");
328   ASSERT_TRUE(RunPageTest(page_url.spec()));
329 }
330
331 // Fails often on Windows dbg bots. http://crbug.com/177163.
332 #if defined(OS_WIN)
333 #define MAYBE_IconUrl DISABLED_IconUrl
334 #else
335 #define MAYBE_IconUrl IconUrl
336 #endif  // defined(OS_WIN)
337 // Tests using the iconUrl parameter to the install function.
338 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MAYBE_IconUrl) {
339   ASSERT_TRUE(RunInstallTest("icon_url.html", "extension.crx"));
340 }
341
342 // http://crbug.com/177163
343 #if defined(OS_WIN) && !defined(NDEBUG)
344 #define MAYBE_BeginInstall DISABLED_BeginInstall
345 #else
346 #define MAYBE_BeginInstall BeginInstall
347 #endif
348 // Tests that the Approvals are properly created in beginInstall.
349 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MAYBE_BeginInstall) {
350   std::string appId = "iladmdjkfniedhfhcfoefgojhgaiaccc";
351   std::string extensionId = "enfkhcelefdadlmkffamgdlgplcionje";
352   ASSERT_TRUE(RunInstallTest("begin_install.html", "extension.crx"));
353
354   scoped_ptr<WebstoreInstaller::Approval> approval =
355       WebstorePrivateApi::PopApprovalForTesting(browser()->profile(), appId);
356   EXPECT_EQ(appId, approval->extension_id);
357   EXPECT_TRUE(approval->use_app_installed_bubble);
358   EXPECT_FALSE(approval->skip_post_install_ui);
359   EXPECT_EQ("2", approval->authuser);
360   EXPECT_EQ(browser()->profile(), approval->profile);
361
362   approval = WebstorePrivateApi::PopApprovalForTesting(
363       browser()->profile(), extensionId);
364   EXPECT_EQ(extensionId, approval->extension_id);
365   EXPECT_FALSE(approval->use_app_installed_bubble);
366   EXPECT_FALSE(approval->skip_post_install_ui);
367   EXPECT_TRUE(approval->authuser.empty());
368   EXPECT_EQ(browser()->profile(), approval->profile);
369 }
370
371 // http://crbug.com/177163
372 #if defined(OS_WIN) && !defined(NDEBUG)
373 #define MAYBE_InstallTheme DISABLED_InstallTheme
374 #else
375 #define MAYBE_InstallTheme InstallTheme
376 #endif
377 // Tests that themes are installed without an install prompt.
378 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, MAYBE_InstallTheme) {
379   WebstoreInstallListener listener;
380   WebstorePrivateApi::SetWebstoreInstallerDelegateForTesting(&listener);
381   ASSERT_TRUE(RunInstallTest("theme.html", "../../theme.crx"));
382   listener.Wait();
383   ASSERT_TRUE(listener.received_success());
384   ASSERT_EQ("iamefpfkojoapidjnbafmgkgncegbkad", listener.id());
385 }
386
387 // Tests that an error is properly reported when an empty crx is returned.
388 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest, EmptyCrx) {
389   ASSERT_TRUE(RunInstallTest("empty.html", "empty.crx"));
390 }
391
392 class ExtensionWebstoreGetWebGLStatusTest : public InProcessBrowserTest {
393  protected:
394   void RunTest(bool webgl_allowed) {
395     // If Gpu access is disallowed then WebGL will not be available.
396     if (!content::GpuDataManager::GetInstance()->GpuAccessAllowed(NULL))
397       webgl_allowed = false;
398
399     static const char kEmptyArgs[] = "[]";
400     static const char kWebGLStatusAllowed[] = "webgl_allowed";
401     static const char kWebGLStatusBlocked[] = "webgl_blocked";
402     scoped_refptr<WebstorePrivateGetWebGLStatusFunction> function =
403         new WebstorePrivateGetWebGLStatusFunction();
404     scoped_ptr<base::Value> result(utils::RunFunctionAndReturnSingleResult(
405             function.get(), kEmptyArgs, browser()));
406     ASSERT_TRUE(result);
407     EXPECT_EQ(base::Value::TYPE_STRING, result->GetType());
408     std::string webgl_status;
409     EXPECT_TRUE(result->GetAsString(&webgl_status));
410     EXPECT_STREQ(webgl_allowed ? kWebGLStatusAllowed : kWebGLStatusBlocked,
411                  webgl_status.c_str());
412   }
413 };
414
415 // Tests getWebGLStatus function when WebGL is allowed.
416 IN_PROC_BROWSER_TEST_F(ExtensionWebstoreGetWebGLStatusTest, Allowed) {
417   bool webgl_allowed = true;
418   RunTest(webgl_allowed);
419 }
420
421 // Tests getWebGLStatus function when WebGL is blacklisted.
422 IN_PROC_BROWSER_TEST_F(ExtensionWebstoreGetWebGLStatusTest, Blocked) {
423   static const std::string json_blacklist =
424       "{\n"
425       "  \"name\": \"gpu blacklist\",\n"
426       "  \"version\": \"1.0\",\n"
427       "  \"entries\": [\n"
428       "    {\n"
429       "      \"id\": 1,\n"
430       "      \"features\": [\n"
431       "        \"webgl\"\n"
432       "      ]\n"
433       "    }\n"
434       "  ]\n"
435       "}";
436   gpu::GPUInfo gpu_info;
437   content::GpuDataManager::GetInstance()->InitializeForTesting(
438       json_blacklist, gpu_info);
439   EXPECT_TRUE(content::GpuDataManager::GetInstance()->IsFeatureBlacklisted(
440       gpu::GPU_FEATURE_TYPE_WEBGL));
441
442   bool webgl_allowed = false;
443   RunTest(webgl_allowed);
444 }
445
446 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
447                        SignIn_UserGestureRequired) {
448   GURL page_url = GetTestServerURL("sign_in_user_gesture_required.html");
449   ASSERT_TRUE(RunPageTest(page_url.spec()));
450 }
451
452 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
453                        SignIn_MissingContinueUrl) {
454   GURL page_url = GetTestServerURL("sign_in_missing_continue_url.html");
455   ASSERT_TRUE(RunPageTest(page_url.spec()));
456 }
457
458 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
459                        SignIn_InvalidContinueUrl) {
460   GURL page_url = GetTestServerURL("sign_in_invalid_continue_url.html");
461   ASSERT_TRUE(RunPageTest(page_url.spec()));
462 }
463
464 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
465                        SignIn_ContinueUrlOnDifferentOrigin) {
466   GURL page_url =
467       GetTestServerURL("sign_in_continue_url_on_different_origin.html");
468   ASSERT_TRUE(RunPageTest(page_url.spec()));
469 }
470
471 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
472                        SignIn_DisallowedInIncognito) {
473   // Make sure that the test is testing something more than the absence of a
474   // sign-in manager for this profile.
475   ASSERT_TRUE(SigninManagerFactory::GetForProfile(profile()));
476
477   GURL page_url =
478       GetTestServerURL("sign_in_disallowed_in_incognito.html");
479   ASSERT_TRUE(
480       RunPageTest(page_url.spec(), ExtensionApiTest::kFlagUseIncognito));
481 }
482
483 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
484                        SignIn_DisabledWhenWebBasedSigninIsEnabled) {
485   // Make sure that the test is testing something more than the absence of a
486   // sign-in manager for this profile.
487   ASSERT_TRUE(SigninManagerFactory::GetForProfile(profile()));
488
489   CommandLine::ForCurrentProcess()->AppendSwitch(
490       switches::kEnableWebBasedSignin);
491   GURL page_url = GetTestServerURL(
492       "sign_in_disabled_when_web_based_signin_is_enabled.html");
493   ASSERT_TRUE(RunPageTest(page_url.spec()));
494 }
495
496 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
497                        SignIn_AlreadySignedIn) {
498   signin_manager_->SetAuthenticatedUsername("user@example.com");
499   GURL page_url = GetTestServerURL("sign_in_already_signed_in.html");
500   ASSERT_TRUE(RunPageTest(page_url.spec()));
501 }
502
503 // The FakeSignInManager class is not implemented for ChromeOS, so there's no
504 // straightforward way to test these flows on that platform.
505 #if !defined(OS_CHROMEOS)
506 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
507                        SignIn_AuthInProgress_Fails) {
508   // Initiate an authentication that will be in progress when the sign-in API is
509   // called.
510   signin_manager_->set_auth_in_progress("user@example.com");
511
512   // Navigate to the page, which will cause the sign-in API to be called.
513   // Then, complete the authentication in a failed state.
514   ResultCatcher catcher;
515   StartSignInTest("sign_in_auth_in_progress_fails.html");
516   signin_manager_->FailSignin(GoogleServiceAuthError::AuthErrorNone());
517   ASSERT_TRUE(catcher.GetNextResult());
518 }
519
520 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
521                        SignIn_AuthInProgress_MergeSessionFails) {
522   // Initiate an authentication that will be in progress when the sign-in API is
523   // called.
524   signin_manager_->set_auth_in_progress("user@example.com");
525
526   // Navigate to the page, which will cause the sign-in API to be called.
527   // Then, complete the authentication in a successful state.
528   ResultCatcher catcher;
529   StartSignInTest("sign_in_auth_in_progress_merge_session_fails.html");
530   signin_manager_->CompletePendingSignin();
531   token_service_->IssueRefreshTokenForUser("user@example.com", "token");
532   signin_manager_->NotifyMergeSessionObservers(
533       GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE));
534   ASSERT_TRUE(catcher.GetNextResult());
535 }
536
537 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
538                        SignIn_AuthInProgress_Succeeds) {
539   // Initiate an authentication that will be in progress when the sign-in API is
540   // called.
541   signin_manager_->set_auth_in_progress("user@example.com");
542
543   // Navigate to the page, which will cause the sign-in API to be called.
544   // Then, complete the authentication in a successful state.
545   ResultCatcher catcher;
546   StartSignInTest("sign_in_auth_in_progress_succeeds.html");
547   signin_manager_->CompletePendingSignin();
548   token_service_->IssueRefreshTokenForUser("user@example.com", "token");
549   signin_manager_->NotifyMergeSessionObservers(
550       GoogleServiceAuthError::AuthErrorNone());
551   ASSERT_TRUE(catcher.GetNextResult());
552 }
553 #endif  // !defined (OS_CHROMEOS)
554
555 IN_PROC_BROWSER_TEST_F(ExtensionWebstorePrivateApiTest,
556                        SignIn_RedirectToSignIn) {
557   GURL signin_url(
558       "chrome://chrome-signin/?source=5&"
559       "continue=http%3A%2F%2Fwww.example.com%3A" +
560       base::IntToString(test_server()->host_port_pair().port()) +
561       "%2Fcontinue");
562   ui_test_utils::UrlLoadObserver observer(
563       signin_url,
564       content::Source<content::NavigationController>(
565           &GetWebContents()->GetController()));
566   StartSignInTest("sign_in_redirect_to_sign_in.html");
567   observer.Wait();
568
569   // TODO(isherman): Also test the redirect back to the continue URL once
570   // sign-in completes?
571 }
572
573 }  // namespace extensions