Index: chrome/browser/services/gcm/gcm_account_tracker_unittest.cc |
diff --git a/chrome/browser/services/gcm/gcm_account_tracker_unittest.cc b/chrome/browser/services/gcm/gcm_account_tracker_unittest.cc |
deleted file mode 100644 |
index cf1a10a745323064cde5990be638b02778030ea1..0000000000000000000000000000000000000000 |
--- a/chrome/browser/services/gcm/gcm_account_tracker_unittest.cc |
+++ /dev/null |
@@ -1,520 +0,0 @@ |
-// Copyright 2014 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 "chrome/browser/services/gcm/gcm_account_tracker.h" |
- |
-#include <map> |
-#include <string> |
- |
-#include "base/memory/scoped_ptr.h" |
-#include "components/gcm_driver/fake_gcm_driver.h" |
-#include "google_apis/gaia/fake_identity_provider.h" |
-#include "google_apis/gaia/fake_oauth2_token_service.h" |
-#include "google_apis/gaia/google_service_auth_error.h" |
-#include "net/http/http_status_code.h" |
-#include "net/url_request/test_url_fetcher_factory.h" |
-#include "net/url_request/url_request_test_util.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
-namespace gcm { |
- |
-namespace { |
- |
-const char kAccountId1[] = "account_1"; |
-const char kAccountId2[] = "account_2"; |
- |
-std::string AccountKeyToObfuscatedId(const std::string email) { |
- return "obfid-" + email; |
-} |
- |
-std::string GetValidTokenInfoResponse(const std::string account_key) { |
- return std::string("{ \"id\": \"") + AccountKeyToObfuscatedId(account_key) + |
- "\" }"; |
-} |
- |
-std::string MakeAccessToken(const std::string& account_key) { |
- return "access_token-" + account_key; |
-} |
- |
-GCMClient::AccountTokenInfo MakeAccountToken(const std::string& account_key) { |
- GCMClient::AccountTokenInfo token_info; |
- token_info.account_id = account_key; |
- token_info.email = account_key; |
- token_info.access_token = MakeAccessToken(account_key); |
- return token_info; |
-} |
- |
-void VerifyAccountTokens( |
- const std::vector<GCMClient::AccountTokenInfo>& expected_tokens, |
- const std::vector<GCMClient::AccountTokenInfo>& actual_tokens) { |
- EXPECT_EQ(expected_tokens.size(), actual_tokens.size()); |
- for (std::vector<GCMClient::AccountTokenInfo>::const_iterator |
- expected_iter = expected_tokens.begin(), |
- actual_iter = actual_tokens.begin(); |
- expected_iter != expected_tokens.end() && |
- actual_iter != actual_tokens.end(); |
- ++expected_iter, ++actual_iter) { |
- EXPECT_EQ(expected_iter->account_id, actual_iter->account_id); |
- EXPECT_EQ(expected_iter->email, actual_iter->email); |
- EXPECT_EQ(expected_iter->access_token, actual_iter->access_token); |
- } |
-} |
- |
-// This version of FakeGCMDriver is customized around handling accounts and |
-// connection events for testing GCMAccountTracker. |
-class CustomFakeGCMDriver : public FakeGCMDriver { |
- public: |
- CustomFakeGCMDriver(); |
- ~CustomFakeGCMDriver() override; |
- |
- // GCMDriver overrides: |
- void SetAccountTokens( |
- const std::vector<GCMClient::AccountTokenInfo>& account_tokens) override; |
- void AddConnectionObserver(GCMConnectionObserver* observer) override; |
- void RemoveConnectionObserver(GCMConnectionObserver* observer) override; |
- bool IsConnected() const override { return connected_; } |
- base::Time GetLastTokenFetchTime() override; |
- void SetLastTokenFetchTime(const base::Time& time) override; |
- |
- // Test results and helpers. |
- void SetConnected(bool connected); |
- void ResetResults(); |
- bool update_accounts_called() const { return update_accounts_called_; } |
- const std::vector<GCMClient::AccountTokenInfo>& accounts() const { |
- return accounts_; |
- } |
- const GCMConnectionObserver* last_connection_observer() const { |
- return last_connection_observer_; |
- } |
- const GCMConnectionObserver* last_removed_connection_observer() const { |
- return removed_connection_observer_; |
- } |
- |
- private: |
- bool connected_; |
- std::vector<GCMClient::AccountTokenInfo> accounts_; |
- bool update_accounts_called_; |
- GCMConnectionObserver* last_connection_observer_; |
- GCMConnectionObserver* removed_connection_observer_; |
- net::IPEndPoint ip_endpoint_; |
- base::Time last_token_fetch_time_; |
- |
- DISALLOW_COPY_AND_ASSIGN(CustomFakeGCMDriver); |
-}; |
- |
-CustomFakeGCMDriver::CustomFakeGCMDriver() |
- : connected_(true), |
- update_accounts_called_(false), |
- last_connection_observer_(NULL), |
- removed_connection_observer_(NULL) { |
-} |
- |
-CustomFakeGCMDriver::~CustomFakeGCMDriver() { |
-} |
- |
-void CustomFakeGCMDriver::SetAccountTokens( |
- const std::vector<GCMClient::AccountTokenInfo>& accounts) { |
- update_accounts_called_ = true; |
- accounts_ = accounts; |
-} |
- |
-void CustomFakeGCMDriver::AddConnectionObserver( |
- GCMConnectionObserver* observer) { |
- last_connection_observer_ = observer; |
-} |
- |
-void CustomFakeGCMDriver::RemoveConnectionObserver( |
- GCMConnectionObserver* observer) { |
- removed_connection_observer_ = observer; |
-} |
- |
-void CustomFakeGCMDriver::SetConnected(bool connected) { |
- connected_ = connected; |
- if (connected && last_connection_observer_) |
- last_connection_observer_->OnConnected(ip_endpoint_); |
-} |
- |
-void CustomFakeGCMDriver::ResetResults() { |
- accounts_.clear(); |
- update_accounts_called_ = false; |
- last_connection_observer_ = NULL; |
- removed_connection_observer_ = NULL; |
-} |
- |
- |
-base::Time CustomFakeGCMDriver::GetLastTokenFetchTime() { |
- return last_token_fetch_time_; |
-} |
- |
-void CustomFakeGCMDriver::SetLastTokenFetchTime(const base::Time& time) { |
- last_token_fetch_time_ = time; |
-} |
- |
-} // namespace |
- |
-class GCMAccountTrackerTest : public testing::Test { |
- public: |
- GCMAccountTrackerTest(); |
- ~GCMAccountTrackerTest() override; |
- |
- // Helpers to pass fake events to the tracker. Tests should have either a pair |
- // of Start/FinishAccountSignIn or SignInAccount per account. Don't mix. |
- // Call to SignOutAccount is not mandatory. |
- void StartAccountSignIn(const std::string& account_key); |
- void FinishAccountSignIn(const std::string& account_key); |
- void SignInAccount(const std::string& account_key); |
- void SignOutAccount(const std::string& account_key); |
- |
- // Helpers for dealing with OAuth2 access token requests. |
- void IssueAccessToken(const std::string& account_key); |
- void IssueExpiredAccessToken(const std::string& account_key); |
- void IssueError(const std::string& account_key); |
- |
- // Accessors to account tracker and gcm driver. |
- GCMAccountTracker* tracker() { return tracker_.get(); } |
- CustomFakeGCMDriver* driver() { return &driver_; } |
- |
- // Accessors to private methods of account tracker. |
- bool IsFetchingRequired() const; |
- bool IsTokenReportingRequired() const; |
- base::TimeDelta GetTimeToNextTokenReporting() const; |
- |
- private: |
- CustomFakeGCMDriver driver_; |
- |
- base::MessageLoop message_loop_; |
- net::TestURLFetcherFactory test_fetcher_factory_; |
- scoped_ptr<FakeOAuth2TokenService> fake_token_service_; |
- scoped_ptr<FakeIdentityProvider> fake_identity_provider_; |
- scoped_ptr<GCMAccountTracker> tracker_; |
-}; |
- |
-GCMAccountTrackerTest::GCMAccountTrackerTest() { |
- fake_token_service_.reset(new FakeOAuth2TokenService()); |
- |
- fake_identity_provider_.reset( |
- new FakeIdentityProvider(fake_token_service_.get())); |
- |
- scoped_ptr<gaia::AccountTracker> gaia_account_tracker( |
- new gaia::AccountTracker( |
- fake_identity_provider_.get(), |
- new net::TestURLRequestContextGetter(message_loop_.task_runner()))); |
- |
- tracker_.reset(new GCMAccountTracker(gaia_account_tracker.Pass(), &driver_)); |
-} |
- |
-GCMAccountTrackerTest::~GCMAccountTrackerTest() { |
- if (tracker_) |
- tracker_->Shutdown(); |
-} |
- |
-void GCMAccountTrackerTest::StartAccountSignIn(const std::string& account_key) { |
- fake_identity_provider_->LogIn(account_key); |
- fake_token_service_->AddAccount(account_key); |
-} |
- |
-void GCMAccountTrackerTest::FinishAccountSignIn( |
- const std::string& account_key) { |
- IssueAccessToken(account_key); |
- |
- net::TestURLFetcher* fetcher = test_fetcher_factory_.GetFetcherByID( |
- gaia::GaiaOAuthClient::kUrlFetcherId); |
- ASSERT_TRUE(fetcher); |
- fetcher->set_response_code(net::HTTP_OK); |
- fetcher->SetResponseString(GetValidTokenInfoResponse(account_key)); |
- fetcher->delegate()->OnURLFetchComplete(fetcher); |
-} |
- |
-void GCMAccountTrackerTest::SignInAccount(const std::string& account_key) { |
- StartAccountSignIn(account_key); |
- FinishAccountSignIn(account_key); |
-} |
- |
-void GCMAccountTrackerTest::SignOutAccount(const std::string& account_key) { |
- fake_token_service_->RemoveAccount(account_key); |
-} |
- |
-void GCMAccountTrackerTest::IssueAccessToken(const std::string& account_key) { |
- fake_token_service_->IssueAllTokensForAccount( |
- account_key, MakeAccessToken(account_key), base::Time::Max()); |
-} |
- |
-void GCMAccountTrackerTest::IssueExpiredAccessToken( |
- const std::string& account_key) { |
- fake_token_service_->IssueAllTokensForAccount( |
- account_key, MakeAccessToken(account_key), base::Time::Now()); |
-} |
- |
-void GCMAccountTrackerTest::IssueError(const std::string& account_key) { |
- fake_token_service_->IssueErrorForAllPendingRequestsForAccount( |
- account_key, |
- GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE)); |
-} |
- |
-bool GCMAccountTrackerTest::IsFetchingRequired() const { |
- return tracker_->IsTokenFetchingRequired(); |
-} |
- |
-bool GCMAccountTrackerTest::IsTokenReportingRequired() const { |
- return tracker_->IsTokenReportingRequired(); |
-} |
- |
-base::TimeDelta GCMAccountTrackerTest::GetTimeToNextTokenReporting() const { |
- return tracker_->GetTimeToNextTokenReporting(); |
-} |
- |
-TEST_F(GCMAccountTrackerTest, NoAccounts) { |
- EXPECT_FALSE(driver()->update_accounts_called()); |
- tracker()->Start(); |
- // Callback should not be called if there where no accounts provided. |
- EXPECT_FALSE(driver()->update_accounts_called()); |
- EXPECT_TRUE(driver()->accounts().empty()); |
-} |
- |
-// Verifies that callback is called after a token is issued for a single account |
-// with a specific scope. In this scenario, the underlying account tracker is |
-// still working when the CompleteCollectingTokens is called for the first time. |
-TEST_F(GCMAccountTrackerTest, SingleAccount) { |
- StartAccountSignIn(kAccountId1); |
- |
- tracker()->Start(); |
- // We don't have any accounts to report, but given the inner account tracker |
- // is still working we don't make a call with empty accounts list. |
- EXPECT_FALSE(driver()->update_accounts_called()); |
- |
- // This concludes the work of inner account tracker. |
- FinishAccountSignIn(kAccountId1); |
- IssueAccessToken(kAccountId1); |
- |
- EXPECT_TRUE(driver()->update_accounts_called()); |
- |
- std::vector<GCMClient::AccountTokenInfo> expected_accounts; |
- expected_accounts.push_back(MakeAccountToken(kAccountId1)); |
- VerifyAccountTokens(expected_accounts, driver()->accounts()); |
-} |
- |
-TEST_F(GCMAccountTrackerTest, MultipleAccounts) { |
- StartAccountSignIn(kAccountId1); |
- StartAccountSignIn(kAccountId2); |
- |
- tracker()->Start(); |
- EXPECT_FALSE(driver()->update_accounts_called()); |
- |
- FinishAccountSignIn(kAccountId1); |
- IssueAccessToken(kAccountId1); |
- EXPECT_FALSE(driver()->update_accounts_called()); |
- |
- FinishAccountSignIn(kAccountId2); |
- IssueAccessToken(kAccountId2); |
- EXPECT_TRUE(driver()->update_accounts_called()); |
- |
- std::vector<GCMClient::AccountTokenInfo> expected_accounts; |
- expected_accounts.push_back(MakeAccountToken(kAccountId1)); |
- expected_accounts.push_back(MakeAccountToken(kAccountId2)); |
- VerifyAccountTokens(expected_accounts, driver()->accounts()); |
-} |
- |
-TEST_F(GCMAccountTrackerTest, AccountAdded) { |
- tracker()->Start(); |
- driver()->ResetResults(); |
- |
- SignInAccount(kAccountId1); |
- EXPECT_FALSE(driver()->update_accounts_called()); |
- |
- IssueAccessToken(kAccountId1); |
- EXPECT_TRUE(driver()->update_accounts_called()); |
- |
- std::vector<GCMClient::AccountTokenInfo> expected_accounts; |
- expected_accounts.push_back(MakeAccountToken(kAccountId1)); |
- VerifyAccountTokens(expected_accounts, driver()->accounts()); |
-} |
- |
-TEST_F(GCMAccountTrackerTest, AccountRemoved) { |
- SignInAccount(kAccountId1); |
- SignInAccount(kAccountId2); |
- |
- tracker()->Start(); |
- IssueAccessToken(kAccountId1); |
- IssueAccessToken(kAccountId2); |
- EXPECT_TRUE(driver()->update_accounts_called()); |
- |
- driver()->ResetResults(); |
- EXPECT_FALSE(driver()->update_accounts_called()); |
- |
- SignOutAccount(kAccountId2); |
- EXPECT_TRUE(driver()->update_accounts_called()); |
- |
- std::vector<GCMClient::AccountTokenInfo> expected_accounts; |
- expected_accounts.push_back(MakeAccountToken(kAccountId1)); |
- VerifyAccountTokens(expected_accounts, driver()->accounts()); |
-} |
- |
-TEST_F(GCMAccountTrackerTest, GetTokenFailed) { |
- SignInAccount(kAccountId1); |
- SignInAccount(kAccountId2); |
- |
- tracker()->Start(); |
- IssueAccessToken(kAccountId1); |
- EXPECT_FALSE(driver()->update_accounts_called()); |
- |
- IssueError(kAccountId2); |
- |
- // Failed token is not retried any more. Account marked as removed. |
- EXPECT_EQ(0UL, tracker()->get_pending_token_request_count()); |
- EXPECT_TRUE(driver()->update_accounts_called()); |
- |
- std::vector<GCMClient::AccountTokenInfo> expected_accounts; |
- expected_accounts.push_back(MakeAccountToken(kAccountId1)); |
- VerifyAccountTokens(expected_accounts, driver()->accounts()); |
-} |
- |
-TEST_F(GCMAccountTrackerTest, GetTokenFailedAccountRemoved) { |
- SignInAccount(kAccountId1); |
- SignInAccount(kAccountId2); |
- |
- tracker()->Start(); |
- IssueAccessToken(kAccountId1); |
- |
- driver()->ResetResults(); |
- SignOutAccount(kAccountId2); |
- IssueError(kAccountId2); |
- |
- EXPECT_TRUE(driver()->update_accounts_called()); |
- |
- std::vector<GCMClient::AccountTokenInfo> expected_accounts; |
- expected_accounts.push_back(MakeAccountToken(kAccountId1)); |
- VerifyAccountTokens(expected_accounts, driver()->accounts()); |
-} |
- |
-TEST_F(GCMAccountTrackerTest, AccountRemovedWhileRequestsPending) { |
- SignInAccount(kAccountId1); |
- SignInAccount(kAccountId2); |
- |
- tracker()->Start(); |
- IssueAccessToken(kAccountId1); |
- EXPECT_FALSE(driver()->update_accounts_called()); |
- |
- SignOutAccount(kAccountId2); |
- IssueAccessToken(kAccountId2); |
- EXPECT_TRUE(driver()->update_accounts_called()); |
- |
- std::vector<GCMClient::AccountTokenInfo> expected_accounts; |
- expected_accounts.push_back(MakeAccountToken(kAccountId1)); |
- VerifyAccountTokens(expected_accounts, driver()->accounts()); |
-} |
- |
-// Makes sure that tracker observes GCM connection when running. |
-TEST_F(GCMAccountTrackerTest, TrackerObservesConnection) { |
- EXPECT_EQ(NULL, driver()->last_connection_observer()); |
- tracker()->Start(); |
- EXPECT_EQ(tracker(), driver()->last_connection_observer()); |
- tracker()->Shutdown(); |
- EXPECT_EQ(tracker(), driver()->last_removed_connection_observer()); |
-} |
- |
-// Makes sure that token fetching happens only after connection is established. |
-TEST_F(GCMAccountTrackerTest, PostponeTokenFetchingUntilConnected) { |
- driver()->SetConnected(false); |
- StartAccountSignIn(kAccountId1); |
- tracker()->Start(); |
- FinishAccountSignIn(kAccountId1); |
- |
- EXPECT_EQ(0UL, tracker()->get_pending_token_request_count()); |
- driver()->SetConnected(true); |
- |
- EXPECT_EQ(1UL, tracker()->get_pending_token_request_count()); |
-} |
- |
-TEST_F(GCMAccountTrackerTest, InvalidateExpiredTokens) { |
- StartAccountSignIn(kAccountId1); |
- StartAccountSignIn(kAccountId2); |
- tracker()->Start(); |
- FinishAccountSignIn(kAccountId1); |
- FinishAccountSignIn(kAccountId2); |
- |
- EXPECT_EQ(2UL, tracker()->get_pending_token_request_count()); |
- |
- IssueExpiredAccessToken(kAccountId1); |
- IssueAccessToken(kAccountId2); |
- // Because the first token is expired, we expect the sanitize to kick in and |
- // clean it up before the SetAccessToken is called. This also means a new |
- // token request will be issued |
- EXPECT_FALSE(driver()->update_accounts_called()); |
- EXPECT_EQ(1UL, tracker()->get_pending_token_request_count()); |
-} |
- |
-// Testing for whether there are still more tokens to be fetched. Typically the |
-// need for token fetching triggers immediate request, unless there is no |
-// connection, that is why connection is set on and off in this test. |
-TEST_F(GCMAccountTrackerTest, IsTokenFetchingRequired) { |
- tracker()->Start(); |
- driver()->SetConnected(false); |
- EXPECT_FALSE(IsFetchingRequired()); |
- StartAccountSignIn(kAccountId1); |
- FinishAccountSignIn(kAccountId1); |
- EXPECT_TRUE(IsFetchingRequired()); |
- |
- driver()->SetConnected(true); |
- EXPECT_FALSE(IsFetchingRequired()); // Indicates that fetching has started. |
- IssueAccessToken(kAccountId1); |
- EXPECT_FALSE(IsFetchingRequired()); |
- |
- driver()->SetConnected(false); |
- StartAccountSignIn(kAccountId2); |
- FinishAccountSignIn(kAccountId2); |
- EXPECT_TRUE(IsFetchingRequired()); |
- |
- IssueExpiredAccessToken(kAccountId2); |
- // Make sure that if the token was expired it is still needed. |
- EXPECT_TRUE(IsFetchingRequired()); |
-} |
- |
-// Tests what is the expected time to the next token fetching. |
-TEST_F(GCMAccountTrackerTest, GetTimeToNextTokenReporting) { |
- tracker()->Start(); |
- // At this point the last token fetch time is never. |
- EXPECT_EQ(base::TimeDelta(), GetTimeToNextTokenReporting()); |
- |
- // Regular case. The tokens have been just reported. |
- driver()->SetLastTokenFetchTime(base::Time::Now()); |
- EXPECT_TRUE(GetTimeToNextTokenReporting() <= |
- base::TimeDelta::FromSeconds(12 * 60 * 60)); |
- |
- // A case when gcm driver is not yet initialized. |
- driver()->SetLastTokenFetchTime(base::Time::Max()); |
- EXPECT_EQ(base::TimeDelta::FromSeconds(12 * 60 * 60), |
- GetTimeToNextTokenReporting()); |
- |
- // A case when token reporting calculation is expected to result in more than |
- // 12 hours, in which case we expect exactly 12 hours. |
- driver()->SetLastTokenFetchTime(base::Time::Now() + |
- base::TimeDelta::FromDays(2)); |
- EXPECT_EQ(base::TimeDelta::FromSeconds(12 * 60 * 60), |
- GetTimeToNextTokenReporting()); |
-} |
- |
-// Tests conditions when token reporting is required. |
-TEST_F(GCMAccountTrackerTest, IsTokenReportingRequired) { |
- tracker()->Start(); |
- // Required because it is overdue. |
- EXPECT_TRUE(IsTokenReportingRequired()); |
- |
- // Not required because it just happened. |
- driver()->SetLastTokenFetchTime(base::Time::Now()); |
- EXPECT_FALSE(IsTokenReportingRequired()); |
- |
- SignInAccount(kAccountId1); |
- IssueAccessToken(kAccountId1); |
- driver()->ResetResults(); |
- // Reporting was triggered, which means testing for required will give false, |
- // but we have the update call. |
- SignOutAccount(kAccountId1); |
- EXPECT_TRUE(driver()->update_accounts_called()); |
- EXPECT_FALSE(IsTokenReportingRequired()); |
-} |
- |
-// TODO(fgorski): Add test for adding account after removal >> make sure it does |
-// not mark removal. |
- |
-} // namespace gcm |