identity_apitest.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
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)
5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/command_line.h"
65e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
75e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/identity/identity_api.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/component_loader.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_apitest.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_browsertest.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_function_test_utils.h"
15b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
20b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/test/base/test_switches.h"
24e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_manager.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_utils.h"
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "extensions/common/id_util.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/google_service_auth_error.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/oauth2_mint_token_flow.h"
31b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "grit/browser_resources.h"
32b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/test/spawned_test_server/spawned_test_server.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Return;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::ReturnRef;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace errors = identity_constants;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace utils = extension_function_test_utils;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kAccessToken[] = "auth_token";
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static const char kExtensionId[] = "ext_id";
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This helps us be able to wait until an AsyncExtensionFunction calls
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// SendResponse.
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class SendResponseDelegate
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public UIThreadExtensionFunction::DelegateForTests {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SendResponseDelegate() : should_post_quit_(false) {}
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~SendResponseDelegate() {}
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void set_should_post_quit(bool should_quit) {
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    should_post_quit_ = should_quit;
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool HasResponse() {
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return response_.get() != NULL;
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool GetResponse() {
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(HasResponse());
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return *response_.get();
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnSendResponse(UIThreadExtensionFunction* function,
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              bool success,
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              bool bad_message) OVERRIDE {
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_FALSE(bad_message);
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_FALSE(HasResponse());
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response_.reset(new bool);
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *response_ = success;
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (should_post_quit_) {
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::MessageLoopForUI::current()->Quit();
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<bool> response_;
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool should_post_quit_;
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class AsyncExtensionBrowserTest : public ExtensionBrowserTest {
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Asynchronous function runner allows tests to manipulate the browser window
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // after the call happens.
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void RunFunctionAsync(
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      UIThreadExtensionFunction* function,
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& args) {
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response_delegate_.reset(new SendResponseDelegate);
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->set_test_delegate(response_delegate_.get());
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<base::ListValue> parsed_args(utils::ParseList(args));
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(parsed_args.get()) <<
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "Could not parse extension function arguments: " << args;
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->SetArgs(parsed_args.get());
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!function->GetExtension()) {
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scoped_refptr<Extension> empty_extension(
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          utils::CreateEmptyExtension());
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      function->set_extension(empty_extension.get());
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    function->set_browser_context(browser()->profile());
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->set_has_callback(true);
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->Run();
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string WaitForError(UIThreadExtensionFunction* function) {
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RunMessageLoopUntilResponse();
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_FALSE(function->GetResultList()) << "Did not expect a result";
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return function->GetError();
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Value* WaitForSingleResult(UIThreadExtensionFunction* function) {
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RunMessageLoopUntilResponse();
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(function->GetError().empty()) << "Unexpected error: "
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                              << function->GetError();
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Value* single_result = NULL;
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (function->GetResultList() != NULL &&
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        function->GetResultList()->Get(0, &single_result)) {
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return single_result->DeepCopy();
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return NULL;
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void RunMessageLoopUntilResponse() {
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If the RunImpl of |function| didn't already call SendResponse, run the
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // message loop until they do.
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!response_delegate_->HasResponse()) {
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      response_delegate_->set_should_post_quit(true);
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::RunMessageLoop();
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(response_delegate_->HasResponse());
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<SendResponseDelegate> response_delegate_;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
147e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass TestHangOAuth2MintTokenFlow : public OAuth2MintTokenFlow {
148e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch public:
149e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  TestHangOAuth2MintTokenFlow()
150e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      : OAuth2MintTokenFlow(NULL, NULL, OAuth2MintTokenFlow::Parameters()) {}
151e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
152e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  virtual void Start() OVERRIDE {
153e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // Do nothing, simulating a hanging network call.
154e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
155e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch};
156e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestOAuth2MintTokenFlow : public OAuth2MintTokenFlow {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ResultType {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ISSUE_ADVICE_SUCCESS,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MINT_TOKEN_SUCCESS,
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MINT_TOKEN_FAILURE,
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MINT_TOKEN_BAD_CREDENTIALS,
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MINT_TOKEN_SERVICE_ERROR
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow(ResultType result,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          OAuth2MintTokenFlow::Delegate* delegate)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : OAuth2MintTokenFlow(NULL, delegate, OAuth2MintTokenFlow::Parameters()),
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result_(result),
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(delegate) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Start() OVERRIDE {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (result_) {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case ISSUE_ADVICE_SUCCESS: {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IssueAdviceInfo info;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnIssueAdviceSuccess(info);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case MINT_TOKEN_SUCCESS: {
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        delegate_->OnMintTokenSuccess(kAccessToken, 3600);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case MINT_TOKEN_FAILURE: {
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GoogleServiceAuthError error(GoogleServiceAuthError::CONNECTION_FAILED);
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        delegate_->OnMintTokenFailure(error);
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case MINT_TOKEN_BAD_CREDENTIALS: {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GoogleServiceAuthError error(
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnMintTokenFailure(error);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      case MINT_TOKEN_SERVICE_ERROR: {
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        GoogleServiceAuthError error =
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            GoogleServiceAuthError::FromServiceError("invalid_scope");
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        delegate_->OnMintTokenFailure(error);
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        break;
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResultType result_;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OAuth2MintTokenFlow::Delegate* delegate_;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Waits for a specific GURL to generate a NOTIFICATION_LOAD_STOP event and
2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// saves a pointer to the window embedding the WebContents, which can be later
2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// closed.
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class WaitForGURLAndCloseWindow : public content::WindowedNotificationObserver {
214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  explicit WaitForGURLAndCloseWindow(GURL url)
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : WindowedNotificationObserver(
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            content::NOTIFICATION_LOAD_STOP,
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            content::NotificationService::AllSources()),
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        url_(url) {}
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // NotificationObserver:
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void Observe(int type,
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       const content::NotificationSource& source,
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE {
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    content::NavigationController* web_auth_flow_controller =
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        content::Source<content::NavigationController>(source).ptr();
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    content::WebContents* web_contents =
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        web_auth_flow_controller->GetWebContents();
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (web_contents->GetURL() == url_) {
2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // It is safe to keep the pointer here, because we know in a test, that
2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // the WebContents won't go away before CloseEmbedderWebContents is
2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // called. Don't copy this code to production.
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      embedder_web_contents_ = web_contents->GetEmbedderWebContents();
235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Condtionally invoke parent class so that Wait will not exit
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // until the target URL arrives.
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      content::WindowedNotificationObserver::Observe(type, source, details);
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Closes the window embedding the WebContents. The action is separated from
2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // the Observe method to make sure the list of observers is not deleted,
2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // while some event is already being processed. (That causes ASAN failures.)
2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void CloseEmbedderWebContents() {
2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (embedder_web_contents_)
2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      embedder_web_contents_->Close();
2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GURL url_;
2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  content::WebContents* embedder_web_contents_;
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockGetAuthTokenFunction : public IdentityGetAuthTokenFunction {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  MockGetAuthTokenFunction() : login_access_token_result_(true),
2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                               login_ui_result_(true),
26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               scope_ui_result_(true),
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               login_ui_shown_(false),
26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               scope_ui_shown_(false) {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void set_login_access_token_result(bool result) {
2667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    login_access_token_result_ = result;
2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void set_login_ui_result(bool result) {
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    login_ui_result_ = result;
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void set_scope_ui_failure(GaiaWebAuthFlow::Failure failure) {
27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_result_ = false;
27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_failure_ = failure;
27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void set_scope_ui_oauth_error(const std::string& oauth_error) {
27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_result_ = false;
28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_failure_ = GaiaWebAuthFlow::OAUTH_ERROR;
28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_oauth_error_ = oauth_error;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool login_ui_shown() const {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return login_ui_shown_;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool scope_ui_shown() const {
28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return scope_ui_shown_;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual void StartLoginAccessTokenRequest() OVERRIDE {
2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (login_access_token_result_) {
2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      OnGetTokenSuccess(login_token_request_.get(), "access_token",
2957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          base::Time::Now() + base::TimeDelta::FromHours(1LL));
2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    } else {
2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      GoogleServiceAuthError error(
2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      OnGetTokenFailure(login_token_request_.get(), error);
3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
3017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ShowLoginPopup() OVERRIDE {
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_FALSE(login_ui_shown_);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    login_ui_shown_ = true;
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (login_ui_result_)
3077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      SigninSuccess();
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    else
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SigninFailed();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ShowOAuthApprovalDialog(
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const IssueAdviceInfo& issue_advice) OVERRIDE {
31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_shown_ = true;
31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (scope_ui_result_) {
31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      OnGaiaFlowCompleted(kAccessToken, "3600");
31890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    } else if (scope_ui_failure_ == GaiaWebAuthFlow::SERVICE_AUTH_ERROR) {
31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GoogleServiceAuthError error(GoogleServiceAuthError::CONNECTION_FAILED);
32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      OnGaiaFlowFailure(scope_ui_failure_, error, "");
32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    } else {
32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      OnGaiaFlowFailure(scope_ui_failure_, error, scope_ui_oauth_error_);
32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_CONST_METHOD0(HasLoginToken, bool());
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(CreateMintTokenFlow,
3297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch               OAuth2MintTokenFlow* (const std::string& login_access_token));
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~MockGetAuthTokenFunction() {}
3337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool login_access_token_result_;
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool login_ui_result_;
33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool scope_ui_result_;
33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GaiaWebAuthFlow::Failure scope_ui_failure_;
33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string scope_ui_oauth_error_;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool login_ui_shown_;
33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool scope_ui_shown_;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MockQueuedMintRequest : public IdentityMintRequestQueue::Request {
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD1(StartMintToken, void(IdentityMintRequestQueue::MintType));
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class GetAuthTokenFunctionTest : public AsyncExtensionBrowserTest {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum OAuth2Fields {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NONE = 0,
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CLIENT_ID = 1,
352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SCOPES = 2,
353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    AS_COMPONENT = 4
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~GetAuthTokenFunctionTest() {}
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper to create an extension with specific OAuth2Info fields set.
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |fields_to_set| should be computed by using fields of Oauth2Fields enum.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* CreateExtension(int fields_to_set) {
361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const Extension* ext;
362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::FilePath manifest_path =
363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        test_data_dir_.AppendASCII("platform_apps/oauth2");
364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::FilePath component_manifest_path =
365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        test_data_dir_.AppendASCII("packaged_app/component_oauth2");
366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if ((fields_to_set & AS_COMPONENT) == 0)
367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ext = LoadExtension(manifest_path);
368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    else
369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ext = LoadExtensionAsComponent(component_manifest_path);
370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    OAuth2Info& oauth2_info =
371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        const_cast<OAuth2Info&>(OAuth2Info::GetOAuth2Info(ext));
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((fields_to_set & CLIENT_ID) != 0)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      oauth2_info.client_id = "client1";
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((fields_to_set & SCOPES) != 0) {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      oauth2_info.scopes.push_back("scope1");
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      oauth2_info.scopes.push_back("scope2");
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    extension_id_ = ext->id();
380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    oauth_scopes_ = std::set<std::string>(oauth2_info.scopes.begin(),
381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          oauth2_info.scopes.end());
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ext;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api() {
386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return IdentityAPI::GetFactoryInstance()->Get(browser()->profile());
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string GetPrimaryAccountId() {
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SigninManagerBase* signin_manager =
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        SigninManagerFactory::GetForProfile(browser()->profile());
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return signin_manager->GetAuthenticatedAccountId();
393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void SetCachedToken(const IdentityTokenCacheValue& token_data) {
396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ExtensionTokenKey key(extension_id_, GetPrimaryAccountId(), oauth_scopes_);
397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    id_api()->SetCachedToken(key, token_data);
398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
400a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const IdentityTokenCacheValue& GetCachedToken() {
401a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ExtensionTokenKey key(extension_id_, GetPrimaryAccountId(), oauth_scopes_);
402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return id_api()->GetCachedToken(key);
403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
405a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void QueueRequestStart(IdentityMintRequestQueue::MintType type,
406a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         IdentityMintRequestQueue::Request* request) {
407a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ExtensionTokenKey key(extension_id_, GetPrimaryAccountId(), oauth_scopes_);
408a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    id_api()->mint_queue()->RequestStart(type, key, request);
409a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
410a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
411a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void QueueRequestComplete(IdentityMintRequestQueue::MintType type,
412a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            IdentityMintRequestQueue::Request* request) {
413a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ExtensionTokenKey key(extension_id_, GetPrimaryAccountId(), oauth_scopes_);
414a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    id_api()->mint_queue()->RequestComplete(type, key, request);
415a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
416a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
417a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private:
418a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string extension_id_;
419a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::set<std::string> oauth_scopes_;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NoClientId) {
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(SCOPES));
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kInvalidClientId), error);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
43090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NoScopes) {
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID));
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kInvalidScopes), error);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
44190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NonInteractiveNotSignedIn) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
45390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NonInteractiveMintFailure) {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_FAILURE, func.get());
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
46990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
4737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       NonInteractiveLoginAccessTokenFailure) {
4747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
4757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
4767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_CALL(*func.get(), HasLoginToken())
4777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      .WillOnce(Return(true));
4787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  func->set_login_access_token_result(false);
4797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string error = utils::RunFunctionAndReturnError(
4807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      func.get(), "[{}]", browser());
4817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
4827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4847dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochIN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveMintAdviceSuccess) {
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
488868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kNoGrant), error);
496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
49790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_ADVICE,
500a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            GetCachedToken().status());
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveMintBadCredentials) {
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_BAD_CREDENTIALS, func.get());
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
51690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
517a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
518a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS,
519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            id_api()->GetAuthStatusForTest().state());
520a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
521a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
523a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       NonInteractiveMintServiceError) {
524a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
525a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
526a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
527a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
528a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SERVICE_ERROR, func.get());
529a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
530a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string error =
531a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      utils::RunFunctionAndReturnError(func.get(), "[{}]", browser());
532a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
533a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
534a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
535a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
536a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(),
537a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            id_api()->GetAuthStatusForTest());
538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveSuccess) {
542ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(OS_WIN) && defined(USE_ASH)
543ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
544a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
545ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return;
546ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif
547ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser()));
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string access_token;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
56190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
563a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            GetCachedToken().status());
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginCanceled) {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(false);
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
57690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveMintBadCredentialsLoginCanceled) {
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_BAD_CREDENTIALS, func.get());
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(false);
589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
59390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveLoginSuccessNoToken) {
598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(false);
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
60690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveLoginSuccessMintFailure) {
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_FAILURE, func.get());
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
62390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
6277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       InteractiveLoginSuccessLoginAccessTokenFailure) {
6287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
6297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
6307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
6317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  func->set_login_ui_result(true);
6327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  func->set_login_access_token_result(false);
6337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string error = utils::RunFunctionAndReturnError(
6347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      func.get(), "[{\"interactive\": true}]", browser());
6357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
6367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(func->login_ui_shown());
6377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(func->scope_ui_shown());
6387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
6397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6407dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochIN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginSuccessMintSuccess) {
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string access_token;
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
65690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginSuccessApprovalAborted) {
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
66990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::WINDOW_CLOSED);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserRejected), error);
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
67490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
67890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveLoginSuccessApprovalSuccess) {
679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
68090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
68490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
68790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(Return(flow));
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string access_token;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
69590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveApprovalAborted) {
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
70790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::WINDOW_CLOSED);
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserRejected), error);
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
71290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
716868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       InteractiveApprovalLoadFailed) {
717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
719868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
720868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      .WillOnce(Return(true));
721868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
722868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
723868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
724868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::LOAD_FAILED);
725868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
726868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
727868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kPageLoadFailure), error);
728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
729868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
730868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
731868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
732868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
73390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveApprovalInvalidRedirect) {
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
73890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
74090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
74190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::INVALID_REDIRECT);
74290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
74390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
74490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kInvalidRedirect), error);
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
74690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
75090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveApprovalConnectionFailure) {
751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
75590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
75790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
75890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::SERVICE_AUTH_ERROR);
759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
76390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
76490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
76590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
76690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
76790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveApprovalOAuthErrors) {
76890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
76990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
77090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::map<std::string, std::string> error_map;
77190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  error_map.insert(std::make_pair("access_denied", errors::kUserRejected));
77290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  error_map.insert(std::make_pair("invalid_scope", errors::kInvalidScopes));
77390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  error_map.insert(std::make_pair(
77490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "unmapped_error", std::string(errors::kAuthFailure) + "unmapped_error"));
77590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
77690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (std::map<std::string, std::string>::const_iterator
77790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)           it = error_map.begin();
77890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       it != error_map.end();
77990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       ++it) {
78090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scoped_refptr<MockGetAuthTokenFunction> func(
78190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        new MockGetAuthTokenFunction());
782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    func->set_extension(extension.get());
78390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
784f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Make sure we don't get a cached issue_advice result, which would cause
785f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // flow to be leaked.
786f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    id_api()->EraseAllCachedTokens();
78790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
78890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
789f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
79090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    func->set_scope_ui_oauth_error(it->first);
79190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::string error = utils::RunFunctionAndReturnError(
79290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        func.get(), "[{\"interactive\": true}]", browser());
79390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(it->second, error);
79490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_FALSE(func->login_ui_shown());
79590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_TRUE(func->scope_ui_shown());
79690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
79790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
79890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
79990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
80090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveApprovalSuccess) {
80190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
80290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
803868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
804868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
80590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
80690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
80790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
80890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(Return(flow));
80990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
81090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
81190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
81290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string access_token;
81390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
81490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
81590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
81690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
81790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
81890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
819a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            GetCachedToken().status());
820c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, NoninteractiveQueue) {
823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
824c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the queue.
828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE;
831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
833a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QueueRequestStart(type, &queued_request);
834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The real request will start processing, but wait in the queue behind
836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the blocker.
837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
838868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunFunctionAsync(func.get(), "[{}]");
839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify that we have fetched the login token at this point.
840868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  testing::Mock::VerifyAndClearExpectations(func.get());
841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The flow will be created after the first queued request clears.
843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
847a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QueueRequestComplete(type, &queued_request);
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
849868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func.get()));
850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
85490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, InteractiveQueue) {
858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
860868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the queue.
863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
868a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QueueRequestStart(type, &queued_request);
869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The real request will start processing, but wait in the queue behind
871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the blocker.
872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow1 = new TestOAuth2MintTokenFlow(
874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow1));
876868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunFunctionAsync(func.get(), "[{\"interactive\": true}]");
877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify that we have fetched the login token and run the first flow.
878868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  testing::Mock::VerifyAndClearExpectations(func.get());
87990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
88190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // The UI will be displayed and a token retrieved after the first
88290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // queued request clears.
883a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QueueRequestComplete(type, &queued_request);
884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
885868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func.get()));
886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
89090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
893e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochIN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, InteractiveQueueShutdown) {
894e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
895e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
896e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  func->set_extension(extension.get());
897e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
898e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Create a fake request to block the queue.
899e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  MockQueuedMintRequest queued_request;
900e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  IdentityMintRequestQueue::MintType type =
901e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
902e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
903e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
904e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  QueueRequestStart(type, &queued_request);
905e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
906e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // The real request will start processing, but wait in the queue behind
907e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // the blocker.
908e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
909e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  TestOAuth2MintTokenFlow* flow1 = new TestOAuth2MintTokenFlow(
910e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
911e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow1));
912e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  RunFunctionAsync(func.get(), "[{\"interactive\": true}]");
913e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Verify that we have fetched the login token and run the first flow.
914e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  testing::Mock::VerifyAndClearExpectations(func.get());
915e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_FALSE(func->scope_ui_shown());
916e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
917e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // After the request is canceled, the function will complete.
918e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  func->OnShutdown();
919e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(std::string(errors::kCanceled), WaitForError(func.get()));
920e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_FALSE(func->login_ui_shown());
921e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_FALSE(func->scope_ui_shown());
922e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
923e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  QueueRequestComplete(type, &queued_request);
924e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
925e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
926e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochIN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, NoninteractiveShutdown) {
927e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
928e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
929e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  func->set_extension(extension.get());
930e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
931e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
932e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  TestHangOAuth2MintTokenFlow* flow = new TestHangOAuth2MintTokenFlow();
933e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
934e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  RunFunctionAsync(func.get(), "[{\"interactive\": false}]");
935e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
936e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // After the request is canceled, the function will complete.
937e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  func->OnShutdown();
938e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  EXPECT_EQ(std::string(errors::kCanceled), WaitForError(func.get()));
939e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
940e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveQueuedNoninteractiveFails) {
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
945868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the interactive queue.
948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
953a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QueueRequestStart(type, &queued_request);
954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Non-interactive requests fail without hitting GAIA, because a
956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // consent UI is known to be up.
957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kNoGrant), error);
961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
96290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
964a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QueueRequestComplete(type, &queued_request);
965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveCacheHit) {
969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
971868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pre-populate the cache with a token
974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
976a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetCachedToken(token);
977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Get a token. Should not require a GAIA request.
979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser()));
983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
98790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveIssueAdviceCacheHit) {
992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
994868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pre-populate the cache with advice
997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IssueAdviceInfo info;
998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(info);
999a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetCachedToken(token);
1000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Should return an error without a GAIA request.
1002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
1003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
1004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
1005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
1006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kNoGrant), error);
1007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
100890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
1009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1011c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
1012c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveCacheHit) {
1013c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
1014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1015868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
1016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1017c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the queue.
1018c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
1019c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
1020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
1021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
1023a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QueueRequestStart(type, &queued_request);
1024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1025c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The real request will start processing, but wait in the queue behind
1026c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the blocker.
1027c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
1028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
1029c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
1030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
1031868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunFunctionAsync(func.get(), "[{\"interactive\": true}]");
1032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Populate the cache with a token while the request is blocked.
1034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
1035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
1036a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetCachedToken(token);
1037c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // When we wake up the request, it returns the cached token without
1039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // displaying a UI, or hitting GAIA.
1040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1041a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  QueueRequestComplete(type, &queued_request);
1042c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1043868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func.get()));
1044c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
1045c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
1046c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
1047c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
104890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
1049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1051c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
1052c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       LoginInvalidatesTokenCache) {
1053c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1054c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
1055868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
1056c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1057c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pre-populate the cache with a token
1058c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
1059c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
1060a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetCachedToken(token);
1061c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1062c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Because the user is not signed in, the token will be removed,
1063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // and we'll hit GAIA for new tokens.
1064c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
1065c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
106790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
1068c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
1069c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
107090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(Return(flow));
1071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1072c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
1073c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
1074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
1075c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
1076c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
1077c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
107890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
1079c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
1080a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            GetCachedToken().status());
1081c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1083eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochIN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ComponentWithChromeClientId) {
1084eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1085eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<const Extension> extension(
1086eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateExtension(SCOPES | AS_COMPONENT));
1087eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  func->set_extension(extension.get());
1088eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
1089eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(oauth2_info.client_id.empty());
1090eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_FALSE(func->GetOAuth2ClientId().empty());
1091eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_NE("client1", func->GetOAuth2ClientId());
1092eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1094eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochIN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ComponentWithNormalClientId) {
1095eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1096eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<const Extension> extension(
1097eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateExtension(CLIENT_ID | SCOPES | AS_COMPONENT));
1098eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  func->set_extension(extension.get());
1099eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ("client1", func->GetOAuth2ClientId());
1100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class RemoveCachedAuthTokenFunctionTest : public ExtensionBrowserTest {
1103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
1104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool InvalidateDefaultToken() {
1105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<IdentityRemoveCachedAuthTokenFunction> func(
1106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        new IdentityRemoveCachedAuthTokenFunction);
11077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    func->set_extension(utils::CreateEmptyExtension(kExtensionId).get());
1108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return utils::RunFunction(
1109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        func.get(),
1110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        std::string("[{\"token\": \"") + kAccessToken + "\"}]",
1111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        browser(),
1112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        extension_function_test_utils::NONE);
1113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api() {
1116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return IdentityAPI::GetFactoryInstance()->Get(browser()->profile());
1117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void SetCachedToken(IdentityTokenCacheValue& token_data) {
1120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ExtensionTokenKey key(extensions::id_util::GenerateId(kExtensionId),
1121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          "test@example.com",
1122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          std::set<std::string>());
1123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    id_api()->SetCachedToken(key, token_data);
1124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const IdentityTokenCacheValue& GetCachedToken() {
1127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return id_api()->GetCachedToken(
1128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        ExtensionTokenKey(extensions::id_util::GenerateId(kExtensionId),
1129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          "test@example.com",
1130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          std::set<std::string>()));
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, NotFound) {
1135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
1136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND,
1137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
1138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, Advice) {
1141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IssueAdviceInfo info;
1142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue advice(info);
1143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetCachedToken(advice);
1144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
1145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_ADVICE,
1146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
1147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, NonMatchingToken) {
1150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token("non_matching_token",
1151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
1152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetCachedToken(token);
1153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
1154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
1155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
1156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("non_matching_token", GetCachedToken().token());
1157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, MatchingToken) {
1160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
1161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
1162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetCachedToken(token);
1163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
1164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            GetCachedToken().status());
1165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
1166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND,
1167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
1168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class LaunchWebAuthFlowFunctionTest : public AsyncExtensionBrowserTest {
1171b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) public:
1172b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1173b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // Reduce performance test variance by disabling background networking.
1174b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    command_line->AppendSwitch(switches::kDisableBackgroundNetworking);
1175b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
1176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
1177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, UserCloseWindow) {
1179b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  net::SpawnedTestServer https_server(
1180b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
1181b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
1182b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL(
1183b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          "chrome/test/data/extensions/api_test/identity")));
1184b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_TRUE(https_server.Start());
1185b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GURL auth_url(https_server.GetURL("files/interaction_required.html"));
1186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1189b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1190b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      utils::CreateEmptyExtension());
1191b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  function->set_extension(empty_extension.get());
1192b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  WaitForGURLAndCloseWindow popup_observer(auth_url);
1194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1195b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string args = "[{\"interactive\": true, \"url\": \"" +
1196b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      auth_url.spec() + "\"}]";
1197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunFunctionAsync(function.get(), args);
1198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1199b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  popup_observer.Wait();
12007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  popup_observer.CloseEmbedderWebContents();
1201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserRejected), WaitForError(function.get()));
1203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, InteractionRequired) {
1206b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  net::SpawnedTestServer https_server(
1207b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
1208b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
1209b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL(
1210b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          "chrome/test/data/extensions/api_test/identity")));
1211b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_TRUE(https_server.Start());
1212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GURL auth_url(https_server.GetURL("files/interaction_required.html"));
1213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1220b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string args = "[{\"interactive\": false, \"url\": \"" +
1221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      auth_url.spec() + "\"}]";
1222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string error =
1223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      utils::RunFunctionAndReturnError(function.get(), args, browser());
1224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kInteractionRequired), error);
1226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, LoadFailed) {
1229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net::SpawnedTestServer https_server(
1230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
1231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
1232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL(
1233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          "chrome/test/data/extensions/api_test/identity")));
1234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(https_server.Start());
1235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GURL auth_url(https_server.GetURL("files/five_hundred.html"));
1236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      utils::CreateEmptyExtension());
1241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  function->set_extension(empty_extension.get());
1242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string args = "[{\"interactive\": true, \"url\": \"" +
1244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      auth_url.spec() + "\"}]";
12457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::string error =
12467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      utils::RunFunctionAndReturnError(function.get(), args, browser());
1247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kPageLoadFailure), error);
1249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, NonInteractiveSuccess) {
1252558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(OS_WIN) && defined(USE_ASH)
1253558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
1254a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
1255558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return;
1256558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
1257558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1264b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  function->InitFinalRedirectURLPrefixForTest("abcdefghij");
1265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
1266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      function.get(),
1267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "[{\"interactive\": false,"
1268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "\"url\": \"https://abcdefghij.chromiumapp.org/callback#test\"}]",
1269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      browser()));
1270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string url;
1272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&url));
1273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"),
1274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            url);
1275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(
1278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LaunchWebAuthFlowFunctionTest, InteractiveFirstNavigationSuccess) {
1279ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(OS_WIN) && defined(USE_ASH)
1280ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
1281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
1282ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return;
1283ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif
1284ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
1285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1291b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  function->InitFinalRedirectURLPrefixForTest("abcdefghij");
1292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
1293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      function.get(),
1294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "[{\"interactive\": true,"
1295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "\"url\": \"https://abcdefghij.chromiumapp.org/callback#test\"}]",
1296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      browser()));
1297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string url;
1299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&url));
1300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"),
1301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            url);
1302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(
1305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LaunchWebAuthFlowFunctionTest, InteractiveSecondNavigationSuccess) {
1306b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  net::SpawnedTestServer https_server(
1307b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
1308b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
1309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL(
1310b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          "chrome/test/data/extensions/api_test/identity")));
1311b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_TRUE(https_server.Start());
1312b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GURL auth_url(https_server.GetURL("files/redirect_to_chromiumapp.html"));
1313b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1320b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  function->InitFinalRedirectURLPrefixForTest("abcdefghij");
1321b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string args = "[{\"interactive\": true, \"url\": \"" +
1322b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      auth_url.spec() + "\"}]";
1323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::Value> value(
1324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      utils::RunFunctionAndReturnSingleResult(function.get(), args, browser()));
1325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string url;
1327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&url));
1328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"),
1329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            url);
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace extensions
1333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Tests the chrome.identity API implemented by custom JS bindings .
1335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeIdentityJsBindings) {
1336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(RunExtensionTest("identity/js_bindings")) << message_;
1337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1338