| OLD | NEW |
| (Empty) |
| 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 #include "chrome/browser/services/gcm/gcm_account_tracker.h" | |
| 6 | |
| 7 #include <map> | |
| 8 #include <string> | |
| 9 | |
| 10 #include "base/memory/scoped_ptr.h" | |
| 11 #include "components/gcm_driver/fake_gcm_driver.h" | |
| 12 #include "google_apis/gaia/fake_identity_provider.h" | |
| 13 #include "google_apis/gaia/fake_oauth2_token_service.h" | |
| 14 #include "google_apis/gaia/google_service_auth_error.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_request_test_util.h" | |
| 18 #include "testing/gtest/include/gtest/gtest.h" | |
| 19 | |
| 20 namespace gcm { | |
| 21 | |
| 22 namespace { | |
| 23 | |
| 24 const char kAccountId1[] = "account_1"; | |
| 25 const char kAccountId2[] = "account_2"; | |
| 26 | |
| 27 std::string AccountKeyToObfuscatedId(const std::string email) { | |
| 28 return "obfid-" + email; | |
| 29 } | |
| 30 | |
| 31 std::string GetValidTokenInfoResponse(const std::string account_key) { | |
| 32 return std::string("{ \"id\": \"") + AccountKeyToObfuscatedId(account_key) + | |
| 33 "\" }"; | |
| 34 } | |
| 35 | |
| 36 std::string MakeAccessToken(const std::string& account_key) { | |
| 37 return "access_token-" + account_key; | |
| 38 } | |
| 39 | |
| 40 GCMClient::AccountTokenInfo MakeAccountToken(const std::string& account_key) { | |
| 41 GCMClient::AccountTokenInfo token_info; | |
| 42 token_info.account_id = account_key; | |
| 43 token_info.email = account_key; | |
| 44 token_info.access_token = MakeAccessToken(account_key); | |
| 45 return token_info; | |
| 46 } | |
| 47 | |
| 48 void VerifyAccountTokens( | |
| 49 const std::vector<GCMClient::AccountTokenInfo>& expected_tokens, | |
| 50 const std::vector<GCMClient::AccountTokenInfo>& actual_tokens) { | |
| 51 EXPECT_EQ(expected_tokens.size(), actual_tokens.size()); | |
| 52 for (std::vector<GCMClient::AccountTokenInfo>::const_iterator | |
| 53 expected_iter = expected_tokens.begin(), | |
| 54 actual_iter = actual_tokens.begin(); | |
| 55 expected_iter != expected_tokens.end() && | |
| 56 actual_iter != actual_tokens.end(); | |
| 57 ++expected_iter, ++actual_iter) { | |
| 58 EXPECT_EQ(expected_iter->account_id, actual_iter->account_id); | |
| 59 EXPECT_EQ(expected_iter->email, actual_iter->email); | |
| 60 EXPECT_EQ(expected_iter->access_token, actual_iter->access_token); | |
| 61 } | |
| 62 } | |
| 63 | |
| 64 // This version of FakeGCMDriver is customized around handling accounts and | |
| 65 // connection events for testing GCMAccountTracker. | |
| 66 class CustomFakeGCMDriver : public FakeGCMDriver { | |
| 67 public: | |
| 68 CustomFakeGCMDriver(); | |
| 69 ~CustomFakeGCMDriver() override; | |
| 70 | |
| 71 // GCMDriver overrides: | |
| 72 void SetAccountTokens( | |
| 73 const std::vector<GCMClient::AccountTokenInfo>& account_tokens) override; | |
| 74 void AddConnectionObserver(GCMConnectionObserver* observer) override; | |
| 75 void RemoveConnectionObserver(GCMConnectionObserver* observer) override; | |
| 76 bool IsConnected() const override { return connected_; } | |
| 77 base::Time GetLastTokenFetchTime() override; | |
| 78 void SetLastTokenFetchTime(const base::Time& time) override; | |
| 79 | |
| 80 // Test results and helpers. | |
| 81 void SetConnected(bool connected); | |
| 82 void ResetResults(); | |
| 83 bool update_accounts_called() const { return update_accounts_called_; } | |
| 84 const std::vector<GCMClient::AccountTokenInfo>& accounts() const { | |
| 85 return accounts_; | |
| 86 } | |
| 87 const GCMConnectionObserver* last_connection_observer() const { | |
| 88 return last_connection_observer_; | |
| 89 } | |
| 90 const GCMConnectionObserver* last_removed_connection_observer() const { | |
| 91 return removed_connection_observer_; | |
| 92 } | |
| 93 | |
| 94 private: | |
| 95 bool connected_; | |
| 96 std::vector<GCMClient::AccountTokenInfo> accounts_; | |
| 97 bool update_accounts_called_; | |
| 98 GCMConnectionObserver* last_connection_observer_; | |
| 99 GCMConnectionObserver* removed_connection_observer_; | |
| 100 net::IPEndPoint ip_endpoint_; | |
| 101 base::Time last_token_fetch_time_; | |
| 102 | |
| 103 DISALLOW_COPY_AND_ASSIGN(CustomFakeGCMDriver); | |
| 104 }; | |
| 105 | |
| 106 CustomFakeGCMDriver::CustomFakeGCMDriver() | |
| 107 : connected_(true), | |
| 108 update_accounts_called_(false), | |
| 109 last_connection_observer_(NULL), | |
| 110 removed_connection_observer_(NULL) { | |
| 111 } | |
| 112 | |
| 113 CustomFakeGCMDriver::~CustomFakeGCMDriver() { | |
| 114 } | |
| 115 | |
| 116 void CustomFakeGCMDriver::SetAccountTokens( | |
| 117 const std::vector<GCMClient::AccountTokenInfo>& accounts) { | |
| 118 update_accounts_called_ = true; | |
| 119 accounts_ = accounts; | |
| 120 } | |
| 121 | |
| 122 void CustomFakeGCMDriver::AddConnectionObserver( | |
| 123 GCMConnectionObserver* observer) { | |
| 124 last_connection_observer_ = observer; | |
| 125 } | |
| 126 | |
| 127 void CustomFakeGCMDriver::RemoveConnectionObserver( | |
| 128 GCMConnectionObserver* observer) { | |
| 129 removed_connection_observer_ = observer; | |
| 130 } | |
| 131 | |
| 132 void CustomFakeGCMDriver::SetConnected(bool connected) { | |
| 133 connected_ = connected; | |
| 134 if (connected && last_connection_observer_) | |
| 135 last_connection_observer_->OnConnected(ip_endpoint_); | |
| 136 } | |
| 137 | |
| 138 void CustomFakeGCMDriver::ResetResults() { | |
| 139 accounts_.clear(); | |
| 140 update_accounts_called_ = false; | |
| 141 last_connection_observer_ = NULL; | |
| 142 removed_connection_observer_ = NULL; | |
| 143 } | |
| 144 | |
| 145 | |
| 146 base::Time CustomFakeGCMDriver::GetLastTokenFetchTime() { | |
| 147 return last_token_fetch_time_; | |
| 148 } | |
| 149 | |
| 150 void CustomFakeGCMDriver::SetLastTokenFetchTime(const base::Time& time) { | |
| 151 last_token_fetch_time_ = time; | |
| 152 } | |
| 153 | |
| 154 } // namespace | |
| 155 | |
| 156 class GCMAccountTrackerTest : public testing::Test { | |
| 157 public: | |
| 158 GCMAccountTrackerTest(); | |
| 159 ~GCMAccountTrackerTest() override; | |
| 160 | |
| 161 // Helpers to pass fake events to the tracker. Tests should have either a pair | |
| 162 // of Start/FinishAccountSignIn or SignInAccount per account. Don't mix. | |
| 163 // Call to SignOutAccount is not mandatory. | |
| 164 void StartAccountSignIn(const std::string& account_key); | |
| 165 void FinishAccountSignIn(const std::string& account_key); | |
| 166 void SignInAccount(const std::string& account_key); | |
| 167 void SignOutAccount(const std::string& account_key); | |
| 168 | |
| 169 // Helpers for dealing with OAuth2 access token requests. | |
| 170 void IssueAccessToken(const std::string& account_key); | |
| 171 void IssueExpiredAccessToken(const std::string& account_key); | |
| 172 void IssueError(const std::string& account_key); | |
| 173 | |
| 174 // Accessors to account tracker and gcm driver. | |
| 175 GCMAccountTracker* tracker() { return tracker_.get(); } | |
| 176 CustomFakeGCMDriver* driver() { return &driver_; } | |
| 177 | |
| 178 // Accessors to private methods of account tracker. | |
| 179 bool IsFetchingRequired() const; | |
| 180 bool IsTokenReportingRequired() const; | |
| 181 base::TimeDelta GetTimeToNextTokenReporting() const; | |
| 182 | |
| 183 private: | |
| 184 CustomFakeGCMDriver driver_; | |
| 185 | |
| 186 base::MessageLoop message_loop_; | |
| 187 net::TestURLFetcherFactory test_fetcher_factory_; | |
| 188 scoped_ptr<FakeOAuth2TokenService> fake_token_service_; | |
| 189 scoped_ptr<FakeIdentityProvider> fake_identity_provider_; | |
| 190 scoped_ptr<GCMAccountTracker> tracker_; | |
| 191 }; | |
| 192 | |
| 193 GCMAccountTrackerTest::GCMAccountTrackerTest() { | |
| 194 fake_token_service_.reset(new FakeOAuth2TokenService()); | |
| 195 | |
| 196 fake_identity_provider_.reset( | |
| 197 new FakeIdentityProvider(fake_token_service_.get())); | |
| 198 | |
| 199 scoped_ptr<gaia::AccountTracker> gaia_account_tracker( | |
| 200 new gaia::AccountTracker( | |
| 201 fake_identity_provider_.get(), | |
| 202 new net::TestURLRequestContextGetter(message_loop_.task_runner()))); | |
| 203 | |
| 204 tracker_.reset(new GCMAccountTracker(gaia_account_tracker.Pass(), &driver_)); | |
| 205 } | |
| 206 | |
| 207 GCMAccountTrackerTest::~GCMAccountTrackerTest() { | |
| 208 if (tracker_) | |
| 209 tracker_->Shutdown(); | |
| 210 } | |
| 211 | |
| 212 void GCMAccountTrackerTest::StartAccountSignIn(const std::string& account_key) { | |
| 213 fake_identity_provider_->LogIn(account_key); | |
| 214 fake_token_service_->AddAccount(account_key); | |
| 215 } | |
| 216 | |
| 217 void GCMAccountTrackerTest::FinishAccountSignIn( | |
| 218 const std::string& account_key) { | |
| 219 IssueAccessToken(account_key); | |
| 220 | |
| 221 net::TestURLFetcher* fetcher = test_fetcher_factory_.GetFetcherByID( | |
| 222 gaia::GaiaOAuthClient::kUrlFetcherId); | |
| 223 ASSERT_TRUE(fetcher); | |
| 224 fetcher->set_response_code(net::HTTP_OK); | |
| 225 fetcher->SetResponseString(GetValidTokenInfoResponse(account_key)); | |
| 226 fetcher->delegate()->OnURLFetchComplete(fetcher); | |
| 227 } | |
| 228 | |
| 229 void GCMAccountTrackerTest::SignInAccount(const std::string& account_key) { | |
| 230 StartAccountSignIn(account_key); | |
| 231 FinishAccountSignIn(account_key); | |
| 232 } | |
| 233 | |
| 234 void GCMAccountTrackerTest::SignOutAccount(const std::string& account_key) { | |
| 235 fake_token_service_->RemoveAccount(account_key); | |
| 236 } | |
| 237 | |
| 238 void GCMAccountTrackerTest::IssueAccessToken(const std::string& account_key) { | |
| 239 fake_token_service_->IssueAllTokensForAccount( | |
| 240 account_key, MakeAccessToken(account_key), base::Time::Max()); | |
| 241 } | |
| 242 | |
| 243 void GCMAccountTrackerTest::IssueExpiredAccessToken( | |
| 244 const std::string& account_key) { | |
| 245 fake_token_service_->IssueAllTokensForAccount( | |
| 246 account_key, MakeAccessToken(account_key), base::Time::Now()); | |
| 247 } | |
| 248 | |
| 249 void GCMAccountTrackerTest::IssueError(const std::string& account_key) { | |
| 250 fake_token_service_->IssueErrorForAllPendingRequestsForAccount( | |
| 251 account_key, | |
| 252 GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE)); | |
| 253 } | |
| 254 | |
| 255 bool GCMAccountTrackerTest::IsFetchingRequired() const { | |
| 256 return tracker_->IsTokenFetchingRequired(); | |
| 257 } | |
| 258 | |
| 259 bool GCMAccountTrackerTest::IsTokenReportingRequired() const { | |
| 260 return tracker_->IsTokenReportingRequired(); | |
| 261 } | |
| 262 | |
| 263 base::TimeDelta GCMAccountTrackerTest::GetTimeToNextTokenReporting() const { | |
| 264 return tracker_->GetTimeToNextTokenReporting(); | |
| 265 } | |
| 266 | |
| 267 TEST_F(GCMAccountTrackerTest, NoAccounts) { | |
| 268 EXPECT_FALSE(driver()->update_accounts_called()); | |
| 269 tracker()->Start(); | |
| 270 // Callback should not be called if there where no accounts provided. | |
| 271 EXPECT_FALSE(driver()->update_accounts_called()); | |
| 272 EXPECT_TRUE(driver()->accounts().empty()); | |
| 273 } | |
| 274 | |
| 275 // Verifies that callback is called after a token is issued for a single account | |
| 276 // with a specific scope. In this scenario, the underlying account tracker is | |
| 277 // still working when the CompleteCollectingTokens is called for the first time. | |
| 278 TEST_F(GCMAccountTrackerTest, SingleAccount) { | |
| 279 StartAccountSignIn(kAccountId1); | |
| 280 | |
| 281 tracker()->Start(); | |
| 282 // We don't have any accounts to report, but given the inner account tracker | |
| 283 // is still working we don't make a call with empty accounts list. | |
| 284 EXPECT_FALSE(driver()->update_accounts_called()); | |
| 285 | |
| 286 // This concludes the work of inner account tracker. | |
| 287 FinishAccountSignIn(kAccountId1); | |
| 288 IssueAccessToken(kAccountId1); | |
| 289 | |
| 290 EXPECT_TRUE(driver()->update_accounts_called()); | |
| 291 | |
| 292 std::vector<GCMClient::AccountTokenInfo> expected_accounts; | |
| 293 expected_accounts.push_back(MakeAccountToken(kAccountId1)); | |
| 294 VerifyAccountTokens(expected_accounts, driver()->accounts()); | |
| 295 } | |
| 296 | |
| 297 TEST_F(GCMAccountTrackerTest, MultipleAccounts) { | |
| 298 StartAccountSignIn(kAccountId1); | |
| 299 StartAccountSignIn(kAccountId2); | |
| 300 | |
| 301 tracker()->Start(); | |
| 302 EXPECT_FALSE(driver()->update_accounts_called()); | |
| 303 | |
| 304 FinishAccountSignIn(kAccountId1); | |
| 305 IssueAccessToken(kAccountId1); | |
| 306 EXPECT_FALSE(driver()->update_accounts_called()); | |
| 307 | |
| 308 FinishAccountSignIn(kAccountId2); | |
| 309 IssueAccessToken(kAccountId2); | |
| 310 EXPECT_TRUE(driver()->update_accounts_called()); | |
| 311 | |
| 312 std::vector<GCMClient::AccountTokenInfo> expected_accounts; | |
| 313 expected_accounts.push_back(MakeAccountToken(kAccountId1)); | |
| 314 expected_accounts.push_back(MakeAccountToken(kAccountId2)); | |
| 315 VerifyAccountTokens(expected_accounts, driver()->accounts()); | |
| 316 } | |
| 317 | |
| 318 TEST_F(GCMAccountTrackerTest, AccountAdded) { | |
| 319 tracker()->Start(); | |
| 320 driver()->ResetResults(); | |
| 321 | |
| 322 SignInAccount(kAccountId1); | |
| 323 EXPECT_FALSE(driver()->update_accounts_called()); | |
| 324 | |
| 325 IssueAccessToken(kAccountId1); | |
| 326 EXPECT_TRUE(driver()->update_accounts_called()); | |
| 327 | |
| 328 std::vector<GCMClient::AccountTokenInfo> expected_accounts; | |
| 329 expected_accounts.push_back(MakeAccountToken(kAccountId1)); | |
| 330 VerifyAccountTokens(expected_accounts, driver()->accounts()); | |
| 331 } | |
| 332 | |
| 333 TEST_F(GCMAccountTrackerTest, AccountRemoved) { | |
| 334 SignInAccount(kAccountId1); | |
| 335 SignInAccount(kAccountId2); | |
| 336 | |
| 337 tracker()->Start(); | |
| 338 IssueAccessToken(kAccountId1); | |
| 339 IssueAccessToken(kAccountId2); | |
| 340 EXPECT_TRUE(driver()->update_accounts_called()); | |
| 341 | |
| 342 driver()->ResetResults(); | |
| 343 EXPECT_FALSE(driver()->update_accounts_called()); | |
| 344 | |
| 345 SignOutAccount(kAccountId2); | |
| 346 EXPECT_TRUE(driver()->update_accounts_called()); | |
| 347 | |
| 348 std::vector<GCMClient::AccountTokenInfo> expected_accounts; | |
| 349 expected_accounts.push_back(MakeAccountToken(kAccountId1)); | |
| 350 VerifyAccountTokens(expected_accounts, driver()->accounts()); | |
| 351 } | |
| 352 | |
| 353 TEST_F(GCMAccountTrackerTest, GetTokenFailed) { | |
| 354 SignInAccount(kAccountId1); | |
| 355 SignInAccount(kAccountId2); | |
| 356 | |
| 357 tracker()->Start(); | |
| 358 IssueAccessToken(kAccountId1); | |
| 359 EXPECT_FALSE(driver()->update_accounts_called()); | |
| 360 | |
| 361 IssueError(kAccountId2); | |
| 362 | |
| 363 // Failed token is not retried any more. Account marked as removed. | |
| 364 EXPECT_EQ(0UL, tracker()->get_pending_token_request_count()); | |
| 365 EXPECT_TRUE(driver()->update_accounts_called()); | |
| 366 | |
| 367 std::vector<GCMClient::AccountTokenInfo> expected_accounts; | |
| 368 expected_accounts.push_back(MakeAccountToken(kAccountId1)); | |
| 369 VerifyAccountTokens(expected_accounts, driver()->accounts()); | |
| 370 } | |
| 371 | |
| 372 TEST_F(GCMAccountTrackerTest, GetTokenFailedAccountRemoved) { | |
| 373 SignInAccount(kAccountId1); | |
| 374 SignInAccount(kAccountId2); | |
| 375 | |
| 376 tracker()->Start(); | |
| 377 IssueAccessToken(kAccountId1); | |
| 378 | |
| 379 driver()->ResetResults(); | |
| 380 SignOutAccount(kAccountId2); | |
| 381 IssueError(kAccountId2); | |
| 382 | |
| 383 EXPECT_TRUE(driver()->update_accounts_called()); | |
| 384 | |
| 385 std::vector<GCMClient::AccountTokenInfo> expected_accounts; | |
| 386 expected_accounts.push_back(MakeAccountToken(kAccountId1)); | |
| 387 VerifyAccountTokens(expected_accounts, driver()->accounts()); | |
| 388 } | |
| 389 | |
| 390 TEST_F(GCMAccountTrackerTest, AccountRemovedWhileRequestsPending) { | |
| 391 SignInAccount(kAccountId1); | |
| 392 SignInAccount(kAccountId2); | |
| 393 | |
| 394 tracker()->Start(); | |
| 395 IssueAccessToken(kAccountId1); | |
| 396 EXPECT_FALSE(driver()->update_accounts_called()); | |
| 397 | |
| 398 SignOutAccount(kAccountId2); | |
| 399 IssueAccessToken(kAccountId2); | |
| 400 EXPECT_TRUE(driver()->update_accounts_called()); | |
| 401 | |
| 402 std::vector<GCMClient::AccountTokenInfo> expected_accounts; | |
| 403 expected_accounts.push_back(MakeAccountToken(kAccountId1)); | |
| 404 VerifyAccountTokens(expected_accounts, driver()->accounts()); | |
| 405 } | |
| 406 | |
| 407 // Makes sure that tracker observes GCM connection when running. | |
| 408 TEST_F(GCMAccountTrackerTest, TrackerObservesConnection) { | |
| 409 EXPECT_EQ(NULL, driver()->last_connection_observer()); | |
| 410 tracker()->Start(); | |
| 411 EXPECT_EQ(tracker(), driver()->last_connection_observer()); | |
| 412 tracker()->Shutdown(); | |
| 413 EXPECT_EQ(tracker(), driver()->last_removed_connection_observer()); | |
| 414 } | |
| 415 | |
| 416 // Makes sure that token fetching happens only after connection is established. | |
| 417 TEST_F(GCMAccountTrackerTest, PostponeTokenFetchingUntilConnected) { | |
| 418 driver()->SetConnected(false); | |
| 419 StartAccountSignIn(kAccountId1); | |
| 420 tracker()->Start(); | |
| 421 FinishAccountSignIn(kAccountId1); | |
| 422 | |
| 423 EXPECT_EQ(0UL, tracker()->get_pending_token_request_count()); | |
| 424 driver()->SetConnected(true); | |
| 425 | |
| 426 EXPECT_EQ(1UL, tracker()->get_pending_token_request_count()); | |
| 427 } | |
| 428 | |
| 429 TEST_F(GCMAccountTrackerTest, InvalidateExpiredTokens) { | |
| 430 StartAccountSignIn(kAccountId1); | |
| 431 StartAccountSignIn(kAccountId2); | |
| 432 tracker()->Start(); | |
| 433 FinishAccountSignIn(kAccountId1); | |
| 434 FinishAccountSignIn(kAccountId2); | |
| 435 | |
| 436 EXPECT_EQ(2UL, tracker()->get_pending_token_request_count()); | |
| 437 | |
| 438 IssueExpiredAccessToken(kAccountId1); | |
| 439 IssueAccessToken(kAccountId2); | |
| 440 // Because the first token is expired, we expect the sanitize to kick in and | |
| 441 // clean it up before the SetAccessToken is called. This also means a new | |
| 442 // token request will be issued | |
| 443 EXPECT_FALSE(driver()->update_accounts_called()); | |
| 444 EXPECT_EQ(1UL, tracker()->get_pending_token_request_count()); | |
| 445 } | |
| 446 | |
| 447 // Testing for whether there are still more tokens to be fetched. Typically the | |
| 448 // need for token fetching triggers immediate request, unless there is no | |
| 449 // connection, that is why connection is set on and off in this test. | |
| 450 TEST_F(GCMAccountTrackerTest, IsTokenFetchingRequired) { | |
| 451 tracker()->Start(); | |
| 452 driver()->SetConnected(false); | |
| 453 EXPECT_FALSE(IsFetchingRequired()); | |
| 454 StartAccountSignIn(kAccountId1); | |
| 455 FinishAccountSignIn(kAccountId1); | |
| 456 EXPECT_TRUE(IsFetchingRequired()); | |
| 457 | |
| 458 driver()->SetConnected(true); | |
| 459 EXPECT_FALSE(IsFetchingRequired()); // Indicates that fetching has started. | |
| 460 IssueAccessToken(kAccountId1); | |
| 461 EXPECT_FALSE(IsFetchingRequired()); | |
| 462 | |
| 463 driver()->SetConnected(false); | |
| 464 StartAccountSignIn(kAccountId2); | |
| 465 FinishAccountSignIn(kAccountId2); | |
| 466 EXPECT_TRUE(IsFetchingRequired()); | |
| 467 | |
| 468 IssueExpiredAccessToken(kAccountId2); | |
| 469 // Make sure that if the token was expired it is still needed. | |
| 470 EXPECT_TRUE(IsFetchingRequired()); | |
| 471 } | |
| 472 | |
| 473 // Tests what is the expected time to the next token fetching. | |
| 474 TEST_F(GCMAccountTrackerTest, GetTimeToNextTokenReporting) { | |
| 475 tracker()->Start(); | |
| 476 // At this point the last token fetch time is never. | |
| 477 EXPECT_EQ(base::TimeDelta(), GetTimeToNextTokenReporting()); | |
| 478 | |
| 479 // Regular case. The tokens have been just reported. | |
| 480 driver()->SetLastTokenFetchTime(base::Time::Now()); | |
| 481 EXPECT_TRUE(GetTimeToNextTokenReporting() <= | |
| 482 base::TimeDelta::FromSeconds(12 * 60 * 60)); | |
| 483 | |
| 484 // A case when gcm driver is not yet initialized. | |
| 485 driver()->SetLastTokenFetchTime(base::Time::Max()); | |
| 486 EXPECT_EQ(base::TimeDelta::FromSeconds(12 * 60 * 60), | |
| 487 GetTimeToNextTokenReporting()); | |
| 488 | |
| 489 // A case when token reporting calculation is expected to result in more than | |
| 490 // 12 hours, in which case we expect exactly 12 hours. | |
| 491 driver()->SetLastTokenFetchTime(base::Time::Now() + | |
| 492 base::TimeDelta::FromDays(2)); | |
| 493 EXPECT_EQ(base::TimeDelta::FromSeconds(12 * 60 * 60), | |
| 494 GetTimeToNextTokenReporting()); | |
| 495 } | |
| 496 | |
| 497 // Tests conditions when token reporting is required. | |
| 498 TEST_F(GCMAccountTrackerTest, IsTokenReportingRequired) { | |
| 499 tracker()->Start(); | |
| 500 // Required because it is overdue. | |
| 501 EXPECT_TRUE(IsTokenReportingRequired()); | |
| 502 | |
| 503 // Not required because it just happened. | |
| 504 driver()->SetLastTokenFetchTime(base::Time::Now()); | |
| 505 EXPECT_FALSE(IsTokenReportingRequired()); | |
| 506 | |
| 507 SignInAccount(kAccountId1); | |
| 508 IssueAccessToken(kAccountId1); | |
| 509 driver()->ResetResults(); | |
| 510 // Reporting was triggered, which means testing for required will give false, | |
| 511 // but we have the update call. | |
| 512 SignOutAccount(kAccountId1); | |
| 513 EXPECT_TRUE(driver()->update_accounts_called()); | |
| 514 EXPECT_FALSE(IsTokenReportingRequired()); | |
| 515 } | |
| 516 | |
| 517 // TODO(fgorski): Add test for adding account after removal >> make sure it does | |
| 518 // not mark removal. | |
| 519 | |
| 520 } // namespace gcm | |
| OLD | NEW |