identity_apitest.cc revision 116680a4aac90f2aa7413d9095a592090648e557
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <set>
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <string>
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <vector>
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
9a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/command_line.h"
10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/prefs/pref_service.h"
115e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
125e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/identity/identity_api.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/component_loader.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_apitest.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_browsertest.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_function_test_utils.h"
20b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/guest_view/guest_view_base.h"
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/signin/account_reconcilor_factory.h"
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/signin/fake_account_reconcilor.h"
2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/signin/fake_signin_manager.h"
2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
32b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/extensions/api/identity.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
36a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/test/base/test_switches.h"
37e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_manager.h"
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/signin/core/common/profile_management_switches.h"
39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/signin/core/common/signin_pref_names.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_utils.h"
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "extensions/common/id_util.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/google_service_auth_error.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/oauth2_mint_token_flow.h"
46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "grit/browser_resources.h"
47b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/test/spawned_test_server/spawned_test_server.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Return;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::ReturnRef;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace errors = identity_constants;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace utils = extension_function_test_utils;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kAccessToken[] = "auth_token";
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static const char kExtensionId[] = "ext_id";
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// This helps us be able to wait until an UIThreadExtensionFunction calls
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// SendResponse.
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class SendResponseDelegate
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public UIThreadExtensionFunction::DelegateForTests {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SendResponseDelegate() : should_post_quit_(false) {}
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~SendResponseDelegate() {}
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void set_should_post_quit(bool should_quit) {
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    should_post_quit_ = should_quit;
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool HasResponse() {
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return response_.get() != NULL;
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool GetResponse() {
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(HasResponse());
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return *response_.get();
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnSendResponse(UIThreadExtensionFunction* function,
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              bool success,
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              bool bad_message) OVERRIDE {
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_FALSE(bad_message);
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_FALSE(HasResponse());
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response_.reset(new bool);
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *response_ = success;
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (should_post_quit_) {
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::MessageLoopForUI::current()->Quit();
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<bool> response_;
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool should_post_quit_;
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class AsyncExtensionBrowserTest : public ExtensionBrowserTest {
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Asynchronous function runner allows tests to manipulate the browser window
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // after the call happens.
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void RunFunctionAsync(
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      UIThreadExtensionFunction* function,
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& args) {
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response_delegate_.reset(new SendResponseDelegate);
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->set_test_delegate(response_delegate_.get());
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<base::ListValue> parsed_args(utils::ParseList(args));
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(parsed_args.get()) <<
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "Could not parse extension function arguments: " << args;
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->SetArgs(parsed_args.get());
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!function->GetExtension()) {
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scoped_refptr<Extension> empty_extension(
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          utils::CreateEmptyExtension());
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      function->set_extension(empty_extension.get());
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    function->set_browser_context(browser()->profile());
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->set_has_callback(true);
127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    function->Run()->Execute();
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string WaitForError(UIThreadExtensionFunction* function) {
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RunMessageLoopUntilResponse();
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_FALSE(function->GetResultList()) << "Did not expect a result";
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return function->GetError();
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Value* WaitForSingleResult(UIThreadExtensionFunction* function) {
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RunMessageLoopUntilResponse();
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(function->GetError().empty()) << "Unexpected error: "
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                              << function->GetError();
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Value* single_result = NULL;
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (function->GetResultList() != NULL &&
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        function->GetResultList()->Get(0, &single_result)) {
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return single_result->DeepCopy();
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return NULL;
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void RunMessageLoopUntilResponse() {
150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // If the RunAsync of |function| didn't already call SendResponse, run the
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // message loop until they do.
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!response_delegate_->HasResponse()) {
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      response_delegate_->set_should_post_quit(true);
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::RunMessageLoop();
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(response_delegate_->HasResponse());
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<SendResponseDelegate> response_delegate_;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
162e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass TestHangOAuth2MintTokenFlow : public OAuth2MintTokenFlow {
163e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch public:
164e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  TestHangOAuth2MintTokenFlow()
165e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      : OAuth2MintTokenFlow(NULL, NULL, OAuth2MintTokenFlow::Parameters()) {}
166e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
167e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  virtual void Start() OVERRIDE {
168e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // Do nothing, simulating a hanging network call.
169e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
170e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch};
171e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestOAuth2MintTokenFlow : public OAuth2MintTokenFlow {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ResultType {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ISSUE_ADVICE_SUCCESS,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MINT_TOKEN_SUCCESS,
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MINT_TOKEN_FAILURE,
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MINT_TOKEN_BAD_CREDENTIALS,
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MINT_TOKEN_SERVICE_ERROR
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow(ResultType result,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          OAuth2MintTokenFlow::Delegate* delegate)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : OAuth2MintTokenFlow(NULL, delegate, OAuth2MintTokenFlow::Parameters()),
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result_(result),
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(delegate) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Start() OVERRIDE {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (result_) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case ISSUE_ADVICE_SUCCESS: {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IssueAdviceInfo info;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnIssueAdviceSuccess(info);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case MINT_TOKEN_SUCCESS: {
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        delegate_->OnMintTokenSuccess(kAccessToken, 3600);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case MINT_TOKEN_FAILURE: {
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GoogleServiceAuthError error(GoogleServiceAuthError::CONNECTION_FAILED);
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        delegate_->OnMintTokenFailure(error);
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case MINT_TOKEN_BAD_CREDENTIALS: {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GoogleServiceAuthError error(
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnMintTokenFailure(error);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      case MINT_TOKEN_SERVICE_ERROR: {
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        GoogleServiceAuthError error =
213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            GoogleServiceAuthError::FromServiceError("invalid_scope");
214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        delegate_->OnMintTokenFailure(error);
215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        break;
216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResultType result_;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OAuth2MintTokenFlow::Delegate* delegate_;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Waits for a specific GURL to generate a NOTIFICATION_LOAD_STOP event and
2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// saves a pointer to the window embedding the WebContents, which can be later
2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// closed.
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class WaitForGURLAndCloseWindow : public content::WindowedNotificationObserver {
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  explicit WaitForGURLAndCloseWindow(GURL url)
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : WindowedNotificationObserver(
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            content::NOTIFICATION_LOAD_STOP,
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            content::NotificationService::AllSources()),
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        url_(url) {}
235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // NotificationObserver:
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void Observe(int type,
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       const content::NotificationSource& source,
239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE {
240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    content::NavigationController* web_auth_flow_controller =
241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        content::Source<content::NavigationController>(source).ptr();
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    content::WebContents* web_contents =
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        web_auth_flow_controller->GetWebContents();
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (web_contents->GetURL() == url_) {
2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // It is safe to keep the pointer here, because we know in a test, that
2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // the WebContents won't go away before CloseEmbedderWebContents is
2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // called. Don't copy this code to production.
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GuestViewBase* guest = GuestViewBase::FromWebContents(web_contents);
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      embedder_web_contents_ = guest->embedder_web_contents();
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Condtionally invoke parent class so that Wait will not exit
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // until the target URL arrives.
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      content::WindowedNotificationObserver::Observe(type, source, details);
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Closes the window embedding the WebContents. The action is separated from
2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // the Observe method to make sure the list of observers is not deleted,
2597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // while some event is already being processed. (That causes ASAN failures.)
2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void CloseEmbedderWebContents() {
2617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (embedder_web_contents_)
2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      embedder_web_contents_->Close();
2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GURL url_;
2677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  content::WebContents* embedder_web_contents_;
268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockGetAuthTokenFunction : public IdentityGetAuthTokenFunction {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  MockGetAuthTokenFunction() : login_access_token_result_(true),
2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                               login_ui_result_(true),
27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               scope_ui_result_(true),
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               login_ui_shown_(false),
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               scope_ui_shown_(false) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void set_login_access_token_result(bool result) {
2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    login_access_token_result_ = result;
2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void set_login_ui_result(bool result) {
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    login_ui_result_ = result;
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void set_scope_ui_failure(GaiaWebAuthFlow::Failure failure) {
29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_result_ = false;
29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_failure_ = failure;
29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void set_scope_ui_oauth_error(const std::string& oauth_error) {
29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_result_ = false;
29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_failure_ = GaiaWebAuthFlow::OAUTH_ERROR;
29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_oauth_error_ = oauth_error;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool login_ui_shown() const {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return login_ui_shown_;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool scope_ui_shown() const {
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return scope_ui_shown_;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const ExtensionTokenKey* extension_token_key() { return token_key_.get(); }
309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual void StartLoginAccessTokenRequest() OVERRIDE {
3117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (login_access_token_result_) {
3127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      OnGetTokenSuccess(login_token_request_.get(), "access_token",
3137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          base::Time::Now() + base::TimeDelta::FromHours(1LL));
3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    } else {
3157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      GoogleServiceAuthError error(
3167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
3177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      OnGetTokenFailure(login_token_request_.get(), error);
3187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
3197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ShowLoginPopup() OVERRIDE {
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_FALSE(login_ui_shown_);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    login_ui_shown_ = true;
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (login_ui_result_)
3257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      SigninSuccess();
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    else
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SigninFailed();
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ShowOAuthApprovalDialog(
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const IssueAdviceInfo& issue_advice) OVERRIDE {
33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_shown_ = true;
33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (scope_ui_result_) {
33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      OnGaiaFlowCompleted(kAccessToken, "3600");
33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    } else if (scope_ui_failure_ == GaiaWebAuthFlow::SERVICE_AUTH_ERROR) {
33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GoogleServiceAuthError error(GoogleServiceAuthError::CONNECTION_FAILED);
33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      OnGaiaFlowFailure(scope_ui_failure_, error, "");
33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    } else {
34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      OnGaiaFlowFailure(scope_ui_failure_, error, scope_ui_oauth_error_);
34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_CONST_METHOD0(HasLoginToken, bool());
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(CreateMintTokenFlow,
3477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch               OAuth2MintTokenFlow* (const std::string& login_access_token));
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~MockGetAuthTokenFunction() {}
3517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool login_access_token_result_;
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool login_ui_result_;
35390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool scope_ui_result_;
35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GaiaWebAuthFlow::Failure scope_ui_failure_;
35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string scope_ui_oauth_error_;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool login_ui_shown_;
35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool scope_ui_shown_;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// TODO(courage): Replace MockGetAuthTokenFunction with
36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// FakeGetAuthTokenFunction in all tests.
36246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class FakeGetAuthTokenFunction : public IdentityGetAuthTokenFunction {
36446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  FakeGetAuthTokenFunction()
36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      : login_access_token_result_(true),
36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        login_ui_result_(true),
36846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        scope_ui_result_(true),
36946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        login_ui_shown_(false),
37046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        scope_ui_shown_(false) {}
37146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
37246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void set_login_access_token_result(bool result) {
37346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    login_access_token_result_ = result;
37446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
37546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
37646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void set_login_ui_result(bool result) { login_ui_result_ = result; }
37746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
37846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void set_mint_token_flow(scoped_ptr<OAuth2MintTokenFlow> flow) {
37946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    flow_ = flow.Pass();
38046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
38146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
38246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void set_scope_ui_failure(GaiaWebAuthFlow::Failure failure) {
38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scope_ui_result_ = false;
38446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scope_ui_failure_ = failure;
38546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
38646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
38746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void set_scope_ui_oauth_error(const std::string& oauth_error) {
38846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scope_ui_result_ = false;
38946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scope_ui_failure_ = GaiaWebAuthFlow::OAUTH_ERROR;
39046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scope_ui_oauth_error_ = oauth_error;
39146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
39246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
39346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool login_ui_shown() const { return login_ui_shown_; }
39446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
39546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool scope_ui_shown() const { return scope_ui_shown_; }
39646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
39746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::string login_access_token() const { return login_access_token_; }
39846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
39946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void ShowLoginPopup() OVERRIDE {
40046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EXPECT_FALSE(login_ui_shown_);
40146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    login_ui_shown_ = true;
40246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (login_ui_result_)
40346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      SigninSuccess();
40446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    else
40546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      SigninFailed();
40646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
40746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
40846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void ShowOAuthApprovalDialog(
40946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const IssueAdviceInfo& issue_advice) OVERRIDE {
41046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scope_ui_shown_ = true;
41146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
41246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (scope_ui_result_) {
41346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      OnGaiaFlowCompleted(kAccessToken, "3600");
41446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    } else if (scope_ui_failure_ == GaiaWebAuthFlow::SERVICE_AUTH_ERROR) {
41546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      GoogleServiceAuthError error(GoogleServiceAuthError::CONNECTION_FAILED);
41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      OnGaiaFlowFailure(scope_ui_failure_, error, "");
41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    } else {
41846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
41946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      OnGaiaFlowFailure(scope_ui_failure_, error, scope_ui_oauth_error_);
42046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
42146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
42246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
42346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual OAuth2MintTokenFlow* CreateMintTokenFlow(
42446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const std::string& login_access_token) OVERRIDE {
42546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EXPECT_TRUE(login_access_token_.empty());
42646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    login_access_token_ = login_access_token;
42746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return flow_.release();
42846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
42946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
43046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
43146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual ~FakeGetAuthTokenFunction() {}
43246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool login_access_token_result_;
43346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool login_ui_result_;
43446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool scope_ui_result_;
43546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GaiaWebAuthFlow::Failure scope_ui_failure_;
43646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::string scope_ui_oauth_error_;
43746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool login_ui_shown_;
43846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool scope_ui_shown_;
43946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
44046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<OAuth2MintTokenFlow> flow_;
44146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
44246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::string login_access_token_;
44346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
44446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MockQueuedMintRequest : public IdentityMintRequestQueue::Request {
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD1(StartMintToken, void(IdentityMintRequestQueue::MintType));
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
450116680a4aac90f2aa7413d9095a592090648e557Ben Murdochgaia::AccountIds CreateIds(std::string email, std::string obfid) {
451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  gaia::AccountIds ids;
45246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ids.account_key = email;
45346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ids.email = email;
45446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ids.gaia = obfid;
45546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return ids;
45646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
45746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class IdentityGetAccountsFunctionTest : public ExtensionBrowserTest {
459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
46046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ExtensionBrowserTest::SetUpCommandLine(command_line);
461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    command_line->AppendSwitch(switches::kExtensionsMultiAccount);
462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) protected:
465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void SetAccountState(gaia::AccountIds ids, bool is_signed_in) {
466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    IdentityAPI::GetFactoryInstance()->Get(profile())->SetAccountStateForTest(
467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        ids, is_signed_in);
468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  testing::AssertionResult ExpectGetAccounts(
471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const std::vector<std::string>& accounts) {
472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_refptr<IdentityGetAccountsFunction> func(
473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        new IdentityGetAccountsFunction);
474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    func->set_extension(utils::CreateEmptyExtension(kExtensionId).get());
475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!utils::RunFunction(
476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            func.get(), std::string("[]"), browser(), utils::NONE)) {
477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return GenerateFailureResult(accounts, NULL)
478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             << "getAccounts did not return a result.";
479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const base::ListValue* callback_arguments = func->GetResultList();
481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!callback_arguments)
482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return GenerateFailureResult(accounts, NULL) << "NULL result";
483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
484cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (callback_arguments->GetSize() != 1) {
485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return GenerateFailureResult(accounts, NULL)
486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             << "Expected 1 argument but got " << callback_arguments->GetSize();
487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const base::ListValue* results;
490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!callback_arguments->GetList(0, &results))
491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GenerateFailureResult(accounts, NULL) << "Result was not an array";
492cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
493cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::set<std::string> result_ids;
494cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (base::ListValue::const_iterator it = results->begin();
495cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         it != results->end();
496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         ++it) {
497cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      scoped_ptr<api::identity::AccountInfo> info =
498cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          api::identity::AccountInfo::FromValue(**it);
499cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (info.get())
500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        result_ids.insert(info->id);
501cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      else
502cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return GenerateFailureResult(accounts, results);
503cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
504cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (std::vector<std::string>::const_iterator it = accounts.begin();
506cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         it != accounts.end();
507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         ++it) {
508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (result_ids.find(*it) == result_ids.end())
509cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return GenerateFailureResult(accounts, results);
510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
511cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
512cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return testing::AssertionResult(true);
513cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
515cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  testing::AssertionResult GenerateFailureResult(
516cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const ::std::vector<std::string>& accounts,
517cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const base::ListValue* results) {
518cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    testing::Message msg("Expected: ");
519cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (std::vector<std::string>::const_iterator it = accounts.begin();
520cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         it != accounts.end();
521cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         ++it) {
522cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      msg << *it << " ";
523cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
524cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    msg << "Actual: ";
525cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!results) {
526cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      msg << "NULL";
527cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
528cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      for (base::ListValue::const_iterator it = results->begin();
529cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)           it != results->end();
530cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)           ++it) {
531cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        scoped_ptr<api::identity::AccountInfo> info =
532cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            api::identity::AccountInfo::FromValue(**it);
533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (info.get())
534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          msg << info->id << " ";
535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        else
536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          msg << *it << "<-" << (*it)->GetType() << " ";
537cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
538cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
539cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
540cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return testing::AssertionFailure(msg);
541cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
542cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
543cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
544cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(IdentityGetAccountsFunctionTest, MultiAccountOn) {
545cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(switches::IsExtensionsMultiAccount());
546cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
547cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
548cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(IdentityGetAccountsFunctionTest, NoneSignedIn) {
549cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(ExpectGetAccounts(std::vector<std::string>()));
550cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
551cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
552cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(IdentityGetAccountsFunctionTest,
553cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       PrimaryAccountSignedIn) {
554cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetAccountState(CreateIds("primary@example.com", "1"), true);
555cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<std::string> primary;
556cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  primary.push_back("1");
557cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(ExpectGetAccounts(primary));
558cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
559cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
560cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(IdentityGetAccountsFunctionTest, TwoAccountsSignedIn) {
561cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetAccountState(CreateIds("primary@example.com", "1"), true);
562cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetAccountState(CreateIds("secondary@example.com", "2"), true);
563cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<std::string> two_accounts;
564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  two_accounts.push_back("1");
565cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  two_accounts.push_back("2");
566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(ExpectGetAccounts(two_accounts));
567cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
568cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
569cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class IdentityOldProfilesGetAccountsFunctionTest
570cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : public IdentityGetAccountsFunctionTest {
571cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
572cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Don't add the multi-account switch that parent class would have.
573cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
574cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
575cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
576cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(IdentityOldProfilesGetAccountsFunctionTest,
577cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       MultiAccountOff) {
578cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(switches::IsExtensionsMultiAccount());
579cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
580cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
581cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(IdentityOldProfilesGetAccountsFunctionTest,
582cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       TwoAccountsSignedIn) {
583cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetAccountState(CreateIds("primary@example.com", "1"), true);
584cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetAccountState(CreateIds("secondary@example.com", "2"), true);
585cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<std::string> only_primary;
586cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  only_primary.push_back("1");
587cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(ExpectGetAccounts(only_primary));
588cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
589cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
590f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class IdentityGetProfileUserInfoFunctionTest : public ExtensionBrowserTest {
591f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) protected:
592f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<api::identity::ProfileUserInfo> RunGetProfileUserInfo() {
593f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    scoped_refptr<IdentityGetProfileUserInfoFunction> func(
594f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        new IdentityGetProfileUserInfoFunction);
595f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    func->set_extension(utils::CreateEmptyExtension(kExtensionId).get());
596f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    scoped_ptr<base::Value> value(
597f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        utils::RunFunctionAndReturnSingleResult(func.get(), "[]", browser()));
598f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return api::identity::ProfileUserInfo::FromValue(*value.get());
599f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
600116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
601116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<api::identity::ProfileUserInfo> RunGetProfileUserInfoWithEmail() {
602116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_refptr<IdentityGetProfileUserInfoFunction> func(
603116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        new IdentityGetProfileUserInfoFunction);
604116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    func->set_extension(CreateExtensionWithEmailPermission());
605116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_ptr<base::Value> value(
606116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        utils::RunFunctionAndReturnSingleResult(func.get(), "[]", browser()));
607116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return api::identity::ProfileUserInfo::FromValue(*value.get());
608116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
609116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
610116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
611116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<Extension> CreateExtensionWithEmailPermission() {
612116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_ptr<base::DictionaryValue> test_extension_value(
613116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        utils::ParseDictionary(
614116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            "{\"name\": \"Test\", \"version\": \"1.0\", "
615116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            "\"permissions\": [\"identity.email\"]}"));
616116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return utils::CreateExtension(test_extension_value.get());
617116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
618f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
619f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
620f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(IdentityGetProfileUserInfoFunctionTest, NotSignedIn) {
621116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<api::identity::ProfileUserInfo> info =
622116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      RunGetProfileUserInfoWithEmail();
623f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(info->email.empty());
624f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(info->id.empty());
625f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
626f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
627f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(IdentityGetProfileUserInfoFunctionTest, SignedIn) {
628f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  profile()->GetPrefs()
629f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ->SetString(prefs::kGoogleServicesUsername, "president@example.com");
630f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  profile()->GetPrefs()
631f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ->SetString(prefs::kGoogleServicesUserAccountId, "12345");
632f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
633116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<api::identity::ProfileUserInfo> info =
634116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      RunGetProfileUserInfoWithEmail();
635f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ("president@example.com", info->email);
636f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ("12345", info->id);
637f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
638f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
639116680a4aac90f2aa7413d9095a592090648e557Ben MurdochIN_PROC_BROWSER_TEST_F(IdentityGetProfileUserInfoFunctionTest,
640116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       NotSignedInNoEmail) {
641116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<api::identity::ProfileUserInfo> info = RunGetProfileUserInfo();
642116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(info->email.empty());
643116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(info->id.empty());
644116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
645116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
646116680a4aac90f2aa7413d9095a592090648e557Ben MurdochIN_PROC_BROWSER_TEST_F(IdentityGetProfileUserInfoFunctionTest,
647116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       SignedInNoEmail) {
648116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
649116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   "president@example.com");
650116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  profile()->GetPrefs()->SetString(prefs::kGoogleServicesUserAccountId,
651116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   "12345");
652116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
653116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<api::identity::ProfileUserInfo> info = RunGetProfileUserInfo();
654116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(info->email.empty());
655116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ("12345", info->id);
656116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
657116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class GetAuthTokenFunctionTest : public AsyncExtensionBrowserTest {
65946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
66046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
66146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    AsyncExtensionBrowserTest::SetUpCommandLine(command_line);
66246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    command_line->AppendSwitch(switches::kExtensionsMultiAccount);
66346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
66446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
66546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
66646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    AsyncExtensionBrowserTest::SetUpInProcessBrowserTestFixture();
66746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
66846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    will_create_browser_context_services_subscription_ =
66946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        BrowserContextDependencyManager::GetInstance()
67046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            ->RegisterWillCreateBrowserContextServicesCallbackForTesting(
67146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                  base::Bind(&GetAuthTokenFunctionTest::
67246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                 OnWillCreateBrowserContextServices,
67346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                             base::Unretained(this)))
67446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            .Pass();
67546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
67646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
67746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void OnWillCreateBrowserContextServices(content::BrowserContext* context) {
67846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // Replace the signin manager and token service with fakes. Do this ahead of
67946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // creating the browser so that a bunch of classes don't register as
68046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // observers and end up needing to unregister when the fake is substituted.
68146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SigninManagerFactory::GetInstance()->SetTestingFactory(
68246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        context, &FakeSigninManagerBase::Build);
68346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ProfileOAuth2TokenServiceFactory::GetInstance()->SetTestingFactory(
68446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        context, &BuildFakeProfileOAuth2TokenService);
685116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    AccountReconcilorFactory::GetInstance()->SetTestingFactory(
686116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        context, &FakeAccountReconcilor::Build);
68746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
68846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
68946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void SetUpOnMainThread() OVERRIDE {
69046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    AsyncExtensionBrowserTest::SetUpOnMainThread();
69146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
69246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // Grab references to the fake signin manager and token service.
69346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    signin_manager_ = static_cast<FakeSigninManagerForTesting*>(
69446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        SigninManagerFactory::GetInstance()->GetForProfile(profile()));
69546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_TRUE(signin_manager_);
69646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    token_service_ = static_cast<FakeProfileOAuth2TokenService*>(
69746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        ProfileOAuth2TokenServiceFactory::GetInstance()->GetForProfile(
69846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            profile()));
69946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ASSERT_TRUE(token_service_);
70046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
70146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
70246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SignIn(const std::string account_key) {
70346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(OS_CHROMEOS)
70446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    signin_manager_->SetAuthenticatedUsername(account_key);
70546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#else
70646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    signin_manager_->SignIn(account_key, "password");
70746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif
70846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
70946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
710116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void SetAccountState(gaia::AccountIds ids, bool is_signed_in) {
71146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    IdentityAPI::GetFactoryInstance()->Get(profile())->SetAccountStateForTest(
71246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        ids, is_signed_in);
71346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
71446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum OAuth2Fields {
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NONE = 0,
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CLIENT_ID = 1,
719eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SCOPES = 2,
720eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    AS_COMPONENT = 4
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  FakeSigninManagerForTesting* signin_manager_;
72446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  FakeProfileOAuth2TokenService* token_service_;
72546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~GetAuthTokenFunctionTest() {}
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper to create an extension with specific OAuth2Info fields set.
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |fields_to_set| should be computed by using fields of Oauth2Fields enum.
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* CreateExtension(int fields_to_set) {
731eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const Extension* ext;
732eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::FilePath manifest_path =
733eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        test_data_dir_.AppendASCII("platform_apps/oauth2");
734eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::FilePath component_manifest_path =
735eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        test_data_dir_.AppendASCII("packaged_app/component_oauth2");
736eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if ((fields_to_set & AS_COMPONENT) == 0)
737eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ext = LoadExtension(manifest_path);
738eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    else
739eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ext = LoadExtensionAsComponent(component_manifest_path);
740eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    OAuth2Info& oauth2_info =
741eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        const_cast<OAuth2Info&>(OAuth2Info::GetOAuth2Info(ext));
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((fields_to_set & CLIENT_ID) != 0)
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      oauth2_info.client_id = "client1";
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((fields_to_set & SCOPES) != 0) {
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      oauth2_info.scopes.push_back("scope1");
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      oauth2_info.scopes.push_back("scope2");
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
748a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
749a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    extension_id_ = ext->id();
750a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    oauth_scopes_ = std::set<std::string>(oauth2_info.scopes.begin(),
751a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          oauth2_info.scopes.end());
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ext;
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api() {
756a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return IdentityAPI::GetFactoryInstance()->Get(browser()->profile());
757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
758a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
759a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string GetPrimaryAccountId() {
7605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SigninManagerBase* signin_manager =
7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        SigninManagerFactory::GetForProfile(browser()->profile());
7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return signin_manager->GetAuthenticatedAccountId();
763a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
764a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
765a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void SetCachedToken(const IdentityTokenCacheValue& token_data) {
766a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ExtensionTokenKey key(extension_id_, GetPrimaryAccountId(), oauth_scopes_);
767a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    id_api()->SetCachedToken(key, token_data);
768a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
769a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
77046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const IdentityTokenCacheValue& GetCachedToken(std::string account_id) {
77146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (account_id.empty())
77246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      account_id = GetPrimaryAccountId();
77346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ExtensionTokenKey key(extension_id_, account_id, oauth_scopes_);
774a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return id_api()->GetCachedToken(key);
775a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
776a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
777a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void QueueRequestStart(IdentityMintRequestQueue::MintType type,
778a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         IdentityMintRequestQueue::Request* request) {
779a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ExtensionTokenKey key(extension_id_, GetPrimaryAccountId(), oauth_scopes_);
780a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    id_api()->mint_queue()->RequestStart(type, key, request);
781a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
782a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
783a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void QueueRequestComplete(IdentityMintRequestQueue::MintType type,
784a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            IdentityMintRequestQueue::Request* request) {
785a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ExtensionTokenKey key(extension_id_, GetPrimaryAccountId(), oauth_scopes_);
786a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    id_api()->mint_queue()->RequestComplete(type, key, request);
787a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
788a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
789a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private:
790a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string extension_id_;
791a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::set<std::string> oauth_scopes_;
79246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
79346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<base::CallbackList<void(content::BrowserContext*)>::Subscription>
79446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      will_create_browser_context_services_subscription_;
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NoClientId) {
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(SCOPES));
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kInvalidClientId), error);
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
80590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NoScopes) {
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID));
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kInvalidScopes), error);
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
81690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NonInteractiveNotSignedIn) {
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
82890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NonInteractiveMintFailure) {
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_FAILURE, func.get());
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
84490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
8487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       NonInteractiveLoginAccessTokenFailure) {
8497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
8507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
8517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_CALL(*func.get(), HasLoginToken())
8527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      .WillOnce(Return(true));
8537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  func->set_login_access_token_result(false);
8547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string error = utils::RunFunctionAndReturnError(
8557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      func.get(), "[{}]", browser());
8567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
8577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
8587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
8597dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochIN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveMintAdviceSuccess) {
861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
863868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
864868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kNoGrant), error);
871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
87290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
874a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_ADVICE,
87546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            GetCachedToken(std::string()).status());
876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveMintBadCredentials) {
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_BAD_CREDENTIALS, func.get());
886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
89190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
892a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
893a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
894a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
895a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       NonInteractiveMintServiceError) {
896a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
897a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
898a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
899a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
900a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SERVICE_ERROR, func.get());
901a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
902a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string error =
903a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      utils::RunFunctionAndReturnError(func.get(), "[{}]", browser());
904a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
905a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
906a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
910f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       NoOptionsSuccess) {
911f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_WIN) && defined(USE_ASH)
912f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
913f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
914f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
915f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif
916f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
917f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
918f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
919f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  func->set_extension(extension.get());
920f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
921f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
922f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
923f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
924f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
925f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      func.get(), "[]", browser()));
926f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::string access_token;
927f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
928f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
929f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
930f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
931f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
932f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            GetCachedToken(std::string()).status());
933f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
934f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
935f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveSuccess) {
937ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(OS_WIN) && defined(USE_ASH)
938ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
939a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
940ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return;
941ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif
942ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
945868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
946868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser()));
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string access_token;
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
95690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
95846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            GetCachedToken(std::string()).status());
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginCanceled) {
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(false);
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
97190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveMintBadCredentialsLoginCanceled) {
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_BAD_CREDENTIALS, func.get());
982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(false);
984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
98890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveLoginSuccessNoToken) {
993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(false);
997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
1000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
100190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
1002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
1005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveLoginSuccessMintFailure) {
1006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
1008c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
1009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
1010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
1011c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_FAILURE, func.get());
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
101890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
10227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       InteractiveLoginSuccessLoginAccessTokenFailure) {
10237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
10247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
10257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
10267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  func->set_login_ui_result(true);
10277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  func->set_login_access_token_result(false);
10287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string error = utils::RunFunctionAndReturnError(
10297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      func.get(), "[{\"interactive\": true}]", browser());
10307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
10317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(func->login_ui_shown());
10327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(func->scope_ui_shown());
10337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
10347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
10357dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochIN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginSuccessMintSuccess) {
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
1040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
1041c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string access_token;
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
105190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginSuccessApprovalAborted) {
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
1059c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
1060c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
106490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::WINDOW_CLOSED);
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserRejected), error);
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
106990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
107390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveLoginSuccessApprovalSuccess) {
1074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
107590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1076868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
1077868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
1078c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
107990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
108290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(Return(flow));
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string access_token;
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
109090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveApprovalAborted) {
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
110290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::WINDOW_CLOSED);
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserRejected), error);
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
110790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
1111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       InteractiveApprovalLoadFailed) {
1112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
1114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
1115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      .WillOnce(Return(true));
1116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
1117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
1118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
1119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::LOAD_FAILED);
1120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
1121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
1122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kPageLoadFailure), error);
1123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
1124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
1125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
112890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveApprovalInvalidRedirect) {
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
113390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
113590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
113690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::INVALID_REDIRECT);
113790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
113890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
113990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kInvalidRedirect), error);
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
114190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
114590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveApprovalConnectionFailure) {
1146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
1148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
1149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
115090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
1151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
115290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
115390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::SERVICE_AUTH_ERROR);
1154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
1155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
1156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
1157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
115890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
115990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
116090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
116190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
116290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveApprovalOAuthErrors) {
116390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
116490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
116590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::map<std::string, std::string> error_map;
116690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  error_map.insert(std::make_pair("access_denied", errors::kUserRejected));
116790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  error_map.insert(std::make_pair("invalid_scope", errors::kInvalidScopes));
116890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  error_map.insert(std::make_pair(
116990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "unmapped_error", std::string(errors::kAuthFailure) + "unmapped_error"));
117090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
117190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (std::map<std::string, std::string>::const_iterator
117290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)           it = error_map.begin();
117390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       it != error_map.end();
117490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       ++it) {
117590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scoped_refptr<MockGetAuthTokenFunction> func(
117690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        new MockGetAuthTokenFunction());
1177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    func->set_extension(extension.get());
117890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
1179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Make sure we don't get a cached issue_advice result, which would cause
1180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // flow to be leaked.
1181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    id_api()->EraseAllCachedTokens();
118290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
118390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
1184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
118590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    func->set_scope_ui_oauth_error(it->first);
118690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::string error = utils::RunFunctionAndReturnError(
118790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        func.get(), "[{\"interactive\": true}]", browser());
118890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(it->second, error);
118990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_FALSE(func->login_ui_shown());
119090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_TRUE(func->scope_ui_shown());
119190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
119290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
119390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
119490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
119590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveApprovalSuccess) {
119690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
119790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
1199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
120090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
120190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
120290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
120390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(Return(flow));
120490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
120590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
120690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
120790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string access_token;
120890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
120990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
121090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
121190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
121290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
121390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
121446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            GetCachedToken(std::string()).status());
1215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, NoninteractiveQueue) {
1218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
1219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
1221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the queue.
1223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
1224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
1225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE;
1226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
1228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QueueRequestStart(type, &queued_request);
1229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The real request will start processing, but wait in the queue behind
1231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the blocker.
1232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
1233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunFunctionAsync(func.get(), "[{}]");
1234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify that we have fetched the login token at this point.
1235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  testing::Mock::VerifyAndClearExpectations(func.get());
1236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The flow will be created after the first queued request clears.
1238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
1239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
1240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QueueRequestComplete(type, &queued_request);
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func.get()));
1245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
1246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
1247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
1248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
124990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
1250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, InteractiveQueue) {
1253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
1254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
1256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the queue.
1258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
1259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
1260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
1261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
1263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QueueRequestStart(type, &queued_request);
1264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The real request will start processing, but wait in the queue behind
1266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the blocker.
1267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
1268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow1 = new TestOAuth2MintTokenFlow(
1269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
1270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow1));
1271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunFunctionAsync(func.get(), "[{\"interactive\": true}]");
1272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify that we have fetched the login token and run the first flow.
1273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  testing::Mock::VerifyAndClearExpectations(func.get());
127490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
1275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
127690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // The UI will be displayed and a token retrieved after the first
127790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // queued request clears.
1278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QueueRequestComplete(type, &queued_request);
1279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func.get()));
1281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
1282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
1283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
1284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
128590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
1286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1288e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochIN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, InteractiveQueueShutdown) {
1289e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
1290e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1291e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  func->set_extension(extension.get());
1292e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1293e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Create a fake request to block the queue.
1294e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  MockQueuedMintRequest queued_request;
1295e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  IdentityMintRequestQueue::MintType type =
1296e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
1297e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1298e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
1299e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  QueueRequestStart(type, &queued_request);
1300e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1301e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // The real request will start processing, but wait in the queue behind
1302e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // the blocker.
1303e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
1304e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  TestOAuth2MintTokenFlow* flow1 = new TestOAuth2MintTokenFlow(
1305e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
1306e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow1));
1307e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  RunFunctionAsync(func.get(), "[{\"interactive\": true}]");
1308e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Verify that we have fetched the login token and run the first flow.
1309e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  testing::Mock::VerifyAndClearExpectations(func.get());
1310e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_FALSE(func->scope_ui_shown());
1311e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1312e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // After the request is canceled, the function will complete.
1313e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  func->OnShutdown();
1314e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(std::string(errors::kCanceled), WaitForError(func.get()));
1315e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_FALSE(func->login_ui_shown());
1316e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_FALSE(func->scope_ui_shown());
1317e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1318e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  QueueRequestComplete(type, &queued_request);
1319e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
1320e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1321e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochIN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, NoninteractiveShutdown) {
1322e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
1323e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1324e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  func->set_extension(extension.get());
1325e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1326e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
1327e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  TestHangOAuth2MintTokenFlow* flow = new TestHangOAuth2MintTokenFlow();
1328e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
1329e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  RunFunctionAsync(func.get(), "[{\"interactive\": false}]");
1330e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1331e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // After the request is canceled, the function will complete.
1332e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  func->OnShutdown();
1333e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(std::string(errors::kCanceled), WaitForError(func.get()));
1334e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
1335e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
1337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveQueuedNoninteractiveFails) {
1338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
1339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
1341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the interactive queue.
1343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
1344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
1345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
1346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
1348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QueueRequestStart(type, &queued_request);
1349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Non-interactive requests fail without hitting GAIA, because a
1351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // consent UI is known to be up.
1352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
1353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
1354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
1355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kNoGrant), error);
1356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
135790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
1358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QueueRequestComplete(type, &queued_request);
1360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
1363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveCacheHit) {
1364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
1365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
1367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pre-populate the cache with a token
1369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
1370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
1371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetCachedToken(token);
1372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Get a token. Should not require a GAIA request.
1374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
1375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
1376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
1377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser()));
1378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
1379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
1380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
1381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
138290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
1383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
1386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveIssueAdviceCacheHit) {
1387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
1388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
1390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pre-populate the cache with advice
1392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IssueAdviceInfo info;
1393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(info);
1394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetCachedToken(token);
1395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Should return an error without a GAIA request.
1397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
1398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
1399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
1400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
1401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kNoGrant), error);
1402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
140390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
1404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
1407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveCacheHit) {
1408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
1409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
1411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the queue.
1413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
1414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
1415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
1416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
1418a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QueueRequestStart(type, &queued_request);
1419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The real request will start processing, but wait in the queue behind
1421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the blocker.
1422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
1423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
1424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
1425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
1426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunFunctionAsync(func.get(), "[{\"interactive\": true}]");
1427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Populate the cache with a token while the request is blocked.
1429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
1430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
1431a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetCachedToken(token);
1432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // When we wake up the request, it returns the cached token without
1434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // displaying a UI, or hitting GAIA.
1435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QueueRequestComplete(type, &queued_request);
1437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func.get()));
1439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
1440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
1441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
1442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
144390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
1444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
1447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       LoginInvalidatesTokenCache) {
1448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
1450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
1451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pre-populate the cache with a token
1453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
1454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
1455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetCachedToken(token);
1456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Because the user is not signed in, the token will be removed,
1458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // and we'll hit GAIA for new tokens.
1459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
1460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
1461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
146290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
1463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
1464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
146590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(Return(flow));
1466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
1468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
1469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
1470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
1471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
1472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
147390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
1474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
147546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            GetCachedToken(std::string()).status());
1476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochIN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ComponentWithChromeClientId) {
1479eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1480eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<const Extension> extension(
1481eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateExtension(SCOPES | AS_COMPONENT));
1482eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  func->set_extension(extension.get());
1483eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
1484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(oauth2_info.client_id.empty());
1485eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_FALSE(func->GetOAuth2ClientId().empty());
1486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_NE("client1", func->GetOAuth2ClientId());
1487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochIN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ComponentWithNormalClientId) {
1490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<const Extension> extension(
1492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateExtension(CLIENT_ID | SCOPES | AS_COMPONENT));
1493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  func->set_extension(extension.get());
1494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ("client1", func->GetOAuth2ClientId());
1495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
149746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, MultiDefaultUser) {
149846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SignIn("primary@example.com");
149946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  token_service_->IssueRefreshTokenForUser("primary@example.com",
150046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                           "refresh_token");
150146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SetAccountState(CreateIds("primary@example.com", "1"), true);
150246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SetAccountState(CreateIds("secondary@example.com", "2"), true);
150346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
150446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
150546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
150646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  func->set_extension(extension.get());
150746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  func->set_mint_token_flow(
150846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      scoped_ptr<OAuth2MintTokenFlow>(new TestOAuth2MintTokenFlow(
150946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get())));
151046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
151146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  RunFunctionAsync(func.get(), "[{}]");
151246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
151346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  token_service_->IssueAllTokensForAccount(
151446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      "primary@example.com",
151546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      "access_token-primary@example.com",
151646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Time::Now() + base::TimeDelta::FromSeconds(3600));
151746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
151846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func.get()));
151946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::string access_token;
152046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
152146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
152246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
152346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            GetCachedToken(std::string()).status());
152446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ("access_token-primary@example.com", func->login_access_token());
152546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
152646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
152746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, MultiPrimaryUser) {
152846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SignIn("primary@example.com");
152946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  token_service_->IssueRefreshTokenForUser("primary@example.com",
153046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                           "refresh_token");
153146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SetAccountState(CreateIds("primary@example.com", "1"), true);
153246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SetAccountState(CreateIds("secondary@example.com", "2"), true);
153346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
153446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
153546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
153646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  func->set_extension(extension.get());
153746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  func->set_mint_token_flow(
153846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      scoped_ptr<OAuth2MintTokenFlow>(new TestOAuth2MintTokenFlow(
153946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get())));
154046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
154146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  RunFunctionAsync(func.get(), "[{\"account\": { \"id\": \"1\" } }]");
154246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
154346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  token_service_->IssueAllTokensForAccount(
154446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      "primary@example.com",
154546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      "access_token-primary@example.com",
154646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Time::Now() + base::TimeDelta::FromSeconds(3600));
154746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
154846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func.get()));
154946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::string access_token;
155046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
155146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
155246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
155346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            GetCachedToken(std::string()).status());
155446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ("access_token-primary@example.com", func->login_access_token());
155546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
155646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
155746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, MultiSecondaryUser) {
155846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SignIn("primary@example.com");
155946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  token_service_->IssueRefreshTokenForUser("secondary@example.com",
156046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                           "refresh_token");
156146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SetAccountState(CreateIds("primary@example.com", "1"), true);
156246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SetAccountState(CreateIds("secondary@example.com", "2"), true);
156346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
156446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
156546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
156646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  func->set_extension(extension.get());
156746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  func->set_mint_token_flow(
156846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      scoped_ptr<OAuth2MintTokenFlow>(new TestOAuth2MintTokenFlow(
156946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get())));
157046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
157146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  RunFunctionAsync(func.get(), "[{\"account\": { \"id\": \"2\" } }]");
157246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
157346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  token_service_->IssueAllTokensForAccount(
157446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      "secondary@example.com",
157546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      "access_token-secondary@example.com",
157646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Time::Now() + base::TimeDelta::FromSeconds(3600));
157746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
157846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func.get()));
157946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::string access_token;
158046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
158146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
158246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
158346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            GetCachedToken("secondary@example.com").status());
158446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ("access_token-secondary@example.com", func->login_access_token());
158546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
158646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
158746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// TODO(courage): negative cases for secondary accounts
158846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1589f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ScopesDefault) {
1590f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1591f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
1592f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  func->set_extension(extension.get());
1593f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
1594f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
1595f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
1596f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
1597f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<base::Value> value(
1598f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      utils::RunFunctionAndReturnSingleResult(func.get(), "[{}]", browser()));
1599f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::string access_token;
1600f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
1601f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
1602f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1603f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const ExtensionTokenKey* token_key = func->extension_token_key();
1604f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(2ul, token_key->scopes.size());
1605f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(token_key->scopes, "scope1"));
1606f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(token_key->scopes, "scope2"));
1607f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
1608f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1609f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ScopesEmpty) {
1610f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1611f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
1612f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  func->set_extension(extension.get());
1613f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1614f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::string error(utils::RunFunctionAndReturnError(
1615f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      func.get(), "[{\"scopes\": []}]", browser()));
1616f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1617f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(errors::kInvalidScopes, error);
1618f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
1619f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1620f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ScopesEmail) {
1621f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1622f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
1623f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  func->set_extension(extension.get());
1624f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
1625f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
1626f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
1627f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
1628f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
1629f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      func.get(), "[{\"scopes\": [\"email\"]}]", browser()));
1630f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::string access_token;
1631f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
1632f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
1633f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1634f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const ExtensionTokenKey* token_key = func->extension_token_key();
1635f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(1ul, token_key->scopes.size());
1636f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(token_key->scopes, "email"));
1637f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
1638f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1639f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ScopesEmailFooBar) {
1640f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1641f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
1642f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  func->set_extension(extension.get());
1643f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
1644f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
1645f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
1646f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
1647f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
1648f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      func.get(), "[{\"scopes\": [\"email\", \"foo\", \"bar\"]}]", browser()));
1649f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::string access_token;
1650f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
1651f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
1652f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1653f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const ExtensionTokenKey* token_key = func->extension_token_key();
1654f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(3ul, token_key->scopes.size());
1655f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(token_key->scopes, "email"));
1656f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(token_key->scopes, "foo"));
1657f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(token_key->scopes, "bar"));
1658f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
1659f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class RemoveCachedAuthTokenFunctionTest : public ExtensionBrowserTest {
1661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
1662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool InvalidateDefaultToken() {
1663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<IdentityRemoveCachedAuthTokenFunction> func(
1664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        new IdentityRemoveCachedAuthTokenFunction);
16657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    func->set_extension(utils::CreateEmptyExtension(kExtensionId).get());
1666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return utils::RunFunction(
1667868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        func.get(),
1668868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        std::string("[{\"token\": \"") + kAccessToken + "\"}]",
1669868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        browser(),
1670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        extension_function_test_utils::NONE);
1671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api() {
1674a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return IdentityAPI::GetFactoryInstance()->Get(browser()->profile());
1675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void SetCachedToken(IdentityTokenCacheValue& token_data) {
1678a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ExtensionTokenKey key(extensions::id_util::GenerateId(kExtensionId),
1679a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          "test@example.com",
1680a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          std::set<std::string>());
1681a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    id_api()->SetCachedToken(key, token_data);
1682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const IdentityTokenCacheValue& GetCachedToken() {
1685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return id_api()->GetCachedToken(
1686a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        ExtensionTokenKey(extensions::id_util::GenerateId(kExtensionId),
1687a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          "test@example.com",
1688a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          std::set<std::string>()));
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, NotFound) {
1693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
1694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND,
1695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
1696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, Advice) {
1699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IssueAdviceInfo info;
1700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue advice(info);
1701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetCachedToken(advice);
1702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
1703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_ADVICE,
1704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
1705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, NonMatchingToken) {
1708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token("non_matching_token",
1709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
1710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetCachedToken(token);
1711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
1712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
1713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
1714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("non_matching_token", GetCachedToken().token());
1715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, MatchingToken) {
1718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
1719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
1720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetCachedToken(token);
1721a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
1722a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            GetCachedToken().status());
1723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
1724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND,
1725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
1726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class LaunchWebAuthFlowFunctionTest : public AsyncExtensionBrowserTest {
1729b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) public:
1730b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
173146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    AsyncExtensionBrowserTest::SetUpCommandLine(command_line);
1732b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // Reduce performance test variance by disabling background networking.
1733b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    command_line->AppendSwitch(switches::kDisableBackgroundNetworking);
1734b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
1735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
1736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, UserCloseWindow) {
1738b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  net::SpawnedTestServer https_server(
1739b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
1740b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
1741b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL(
1742b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          "chrome/test/data/extensions/api_test/identity")));
1743b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_TRUE(https_server.Start());
1744b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GURL auth_url(https_server.GetURL("files/interaction_required.html"));
1745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1748b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1749b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      utils::CreateEmptyExtension());
1750b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  function->set_extension(empty_extension.get());
1751b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1752868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  WaitForGURLAndCloseWindow popup_observer(auth_url);
1753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1754b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string args = "[{\"interactive\": true, \"url\": \"" +
1755b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      auth_url.spec() + "\"}]";
1756868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunFunctionAsync(function.get(), args);
1757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1758b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  popup_observer.Wait();
17597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  popup_observer.CloseEmbedderWebContents();
1760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1761868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserRejected), WaitForError(function.get()));
1762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, InteractionRequired) {
1765b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  net::SpawnedTestServer https_server(
1766b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
1767b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
1768b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL(
1769b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          "chrome/test/data/extensions/api_test/identity")));
1770b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_TRUE(https_server.Start());
1771b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GURL auth_url(https_server.GetURL("files/interaction_required.html"));
1772b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1779b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string args = "[{\"interactive\": false, \"url\": \"" +
1780b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      auth_url.spec() + "\"}]";
1781868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string error =
1782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      utils::RunFunctionAndReturnError(function.get(), args, browser());
1783868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1784868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kInteractionRequired), error);
1785868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1786868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1787868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, LoadFailed) {
1788868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net::SpawnedTestServer https_server(
1789868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
1790868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
1791868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL(
1792868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          "chrome/test/data/extensions/api_test/identity")));
1793868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(https_server.Start());
1794868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GURL auth_url(https_server.GetURL("files/five_hundred.html"));
1795868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1796868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1797868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1798868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1799868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      utils::CreateEmptyExtension());
1800868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  function->set_extension(empty_extension.get());
1801868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1802868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string args = "[{\"interactive\": true, \"url\": \"" +
1803868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      auth_url.spec() + "\"}]";
18047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::string error =
18057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      utils::RunFunctionAndReturnError(function.get(), args, browser());
1806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1807868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kPageLoadFailure), error);
1808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, NonInteractiveSuccess) {
1811558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(OS_WIN) && defined(USE_ASH)
1812558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
1813a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
1814558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return;
1815558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
1816558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1820c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1823b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  function->InitFinalRedirectURLPrefixForTest("abcdefghij");
1824c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
1825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      function.get(),
1826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "[{\"interactive\": false,"
1827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "\"url\": \"https://abcdefghij.chromiumapp.org/callback#test\"}]",
1828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      browser()));
1829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string url;
1831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&url));
1832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"),
1833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            url);
1834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(
1837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LaunchWebAuthFlowFunctionTest, InteractiveFirstNavigationSuccess) {
1838ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(OS_WIN) && defined(USE_ASH)
1839ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
1840a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
1841ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return;
1842ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif
1843ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
1844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1850b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  function->InitFinalRedirectURLPrefixForTest("abcdefghij");
1851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
1852868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      function.get(),
1853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "[{\"interactive\": true,"
1854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "\"url\": \"https://abcdefghij.chromiumapp.org/callback#test\"}]",
1855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      browser()));
1856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string url;
1858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&url));
1859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"),
1860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            url);
1861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1863cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest,
1864cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       DISABLED_InteractiveSecondNavigationSuccess) {
1865b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  net::SpawnedTestServer https_server(
1866b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
1867b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
1868b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL(
1869b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          "chrome/test/data/extensions/api_test/identity")));
1870b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_TRUE(https_server.Start());
1871b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GURL auth_url(https_server.GetURL("files/redirect_to_chromiumapp.html"));
1872b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1879b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  function->InitFinalRedirectURLPrefixForTest("abcdefghij");
1880b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string args = "[{\"interactive\": true, \"url\": \"" +
1881b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      auth_url.spec() + "\"}]";
1882868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::Value> value(
1883868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      utils::RunFunctionAndReturnSingleResult(function.get(), args, browser()));
1884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string url;
1886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&url));
1887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"),
1888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            url);
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace extensions
1892f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1893f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Tests the chrome.identity API implemented by custom JS bindings .
1894f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeIdentityJsBindings) {
1895f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(RunExtensionTest("identity/js_bindings")) << message_;
1896f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1897