identity_apitest.cc revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
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)
55e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
65e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/identity/identity_api.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/component_loader.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_apitest.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_browsertest.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_function_test_utils.h"
14b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
17b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_utils.h"
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "extensions/common/id_util.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/google_service_auth_error.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/oauth2_mint_token_flow.h"
26b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "grit/browser_resources.h"
27b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/test/spawned_test_server/spawned_test_server.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(OS_WIN) && defined(USE_ASH)
33ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/win/windows_version.h"
34ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif
35ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Return;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::ReturnRef;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace errors = identity_constants;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace utils = extension_function_test_utils;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kAccessToken[] = "auth_token";
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static const char kExtensionId[] = "ext_id";
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This helps us be able to wait until an AsyncExtensionFunction calls
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// SendResponse.
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class SendResponseDelegate
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public UIThreadExtensionFunction::DelegateForTests {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SendResponseDelegate() : should_post_quit_(false) {}
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~SendResponseDelegate() {}
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void set_should_post_quit(bool should_quit) {
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    should_post_quit_ = should_quit;
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool HasResponse() {
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return response_.get() != NULL;
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool GetResponse() {
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(HasResponse());
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return *response_.get();
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnSendResponse(UIThreadExtensionFunction* function,
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              bool success,
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              bool bad_message) OVERRIDE {
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_FALSE(bad_message);
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_FALSE(HasResponse());
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response_.reset(new bool);
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *response_ = success;
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (should_post_quit_) {
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::MessageLoopForUI::current()->Quit();
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<bool> response_;
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool should_post_quit_;
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class AsyncExtensionBrowserTest : public ExtensionBrowserTest {
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Asynchronous function runner allows tests to manipulate the browser window
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // after the call happens.
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void RunFunctionAsync(
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      UIThreadExtensionFunction* function,
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& args) {
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response_delegate_.reset(new SendResponseDelegate);
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->set_test_delegate(response_delegate_.get());
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<base::ListValue> parsed_args(utils::ParseList(args));
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(parsed_args.get()) <<
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "Could not parse extension function arguments: " << args;
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->SetArgs(parsed_args.get());
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!function->GetExtension()) {
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scoped_refptr<Extension> empty_extension(
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          utils::CreateEmptyExtension());
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      function->set_extension(empty_extension.get());
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->set_profile(browser()->profile());
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->set_has_callback(true);
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->Run();
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string WaitForError(UIThreadExtensionFunction* function) {
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RunMessageLoopUntilResponse();
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_FALSE(function->GetResultList()) << "Did not expect a result";
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return function->GetError();
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Value* WaitForSingleResult(UIThreadExtensionFunction* function) {
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RunMessageLoopUntilResponse();
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(function->GetError().empty()) << "Unexpected error: "
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                              << function->GetError();
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Value* single_result = NULL;
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (function->GetResultList() != NULL &&
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        function->GetResultList()->Get(0, &single_result)) {
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return single_result->DeepCopy();
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return NULL;
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void RunMessageLoopUntilResponse() {
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If the RunImpl of |function| didn't already call SendResponse, run the
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // message loop until they do.
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!response_delegate_->HasResponse()) {
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      response_delegate_->set_should_post_quit(true);
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::RunMessageLoop();
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(response_delegate_->HasResponse());
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<SendResponseDelegate> response_delegate_;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestOAuth2MintTokenFlow : public OAuth2MintTokenFlow {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ResultType {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ISSUE_ADVICE_SUCCESS,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MINT_TOKEN_SUCCESS,
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MINT_TOKEN_FAILURE,
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MINT_TOKEN_BAD_CREDENTIALS
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow(ResultType result,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          OAuth2MintTokenFlow::Delegate* delegate)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : OAuth2MintTokenFlow(NULL, delegate, OAuth2MintTokenFlow::Parameters()),
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result_(result),
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(delegate) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Start() OVERRIDE {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (result_) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case ISSUE_ADVICE_SUCCESS: {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IssueAdviceInfo info;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnIssueAdviceSuccess(info);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case MINT_TOKEN_SUCCESS: {
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        delegate_->OnMintTokenSuccess(kAccessToken, 3600);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case MINT_TOKEN_FAILURE: {
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GoogleServiceAuthError error(GoogleServiceAuthError::CONNECTION_FAILED);
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        delegate_->OnMintTokenFailure(error);
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case MINT_TOKEN_BAD_CREDENTIALS: {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GoogleServiceAuthError error(
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnMintTokenFailure(error);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResultType result_;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OAuth2MintTokenFlow::Delegate* delegate_;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserContextKeyedService* IdentityAPITestFactory(
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    content::BrowserContext* profile) {
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return new IdentityAPI(static_cast<Profile*>(profile));
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Waits for a specific GURL to generate a NOTIFICATION_LOAD_STOP event and
1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// saves a pointer to the window embedding the WebContents, which can be later
1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// closed.
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class WaitForGURLAndCloseWindow : public content::WindowedNotificationObserver {
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  explicit WaitForGURLAndCloseWindow(GURL url)
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : WindowedNotificationObserver(
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            content::NOTIFICATION_LOAD_STOP,
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            content::NotificationService::AllSources()),
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        url_(url) {}
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // NotificationObserver:
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void Observe(int type,
210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       const content::NotificationSource& source,
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE {
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    content::NavigationController* web_auth_flow_controller =
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        content::Source<content::NavigationController>(source).ptr();
214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    content::WebContents* web_contents =
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        web_auth_flow_controller->GetWebContents();
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (web_contents->GetURL() == url_) {
2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // It is safe to keep the pointer here, because we know in a test, that
2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // the WebContents won't go away before CloseEmbedderWebContents is
2207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // called. Don't copy this code to production.
2217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      embedder_web_contents_ = web_contents->GetEmbedderWebContents();
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Condtionally invoke parent class so that Wait will not exit
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // until the target URL arrives.
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      content::WindowedNotificationObserver::Observe(type, source, details);
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Closes the window embedding the WebContents. The action is separated from
2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // the Observe method to make sure the list of observers is not deleted,
2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // while some event is already being processed. (That causes ASAN failures.)
2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void CloseEmbedderWebContents() {
2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (embedder_web_contents_)
2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      embedder_web_contents_->Close();
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GURL url_;
2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  content::WebContents* embedder_web_contents_;
239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockGetAuthTokenFunction : public IdentityGetAuthTokenFunction {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  MockGetAuthTokenFunction() : login_access_token_result_(true),
2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                               login_ui_result_(true),
24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               scope_ui_result_(true),
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               login_ui_shown_(false),
24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               scope_ui_shown_(false) {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void set_login_access_token_result(bool result) {
2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    login_access_token_result_ = result;
2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void set_login_ui_result(bool result) {
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    login_ui_result_ = result;
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void set_scope_ui_failure(GaiaWebAuthFlow::Failure failure) {
26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_result_ = false;
26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_failure_ = failure;
26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void set_scope_ui_oauth_error(const std::string& oauth_error) {
26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_result_ = false;
26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_failure_ = GaiaWebAuthFlow::OAUTH_ERROR;
26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_oauth_error_ = oauth_error;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool login_ui_shown() const {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return login_ui_shown_;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool scope_ui_shown() const {
27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return scope_ui_shown_;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual void StartLoginAccessTokenRequest() OVERRIDE {
2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (login_access_token_result_) {
2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      OnGetTokenSuccess(login_token_request_.get(), "access_token",
2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          base::Time::Now() + base::TimeDelta::FromHours(1LL));
2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    } else {
2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      GoogleServiceAuthError error(
2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      OnGetTokenFailure(login_token_request_.get(), error);
2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ShowLoginPopup() OVERRIDE {
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_FALSE(login_ui_shown_);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    login_ui_shown_ = true;
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (login_ui_result_)
2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      SigninSuccess();
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    else
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SigninFailed();
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ShowOAuthApprovalDialog(
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const IssueAdviceInfo& issue_advice) OVERRIDE {
30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_shown_ = true;
30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (scope_ui_result_) {
30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      OnGaiaFlowCompleted(kAccessToken, "3600");
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    } else if (scope_ui_failure_ == GaiaWebAuthFlow::SERVICE_AUTH_ERROR) {
30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GoogleServiceAuthError error(GoogleServiceAuthError::CONNECTION_FAILED);
30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      OnGaiaFlowFailure(scope_ui_failure_, error, "");
30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    } else {
30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      OnGaiaFlowFailure(scope_ui_failure_, error, scope_ui_oauth_error_);
31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_CONST_METHOD0(HasLoginToken, bool());
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(CreateMintTokenFlow,
3167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch               OAuth2MintTokenFlow* (const std::string& login_access_token));
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~MockGetAuthTokenFunction() {}
3207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool login_access_token_result_;
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool login_ui_result_;
32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool scope_ui_result_;
32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GaiaWebAuthFlow::Failure scope_ui_failure_;
32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string scope_ui_oauth_error_;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool login_ui_shown_;
32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool scope_ui_shown_;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MockQueuedMintRequest : public IdentityMintRequestQueue::Request {
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD1(StartMintToken, void(IdentityMintRequestQueue::MintType));
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class GetAuthTokenFunctionTest : public AsyncExtensionBrowserTest {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum OAuth2Fields {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NONE = 0,
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CLIENT_ID = 1,
339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SCOPES = 2,
340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    AS_COMPONENT = 4
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~GetAuthTokenFunctionTest() {}
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper to create an extension with specific OAuth2Info fields set.
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |fields_to_set| should be computed by using fields of Oauth2Fields enum.
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* CreateExtension(int fields_to_set) {
348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const Extension* ext;
349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::FilePath manifest_path =
350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        test_data_dir_.AppendASCII("platform_apps/oauth2");
351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::FilePath component_manifest_path =
352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        test_data_dir_.AppendASCII("packaged_app/component_oauth2");
353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if ((fields_to_set & AS_COMPONENT) == 0)
354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ext = LoadExtension(manifest_path);
355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    else
356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ext = LoadExtensionAsComponent(component_manifest_path);
357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    OAuth2Info& oauth2_info =
358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        const_cast<OAuth2Info&>(OAuth2Info::GetOAuth2Info(ext));
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((fields_to_set & CLIENT_ID) != 0)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      oauth2_info.client_id = "client1";
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((fields_to_set & SCOPES) != 0) {
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      oauth2_info.scopes.push_back("scope1");
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      oauth2_info.scopes.push_back("scope2");
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ext;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api() {
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return IdentityAPI::GetFactoryInstance()->GetForProfile(
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        browser()->profile());
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NoClientId) {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(SCOPES));
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kInvalidClientId), error);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NoScopes) {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID));
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kInvalidScopes), error);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NonInteractiveNotSignedIn) {
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NonInteractiveMintFailure) {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_FAILURE, func.get());
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
42190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
4257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       NonInteractiveLoginAccessTokenFailure) {
4267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
4277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
4287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_CALL(*func.get(), HasLoginToken())
4297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      .WillOnce(Return(true));
4307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  func->set_login_access_token_result(false);
4317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string error = utils::RunFunctionAndReturnError(
4327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      func.get(), "[{}]", browser());
4337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
4347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4367dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochIN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveMintAdviceSuccess) {
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kNoGrant), error);
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
44990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(
453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      IdentityTokenCacheValue::CACHE_STATUS_ADVICE,
454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      id_api()->GetCachedToken(extension->id(), oauth2_info.scopes).status());
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveMintBadCredentials) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_BAD_CREDENTIALS, func.get());
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
47090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveSuccess) {
475ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(OS_WIN) && defined(USE_ASH)
476ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
477ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (base::win::GetVersion() >= base::win::VERSION_WIN8)
478ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return;
479ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif
480ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser()));
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string access_token;
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
49590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            id_api()->GetCachedToken(extension->id(),
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     oauth2_info.scopes).status());
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginCanceled) {
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(false);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
51190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveMintBadCredentialsLoginCanceled) {
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_BAD_CREDENTIALS, func.get());
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(false);
524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
52890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveLoginSuccessNoToken) {
533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(false);
537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
54190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveLoginSuccessMintFailure) {
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_FAILURE, func.get());
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
55890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
5627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       InteractiveLoginSuccessLoginAccessTokenFailure) {
5637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
5647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
5657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
5667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  func->set_login_ui_result(true);
5677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  func->set_login_access_token_result(false);
5687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string error = utils::RunFunctionAndReturnError(
5697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      func.get(), "[{\"interactive\": true}]", browser());
5707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
5717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(func->login_ui_shown());
5727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(func->scope_ui_shown());
5737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
5747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5757dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochIN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginSuccessMintSuccess) {
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string access_token;
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
59190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginSuccessApprovalAborted) {
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
60490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::WINDOW_CLOSED);
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserRejected), error);
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
60990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
61390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveLoginSuccessApprovalSuccess) {
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
61590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
617868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
61990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
62290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(Return(flow));
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string access_token;
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
63090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveApprovalAborted) {
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
64290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::WINDOW_CLOSED);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserRejected), error);
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
64790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       InteractiveApprovalLoadFailed) {
652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      .WillOnce(Return(true));
656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
659868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::LOAD_FAILED);
660868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kPageLoadFailure), error);
663868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
664868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
665868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
666868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
667868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
66890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveApprovalInvalidRedirect) {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
67390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
67590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
67690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::INVALID_REDIRECT);
67790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
67890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
67990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kInvalidRedirect), error);
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
68190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
68590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveApprovalConnectionFailure) {
686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
69090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
69290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
69390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::SERVICE_AUTH_ERROR);
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
69890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
69990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
70090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
70190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
70290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveApprovalOAuthErrors) {
70390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
70490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
70590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::map<std::string, std::string> error_map;
70690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  error_map.insert(std::make_pair("access_denied", errors::kUserRejected));
70790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  error_map.insert(std::make_pair("invalid_scope", errors::kInvalidScopes));
70890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  error_map.insert(std::make_pair(
70990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "unmapped_error", std::string(errors::kAuthFailure) + "unmapped_error"));
71090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
71190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (std::map<std::string, std::string>::const_iterator
71290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)           it = error_map.begin();
71390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       it != error_map.end();
71490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       ++it) {
71590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scoped_refptr<MockGetAuthTokenFunction> func(
71690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        new MockGetAuthTokenFunction());
717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    func->set_extension(extension.get());
71890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
71990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
72090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
72190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ON_CALL(*func.get(), CreateMintTokenFlow(_)).WillByDefault(Return(flow));
72290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    func->set_scope_ui_oauth_error(it->first);
72390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::string error = utils::RunFunctionAndReturnError(
72490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        func.get(), "[{\"interactive\": true}]", browser());
72590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(it->second, error);
72690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_FALSE(func->login_ui_shown());
72790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_TRUE(func->scope_ui_shown());
72890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
72990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
73090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
73190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
73290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveApprovalSuccess) {
73390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
734868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
73590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
736868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
737868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
73890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
73990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
74090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
74190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(Return(flow));
74290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
74390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
74490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
74590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string access_token;
74690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
74790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
74890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
74990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
75090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
75190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
75290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            id_api()->GetCachedToken(extension->id(),
75390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                     oauth2_info.scopes).status());
754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, NoninteractiveQueue) {
757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
759868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the queue.
762868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopes(oauth2_info.scopes.begin(),
764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               oauth2_info.scopes.end());
765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api =
766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(
767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          browser()->profile());
768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue* queue = id_api->mint_queue();
769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE;
772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestStart(type, extension->id(), scopes, &queued_request);
775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The real request will start processing, but wait in the queue behind
777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the blocker.
778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
779868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunFunctionAsync(func.get(), "[{}]");
780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify that we have fetched the login token at this point.
781868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  testing::Mock::VerifyAndClearExpectations(func.get());
782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The flow will be created after the first queued request clears.
784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestComplete(type, extension->id(), scopes, &queued_request);
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
790868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func.get()));
791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
79590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, InteractiveQueue) {
799c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
801868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the queue.
804868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopes(oauth2_info.scopes.begin(),
806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               oauth2_info.scopes.end());
807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api =
808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(
809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          browser()->profile());
810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue* queue = id_api->mint_queue();
811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
813c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestStart(type, extension->id(), scopes, &queued_request);
817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The real request will start processing, but wait in the queue behind
819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the blocker.
820c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow1 = new TestOAuth2MintTokenFlow(
822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow1));
824868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunFunctionAsync(func.get(), "[{\"interactive\": true}]");
825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify that we have fetched the login token and run the first flow.
826868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  testing::Mock::VerifyAndClearExpectations(func.get());
82790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
82990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // The UI will be displayed and a token retrieved after the first
83090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // queued request clears.
831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestComplete(type, extension->id(), scopes, &queued_request);
832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
833868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func.get()));
834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
83890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveQueuedNoninteractiveFails) {
843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
845868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the interactive queue.
848868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopes(oauth2_info.scopes.begin(),
850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               oauth2_info.scopes.end());
851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api =
852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(
853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          browser()->profile());
854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue* queue = id_api->mint_queue();
855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestStart(type, extension->id(), scopes, &queued_request);
861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Non-interactive requests fail without hitting GAIA, because a
863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // consent UI is known to be up.
864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kNoGrant), error);
868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
86990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestComplete(type, extension->id(), scopes, &queued_request);
872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveCacheHit) {
876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
878868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pre-populate the cache with a token
881868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id_api()->SetCachedToken(extension->id(), oauth2_info.scopes, token);
885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Get a token. Should not require a GAIA request.
887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser()));
891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
89590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveIssueAdviceCacheHit) {
900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pre-populate the cache with advice
905868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IssueAdviceInfo info;
907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(info);
908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id_api()->SetCachedToken(extension->id(), oauth2_info.scopes, token);
909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Should return an error without a GAIA request.
911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kNoGrant), error);
916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
91790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveCacheHit) {
922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
924868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the queue.
927868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopes(oauth2_info.scopes.begin(),
929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               oauth2_info.scopes.end());
930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue* queue = id_api()->mint_queue();
931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestStart(type, extension->id(), scopes, &queued_request);
937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The real request will start processing, but wait in the queue behind
939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the blocker.
940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
944868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunFunctionAsync(func.get(), "[{\"interactive\": true}]");
945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Populate the cache with a token while the request is blocked.
947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id_api()->SetCachedToken(extension->id(), oauth2_info.scopes, token);
950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // When we wake up the request, it returns the cached token without
952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // displaying a UI, or hitting GAIA.
953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestComplete(type, extension->id(), scopes, &queued_request);
955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
956868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func.get()));
957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
96190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       LoginInvalidatesTokenCache) {
966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
968868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pre-populate the cache with a token
971868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id_api()->SetCachedToken(extension->id(), oauth2_info.scopes, token);
975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Because the user is not signed in, the token will be removed,
977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // and we'll hit GAIA for new tokens.
978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
98190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
98490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(Return(flow));
985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
99290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            id_api()->GetCachedToken(extension->id(),
995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     oauth2_info.scopes).status());
996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
998eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochIN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ComponentWithChromeClientId) {
999eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1000eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<const Extension> extension(
1001eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateExtension(SCOPES | AS_COMPONENT));
1002eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  func->set_extension(extension.get());
1003eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
1004eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(oauth2_info.client_id.empty());
1005eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_FALSE(func->GetOAuth2ClientId().empty());
1006eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_NE("client1", func->GetOAuth2ClientId());
1007eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1008eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1009eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochIN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ComponentWithNormalClientId) {
1010eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
1011eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<const Extension> extension(
1012eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateExtension(CLIENT_ID | SCOPES | AS_COMPONENT));
1013eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  func->set_extension(extension.get());
1014eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ("client1", func->GetOAuth2ClientId());
1015eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1016eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1017c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class RemoveCachedAuthTokenFunctionTest : public ExtensionBrowserTest {
1018c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
1019c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool InvalidateDefaultToken() {
1020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<IdentityRemoveCachedAuthTokenFunction> func(
1021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        new IdentityRemoveCachedAuthTokenFunction);
10227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    func->set_extension(utils::CreateEmptyExtension(kExtensionId).get());
1023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return utils::RunFunction(
1024868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        func.get(),
1025868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        std::string("[{\"token\": \"") + kAccessToken + "\"}]",
1026868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        browser(),
1027c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        extension_function_test_utils::NONE);
1028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1029c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api() {
1031c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return IdentityAPI::GetFactoryInstance()->GetForProfile(
1032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        browser()->profile());
1033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void SetCachedToken(IdentityTokenCacheValue& token_data) {
1036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    id_api()->SetCachedToken(extensions::id_util::GenerateId(kExtensionId),
1037c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             std::vector<std::string>(), token_data);
1038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const IdentityTokenCacheValue& GetCachedToken() {
1041c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return id_api()->GetCachedToken(
1042c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        extensions::id_util::GenerateId(kExtensionId),
1043c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::vector<std::string>());
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1047c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, NotFound) {
1048c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
1049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND,
1050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
1051c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1052c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1053c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, Advice) {
1054c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IssueAdviceInfo info;
1055c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue advice(info);
1056c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetCachedToken(advice);
1057c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
1058c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_ADVICE,
1059c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
1060c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1061c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1062c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, NonMatchingToken) {
1063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token("non_matching_token",
1064c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
1065c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetCachedToken(token);
1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
1067c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
1068c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
1069c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("non_matching_token", GetCachedToken().token());
1070c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1072c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, MatchingToken) {
1073c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
1074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
1075c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetCachedToken(token);
1076c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
1077c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND,
1078c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
1079c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1080c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1081c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class LaunchWebAuthFlowFunctionTest : public AsyncExtensionBrowserTest {
1082b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) public:
1083b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1084b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // Reduce performance test variance by disabling background networking.
1085b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    command_line->AppendSwitch(switches::kDisableBackgroundNetworking);
1086b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
1087c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
1088c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, UserCloseWindow) {
1090b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  net::SpawnedTestServer https_server(
1091b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
1092b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
1093b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL(
1094b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          "chrome/test/data/extensions/api_test/identity")));
1095b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_TRUE(https_server.Start());
1096b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GURL auth_url(https_server.GetURL("files/interaction_required.html"));
1097c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1098c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1099c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1100b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1101b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      utils::CreateEmptyExtension());
1102b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  function->set_extension(empty_extension.get());
1103b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  WaitForGURLAndCloseWindow popup_observer(auth_url);
1105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1106b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string args = "[{\"interactive\": true, \"url\": \"" +
1107b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      auth_url.spec() + "\"}]";
1108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunFunctionAsync(function.get(), args);
1109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1110b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  popup_observer.Wait();
11117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  popup_observer.CloseEmbedderWebContents();
1112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserRejected), WaitForError(function.get()));
1114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, InteractionRequired) {
1117b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  net::SpawnedTestServer https_server(
1118b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
1119b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
1120b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL(
1121b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          "chrome/test/data/extensions/api_test/identity")));
1122b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_TRUE(https_server.Start());
1123b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GURL auth_url(https_server.GetURL("files/interaction_required.html"));
1124b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1131b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string args = "[{\"interactive\": false, \"url\": \"" +
1132b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      auth_url.spec() + "\"}]";
1133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string error =
1134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      utils::RunFunctionAndReturnError(function.get(), args, browser());
1135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kInteractionRequired), error);
1137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, LoadFailed) {
1140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net::SpawnedTestServer https_server(
1141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
1142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
1143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL(
1144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          "chrome/test/data/extensions/api_test/identity")));
1145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(https_server.Start());
1146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GURL auth_url(https_server.GetURL("files/five_hundred.html"));
1147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      utils::CreateEmptyExtension());
1152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  function->set_extension(empty_extension.get());
1153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string args = "[{\"interactive\": true, \"url\": \"" +
1155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      auth_url.spec() + "\"}]";
11567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::string error =
11577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      utils::RunFunctionAndReturnError(function.get(), args, browser());
1158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kPageLoadFailure), error);
1160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, NonInteractiveSuccess) {
1163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1169b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  function->InitFinalRedirectURLPrefixForTest("abcdefghij");
1170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
1171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      function.get(),
1172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "[{\"interactive\": false,"
1173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "\"url\": \"https://abcdefghij.chromiumapp.org/callback#test\"}]",
1174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      browser()));
1175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string url;
1177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&url));
1178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"),
1179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            url);
1180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(
1183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LaunchWebAuthFlowFunctionTest, InteractiveFirstNavigationSuccess) {
1184ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(OS_WIN) && defined(USE_ASH)
1185ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
1186ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (base::win::GetVersion() >= base::win::VERSION_WIN8)
1187ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return;
1188ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif
1189ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
1190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1196b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  function->InitFinalRedirectURLPrefixForTest("abcdefghij");
1197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
1198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      function.get(),
1199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "[{\"interactive\": true,"
1200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "\"url\": \"https://abcdefghij.chromiumapp.org/callback#test\"}]",
1201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      browser()));
1202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string url;
1204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&url));
1205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"),
1206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            url);
1207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(
1210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LaunchWebAuthFlowFunctionTest, InteractiveSecondNavigationSuccess) {
1211b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  net::SpawnedTestServer https_server(
1212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
1213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
1214b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL(
1215b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          "chrome/test/data/extensions/api_test/identity")));
1216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_TRUE(https_server.Start());
1217b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GURL auth_url(https_server.GetURL("files/redirect_to_chromiumapp.html"));
1218b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1225b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  function->InitFinalRedirectURLPrefixForTest("abcdefghij");
1226b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string args = "[{\"interactive\": true, \"url\": \"" +
1227b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      auth_url.spec() + "\"}]";
1228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::Value> value(
1229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      utils::RunFunctionAndReturnSingleResult(function.get(), args, browser()));
1230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string url;
1232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&url));
1233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"),
1234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            url);
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace extensions
1238