// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// A complete set of unit tests for GaiaOAuthClient.

#include <string>
#include <vector>

#include "base/json/json_reader.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "google_apis/gaia/gaia_oauth_client.h"
#include "net/base/net_errors.h"
#include "net/http/http_status_code.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_status.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using ::testing::_;
using ::testing::Eq;
using ::testing::HasSubstr;
using ::testing::Pointee;
using ::testing::SaveArg;

namespace {

// Responds as though OAuth returned from the server.
class MockOAuthFetcher : public net::TestURLFetcher {
 public:
  MockOAuthFetcher(int response_code,
                   int max_failure_count,
                   bool complete_immediately,
                   const GURL& url,
                   const std::string& results,
                   net::URLFetcher::RequestType request_type,
                   net::URLFetcherDelegate* d)
      : net::TestURLFetcher(0, url, d),
        max_failure_count_(max_failure_count),
        current_failure_count_(0),
        complete_immediately_(complete_immediately) {
    set_url(url);
    set_response_code(response_code);
    SetResponseString(results);
  }

  ~MockOAuthFetcher() override {}

  void Start() override {
    if ((GetResponseCode() != net::HTTP_OK) && (max_failure_count_ != -1) &&
        (current_failure_count_ == max_failure_count_)) {
      set_response_code(net::HTTP_OK);
    }

    net::Error error = net::OK;
    if (GetResponseCode() != net::HTTP_OK) {
      error = net::ERR_FAILED;
      current_failure_count_++;
    }
    set_status(net::URLRequestStatus::FromError(error));

    if (complete_immediately_)
      delegate()->OnURLFetchComplete(this);
  }

  void Finish() {
    ASSERT_FALSE(complete_immediately_);
    delegate()->OnURLFetchComplete(this);
  }

 private:
  int max_failure_count_;
  int current_failure_count_;
  bool complete_immediately_;
  DISALLOW_COPY_AND_ASSIGN(MockOAuthFetcher);
};

class MockOAuthFetcherFactory : public net::URLFetcherFactory,
                                public net::ScopedURLFetcherFactory {
 public:
  MockOAuthFetcherFactory()
      : net::ScopedURLFetcherFactory(this),
        response_code_(net::HTTP_OK),
        complete_immediately_(true) {
  }
  ~MockOAuthFetcherFactory() override {}
  std::unique_ptr<net::URLFetcher> CreateURLFetcher(
      int id,
      const GURL& url,
      net::URLFetcher::RequestType request_type,
      net::URLFetcherDelegate* d) override {
    url_fetcher_ = new MockOAuthFetcher(
        response_code_,
        max_failure_count_,
        complete_immediately_,
        url,
        results_,
        request_type,
        d);
    return std::unique_ptr<net::URLFetcher>(url_fetcher_);
  }
  void set_response_code(int response_code) {
    response_code_ = response_code;
  }
  void set_max_failure_count(int count) {
    max_failure_count_ = count;
  }
  void set_results(const std::string& results) {
    results_ = results;
  }
  MockOAuthFetcher* get_url_fetcher() {
    return url_fetcher_;
  }
  void set_complete_immediately(bool complete_immediately) {
    complete_immediately_ = complete_immediately;
  }
 private:
  MockOAuthFetcher* url_fetcher_;
  int response_code_;
  bool complete_immediately_;
  int max_failure_count_;
  std::string results_;
  DISALLOW_COPY_AND_ASSIGN(MockOAuthFetcherFactory);
};

const std::string kTestAccessToken = "1/fFAGRNJru1FTz70BzhT3Zg";
const std::string kTestAccessTokenHandle = "1/kjhH87dfgkj87Hhj5KJkjZ";
const std::string kTestRefreshToken =
    "1/6BMfW9j53gdGImsixUH6kU5RsR4zwI9lUVX-tqf8JXQ";
const std::string kTestUserEmail = "a_user@gmail.com";
const std::string kTestUserId = "8675309";
const int kTestExpiresIn = 3920;

const std::string kDummyGetTokensResult =
    "{\"access_token\":\"" + kTestAccessToken + "\","
    "\"expires_in\":" + base::IntToString(kTestExpiresIn) + ","
    "\"refresh_token\":\"" + kTestRefreshToken + "\"}";

const std::string kDummyRefreshTokenResult =
    "{\"access_token\":\"" + kTestAccessToken + "\","
    "\"expires_in\":" + base::IntToString(kTestExpiresIn) + "}";

const std::string kDummyUserInfoResult =
    "{\"email\":\"" + kTestUserEmail + "\"}";

const std::string kDummyUserIdResult =
    "{\"id\":\"" + kTestUserId + "\"}";

const std::string kDummyFullUserInfoResult =
    "{"
      "\"family_name\": \"Bar\", "
      "\"name\": \"Foo Bar\", "
      "\"picture\": \"https://lh4.googleusercontent.com/hash/photo.jpg\", "
      "\"locale\": \"en\", "
      "\"gender\": \"male\", "
      "\"link\": \"https://plus.google.com/+FooBar\", "
      "\"given_name\": \"Foo\", "
      "\"id\": \"12345678901234567890\""
    "}";

const std::string kDummyTokenInfoResult =
  "{\"issued_to\": \"1234567890.apps.googleusercontent.com\","
  "\"audience\": \"1234567890.apps.googleusercontent.com\","
  "\"scope\": \"https://googleapis.com/oauth2/v2/tokeninfo\","
  "\"expires_in\":" + base::IntToString(kTestExpiresIn) + "}";

const std::string kDummyTokenHandleInfoResult =
    "{\"audience\": \"1234567890.apps.googleusercontent.com\","
    "\"expires_in\":" + base::IntToString(kTestExpiresIn) + "}";

}  // namespace

namespace gaia {

class GaiaOAuthClientTest : public testing::Test {
 protected:
  void SetUp() override {
    client_info_.client_id = "test_client_id";
    client_info_.client_secret = "test_client_secret";
    client_info_.redirect_uri = "test_redirect_uri";
  };

 protected:
  net::TestURLRequestContextGetter* GetRequestContext() {
    if (!request_context_getter_.get()) {
      request_context_getter_ = new net::TestURLRequestContextGetter(
          message_loop_.task_runner());
    }
    return request_context_getter_.get();
  }

  base::MessageLoop message_loop_;
  scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
  OAuthClientInfo client_info_;
};

class MockGaiaOAuthClientDelegate : public gaia::GaiaOAuthClient::Delegate {
 public:
  MockGaiaOAuthClientDelegate() {}
  ~MockGaiaOAuthClientDelegate() {}

  MOCK_METHOD3(OnGetTokensResponse, void(const std::string& refresh_token,
                                         const std::string& access_token,
                                         int expires_in_seconds));
  MOCK_METHOD2(OnRefreshTokenResponse, void(const std::string& access_token,
                                            int expires_in_seconds));
  MOCK_METHOD1(OnGetUserEmailResponse, void(const std::string& user_email));
  MOCK_METHOD1(OnGetUserIdResponse, void(const std::string& user_id));
  MOCK_METHOD0(OnOAuthError, void());
  MOCK_METHOD1(OnNetworkError, void(int response_code));

  // gMock doesn't like methods that take or return scoped_ptr.  A
  // work-around is to create a mock method that takes a raw ptr, and
  // override the problematic method to call through to it.
  // https://groups.google.com/a/chromium.org/d/msg/chromium-dev/01sDxsJ1OYw/I_S0xCBRF2oJ
  MOCK_METHOD1(OnGetUserInfoResponsePtr,
               void(const base::DictionaryValue* user_info));
  void OnGetUserInfoResponse(
      std::unique_ptr<base::DictionaryValue> user_info) override {
    user_info_.reset(user_info.release());
    OnGetUserInfoResponsePtr(user_info_.get());
  }
  MOCK_METHOD1(OnGetTokenInfoResponsePtr,
               void(const base::DictionaryValue* token_info));
  void OnGetTokenInfoResponse(
      std::unique_ptr<base::DictionaryValue> token_info) override {
    token_info_.reset(token_info.release());
    OnGetTokenInfoResponsePtr(token_info_.get());
  }

 private:
  std::unique_ptr<base::DictionaryValue> user_info_;
  std::unique_ptr<base::DictionaryValue> token_info_;
  DISALLOW_COPY_AND_ASSIGN(MockGaiaOAuthClientDelegate);
};

TEST_F(GaiaOAuthClientTest, NetworkFailure) {
  int response_code = net::HTTP_INTERNAL_SERVER_ERROR;

  MockGaiaOAuthClientDelegate delegate;
  EXPECT_CALL(delegate, OnNetworkError(response_code))
      .Times(1);

  MockOAuthFetcherFactory factory;
  factory.set_response_code(response_code);
  factory.set_max_failure_count(4);

  GaiaOAuthClient auth(GetRequestContext());
  auth.GetTokensFromAuthCode(client_info_, "auth_code", 2, &delegate);
}

TEST_F(GaiaOAuthClientTest, NetworkFailureRecover) {
  int response_code = net::HTTP_INTERNAL_SERVER_ERROR;

  MockGaiaOAuthClientDelegate delegate;
  EXPECT_CALL(delegate, OnGetTokensResponse(kTestRefreshToken, kTestAccessToken,
      kTestExpiresIn)).Times(1);

  MockOAuthFetcherFactory factory;
  factory.set_response_code(response_code);
  factory.set_max_failure_count(4);
  factory.set_results(kDummyGetTokensResult);

  GaiaOAuthClient auth(GetRequestContext());
  auth.GetTokensFromAuthCode(client_info_, "auth_code", -1, &delegate);
}

TEST_F(GaiaOAuthClientTest, OAuthFailure) {
  int response_code = net::HTTP_BAD_REQUEST;

  MockGaiaOAuthClientDelegate delegate;
  EXPECT_CALL(delegate, OnOAuthError()).Times(1);

  MockOAuthFetcherFactory factory;
  factory.set_response_code(response_code);
  factory.set_max_failure_count(-1);
  factory.set_results(kDummyGetTokensResult);

  GaiaOAuthClient auth(GetRequestContext());
  auth.GetTokensFromAuthCode(client_info_, "auth_code", -1, &delegate);
}


TEST_F(GaiaOAuthClientTest, GetTokensSuccess) {
  MockGaiaOAuthClientDelegate delegate;
  EXPECT_CALL(delegate, OnGetTokensResponse(kTestRefreshToken, kTestAccessToken,
      kTestExpiresIn)).Times(1);

  MockOAuthFetcherFactory factory;
  factory.set_results(kDummyGetTokensResult);

  GaiaOAuthClient auth(GetRequestContext());
  auth.GetTokensFromAuthCode(client_info_, "auth_code", -1, &delegate);
}

TEST_F(GaiaOAuthClientTest, GetTokensAfterNetworkFailure) {
  int response_code = net::HTTP_INTERNAL_SERVER_ERROR;

  MockGaiaOAuthClientDelegate failure_delegate;
  EXPECT_CALL(failure_delegate, OnNetworkError(response_code)).Times(1);

  MockGaiaOAuthClientDelegate success_delegate;
  EXPECT_CALL(success_delegate, OnGetTokensResponse(kTestRefreshToken,
      kTestAccessToken, kTestExpiresIn)).Times(1);

  MockOAuthFetcherFactory factory;
  factory.set_response_code(response_code);
  factory.set_max_failure_count(4);
  factory.set_results(kDummyGetTokensResult);

  GaiaOAuthClient auth(GetRequestContext());
  auth.GetTokensFromAuthCode(client_info_, "auth_code", 2, &failure_delegate);
  auth.GetTokensFromAuthCode(client_info_, "auth_code", -1, &success_delegate);
}

TEST_F(GaiaOAuthClientTest, RefreshTokenSuccess) {
  MockGaiaOAuthClientDelegate delegate;
  EXPECT_CALL(delegate, OnRefreshTokenResponse(kTestAccessToken,
      kTestExpiresIn)).Times(1);

  MockOAuthFetcherFactory factory;
  factory.set_results(kDummyRefreshTokenResult);
  factory.set_complete_immediately(false);

  GaiaOAuthClient auth(GetRequestContext());
  auth.RefreshToken(client_info_, "refresh_token", std::vector<std::string>(),
                    -1, &delegate);
  EXPECT_THAT(factory.get_url_fetcher()->upload_data(),
              Not(HasSubstr("scope")));
  factory.get_url_fetcher()->Finish();
}

TEST_F(GaiaOAuthClientTest, RefreshTokenDownscopingSuccess) {
  MockGaiaOAuthClientDelegate delegate;
  EXPECT_CALL(delegate, OnRefreshTokenResponse(kTestAccessToken,
      kTestExpiresIn)).Times(1);

  MockOAuthFetcherFactory factory;
  factory.set_results(kDummyRefreshTokenResult);
  factory.set_complete_immediately(false);

  GaiaOAuthClient auth(GetRequestContext());
  auth.RefreshToken(client_info_, "refresh_token",
                    std::vector<std::string>(1, "scope4test"), -1, &delegate);
  EXPECT_THAT(factory.get_url_fetcher()->upload_data(),
              HasSubstr("&scope=scope4test"));
  factory.get_url_fetcher()->Finish();
}


TEST_F(GaiaOAuthClientTest, GetUserEmail) {
  MockGaiaOAuthClientDelegate delegate;
  EXPECT_CALL(delegate, OnGetUserEmailResponse(kTestUserEmail)).Times(1);

  MockOAuthFetcherFactory factory;
  factory.set_results(kDummyUserInfoResult);

  GaiaOAuthClient auth(GetRequestContext());
  auth.GetUserEmail("access_token", 1, &delegate);
}

TEST_F(GaiaOAuthClientTest, GetUserId) {
  MockGaiaOAuthClientDelegate delegate;
  EXPECT_CALL(delegate, OnGetUserIdResponse(kTestUserId)).Times(1);

  MockOAuthFetcherFactory factory;
  factory.set_results(kDummyUserIdResult);

  GaiaOAuthClient auth(GetRequestContext());
  auth.GetUserId("access_token", 1, &delegate);
}

TEST_F(GaiaOAuthClientTest, GetUserInfo) {
  const base::DictionaryValue* captured_result;

  MockGaiaOAuthClientDelegate delegate;
  EXPECT_CALL(delegate, OnGetUserInfoResponsePtr(_))
      .WillOnce(SaveArg<0>(&captured_result));

  MockOAuthFetcherFactory factory;
  factory.set_results(kDummyFullUserInfoResult);

  GaiaOAuthClient auth(GetRequestContext());
  auth.GetUserInfo("access_token", 1, &delegate);

  std::unique_ptr<base::Value> value =
      base::JSONReader::Read(kDummyFullUserInfoResult);
  DCHECK(value);
  ASSERT_TRUE(value->IsType(base::Value::Type::DICTIONARY));
  base::DictionaryValue* expected_result;
  value->GetAsDictionary(&expected_result);

  ASSERT_TRUE(expected_result->Equals(captured_result));
}

TEST_F(GaiaOAuthClientTest, GetTokenInfo) {
  const base::DictionaryValue* captured_result;

  MockGaiaOAuthClientDelegate delegate;
  EXPECT_CALL(delegate, OnGetTokenInfoResponsePtr(_))
      .WillOnce(SaveArg<0>(&captured_result));

  MockOAuthFetcherFactory factory;
  factory.set_results(kDummyTokenInfoResult);

  GaiaOAuthClient auth(GetRequestContext());
  auth.GetTokenInfo("some_token", 1, &delegate);

  std::string issued_to;
  ASSERT_TRUE(captured_result->GetString("issued_to", &issued_to));
  ASSERT_EQ("1234567890.apps.googleusercontent.com", issued_to);
}

TEST_F(GaiaOAuthClientTest, GetTokenHandleInfo) {
  const base::DictionaryValue* captured_result;

  MockGaiaOAuthClientDelegate delegate;
  EXPECT_CALL(delegate, OnGetTokenInfoResponsePtr(_))
      .WillOnce(SaveArg<0>(&captured_result));

  MockOAuthFetcherFactory factory;
  factory.set_results(kDummyTokenHandleInfoResult);

  GaiaOAuthClient auth(GetRequestContext());
  auth.GetTokenHandleInfo("some_handle", 1, &delegate);

  std::string audience;
  ASSERT_TRUE(captured_result->GetString("audience", &audience));
  ASSERT_EQ("1234567890.apps.googleusercontent.com", audience);
}

}  // namespace gaia
