identity_apitest.cc revision 868fa2fe829687343ffae624259930155e16dbd8
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_util.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stringprintf.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/identity/identity_api.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/component_loader.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_apitest.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_browsertest.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_function_test_utils.h"
13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_notification_types.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"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "googleurl/src/gurl.h"
27b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "grit/browser_resources.h"
28b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/test/spawned_test_server/spawned_test_server.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Return;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::ReturnRef;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace errors = identity_constants;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace utils = extension_function_test_utils;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kAccessToken[] = "auth_token";
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static const char kExtensionId[] = "ext_id";
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This helps us be able to wait until an AsyncExtensionFunction calls
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// SendResponse.
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class SendResponseDelegate
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public UIThreadExtensionFunction::DelegateForTests {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SendResponseDelegate() : should_post_quit_(false) {}
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~SendResponseDelegate() {}
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void set_should_post_quit(bool should_quit) {
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    should_post_quit_ = should_quit;
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool HasResponse() {
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return response_.get() != NULL;
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool GetResponse() {
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(HasResponse());
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return *response_.get();
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnSendResponse(UIThreadExtensionFunction* function,
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              bool success,
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              bool bad_message) OVERRIDE {
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_FALSE(bad_message);
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_FALSE(HasResponse());
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response_.reset(new bool);
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *response_ = success;
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (should_post_quit_) {
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::MessageLoopForUI::current()->Quit();
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<bool> response_;
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool should_post_quit_;
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class AsyncExtensionBrowserTest : public ExtensionBrowserTest {
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Asynchronous function runner allows tests to manipulate the browser window
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // after the call happens.
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void RunFunctionAsync(
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      UIThreadExtensionFunction* function,
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& args) {
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response_delegate_.reset(new SendResponseDelegate);
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->set_test_delegate(response_delegate_.get());
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<base::ListValue> parsed_args(utils::ParseList(args));
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(parsed_args.get()) <<
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "Could not parse extension function arguments: " << args;
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->SetArgs(parsed_args.get());
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!function->GetExtension()) {
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      scoped_refptr<Extension> empty_extension(
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          utils::CreateEmptyExtension());
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      function->set_extension(empty_extension.get());
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->set_profile(browser()->profile());
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->set_has_callback(true);
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    function->Run();
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string WaitForError(UIThreadExtensionFunction* function) {
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RunMessageLoopUntilResponse();
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_FALSE(function->GetResultList()) << "Did not expect a result";
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return function->GetError();
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Value* WaitForSingleResult(UIThreadExtensionFunction* function) {
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RunMessageLoopUntilResponse();
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(function->GetError().empty()) << "Unexpected error: "
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                              << function->GetError();
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::Value* single_result = NULL;
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (function->GetResultList() != NULL &&
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        function->GetResultList()->Get(0, &single_result)) {
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return single_result->DeepCopy();
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return NULL;
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void RunMessageLoopUntilResponse() {
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If the RunImpl of |function| didn't already call SendResponse, run the
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // message loop until they do.
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!response_delegate_->HasResponse()) {
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      response_delegate_->set_should_post_quit(true);
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::RunMessageLoop();
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(response_delegate_->HasResponse());
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<SendResponseDelegate> response_delegate_;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestOAuth2MintTokenFlow : public OAuth2MintTokenFlow {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ResultType {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ISSUE_ADVICE_SUCCESS,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MINT_TOKEN_SUCCESS,
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MINT_TOKEN_FAILURE,
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MINT_TOKEN_BAD_CREDENTIALS
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow(ResultType result,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          OAuth2MintTokenFlow::Delegate* delegate)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : OAuth2MintTokenFlow(NULL, delegate, OAuth2MintTokenFlow::Parameters()),
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result_(result),
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(delegate) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Start() OVERRIDE {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (result_) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case ISSUE_ADVICE_SUCCESS: {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IssueAdviceInfo info;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnIssueAdviceSuccess(info);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case MINT_TOKEN_SUCCESS: {
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        delegate_->OnMintTokenSuccess(kAccessToken, 3600);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case MINT_TOKEN_FAILURE: {
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GoogleServiceAuthError error(GoogleServiceAuthError::CONNECTION_FAILED);
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        delegate_->OnMintTokenFailure(error);
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case MINT_TOKEN_BAD_CREDENTIALS: {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GoogleServiceAuthError error(
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delegate_->OnMintTokenFailure(error);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResultType result_;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OAuth2MintTokenFlow::Delegate* delegate_;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserContextKeyedService* IdentityAPITestFactory(
18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    content::BrowserContext* profile) {
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return new IdentityAPI(static_cast<Profile*>(profile));
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// DO NOT USE THIS CLASS until finding a safe way to close the window.
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Waits for a specific GURL to generate a NOTIFICATION_LOAD_STOP
195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// event, and closes the window embedding the webcontents.
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class WaitForGURLAndCloseWindow : public content::WindowedNotificationObserver {
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  explicit WaitForGURLAndCloseWindow(GURL url)
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : WindowedNotificationObserver(
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            content::NOTIFICATION_LOAD_STOP,
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            content::NotificationService::AllSources()),
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        url_(url) {}
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // NotificationObserver:
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void Observe(int type,
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       const content::NotificationSource& source,
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE {
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    content::NavigationController* web_auth_flow_controller =
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        content::Source<content::NavigationController>(source).ptr();
210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    content::WebContents* web_contents =
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        web_auth_flow_controller->GetWebContents();
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (web_contents->GetURL() == url_) {
214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      web_contents->GetEmbedderWebContents()->Close();
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Condtionally invoke parent class so that Wait will not exit
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // until the target URL arrives.
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      content::WindowedNotificationObserver::Observe(type, source, details);
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GURL url_;
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockGetAuthTokenFunction : public IdentityGetAuthTokenFunction {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockGetAuthTokenFunction() : login_ui_result_(true),
23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               scope_ui_result_(true),
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               login_ui_shown_(false),
23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               scope_ui_shown_(false) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void set_login_ui_result(bool result) {
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    login_ui_result_ = result;
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void set_scope_ui_failure(GaiaWebAuthFlow::Failure failure) {
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_result_ = false;
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_failure_ = failure;
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void set_scope_ui_oauth_error(const std::string& oauth_error) {
24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_result_ = false;
24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_failure_ = GaiaWebAuthFlow::OAUTH_ERROR;
24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_oauth_error_ = oauth_error;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool login_ui_shown() const {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return login_ui_shown_;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool scope_ui_shown() const {
25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return scope_ui_shown_;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ShowLoginPopup() OVERRIDE {
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_FALSE(login_ui_shown_);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    login_ui_shown_ = true;
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (login_ui_result_)
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SigninSuccess("fake_refresh_token");
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    else
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SigninFailed();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ShowOAuthApprovalDialog(
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const IssueAdviceInfo& issue_advice) OVERRIDE {
26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scope_ui_shown_ = true;
27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (scope_ui_result_) {
27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      OnGaiaFlowCompleted(kAccessToken, "3600");
27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    } else if (scope_ui_failure_ == GaiaWebAuthFlow::SERVICE_AUTH_ERROR) {
27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GoogleServiceAuthError error(GoogleServiceAuthError::CONNECTION_FAILED);
27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      OnGaiaFlowFailure(scope_ui_failure_, error, "");
27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    } else {
27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      OnGaiaFlowFailure(scope_ui_failure_, error, scope_ui_oauth_error_);
27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_CONST_METHOD0(HasLoginToken, bool());
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(CreateMintTokenFlow,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               OAuth2MintTokenFlow* (OAuth2MintTokenFlow::Mode mode));
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~MockGetAuthTokenFunction() {}
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool login_ui_result_;
28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool scope_ui_result_;
29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GaiaWebAuthFlow::Failure scope_ui_failure_;
29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string scope_ui_oauth_error_;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool login_ui_shown_;
29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool scope_ui_shown_;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MockQueuedMintRequest : public IdentityMintRequestQueue::Request {
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD1(StartMintToken, void(IdentityMintRequestQueue::MintType));
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class GetAuthTokenFunctionTest : public AsyncExtensionBrowserTest {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum OAuth2Fields {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NONE = 0,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CLIENT_ID = 1,
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SCOPES = 2
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~GetAuthTokenFunctionTest() {}
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper to create an extension with specific OAuth2Info fields set.
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |fields_to_set| should be computed by using fields of Oauth2Fields enum.
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Extension* CreateExtension(int fields_to_set) {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Extension* ext = LoadExtension(
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        test_data_dir_.AppendASCII("platform_apps/oauth2"));
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OAuth2Info& oauth2_info = const_cast<OAuth2Info&>(
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        OAuth2Info::GetOAuth2Info(ext));
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((fields_to_set & CLIENT_ID) != 0)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      oauth2_info.client_id = "client1";
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((fields_to_set & SCOPES) != 0) {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      oauth2_info.scopes.push_back("scope1");
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      oauth2_info.scopes.push_back("scope2");
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ext;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api() {
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return IdentityAPI::GetFactoryInstance()->GetForProfile(
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        browser()->profile());
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NoClientId) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(SCOPES));
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kInvalidClientId), error);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NoScopes) {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID));
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kInvalidScopes), error);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NonInteractiveNotSignedIn) {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NonInteractiveMintFailure) {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_FAILURE, func.get());
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser());
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveMintAdviceSuccess) {
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kNoGrant), error);
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(
400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      IdentityTokenCacheValue::CACHE_STATUS_ADVICE,
401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      id_api()->GetCachedToken(extension->id(), oauth2_info.scopes).status());
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveMintBadCredentials) {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_BAD_CREDENTIALS, func.get());
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveSuccess) {
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
425868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{}]", browser()));
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string access_token;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            id_api()->GetCachedToken(extension->id(),
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     oauth2_info.scopes).status());
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginCanceled) {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(false);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
45290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveMintBadCredentialsLoginCanceled) {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_BAD_CREDENTIALS, func.get());
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(false);
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
46990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveLoginSuccessNoToken) {
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(false);
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserNotSignedIn), error);
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
48290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveLoginSuccessMintFailure) {
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_FAILURE, func.get());
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
49990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginSuccessMintSuccess) {
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string access_token;
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
51890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveLoginSuccessApprovalAborted) {
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
53190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::WINDOW_CLOSED);
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserRejected), error);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
53690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
54090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveLoginSuccessApprovalSuccess) {
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
54290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(false));
545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
54690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
54990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(Return(flow));
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string access_token;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
55790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InteractiveApprovalAborted) {
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
56990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::WINDOW_CLOSED);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserRejected), error);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
57490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       InteractiveApprovalLoadFailed) {
579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
580868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      .WillOnce(Return(true));
583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
584868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::LOAD_FAILED);
587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
589868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kPageLoadFailure), error);
590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
593868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
59590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveApprovalInvalidRedirect) {
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())
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(Return(true));
60090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
60290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
60390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::INVALID_REDIRECT);
60490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
60590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
60690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kInvalidRedirect), error);
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
60890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
61290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveApprovalConnectionFailure) {
613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_extension(CreateExtension(CLIENT_ID | SCOPES));
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
61790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
61990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
62090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  func->set_scope_ui_failure(GaiaWebAuthFlow::SERVICE_AUTH_ERROR);
621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser());
623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(StartsWithASCII(error, errors::kAuthFailure, false));
624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
62590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
62690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
62790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
62890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
62990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveApprovalOAuthErrors) {
63090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
63190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
63290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::map<std::string, std::string> error_map;
63390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  error_map.insert(std::make_pair("access_denied", errors::kUserRejected));
63490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  error_map.insert(std::make_pair("invalid_scope", errors::kInvalidScopes));
63590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  error_map.insert(std::make_pair(
63690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "unmapped_error", std::string(errors::kAuthFailure) + "unmapped_error"));
63790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
63890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (std::map<std::string, std::string>::const_iterator
63990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)           it = error_map.begin();
64090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       it != error_map.end();
64190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       ++it) {
64290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    scoped_refptr<MockGetAuthTokenFunction> func(
64390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        new MockGetAuthTokenFunction());
644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    func->set_extension(extension.get());
64590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
64690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
64790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
64890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ON_CALL(*func.get(), CreateMintTokenFlow(_)).WillByDefault(Return(flow));
64990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    func->set_scope_ui_oauth_error(it->first);
65090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::string error = utils::RunFunctionAndReturnError(
65190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        func.get(), "[{\"interactive\": true}]", browser());
65290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(it->second, error);
65390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_FALSE(func->login_ui_shown());
65490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_TRUE(func->scope_ui_shown());
65590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
65690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
65790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
65890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
65990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       InteractiveApprovalSuccess) {
66090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
66290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
663868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
664868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
66590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
66690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
66790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
66890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(Return(flow));
66990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
67090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
67190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
67290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string access_token;
67390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
67490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
67590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
67690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
67790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
67890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
67990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            id_api()->GetCachedToken(extension->id(),
68090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                     oauth2_info.scopes).status());
681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, NoninteractiveQueue) {
684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
686868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the queue.
689868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopes(oauth2_info.scopes.begin(),
691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               oauth2_info.scopes.end());
692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api =
693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          browser()->profile());
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue* queue = id_api->mint_queue();
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE;
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestStart(type, extension->id(), scopes, &queued_request);
702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The real request will start processing, but wait in the queue behind
704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the blocker.
705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
706868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunFunctionAsync(func.get(), "[{}]");
707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify that we have fetched the login token at this point.
708868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  testing::Mock::VerifyAndClearExpectations(func.get());
709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The flow will be created after the first queued request clears.
711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS, func.get());
713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestComplete(type, extension->id(), scopes, &queued_request);
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func.get()));
718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
72290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, InteractiveQueue) {
726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the queue.
731868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopes(oauth2_info.scopes.begin(),
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               oauth2_info.scopes.end());
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api =
735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(
736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          browser()->profile());
737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue* queue = id_api->mint_queue();
738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestStart(type, extension->id(), scopes, &queued_request);
744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The real request will start processing, but wait in the queue behind
746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the blocker.
747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow1 = new TestOAuth2MintTokenFlow(
749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow1));
751868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunFunctionAsync(func.get(), "[{\"interactive\": true}]");
752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify that we have fetched the login token and run the first flow.
753868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  testing::Mock::VerifyAndClearExpectations(func.get());
75490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
75690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // The UI will be displayed and a token retrieved after the first
75790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // queued request clears.
758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestComplete(type, extension->id(), scopes, &queued_request);
759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
760868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func.get()));
761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
76590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveQueuedNoninteractiveFails) {
770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
772868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the interactive queue.
775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopes(oauth2_info.scopes.begin(),
777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               oauth2_info.scopes.end());
778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api =
779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::IdentityAPI::GetFactoryInstance()->GetForProfile(
780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          browser()->profile());
781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue* queue = id_api->mint_queue();
782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestStart(type, extension->id(), scopes, &queued_request);
788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Non-interactive requests fail without hitting GAIA, because a
790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // consent UI is known to be up.
791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kNoGrant), error);
795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
79690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestComplete(type, extension->id(), scopes, &queued_request);
799c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveCacheHit) {
803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
805868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pre-populate the cache with a token
808868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id_api()->SetCachedToken(extension->id(), oauth2_info.scopes, token);
812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
813c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Get a token. Should not require a GAIA request.
814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser()));
818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
820c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
82290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
824c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       NonInteractiveIssueAdviceCacheHit) {
827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
829868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pre-populate the cache with advice
832868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IssueAdviceInfo info;
834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(info);
835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id_api()->SetCachedToken(extension->id(), oauth2_info.scopes, token);
836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Should return an error without a GAIA request.
838c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(true));
840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(
841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{}]", browser());
842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(errors::kNoGrant), error);
843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
84490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       InteractiveCacheHit) {
849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
851868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a fake request to block the queue.
854868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::set<std::string> scopes(oauth2_info.scopes.begin(),
856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               oauth2_info.scopes.end());
857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue* queue = id_api()->mint_queue();
858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockQueuedMintRequest queued_request;
859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType type =
860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE;
861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(queued_request, StartMintToken(type)).Times(1);
863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestStart(type, extension->id(), scopes, &queued_request);
864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The real request will start processing, but wait in the queue behind
866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the blocker.
867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken()).WillOnce(Return(true));
868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_)).WillOnce(Return(flow));
871868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunFunctionAsync(func.get(), "[{\"interactive\": true}]");
872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Populate the cache with a token while the request is blocked.
874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id_api()->SetCachedToken(extension->id(), oauth2_info.scopes, token);
877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // When we wake up the request, it returns the cached token without
879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // displaying a UI, or hitting GAIA.
880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  queue->RequestComplete(type, extension->id(), scopes, &queued_request);
882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
883868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::Value> value(WaitForSingleResult(func.get()));
884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(func->login_ui_shown());
88890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FALSE(func->scope_ui_shown());
889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       LoginInvalidatesTokenCache) {
893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
895868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  func->set_extension(extension.get());
896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pre-populate the cache with a token
898868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension.get());
899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  id_api()->SetCachedToken(extension->id(), oauth2_info.scopes, token);
902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Because the user is not signed in, the token will be removed,
904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // and we'll hit GAIA for new tokens.
905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), HasLoginToken())
906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillOnce(Return(false));
907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  func->set_login_ui_result(true);
90890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestOAuth2MintTokenFlow* flow = new TestOAuth2MintTokenFlow(
909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS, func.get());
910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*func.get(), CreateMintTokenFlow(_))
91190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      .WillOnce(Return(flow));
912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      func.get(), "[{\"interactive\": true}]", browser()));
915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string access_token;
916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&access_token));
917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string(kAccessToken), access_token);
918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(func->login_ui_shown());
91990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(func->scope_ui_shown());
920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            id_api()->GetCachedToken(extension->id(),
922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     oauth2_info.scopes).status());
923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class RemoveCachedAuthTokenFunctionTest : public ExtensionBrowserTest {
926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool InvalidateDefaultToken() {
928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<IdentityRemoveCachedAuthTokenFunction> func(
929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        new IdentityRemoveCachedAuthTokenFunction);
930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    func->set_extension(utils::CreateEmptyExtension(kExtensionId));
931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return utils::RunFunction(
932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        func.get(),
933868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        std::string("[{\"token\": \"") + kAccessToken + "\"}]",
934868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        browser(),
935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        extension_function_test_utils::NONE);
936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityAPI* id_api() {
939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return IdentityAPI::GetFactoryInstance()->GetForProfile(
940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        browser()->profile());
941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void SetCachedToken(IdentityTokenCacheValue& token_data) {
944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    id_api()->SetCachedToken(extensions::id_util::GenerateId(kExtensionId),
945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             std::vector<std::string>(), token_data);
946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const IdentityTokenCacheValue& GetCachedToken() {
949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return id_api()->GetCachedToken(
950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        extensions::id_util::GenerateId(kExtensionId),
951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::vector<std::string>());
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, NotFound) {
956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND,
958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, Advice) {
962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IssueAdviceInfo info;
963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue advice(info);
964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetCachedToken(advice);
965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_ADVICE,
967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, NonMatchingToken) {
971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token("non_matching_token",
972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetCachedToken(token);
974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN,
976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("non_matching_token", GetCachedToken().token());
978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RemoveCachedAuthTokenFunctionTest, MatchingToken) {
981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue token(kAccessToken,
982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                base::TimeDelta::FromSeconds(3600));
983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetCachedToken(token);
984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(InvalidateDefaultToken());
985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND,
986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetCachedToken().status());
987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class LaunchWebAuthFlowFunctionTest : public AsyncExtensionBrowserTest {
990b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) public:
991b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
992b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // Reduce performance test variance by disabling background networking.
993b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    command_line->AppendSwitch(switches::kDisableBackgroundNetworking);
994b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
997868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest,
998868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       DISABLED_UserCloseWindow) {
999b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  net::SpawnedTestServer https_server(
1000b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
1001b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
1002b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL(
1003b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          "chrome/test/data/extensions/api_test/identity")));
1004b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_TRUE(https_server.Start());
1005b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GURL auth_url(https_server.GetURL("files/interaction_required.html"));
1006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1008c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1009b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1010b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      utils::CreateEmptyExtension());
1011b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  function->set_extension(empty_extension.get());
1012b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1013868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  WaitForGURLAndCloseWindow popup_observer(auth_url);
1014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1015b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string args = "[{\"interactive\": true, \"url\": \"" +
1016b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      auth_url.spec() + "\"}]";
1017868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RunFunctionAsync(function.get(), args);
1018c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1019b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  popup_observer.Wait();
1020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1021868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kUserRejected), WaitForError(function.get()));
1022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, InteractionRequired) {
1025b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  net::SpawnedTestServer https_server(
1026b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
1027b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
1028b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL(
1029b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          "chrome/test/data/extensions/api_test/identity")));
1030b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_TRUE(https_server.Start());
1031b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GURL auth_url(https_server.GetURL("files/interaction_required.html"));
1032b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1037c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1039b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string args = "[{\"interactive\": false, \"url\": \"" +
1040b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      auth_url.spec() + "\"}]";
1041868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string error =
1042868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      utils::RunFunctionAndReturnError(function.get(), args, browser());
1043868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1044868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kInteractionRequired), error);
1045868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1046868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1047868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, LoadFailed) {
1048868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net::SpawnedTestServer https_server(
1049868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
1050868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
1051868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL(
1052868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          "chrome/test/data/extensions/api_test/identity")));
1053868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(https_server.Start());
1054868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GURL auth_url(https_server.GetURL("files/five_hundred.html"));
1055868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1056868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1057868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1058868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1059868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      utils::CreateEmptyExtension());
1060868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  function->set_extension(empty_extension.get());
1061868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1062868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string args = "[{\"interactive\": true, \"url\": \"" +
1063868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      auth_url.spec() + "\"}]";
1064b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string error = utils::RunFunctionAndReturnError(function, args,
1065b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                                       browser());
1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1067868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(std::string(errors::kPageLoadFailure), error);
1068c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1069c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1070c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(LaunchWebAuthFlowFunctionTest, NonInteractiveSuccess) {
1071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1072c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1073c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1075c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1076c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1077b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  function->InitFinalRedirectURLPrefixForTest("abcdefghij");
1078c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
1079868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      function.get(),
1080c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "[{\"interactive\": false,"
1081c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "\"url\": \"https://abcdefghij.chromiumapp.org/callback#test\"}]",
1082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      browser()));
1083c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1084c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string url;
1085c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&url));
1086c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"),
1087c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            url);
1088c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1089c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1090c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(
1091c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LaunchWebAuthFlowFunctionTest, InteractiveFirstNavigationSuccess) {
1092c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1094c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1095c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1096c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1097c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1098b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  function->InitFinalRedirectURLPrefixForTest("abcdefghij");
1099c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
1100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      function.get(),
1101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "[{\"interactive\": true,"
1102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "\"url\": \"https://abcdefghij.chromiumapp.org/callback#test\"}]",
1103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      browser()));
1104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string url;
1106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&url));
1107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"),
1108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            url);
1109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(
1112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LaunchWebAuthFlowFunctionTest, InteractiveSecondNavigationSuccess) {
1113b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  net::SpawnedTestServer https_server(
1114b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS,
1115b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      net::SpawnedTestServer::kLocalhost,
1116b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL(
1117b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          "chrome/test/data/extensions/api_test/identity")));
1118b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_TRUE(https_server.Start());
1119b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GURL auth_url(https_server.GetURL("files/redirect_to_chromiumapp.html"));
1120b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
1122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new IdentityLaunchWebAuthFlowFunction());
1123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<Extension> empty_extension(
1124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      utils::CreateEmptyExtension());
1125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  function->set_extension(empty_extension.get());
1126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1127b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  function->InitFinalRedirectURLPrefixForTest("abcdefghij");
1128b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  std::string args = "[{\"interactive\": true, \"url\": \"" +
1129b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      auth_url.spec() + "\"}]";
1130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<base::Value> value(
1131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      utils::RunFunctionAndReturnSingleResult(function.get(), args, browser()));
1132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string url;
1134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(value->GetAsString(&url));
1135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(std::string("https://abcdefghij.chromiumapp.org/callback#test"),
1136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            url);
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace extensions
1140