identity_apitest.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_util.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stringprintf.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/identity/identity_api.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/identity/web_auth_flow.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_apitest.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_browsertest.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_function_test_utils.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_notification_types.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_utils.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "extensions/common/id_util.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/google_service_auth_error.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/oauth2_mint_token_flow.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "googleurl/src/gurl.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Return;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::ReturnRef;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace errors = identity_constants;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace utils = extension_function_test_utils;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kAccessToken[] = "auth_token";
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static const char kExtensionId[] = "ext_id";
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This helps us be able to wait until an AsyncExtensionFunction calls
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// SendResponse.
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class SendResponseDelegate
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public UIThreadExtensionFunction::DelegateForTests {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SendResponseDelegate() : should_post_quit_(false) {}
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~SendResponseDelegate() {}
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void set_should_post_quit(bool should_quit) {
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    should_post_quit_ = should_quit;
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool HasResponse() {
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return response_.get() != NULL;
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool GetResponse() {
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(HasResponse());
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return *response_.get();
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnSendResponse(UIThreadExtensionFunction* function,
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              bool success,
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              bool bad_message) OVERRIDE {
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_FALSE(bad_message);
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_FALSE(HasResponse());
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response_.reset(new bool);
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *response_ = success;
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (should_post_quit_) {
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      MessageLoopForUI::current()->Quit();
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<bool> response_;
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool should_post_quit_;
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class AsyncExtensionBrowserTest : public ExtensionBrowserTest {
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Asynchronous function runner allows tests to manipulate the browser window
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // after the call happens.
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void RunFunctionAsync(
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      UIThreadExtensionFunction* function,
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& args) {
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response_delegate_.reset(new SendResponseDelegate);
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->set_test_delegate(response_delegate_.get());
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<base::ListValue> parsed_args(utils::ParseList(args));
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(parsed_args.get()) <<
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "Could not parse extension function arguments: " << args;
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->SetArgs(parsed_args.get());
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!function->GetExtension()) {
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scoped_refptr<Extension> empty_extension(
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          utils::CreateEmptyExtension());
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      function->set_extension(empty_extension.get());
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->set_profile(browser()->profile());
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->set_has_callback(true);
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->Run();
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string WaitForError(UIThreadExtensionFunction* function) {
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RunMessageLoopUntilResponse();
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_FALSE(function->GetResultList()) << "Did not expect a result";
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return function->GetError();
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Value* WaitForSingleResult(UIThreadExtensionFunction* function) {
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RunMessageLoopUntilResponse();
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(function->GetError().empty()) << "Unexpected error: "
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                              << function->GetError();
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Value* single_result = NULL;
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (function->GetResultList() != NULL &&
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        function->GetResultList()->Get(0, &single_result)) {
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return single_result->DeepCopy();
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return NULL;
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void RunMessageLoopUntilResponse() {
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If the RunImpl of |function| didn't already call SendResponse, run the
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // message loop until they do.
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!response_delegate_->HasResponse()) {
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      response_delegate_->set_should_post_quit(true);
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::RunMessageLoop();
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(response_delegate_->HasResponse());
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<SendResponseDelegate> response_delegate_;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestOAuth2MintTokenFlow : public OAuth2MintTokenFlow {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ResultType {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ISSUE_ADVICE_SUCCESS,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MINT_TOKEN_SUCCESS,
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MINT_TOKEN_FAILURE,
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MINT_TOKEN_BAD_CREDENTIALS
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow(ResultType result,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          OAuth2MintTokenFlow::Delegate* delegate)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : OAuth2MintTokenFlow(NULL, delegate, OAuth2MintTokenFlow::Parameters()),
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result_(result),
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(delegate) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Start() OVERRIDE {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (result_) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case ISSUE_ADVICE_SUCCESS: {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IssueAdviceInfo info;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnIssueAdviceSuccess(info);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case MINT_TOKEN_SUCCESS: {
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        delegate_->OnMintTokenSuccess(kAccessToken, 3600);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case MINT_TOKEN_FAILURE: {
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GoogleServiceAuthError error(GoogleServiceAuthError::CONNECTION_FAILED);
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        delegate_->OnMintTokenFailure(error);
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case MINT_TOKEN_BAD_CREDENTIALS: {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GoogleServiceAuthError error(
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnMintTokenFailure(error);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResultType result_;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OAuth2MintTokenFlow::Delegate* delegate_;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ProfileKeyedService* IdentityAPITestFactory(content::BrowserContext* profile) {
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return new IdentityAPI(static_cast<Profile*>(profile));
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockGetAuthTokenFunction : public IdentityGetAuthTokenFunction {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockGetAuthTokenFunction() : login_ui_result_(true),
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               install_ui_result_(false),
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               login_ui_shown_(false),
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               install_ui_shown_(false) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void set_login_ui_result(bool result) {
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    login_ui_result_ = result;
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_install_ui_result(bool result) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    install_ui_result_ = result;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool login_ui_shown() const {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return login_ui_shown_;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool install_ui_shown() const {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return install_ui_shown_;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ShowLoginPopup() OVERRIDE {
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_FALSE(login_ui_shown_);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    login_ui_shown_ = true;
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (login_ui_result_)
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SigninSuccess("fake_refresh_token");
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    else
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SigninFailed();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ShowOAuthApprovalDialog(
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const IssueAdviceInfo& issue_advice) OVERRIDE {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    install_ui_shown_ = true;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Call InstallUIProceed or InstallUIAbort based on the flag.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (install_ui_result_)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InstallUIProceed();
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InstallUIAbort(true);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_CONST_METHOD0(HasLoginToken, bool());
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(CreateMintTokenFlow,
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               OAuth2MintTokenFlow* (OAuth2MintTokenFlow::Mode mode));
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~MockGetAuthTokenFunction() {}
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool login_ui_result_;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool install_ui_result_;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool login_ui_shown_;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool install_ui_shown_;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MockQueuedMintRequest : public IdentityMintRequestQueue::Request {
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD1(StartMintToken, void(IdentityMintRequestQueue::MintType));
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class GetAuthTokenFunctionTest : public AsyncExtensionBrowserTest {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum OAuth2Fields {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NONE = 0,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CLIENT_ID = 1,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SCOPES = 2
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~GetAuthTokenFunctionTest() {}
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper to create an extension with specific OAuth2Info fields set.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |fields_to_set| should be computed by using fields of Oauth2Fields enum.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* CreateExtension(int fields_to_set) {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Extension* ext = LoadExtension(
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        test_data_dir_.AppendASCII("platform_apps/oauth2"));
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OAuth2Info& oauth2_info = const_cast<OAuth2Info&>(
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        OAuth2Info::GetOAuth2Info(ext));
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((fields_to_set & CLIENT_ID) != 0)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      oauth2_info.client_id = "client1";
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((fields_to_set & SCOPES) != 0) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      oauth2_info.scopes.push_back("scope1");
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      oauth2_info.scopes.push_back("scope2");
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ext;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api() {
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return IdentityAPI::GetFactoryInstance()->GetForProfile(
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        browser()->profile());
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NoClientId) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(SCOPES));
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kInvalidClientId), error);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NoScopes) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID));
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kInvalidScopes), error);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NonInteractiveNotSignedIn) {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NonInteractiveMintFailure) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_FAILURE, func.get());
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveMintAdviceSuccess) {
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(extension);
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kNoGrant), error);
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension);
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_ADVICE,
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            id_api()->GetCachedToken(extension->id(),
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     oauth2_info.scopes).status());
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveMintBadCredentials) {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_BAD_CREDENTIALS, func.get());
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveSuccess) {
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(extension);
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension);
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser()));
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string access_token;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            id_api()->GetCachedToken(extension->id(),
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     oauth2_info.scopes).status());
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginCanceled) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(false);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveMintBadCredentialsLoginCanceled) {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_BAD_CREDENTIALS, func.get());
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(false);
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveLoginSuccessNoToken) {
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(false);
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveLoginSuccessMintFailure) {
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_FAILURE, func.get());
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginSuccessMintSuccess) {
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string access_token;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginSuccessApprovalAborted) {
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_install_ui_result(false);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserRejected), error);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->install_ui_shown());
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginSuccessApprovalDoneMintFailure) {
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow1 = new TestOAuth2MintTokenFlow(
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow2 = new TestOAuth2MintTokenFlow(
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_FAILURE, func.get());
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(flow1))
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(flow2));
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_install_ui_result(true);
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->install_ui_shown());
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginSuccessApprovalDoneMintSuccess) {
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(extension);
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow1 = new TestOAuth2MintTokenFlow(
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow2 = new TestOAuth2MintTokenFlow(
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(flow1))
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(flow2));
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_install_ui_result(true);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string access_token;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->install_ui_shown());
538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            id_api()->GetCachedToken(extension->id(),
540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     oauth2_info.scopes).status());
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveApprovalAborted) {
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_install_ui_result(false);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserRejected), error);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->install_ui_shown());
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveApprovalDoneMintSuccess) {
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow1 = new TestOAuth2MintTokenFlow(
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow2 = new TestOAuth2MintTokenFlow(
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(flow1))
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(flow2));
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_install_ui_result(true);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string access_token;
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->install_ui_shown());
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveApprovalDoneMintBadCredentials) {
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow1 = new TestOAuth2MintTokenFlow(
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow2 = new TestOAuth2MintTokenFlow(
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_BAD_CREDENTIALS, func.get());
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(flow1))
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(flow2));
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_install_ui_result(true);
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->install_ui_shown());
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, NoninteractiveQueue) {
607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(extension);
610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the queue.
612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension);
613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopes(oauth2_info.scopes.begin(),
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               oauth2_info.scopes.end());
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api =
616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(
617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          browser()->profile());
618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue* queue = id_api->mint_queue();
619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE;
622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestStart(type, extension->id(), scopes, &queued_request);
625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The real request will start processing, but wait in the queue behind
627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the blocker.
628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RunFunctionAsync(func, "[{}]");
630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify that we have fetched the login token at this point.
631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  testing::Mock::VerifyAndClearExpectations(func);
632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The flow will be created after the first queued request clears.
634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestComplete(type, extension->id(), scopes, &queued_request);
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func));
641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, InteractiveQueue) {
649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(extension);
652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the queue.
654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension);
655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopes(oauth2_info.scopes.begin(),
656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               oauth2_info.scopes.end());
657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api =
658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(
659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          browser()->profile());
660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue* queue = id_api->mint_queue();
661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestStart(type, extension->id(), scopes, &queued_request);
667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The real request will start processing, but wait in the queue behind
669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the blocker.
670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow1 = new TestOAuth2MintTokenFlow(
672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow1));
674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RunFunctionAsync(func, "[{\"interactive\": true}]");
675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify that we have fetched the login token and run the first flow.
676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  testing::Mock::VerifyAndClearExpectations(func);
677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The UI will be displayed and the second flow will be created
680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // after the first queued request clears.
681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_install_ui_result(true);
682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow2 = new TestOAuth2MintTokenFlow(
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow2));
685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestComplete(type, extension->id(), scopes, &queued_request);
687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func));
689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->install_ui_shown());
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveQueuedNoninteractiveFails) {
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(extension);
701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the interactive queue.
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension);
704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopes(oauth2_info.scopes.begin(),
705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               oauth2_info.scopes.end());
706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api =
707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(
708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          browser()->profile());
709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue* queue = id_api->mint_queue();
710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestStart(type, extension->id(), scopes, &queued_request);
716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Non-interactive requests fail without hitting GAIA, because a
718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // consent UI is known to be up.
719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kNoGrant), error);
723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestComplete(type, extension->id(), scopes, &queued_request);
727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveCacheHit) {
731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(extension);
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pre-populate the cache with a token
736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension);
737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id_api()->SetCachedToken(extension->id(), oauth2_info.scopes, token);
740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Get a token. Should not require a GAIA request.
742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser()));
746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveIssueAdviceCacheHit) {
755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(extension);
758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pre-populate the cache with advice
760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension);
761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IssueAdviceInfo info;
762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(info);
763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id_api()->SetCachedToken(extension->id(), oauth2_info.scopes, token);
764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Should return an error without a GAIA request.
766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kNoGrant), error);
771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveCacheHit) {
777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(extension);
780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the queue.
782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension);
783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopes(oauth2_info.scopes.begin(),
784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               oauth2_info.scopes.end());
785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue* queue = id_api()->mint_queue();
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestStart(type, extension->id(), scopes, &queued_request);
792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The real request will start processing, but wait in the queue behind
794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the blocker.
795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
799c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RunFunctionAsync(func, "[{\"interactive\": true}]");
800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Populate the cache with a token while the request is blocked.
802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id_api()->SetCachedToken(extension->id(), oauth2_info.scopes, token);
805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // When we wake up the request, it returns the cached token without
807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // displaying a UI, or hitting GAIA.
808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestComplete(type, extension->id(), scopes, &queued_request);
810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func));
812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
813c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->install_ui_shown());
817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
820c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       LoginInvalidatesTokenCache) {
821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(extension);
824c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pre-populate the cache with a token
826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension);
827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id_api()->SetCachedToken(extension->id(), oauth2_info.scopes, token);
830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Because the user is not signed in, the token will be removed,
832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // and we'll hit GAIA for new tokens.
833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow1 = new TestOAuth2MintTokenFlow(
837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
838c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow2 = new TestOAuth2MintTokenFlow(
839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(flow1))
842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(flow2));
843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_install_ui_result(true);
845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->install_ui_shown());
852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            id_api()->GetCachedToken(extension->id(),
854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     oauth2_info.scopes).status());
855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class RemoveCachedAuthTokenFunctionTest : public ExtensionBrowserTest {
858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool InvalidateDefaultToken() {
860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<IdentityRemoveCachedAuthTokenFunction> func(
861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        new IdentityRemoveCachedAuthTokenFunction);
862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    func->set_extension(utils::CreateEmptyExtension(kExtensionId));
863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return utils::RunFunction(
864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        func, std::string("[{\"token\": \"") + kAccessToken + "\"}]", browser(),
865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        extension_function_test_utils::NONE);
866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api() {
869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return IdentityAPI::GetFactoryInstance()->GetForProfile(
870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        browser()->profile());
871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void SetCachedToken(IdentityTokenCacheValue& token_data) {
874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    id_api()->SetCachedToken(extensions::id_util::GenerateId(kExtensionId),
875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             std::vector<std::string>(), token_data);
876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const IdentityTokenCacheValue& GetCachedToken() {
879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return id_api()->GetCachedToken(
880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        extensions::id_util::GenerateId(kExtensionId),
881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::vector<std::string>());
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, NotFound) {
886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND,
888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, Advice) {
892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IssueAdviceInfo info;
893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue advice(info);
894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetCachedToken(advice);
895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_ADVICE,
897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, NonMatchingToken) {
901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token("non_matching_token",
902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetCachedToken(token);
904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("non_matching_token", GetCachedToken().token());
908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, MatchingToken) {
911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetCachedToken(token);
914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND,
916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class LaunchWebAuthFlowFunctionTest : public AsyncExtensionBrowserTest {
920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, UserCloseWindow) {
923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content::WindowedNotificationObserver observer(
924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chrome::NOTIFICATION_BROWSER_WINDOW_READY,
925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::NotificationService::AllSources());
926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RunFunctionAsync(
931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      function, "[{\"interactive\": true, \"url\": \"data:text/html,auth\"}]");
932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer.Wait();
934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Browser* web_auth_flow_browser =
935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::Source<Browser>(observer.source()).ptr();
936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  web_auth_flow_browser->window()->Close();
937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserRejected), WaitForError(function));
939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, InteractionRequired) {
942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      function, "[{\"interactive\": false, \"url\": \"data:text/html,auth\"}]",
950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      browser());
951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kInteractionRequired), error);
953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, NonInteractiveSuccess) {
956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->InitFinalRedirectURLPrefixesForTest("abcdefghij");
963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      function,
965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "[{\"interactive\": false,"
966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "\"url\": \"https://abcdefghij.chromiumapp.org/callback#test\"}]",
967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      browser()));
968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string url;
970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&url));
971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"),
972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            url);
973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(
976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LaunchWebAuthFlowFunctionTest, InteractiveFirstNavigationSuccess) {
977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->InitFinalRedirectURLPrefixesForTest("abcdefghij");
984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      function,
986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "[{\"interactive\": true,"
987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "\"url\": \"https://abcdefghij.chromiumapp.org/callback#test\"}]",
988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      browser()));
989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string url;
991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&url));
992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"),
993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            url);
994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(
997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LaunchWebAuthFlowFunctionTest, InteractiveSecondNavigationSuccess) {
998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->InitFinalRedirectURLPrefixesForTest("abcdefghij");
1005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
1006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      function,
1007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "[{\"interactive\": true,"
1008c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "\"url\": \"data:text/html,<script>window.location.replace('"
1009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "https://abcdefghij.chromiumapp.org/callback#test')</script>\"}]",
1010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      browser()));
1011c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1012c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string url;
1013c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&url));
1014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"),
1015c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            url);
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace extensions
1019