| Index: blimp/client/core/session/identity_source_unittest.cc
|
| diff --git a/blimp/client/core/session/identity_source_unittest.cc b/blimp/client/core/session/identity_source_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..64118c80c4e177a25cfb626c74a82dab2ad06206
|
| --- /dev/null
|
| +++ b/blimp/client/core/session/identity_source_unittest.cc
|
| @@ -0,0 +1,184 @@
|
| +// Copyright 2016 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.
|
| +
|
| +#include "blimp/client/core/session/identity_source.h"
|
| +
|
| +#include <memory>
|
| +#include <string>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/callback.h"
|
| +#include "base/macros.h"
|
| +#include "base/memory/ptr_util.h"
|
| +#include "blimp/client/test/test_blimp_client_context_delegate.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace blimp {
|
| +namespace client {
|
| +namespace {
|
| +
|
| +class MockIdentitySource : public IdentitySource {
|
| + public:
|
| + explicit MockIdentitySource(BlimpClientContextDelegate* delegate,
|
| + const IdentitySource::TokenCallback& callback)
|
| + : IdentitySource(delegate, callback),
|
| + success_(0),
|
| + fail_(0),
|
| + refresh_(0),
|
| + token_callback_count_(0) {}
|
| + ~MockIdentitySource() override{};
|
| +
|
| + void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
|
| + const std::string& access_token,
|
| + const base::Time& expiration_time) override {
|
| + IdentitySource::OnGetTokenSuccess(request, access_token, expiration_time);
|
| + success_++;
|
| + token_ = access_token;
|
| + }
|
| +
|
| + void OnGetTokenFailure(const OAuth2TokenService::Request* request,
|
| + const GoogleServiceAuthError& error) override {
|
| + IdentitySource::OnGetTokenFailure(request, error);
|
| + fail_++;
|
| + token_.clear();
|
| + }
|
| +
|
| + void OnRefreshTokenAvailable(const std::string& account_id) override {
|
| + IdentitySource::OnRefreshTokenAvailable(account_id);
|
| + refresh_++;
|
| + }
|
| +
|
| + void MockTokenCall(const std::string& token) {
|
| + token_callback_count_++;
|
| + callback_token_ = token;
|
| + }
|
| +
|
| + IdentityProvider* GetIdentityProvider() { return identity_provider_.get(); }
|
| +
|
| + int Succeeded() { return success_; }
|
| + int Failed() { return fail_; }
|
| + int Refreshed() { return refresh_; }
|
| + int TokenCallbackCount() { return token_callback_count_; }
|
| + // Return the token passed to TokenCallback.
|
| + const std::string& CallbackToken() { return callback_token_; }
|
| + // Return the token get from OAuth2TokenService.
|
| + const std::string& Token() { return token_; }
|
| +
|
| + // Reset test recording data.
|
| + void ResetTestRecords() {
|
| + success_ = 0;
|
| + fail_ = 0;
|
| + refresh_ = 0;
|
| + token_callback_count_ = 0;
|
| + callback_token_.clear();
|
| + token_.clear();
|
| + }
|
| +
|
| + private:
|
| + std::string token_;
|
| + int success_;
|
| + int fail_;
|
| + int refresh_;
|
| +
|
| + int token_callback_count_;
|
| + std::string callback_token_;
|
| + DISALLOW_COPY_AND_ASSIGN(MockIdentitySource);
|
| +};
|
| +
|
| +class IdentitySourceTest : public testing::Test {
|
| + public:
|
| + IdentitySourceTest() = default;
|
| + ~IdentitySourceTest() override = default;
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(IdentitySourceTest);
|
| +};
|
| +
|
| +TEST_F(IdentitySourceTest, TestConnect) {
|
| + TestBlimpClientContextDelegate mock_blimp_delegate;
|
| + MockIdentitySource auth(
|
| + &mock_blimp_delegate,
|
| + base::Bind(&MockIdentitySource::MockTokenCall, base::Unretained(&auth)));
|
| + FakeIdentityProvider* id_provider =
|
| + static_cast<FakeIdentityProvider*>(auth.GetIdentityProvider());
|
| + FakeOAuth2TokenService* token_service = mock_blimp_delegate.GetTokenService();
|
| +
|
| + // Connect when user is not signed in. Nothing happens.
|
| + id_provider->LogOut();
|
| + auth.Connect();
|
| + DCHECK_EQ(auth.Succeeded(), 0);
|
| + DCHECK_EQ(auth.Failed(), 0);
|
| + DCHECK_EQ(auth.Refreshed(), 0);
|
| + DCHECK_EQ(auth.Token(), std::string());
|
| + auth.ResetTestRecords();
|
| +
|
| + FakeOAuth2TokenServiceDelegate* mock_token_service_delegate =
|
| + token_service->GetFakeOAuth2TokenServiceDelegate();
|
| +
|
| + // Connect when user signed in, but no refresh token, refresh token observer
|
| + // should be added.
|
| + std::string account = "mock_account";
|
| + id_provider->LogIn(account);
|
| + mock_token_service_delegate->RevokeCredentials(account);
|
| + // Mock duplicate connect calls in this test.
|
| + auth.Connect();
|
| + auth.Connect();
|
| + DCHECK_EQ(auth.Succeeded(), 0);
|
| + DCHECK_EQ(auth.Failed(), 0);
|
| + DCHECK_EQ(auth.Refreshed(), 0);
|
| + DCHECK_EQ(auth.TokenCallbackCount(), 0);
|
| + auth.ResetTestRecords();
|
| +
|
| + // Issue refresh token, listener should be triggered, and request should be
|
| + // sent.
|
| + mock_token_service_delegate->UpdateCredentials(account, "mock_refresh_token");
|
| + DCHECK_EQ(auth.Succeeded(), 0);
|
| + DCHECK_EQ(auth.Failed(), 0);
|
| + DCHECK_EQ(auth.Refreshed(), 1);
|
| + DCHECK_EQ(auth.TokenCallbackCount(), 0);
|
| + auth.ResetTestRecords();
|
| +
|
| + // Fire access token success, first request should be fulfilled.
|
| + base::Time time;
|
| + std::string mock_access_token = "mock_access_token";
|
| + token_service->IssueAllTokensForAccount(account, mock_access_token, time);
|
| + DCHECK_EQ(auth.Succeeded(), 1);
|
| + DCHECK_EQ(auth.Failed(), 0);
|
| + DCHECK_EQ(auth.Token(), mock_access_token);
|
| + DCHECK_EQ(auth.TokenCallbackCount(), 1);
|
| + DCHECK_EQ(auth.CallbackToken(), mock_access_token);
|
| + auth.ResetTestRecords();
|
| +
|
| + // Connect again and fire access token failed.
|
| + GoogleServiceAuthError error(GoogleServiceAuthError::State::REQUEST_CANCELED);
|
| + auth.Connect();
|
| + auth.Connect();
|
| + token_service->IssueErrorForAllPendingRequestsForAccount(account, error);
|
| + DCHECK_EQ(auth.Succeeded(), 0);
|
| + DCHECK_EQ(auth.Failed(), 1);
|
| + DCHECK_EQ(auth.Token(), std::string());
|
| + DCHECK_EQ(auth.TokenCallbackCount(), 0);
|
| + auth.ResetTestRecords();
|
| +
|
| + // Refresh token listener should have been removed.
|
| + mock_token_service_delegate->UpdateCredentials(account, "mock_refresh_token");
|
| + DCHECK_EQ(auth.Refreshed(), 0);
|
| + auth.ResetTestRecords();
|
| +
|
| + // Direct connect with refresh token, and no listener should be
|
| + // added.
|
| + auth.Connect();
|
| + auth.Connect();
|
| + token_service->IssueAllTokensForAccount(account, mock_access_token, time);
|
| + DCHECK_EQ(auth.Succeeded(), 1);
|
| + DCHECK_EQ(auth.Token(), mock_access_token);
|
| + mock_token_service_delegate->UpdateCredentials(account, "mock_refresh_token");
|
| + DCHECK_EQ(auth.Refreshed(), 0);
|
| + DCHECK_EQ(auth.TokenCallbackCount(), 1);
|
| + DCHECK_EQ(auth.CallbackToken(), mock_access_token);
|
| +}
|
| +
|
| +} // namespace
|
| +} // namespace client
|
| +} // namespace blimp
|
|
|