Home | History | Annotate | Download | only in gaia
      1 // Copyright 2014 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 OAuth2AccessTokenFetcherImpl.
      6 
      7 #include <string>
      8 
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/run_loop.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_impl.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 static const char kValidFailureTokenResponse[] =
     54     "{"
     55     "  \"error\": \"invalid_grant\""
     56     "}";
     57 
     58 class MockUrlFetcherFactory : public ScopedURLFetcherFactory,
     59                               public URLFetcherFactory {
     60  public:
     61   MockUrlFetcherFactory() : ScopedURLFetcherFactory(this) {}
     62   virtual ~MockUrlFetcherFactory() {}
     63 
     64   MOCK_METHOD4(CreateURLFetcher,
     65                URLFetcher*(int id,
     66                            const GURL& url,
     67                            URLFetcher::RequestType request_type,
     68                            URLFetcherDelegate* d));
     69 };
     70 
     71 class MockOAuth2AccessTokenConsumer : public OAuth2AccessTokenConsumer {
     72  public:
     73   MockOAuth2AccessTokenConsumer() {}
     74   ~MockOAuth2AccessTokenConsumer() {}
     75 
     76   MOCK_METHOD2(OnGetTokenSuccess,
     77                void(const std::string& access_token,
     78                     const base::Time& expiration_time));
     79   MOCK_METHOD1(OnGetTokenFailure, void(const GoogleServiceAuthError& error));
     80 };
     81 
     82 }  // namespace
     83 
     84 class OAuth2AccessTokenFetcherImplTest : public testing::Test {
     85  public:
     86   OAuth2AccessTokenFetcherImplTest()
     87       : request_context_getter_(new net::TestURLRequestContextGetter(
     88             base::MessageLoopProxy::current())),
     89         fetcher_(&consumer_, request_context_getter_, "refresh_token") {
     90     base::RunLoop().RunUntilIdle();
     91   }
     92 
     93   virtual ~OAuth2AccessTokenFetcherImplTest() {}
     94 
     95   virtual TestURLFetcher* SetupGetAccessToken(bool fetch_succeeds,
     96                                               int response_code,
     97                                               const std::string& body) {
     98     GURL url(GaiaUrls::GetInstance()->oauth2_token_url());
     99     TestURLFetcher* url_fetcher = new TestURLFetcher(0, url, &fetcher_);
    100     URLRequestStatus::Status status =
    101         fetch_succeeds ? URLRequestStatus::SUCCESS : URLRequestStatus::FAILED;
    102     url_fetcher->set_status(URLRequestStatus(status, 0));
    103 
    104     if (response_code != 0)
    105       url_fetcher->set_response_code(response_code);
    106 
    107     if (!body.empty())
    108       url_fetcher->SetResponseString(body);
    109 
    110     EXPECT_CALL(factory_, CreateURLFetcher(_, url, _, _))
    111         .WillOnce(Return(url_fetcher));
    112     return url_fetcher;
    113   }
    114 
    115  protected:
    116   base::MessageLoop message_loop_;
    117   MockUrlFetcherFactory factory_;
    118   MockOAuth2AccessTokenConsumer consumer_;
    119   scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
    120   OAuth2AccessTokenFetcherImpl fetcher_;
    121 };
    122 
    123 // These four tests time out, see http://crbug.com/113446.
    124 TEST_F(OAuth2AccessTokenFetcherImplTest,
    125        DISABLED_GetAccessTokenRequestFailure) {
    126   TestURLFetcher* url_fetcher = SetupGetAccessToken(false, 0, std::string());
    127   EXPECT_CALL(consumer_, OnGetTokenFailure(_)).Times(1);
    128   fetcher_.Start("client_id", "client_secret", ScopeList());
    129   fetcher_.OnURLFetchComplete(url_fetcher);
    130 }
    131 
    132 TEST_F(OAuth2AccessTokenFetcherImplTest,
    133        DISABLED_GetAccessTokenResponseCodeFailure) {
    134   TestURLFetcher* url_fetcher =
    135       SetupGetAccessToken(true, net::HTTP_FORBIDDEN, std::string());
    136   EXPECT_CALL(consumer_, OnGetTokenFailure(_)).Times(1);
    137   fetcher_.Start("client_id", "client_secret", ScopeList());
    138   fetcher_.OnURLFetchComplete(url_fetcher);
    139 }
    140 
    141 TEST_F(OAuth2AccessTokenFetcherImplTest, DISABLED_Success) {
    142   TestURLFetcher* url_fetcher =
    143       SetupGetAccessToken(true, net::HTTP_OK, kValidTokenResponse);
    144   EXPECT_CALL(consumer_, OnGetTokenSuccess("at1", _)).Times(1);
    145   fetcher_.Start("client_id", "client_secret", ScopeList());
    146   fetcher_.OnURLFetchComplete(url_fetcher);
    147 }
    148 
    149 TEST_F(OAuth2AccessTokenFetcherImplTest, DISABLED_MakeGetAccessTokenBody) {
    150   {  // No scope.
    151     std::string body =
    152         "client_id=cid1&"
    153         "client_secret=cs1&"
    154         "grant_type=refresh_token&"
    155         "refresh_token=rt1";
    156     EXPECT_EQ(body,
    157               OAuth2AccessTokenFetcherImpl::MakeGetAccessTokenBody(
    158                   "cid1", "cs1", "rt1", ScopeList()));
    159   }
    160 
    161   {  // One scope.
    162     std::string body =
    163         "client_id=cid1&"
    164         "client_secret=cs1&"
    165         "grant_type=refresh_token&"
    166         "refresh_token=rt1&"
    167         "scope=https://www.googleapis.com/foo";
    168     ScopeList scopes;
    169     scopes.push_back("https://www.googleapis.com/foo");
    170     EXPECT_EQ(body,
    171               OAuth2AccessTokenFetcherImpl::MakeGetAccessTokenBody(
    172                   "cid1", "cs1", "rt1", scopes));
    173   }
    174 
    175   {  // Multiple scopes.
    176     std::string body =
    177         "client_id=cid1&"
    178         "client_secret=cs1&"
    179         "grant_type=refresh_token&"
    180         "refresh_token=rt1&"
    181         "scope=https://www.googleapis.com/foo+"
    182         "https://www.googleapis.com/bar+"
    183         "https://www.googleapis.com/baz";
    184     ScopeList scopes;
    185     scopes.push_back("https://www.googleapis.com/foo");
    186     scopes.push_back("https://www.googleapis.com/bar");
    187     scopes.push_back("https://www.googleapis.com/baz");
    188     EXPECT_EQ(body,
    189               OAuth2AccessTokenFetcherImpl::MakeGetAccessTokenBody(
    190                   "cid1", "cs1", "rt1", scopes));
    191   }
    192 }
    193 
    194 // http://crbug.com/114215
    195 #if defined(OS_WIN)
    196 #define MAYBE_ParseGetAccessTokenResponse DISABLED_ParseGetAccessTokenResponse
    197 #else
    198 #define MAYBE_ParseGetAccessTokenResponse ParseGetAccessTokenResponse
    199 #endif  // defined(OS_WIN)
    200 TEST_F(OAuth2AccessTokenFetcherImplTest, MAYBE_ParseGetAccessTokenResponse) {
    201   {  // No body.
    202     TestURLFetcher url_fetcher(0, GURL("www.google.com"), NULL);
    203 
    204     std::string at;
    205     int expires_in;
    206     EXPECT_FALSE(
    207         OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenSuccessResponse(
    208             &url_fetcher, &at, &expires_in));
    209     EXPECT_TRUE(at.empty());
    210   }
    211   {  // Bad json.
    212     TestURLFetcher url_fetcher(0, GURL("www.google.com"), NULL);
    213     url_fetcher.SetResponseString("foo");
    214 
    215     std::string at;
    216     int expires_in;
    217     EXPECT_FALSE(
    218         OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenSuccessResponse(
    219             &url_fetcher, &at, &expires_in));
    220     EXPECT_TRUE(at.empty());
    221   }
    222   {  // Valid json: access token missing.
    223     TestURLFetcher url_fetcher(0, GURL("www.google.com"), NULL);
    224     url_fetcher.SetResponseString(kTokenResponseNoAccessToken);
    225 
    226     std::string at;
    227     int expires_in;
    228     EXPECT_FALSE(
    229         OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenSuccessResponse(
    230             &url_fetcher, &at, &expires_in));
    231     EXPECT_TRUE(at.empty());
    232   }
    233   {  // Valid json: all good.
    234     TestURLFetcher url_fetcher(0, GURL("www.google.com"), NULL);
    235     url_fetcher.SetResponseString(kValidTokenResponse);
    236 
    237     std::string at;
    238     int expires_in;
    239     EXPECT_TRUE(
    240         OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenSuccessResponse(
    241             &url_fetcher, &at, &expires_in));
    242     EXPECT_EQ("at1", at);
    243     EXPECT_EQ(3600, expires_in);
    244   }
    245   {  // Valid json: invalid error response.
    246     TestURLFetcher url_fetcher(0, GURL("www.google.com"), NULL);
    247     url_fetcher.SetResponseString(kTokenResponseNoAccessToken);
    248 
    249     std::string error;
    250     EXPECT_FALSE(
    251         OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenFailureResponse(
    252             &url_fetcher, &error));
    253     EXPECT_TRUE(error.empty());
    254   }
    255   {  // Valid json: error response.
    256     TestURLFetcher url_fetcher(0, GURL("www.google.com"), NULL);
    257     url_fetcher.SetResponseString(kValidFailureTokenResponse);
    258 
    259     std::string error;
    260     EXPECT_TRUE(
    261         OAuth2AccessTokenFetcherImpl::ParseGetAccessTokenFailureResponse(
    262             &url_fetcher, &error));
    263     EXPECT_EQ("invalid_grant", error);
    264   }
    265 }
    266