Home | History | Annotate | Download | only in gaia
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 //
      5 // A complete set of unit tests for OAuth2AccessTokenFetcher.
      6 
      7 #include <string>
      8 
      9 #include "base/memory/scoped_ptr.h"
     10 #include "content/public/test/test_browser_thread_bundle.h"
     11 #include "google_apis/gaia/gaia_urls.h"
     12 #include "google_apis/gaia/google_service_auth_error.h"
     13 #include "google_apis/gaia/oauth2_access_token_consumer.h"
     14 #include "google_apis/gaia/oauth2_access_token_fetcher.h"
     15 #include "net/http/http_status_code.h"
     16 #include "net/url_request/test_url_fetcher_factory.h"
     17 #include "net/url_request/url_fetcher.h"
     18 #include "net/url_request/url_fetcher_delegate.h"
     19 #include "net/url_request/url_fetcher_factory.h"
     20 #include "net/url_request/url_request.h"
     21 #include "net/url_request/url_request_status.h"
     22 #include "net/url_request/url_request_test_util.h"
     23 #include "testing/gmock/include/gmock/gmock.h"
     24 #include "testing/gtest/include/gtest/gtest.h"
     25 #include "url/gurl.h"
     26 
     27 using net::ResponseCookies;
     28 using net::ScopedURLFetcherFactory;
     29 using net::TestURLFetcher;
     30 using net::URLFetcher;
     31 using net::URLFetcherDelegate;
     32 using net::URLFetcherFactory;
     33 using net::URLRequestStatus;
     34 using testing::_;
     35 using testing::Return;
     36 
     37 namespace {
     38 
     39 typedef std::vector<std::string> ScopeList;
     40 
     41 static const char kValidTokenResponse[] =
     42     "{"
     43     "  \"access_token\": \"at1\","
     44     "  \"expires_in\": 3600,"
     45     "  \"token_type\": \"Bearer\""
     46     "}";
     47 static const char kTokenResponseNoAccessToken[] =
     48     "{"
     49     "  \"expires_in\": 3600,"
     50     "  \"token_type\": \"Bearer\""
     51     "}";
     52 
     53 class MockUrlFetcherFactory : public ScopedURLFetcherFactory,
     54                               public URLFetcherFactory {
     55 public:
     56   MockUrlFetcherFactory()
     57       : ScopedURLFetcherFactory(this) {
     58   }
     59   virtual ~MockUrlFetcherFactory() {}
     60 
     61   MOCK_METHOD4(
     62       CreateURLFetcher,
     63       URLFetcher* (int id,
     64                    const GURL& url,
     65                    URLFetcher::RequestType request_type,
     66                    URLFetcherDelegate* d));
     67 };
     68 
     69 class MockOAuth2AccessTokenConsumer : public OAuth2AccessTokenConsumer {
     70  public:
     71   MockOAuth2AccessTokenConsumer() {}
     72   ~MockOAuth2AccessTokenConsumer() {}
     73 
     74   MOCK_METHOD2(OnGetTokenSuccess, void(const std::string& access_token,
     75                                        const base::Time& expiration_time));
     76   MOCK_METHOD1(OnGetTokenFailure,
     77                void(const GoogleServiceAuthError& error));
     78 };
     79 
     80 }  // namespace
     81 
     82 class OAuth2AccessTokenFetcherTest : public testing::Test {
     83  public:
     84   OAuth2AccessTokenFetcherTest()
     85     : request_context_getter_(new net::TestURLRequestContextGetter(
     86           base::MessageLoopProxy::current())),
     87       fetcher_(&consumer_, request_context_getter_) {
     88   }
     89 
     90   virtual ~OAuth2AccessTokenFetcherTest() {}
     91 
     92   virtual TestURLFetcher* SetupGetAccessToken(
     93       bool fetch_succeeds, int response_code, const std::string& body) {
     94     GURL url(GaiaUrls::GetInstance()->oauth2_token_url());
     95     TestURLFetcher* url_fetcher = new TestURLFetcher(0, url, &fetcher_);
     96     URLRequestStatus::Status status =
     97         fetch_succeeds ? URLRequestStatus::SUCCESS : URLRequestStatus::FAILED;
     98     url_fetcher->set_status(URLRequestStatus(status, 0));
     99 
    100     if (response_code != 0)
    101       url_fetcher->set_response_code(response_code);
    102 
    103     if (!body.empty())
    104       url_fetcher->SetResponseString(body);
    105 
    106     EXPECT_CALL(factory_, CreateURLFetcher(_, url, _, _))
    107         .WillOnce(Return(url_fetcher));
    108     return url_fetcher;
    109   }
    110 
    111  protected:
    112   content::TestBrowserThreadBundle thread_bundle_;
    113   MockUrlFetcherFactory factory_;
    114   MockOAuth2AccessTokenConsumer consumer_;
    115   scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
    116   OAuth2AccessTokenFetcher fetcher_;
    117 };
    118 
    119 // These four tests time out, see http://crbug.com/113446.
    120 TEST_F(OAuth2AccessTokenFetcherTest, DISABLED_GetAccessTokenRequestFailure) {
    121   TestURLFetcher* url_fetcher = SetupGetAccessToken(false, 0, std::string());
    122   EXPECT_CALL(consumer_, OnGetTokenFailure(_)).Times(1);
    123   fetcher_.Start("client_id", "client_secret", "refresh_token", ScopeList());
    124   fetcher_.OnURLFetchComplete(url_fetcher);
    125 }
    126 
    127 TEST_F(OAuth2AccessTokenFetcherTest,
    128        DISABLED_GetAccessTokenResponseCodeFailure) {
    129   TestURLFetcher* url_fetcher =
    130       SetupGetAccessToken(true, net::HTTP_FORBIDDEN, std::string());
    131   EXPECT_CALL(consumer_, OnGetTokenFailure(_)).Times(1);
    132   fetcher_.Start("client_id", "client_secret", "refresh_token", ScopeList());
    133   fetcher_.OnURLFetchComplete(url_fetcher);
    134 }
    135 
    136 TEST_F(OAuth2AccessTokenFetcherTest, DISABLED_Success) {
    137   TestURLFetcher* url_fetcher = SetupGetAccessToken(
    138       true, net::HTTP_OK, kValidTokenResponse);
    139   EXPECT_CALL(consumer_, OnGetTokenSuccess("at1", _)).Times(1);
    140   fetcher_.Start("client_id", "client_secret", "refresh_token", ScopeList());
    141   fetcher_.OnURLFetchComplete(url_fetcher);
    142 }
    143 
    144 TEST_F(OAuth2AccessTokenFetcherTest, DISABLED_MakeGetAccessTokenBody) {
    145   {  // No scope.
    146     std::string body =
    147         "client_id=cid1&"
    148         "client_secret=cs1&"
    149         "grant_type=refresh_token&"
    150         "refresh_token=rt1";
    151     EXPECT_EQ(body, OAuth2AccessTokenFetcher::MakeGetAccessTokenBody(
    152         "cid1", "cs1", "rt1", ScopeList()));
    153   }
    154 
    155   {  // One scope.
    156     std::string body =
    157         "client_id=cid1&"
    158         "client_secret=cs1&"
    159         "grant_type=refresh_token&"
    160         "refresh_token=rt1&"
    161         "scope=https://www.googleapis.com/foo";
    162     ScopeList scopes;
    163     scopes.push_back("https://www.googleapis.com/foo");
    164     EXPECT_EQ(body, OAuth2AccessTokenFetcher::MakeGetAccessTokenBody(
    165         "cid1", "cs1", "rt1", scopes));
    166   }
    167 
    168   {  // Multiple scopes.
    169     std::string body =
    170         "client_id=cid1&"
    171         "client_secret=cs1&"
    172         "grant_type=refresh_token&"
    173         "refresh_token=rt1&"
    174         "scope=https://www.googleapis.com/foo+"
    175         "https://www.googleapis.com/bar+"
    176         "https://www.googleapis.com/baz";
    177     ScopeList scopes;
    178     scopes.push_back("https://www.googleapis.com/foo");
    179     scopes.push_back("https://www.googleapis.com/bar");
    180     scopes.push_back("https://www.googleapis.com/baz");
    181     EXPECT_EQ(body, OAuth2AccessTokenFetcher::MakeGetAccessTokenBody(
    182         "cid1", "cs1", "rt1", scopes));
    183   }
    184 }
    185 
    186 // http://crbug.com/114215
    187 #if defined(OS_WIN)
    188 #define MAYBE_ParseGetAccessTokenResponse DISABLED_ParseGetAccessTokenResponse
    189 #else
    190 #define MAYBE_ParseGetAccessTokenResponse ParseGetAccessTokenResponse
    191 #endif // defined(OS_WIN)
    192 TEST_F(OAuth2AccessTokenFetcherTest, MAYBE_ParseGetAccessTokenResponse) {
    193   {  // No body.
    194     TestURLFetcher url_fetcher(0, GURL("www.google.com"), NULL);
    195 
    196     std::string at;
    197     int expires_in;
    198     EXPECT_FALSE(OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
    199         &url_fetcher, &at, &expires_in));
    200     EXPECT_TRUE(at.empty());
    201   }
    202   {  // Bad json.
    203     TestURLFetcher url_fetcher(0, GURL("www.google.com"), NULL);
    204     url_fetcher.SetResponseString("foo");
    205 
    206     std::string at;
    207     int expires_in;
    208     EXPECT_FALSE(OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
    209         &url_fetcher, &at, &expires_in));
    210     EXPECT_TRUE(at.empty());
    211   }
    212   {  // Valid json: access token missing.
    213     TestURLFetcher url_fetcher(0, GURL("www.google.com"), NULL);
    214     url_fetcher.SetResponseString(kTokenResponseNoAccessToken);
    215 
    216     std::string at;
    217     int expires_in;
    218     EXPECT_FALSE(OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
    219         &url_fetcher, &at, &expires_in));
    220     EXPECT_TRUE(at.empty());
    221   }
    222   {  // Valid json: all good.
    223     TestURLFetcher url_fetcher(0, GURL("www.google.com"), NULL);
    224     url_fetcher.SetResponseString(kValidTokenResponse);
    225 
    226     std::string at;
    227     int expires_in;
    228     EXPECT_TRUE(OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
    229         &url_fetcher, &at, &expires_in));
    230     EXPECT_EQ("at1", at);
    231     EXPECT_EQ(3600, expires_in);
    232   }
    233 }
    234