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.
5 #include "google_apis/gaia/account_tracker.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/strings/stringprintf.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/gaia_oauth_client.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_delegate.h"
18 #include "net/url_request/url_request_test_util.h"
19 #include "testing/gtest/include/gtest/gtest.h"
23 const char kPrimaryAccountKey
[] = "primary_account@example.com";
25 enum TrackingEventType
{
32 std::string
AccountKeyToObfuscatedId(const std::string email
) {
33 return "obfid-" + email
;
38 TrackingEvent(TrackingEventType type
,
39 const std::string
& account_key
,
40 const std::string
& gaia_id
)
42 account_key_(account_key
),
45 TrackingEvent(TrackingEventType type
,
46 const std::string
& account_key
)
48 account_key_(account_key
),
49 gaia_id_(AccountKeyToObfuscatedId(account_key
)) {}
51 bool operator==(const TrackingEvent
& event
) const {
52 return type_
== event
.type_
&& account_key_
== event
.account_key_
&&
53 gaia_id_
== event
.gaia_id_
;
56 std::string
ToString() const {
57 const char * typestr
= "INVALID";
72 return base::StringPrintf("{ type: %s, email: %s, gaia: %s }",
79 friend bool CompareByUser(TrackingEvent a
, TrackingEvent b
);
81 TrackingEventType type_
;
82 std::string account_key_
;
86 bool CompareByUser(TrackingEvent a
, TrackingEvent b
) {
87 return a
.account_key_
< b
.account_key_
;
90 std::string
Str(const std::vector
<TrackingEvent
>& events
) {
91 std::string str
= "[";
92 bool needs_comma
= false;
93 for (std::vector
<TrackingEvent
>::const_iterator it
=
94 events
.begin(); it
!= events
.end(); ++it
) {
98 str
+= it
->ToString();
108 class AccountTrackerObserver
: public AccountTracker::Observer
{
110 AccountTrackerObserver() {}
111 virtual ~AccountTrackerObserver() {}
113 testing::AssertionResult
CheckEvents();
114 testing::AssertionResult
CheckEvents(const TrackingEvent
& e1
);
115 testing::AssertionResult
CheckEvents(const TrackingEvent
& e1
,
116 const TrackingEvent
& e2
);
117 testing::AssertionResult
CheckEvents(const TrackingEvent
& e1
,
118 const TrackingEvent
& e2
,
119 const TrackingEvent
& e3
);
120 testing::AssertionResult
CheckEvents(const TrackingEvent
& e1
,
121 const TrackingEvent
& e2
,
122 const TrackingEvent
& e3
,
123 const TrackingEvent
& e4
);
124 testing::AssertionResult
CheckEvents(const TrackingEvent
& e1
,
125 const TrackingEvent
& e2
,
126 const TrackingEvent
& e3
,
127 const TrackingEvent
& e4
,
128 const TrackingEvent
& e5
);
129 testing::AssertionResult
CheckEvents(const TrackingEvent
& e1
,
130 const TrackingEvent
& e2
,
131 const TrackingEvent
& e3
,
132 const TrackingEvent
& e4
,
133 const TrackingEvent
& e5
,
134 const TrackingEvent
& e6
);
136 void SortEventsByUser();
138 // AccountTracker::Observer implementation
139 virtual void OnAccountAdded(const AccountIds
& ids
) OVERRIDE
;
140 virtual void OnAccountRemoved(const AccountIds
& ids
) OVERRIDE
;
141 virtual void OnAccountSignInChanged(const AccountIds
& ids
, bool is_signed_in
)
145 testing::AssertionResult
CheckEvents(
146 const std::vector
<TrackingEvent
>& events
);
148 std::vector
<TrackingEvent
> events_
;
151 void AccountTrackerObserver::OnAccountAdded(const AccountIds
& ids
) {
152 events_
.push_back(TrackingEvent(ADDED
, ids
.email
, ids
.gaia
));
155 void AccountTrackerObserver::OnAccountRemoved(const AccountIds
& ids
) {
156 events_
.push_back(TrackingEvent(REMOVED
, ids
.email
, ids
.gaia
));
159 void AccountTrackerObserver::OnAccountSignInChanged(const AccountIds
& ids
,
162 TrackingEvent(is_signed_in
? SIGN_IN
: SIGN_OUT
, ids
.email
, ids
.gaia
));
165 void AccountTrackerObserver::Clear() {
169 void AccountTrackerObserver::SortEventsByUser() {
170 std::stable_sort(events_
.begin(), events_
.end(), CompareByUser
);
173 testing::AssertionResult
AccountTrackerObserver::CheckEvents() {
174 std::vector
<TrackingEvent
> events
;
175 return CheckEvents(events
);
178 testing::AssertionResult
AccountTrackerObserver::CheckEvents(
179 const TrackingEvent
& e1
) {
180 std::vector
<TrackingEvent
> events
;
181 events
.push_back(e1
);
182 return CheckEvents(events
);
185 testing::AssertionResult
AccountTrackerObserver::CheckEvents(
186 const TrackingEvent
& e1
,
187 const TrackingEvent
& e2
) {
188 std::vector
<TrackingEvent
> events
;
189 events
.push_back(e1
);
190 events
.push_back(e2
);
191 return CheckEvents(events
);
194 testing::AssertionResult
AccountTrackerObserver::CheckEvents(
195 const TrackingEvent
& e1
,
196 const TrackingEvent
& e2
,
197 const TrackingEvent
& e3
) {
198 std::vector
<TrackingEvent
> events
;
199 events
.push_back(e1
);
200 events
.push_back(e2
);
201 events
.push_back(e3
);
202 return CheckEvents(events
);
205 testing::AssertionResult
AccountTrackerObserver::CheckEvents(
206 const TrackingEvent
& e1
,
207 const TrackingEvent
& e2
,
208 const TrackingEvent
& e3
,
209 const TrackingEvent
& e4
) {
210 std::vector
<TrackingEvent
> events
;
211 events
.push_back(e1
);
212 events
.push_back(e2
);
213 events
.push_back(e3
);
214 events
.push_back(e4
);
215 return CheckEvents(events
);
218 testing::AssertionResult
AccountTrackerObserver::CheckEvents(
219 const TrackingEvent
& e1
,
220 const TrackingEvent
& e2
,
221 const TrackingEvent
& e3
,
222 const TrackingEvent
& e4
,
223 const TrackingEvent
& e5
) {
224 std::vector
<TrackingEvent
> events
;
225 events
.push_back(e1
);
226 events
.push_back(e2
);
227 events
.push_back(e3
);
228 events
.push_back(e4
);
229 events
.push_back(e5
);
230 return CheckEvents(events
);
233 testing::AssertionResult
AccountTrackerObserver::CheckEvents(
234 const TrackingEvent
& e1
,
235 const TrackingEvent
& e2
,
236 const TrackingEvent
& e3
,
237 const TrackingEvent
& e4
,
238 const TrackingEvent
& e5
,
239 const TrackingEvent
& e6
) {
240 std::vector
<TrackingEvent
> events
;
241 events
.push_back(e1
);
242 events
.push_back(e2
);
243 events
.push_back(e3
);
244 events
.push_back(e4
);
245 events
.push_back(e5
);
246 events
.push_back(e6
);
247 return CheckEvents(events
);
250 testing::AssertionResult
AccountTrackerObserver::CheckEvents(
251 const std::vector
<TrackingEvent
>& events
) {
252 std::string maybe_newline
= (events
.size() + events_
.size()) > 2 ? "\n" : "";
253 testing::AssertionResult
result(
255 ? testing::AssertionSuccess()
256 : (testing::AssertionFailure()
257 << "Expected " << maybe_newline
<< Str(events
) << ", "
258 << maybe_newline
<< "Got " << maybe_newline
<< Str(events_
)));
263 class IdentityAccountTrackerTest
: public testing::Test
{
265 IdentityAccountTrackerTest() {}
267 virtual ~IdentityAccountTrackerTest() {}
269 virtual void SetUp() OVERRIDE
{
271 fake_oauth2_token_service_
.reset(new FakeOAuth2TokenService());
273 fake_identity_provider_
.reset(
274 new FakeIdentityProvider(fake_oauth2_token_service_
.get()));
276 account_tracker_
.reset(
277 new AccountTracker(fake_identity_provider_
.get(),
278 new net::TestURLRequestContextGetter(
279 message_loop_
.message_loop_proxy())));
280 account_tracker_
->AddObserver(&observer_
);
283 virtual void TearDown() OVERRIDE
{
284 account_tracker_
->RemoveObserver(&observer_
);
285 account_tracker_
->Shutdown();
288 AccountTrackerObserver
* observer() {
292 AccountTracker
* account_tracker() {
293 return account_tracker_
.get();
296 // Helpers to pass fake events to the tracker.
298 void NotifyLogin(const std::string account_key
) {
299 identity_provider()->LogIn(account_key
);
302 void NotifyLogout() { identity_provider()->LogOut(); }
304 void NotifyTokenAvailable(const std::string
& username
) {
305 fake_oauth2_token_service_
->AddAccount(username
);
308 void NotifyTokenRevoked(const std::string
& username
) {
309 fake_oauth2_token_service_
->RemoveAccount(username
);
312 // Helpers to fake access token and user info fetching
313 void IssueAccessToken(const std::string
& username
) {
314 fake_oauth2_token_service_
->IssueAllTokensForAccount(
315 username
, "access_token-" + username
, base::Time::Max());
318 std::string
GetValidTokenInfoResponse(const std::string account_key
) {
319 return std::string("{ \"id\": \"") + AccountKeyToObfuscatedId(account_key
) +
323 void ReturnOAuthUrlFetchResults(int fetcher_id
,
324 net::HttpStatusCode response_code
,
325 const std::string
& response_string
);
327 void ReturnOAuthUrlFetchSuccess(const std::string
& account_key
);
328 void ReturnOAuthUrlFetchFailure(const std::string
& account_key
);
330 void SetupPrimaryLogin() {
331 // Initial setup for tests that start with a signed in profile.
332 NotifyLogin(kPrimaryAccountKey
);
333 NotifyTokenAvailable(kPrimaryAccountKey
);
334 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
338 std::string
active_account_id() {
339 return identity_provider()->GetActiveAccountId();
343 FakeIdentityProvider
* identity_provider() {
344 return static_cast<FakeIdentityProvider
*>(
345 account_tracker_
->identity_provider());
348 base::MessageLoopForIO message_loop_
; // net:: stuff needs IO message loop.
349 net::TestURLFetcherFactory test_fetcher_factory_
;
350 scoped_ptr
<FakeOAuth2TokenService
> fake_oauth2_token_service_
;
351 scoped_ptr
<FakeIdentityProvider
> fake_identity_provider_
;
353 scoped_ptr
<AccountTracker
> account_tracker_
;
354 AccountTrackerObserver observer_
;
357 void IdentityAccountTrackerTest::ReturnOAuthUrlFetchResults(
359 net::HttpStatusCode response_code
,
360 const std::string
& response_string
) {
362 net::TestURLFetcher
* fetcher
=
363 test_fetcher_factory_
.GetFetcherByID(fetcher_id
);
364 ASSERT_TRUE(fetcher
);
365 fetcher
->set_response_code(response_code
);
366 fetcher
->SetResponseString(response_string
);
367 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
370 void IdentityAccountTrackerTest::ReturnOAuthUrlFetchSuccess(
371 const std::string
& account_key
) {
372 IssueAccessToken(account_key
);
373 ReturnOAuthUrlFetchResults(gaia::GaiaOAuthClient::kUrlFetcherId
,
375 GetValidTokenInfoResponse(account_key
));
378 void IdentityAccountTrackerTest::ReturnOAuthUrlFetchFailure(
379 const std::string
& account_key
) {
380 IssueAccessToken(account_key
);
381 ReturnOAuthUrlFetchResults(
382 gaia::GaiaOAuthClient::kUrlFetcherId
, net::HTTP_BAD_REQUEST
, "");
385 // Primary tests just involve the Active account
387 TEST_F(IdentityAccountTrackerTest
, PrimaryNoEventsBeforeLogin
) {
388 NotifyTokenAvailable(kPrimaryAccountKey
);
389 NotifyTokenRevoked(kPrimaryAccountKey
);
391 EXPECT_TRUE(observer()->CheckEvents());
394 TEST_F(IdentityAccountTrackerTest
, PrimaryLoginThenTokenAvailable
) {
395 NotifyLogin(kPrimaryAccountKey
);
396 NotifyTokenAvailable(kPrimaryAccountKey
);
397 EXPECT_TRUE(observer()->CheckEvents());
399 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
401 observer()->CheckEvents(TrackingEvent(ADDED
, kPrimaryAccountKey
),
402 TrackingEvent(SIGN_IN
, kPrimaryAccountKey
)));
405 TEST_F(IdentityAccountTrackerTest
, PrimaryTokenAvailableThenLogin
) {
406 NotifyTokenAvailable(kPrimaryAccountKey
);
407 EXPECT_TRUE(observer()->CheckEvents());
409 NotifyLogin(kPrimaryAccountKey
);
410 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
412 observer()->CheckEvents(TrackingEvent(ADDED
, kPrimaryAccountKey
),
413 TrackingEvent(SIGN_IN
, kPrimaryAccountKey
)));
416 TEST_F(IdentityAccountTrackerTest
, PrimaryTokenAvailableAndRevokedThenLogin
) {
417 NotifyTokenAvailable(kPrimaryAccountKey
);
418 EXPECT_TRUE(observer()->CheckEvents());
420 NotifyLogin(kPrimaryAccountKey
);
421 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
423 observer()->CheckEvents(TrackingEvent(ADDED
, kPrimaryAccountKey
),
424 TrackingEvent(SIGN_IN
, kPrimaryAccountKey
)));
427 TEST_F(IdentityAccountTrackerTest
, PrimaryRevokeThenLogout
) {
428 NotifyLogin(kPrimaryAccountKey
);
429 NotifyTokenAvailable(kPrimaryAccountKey
);
430 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
433 NotifyTokenRevoked(kPrimaryAccountKey
);
435 observer()->CheckEvents(TrackingEvent(SIGN_OUT
, kPrimaryAccountKey
)));
439 observer()->CheckEvents(TrackingEvent(REMOVED
, kPrimaryAccountKey
)));
442 TEST_F(IdentityAccountTrackerTest
, PrimaryRevokeThenLogin
) {
443 NotifyLogin(kPrimaryAccountKey
);
444 NotifyTokenAvailable(kPrimaryAccountKey
);
445 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
446 NotifyTokenRevoked(kPrimaryAccountKey
);
449 NotifyLogin(kPrimaryAccountKey
);
450 EXPECT_TRUE(observer()->CheckEvents());
453 TEST_F(IdentityAccountTrackerTest
, PrimaryRevokeThenTokenAvailable
) {
454 NotifyLogin(kPrimaryAccountKey
);
455 NotifyTokenAvailable(kPrimaryAccountKey
);
456 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
457 NotifyTokenRevoked(kPrimaryAccountKey
);
460 NotifyTokenAvailable(kPrimaryAccountKey
);
462 observer()->CheckEvents(TrackingEvent(SIGN_IN
, kPrimaryAccountKey
)));
465 TEST_F(IdentityAccountTrackerTest
, PrimaryLogoutThenRevoke
) {
466 NotifyLogin(kPrimaryAccountKey
);
467 NotifyTokenAvailable(kPrimaryAccountKey
);
468 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
473 observer()->CheckEvents(TrackingEvent(SIGN_OUT
, kPrimaryAccountKey
),
474 TrackingEvent(REMOVED
, kPrimaryAccountKey
)));
476 NotifyTokenRevoked(kPrimaryAccountKey
);
477 EXPECT_TRUE(observer()->CheckEvents());
480 TEST_F(IdentityAccountTrackerTest
, PrimaryLogoutFetchCancelAvailable
) {
481 NotifyLogin(kPrimaryAccountKey
);
482 NotifyTokenAvailable(kPrimaryAccountKey
);
483 // TokenAvailable kicks off a fetch. Logout without satisfying it.
485 EXPECT_TRUE(observer()->CheckEvents());
487 NotifyLogin(kPrimaryAccountKey
);
488 NotifyTokenAvailable(kPrimaryAccountKey
);
489 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
490 EXPECT_TRUE(observer()->CheckEvents(
491 TrackingEvent(ADDED
, kPrimaryAccountKey
),
492 TrackingEvent(SIGN_IN
, kPrimaryAccountKey
)));
495 // Non-primary accounts
497 TEST_F(IdentityAccountTrackerTest
, Available
) {
500 NotifyTokenAvailable("user@example.com");
501 EXPECT_TRUE(observer()->CheckEvents());
503 ReturnOAuthUrlFetchSuccess("user@example.com");
504 EXPECT_TRUE(observer()->CheckEvents(
505 TrackingEvent(ADDED
, "user@example.com"),
506 TrackingEvent(SIGN_IN
, "user@example.com")));
509 TEST_F(IdentityAccountTrackerTest
, Revoke
) {
512 account_tracker()->OnRefreshTokenRevoked("user@example.com");
513 EXPECT_TRUE(observer()->CheckEvents());
516 TEST_F(IdentityAccountTrackerTest
, AvailableRevokeAvailable
) {
519 NotifyTokenAvailable("user@example.com");
520 ReturnOAuthUrlFetchSuccess("user@example.com");
521 NotifyTokenRevoked("user@example.com");
522 EXPECT_TRUE(observer()->CheckEvents(
523 TrackingEvent(ADDED
, "user@example.com"),
524 TrackingEvent(SIGN_IN
, "user@example.com"),
525 TrackingEvent(SIGN_OUT
, "user@example.com")));
527 NotifyTokenAvailable("user@example.com");
528 EXPECT_TRUE(observer()->CheckEvents(
529 TrackingEvent(SIGN_IN
, "user@example.com")));
532 TEST_F(IdentityAccountTrackerTest
, AvailableRevokeAvailableWithPendingFetch
) {
535 NotifyTokenAvailable("user@example.com");
536 NotifyTokenRevoked("user@example.com");
537 EXPECT_TRUE(observer()->CheckEvents());
539 NotifyTokenAvailable("user@example.com");
540 ReturnOAuthUrlFetchSuccess("user@example.com");
541 EXPECT_TRUE(observer()->CheckEvents(
542 TrackingEvent(ADDED
, "user@example.com"),
543 TrackingEvent(SIGN_IN
, "user@example.com")));
546 TEST_F(IdentityAccountTrackerTest
, AvailableRevokeRevoke
) {
549 NotifyTokenAvailable("user@example.com");
550 ReturnOAuthUrlFetchSuccess("user@example.com");
551 NotifyTokenRevoked("user@example.com");
552 EXPECT_TRUE(observer()->CheckEvents(
553 TrackingEvent(ADDED
, "user@example.com"),
554 TrackingEvent(SIGN_IN
, "user@example.com"),
555 TrackingEvent(SIGN_OUT
, "user@example.com")));
557 NotifyTokenRevoked("user@example.com");
558 EXPECT_TRUE(observer()->CheckEvents());
561 TEST_F(IdentityAccountTrackerTest
, AvailableAvailable
) {
564 NotifyTokenAvailable("user@example.com");
565 ReturnOAuthUrlFetchSuccess("user@example.com");
566 EXPECT_TRUE(observer()->CheckEvents(
567 TrackingEvent(ADDED
, "user@example.com"),
568 TrackingEvent(SIGN_IN
, "user@example.com")));
570 NotifyTokenAvailable("user@example.com");
571 EXPECT_TRUE(observer()->CheckEvents());
574 TEST_F(IdentityAccountTrackerTest
, TwoAccounts
) {
577 NotifyTokenAvailable("alpha@example.com");
578 ReturnOAuthUrlFetchSuccess("alpha@example.com");
579 EXPECT_TRUE(observer()->CheckEvents(
580 TrackingEvent(ADDED
, "alpha@example.com"),
581 TrackingEvent(SIGN_IN
, "alpha@example.com")));
583 NotifyTokenAvailable("beta@example.com");
584 ReturnOAuthUrlFetchSuccess("beta@example.com");
585 EXPECT_TRUE(observer()->CheckEvents(
586 TrackingEvent(ADDED
, "beta@example.com"),
587 TrackingEvent(SIGN_IN
, "beta@example.com")));
589 NotifyTokenRevoked("alpha@example.com");
591 observer()->CheckEvents(TrackingEvent(SIGN_OUT
, "alpha@example.com")));
593 NotifyTokenRevoked("beta@example.com");
594 EXPECT_TRUE(observer()->CheckEvents(
595 TrackingEvent(SIGN_OUT
, "beta@example.com")));
598 TEST_F(IdentityAccountTrackerTest
, AvailableTokenFetchFailAvailable
) {
601 NotifyTokenAvailable("user@example.com");
602 ReturnOAuthUrlFetchFailure("user@example.com");
603 EXPECT_TRUE(observer()->CheckEvents());
605 NotifyTokenAvailable("user@example.com");
606 ReturnOAuthUrlFetchSuccess("user@example.com");
607 EXPECT_TRUE(observer()->CheckEvents(
608 TrackingEvent(ADDED
, "user@example.com"),
609 TrackingEvent(SIGN_IN
, "user@example.com")));
612 TEST_F(IdentityAccountTrackerTest
, MultiSignOutSignIn
) {
615 NotifyTokenAvailable("alpha@example.com");
616 ReturnOAuthUrlFetchSuccess("alpha@example.com");
617 NotifyTokenAvailable("beta@example.com");
618 ReturnOAuthUrlFetchSuccess("beta@example.com");
620 observer()->SortEventsByUser();
621 EXPECT_TRUE(observer()->CheckEvents(
622 TrackingEvent(ADDED
, "alpha@example.com"),
623 TrackingEvent(SIGN_IN
, "alpha@example.com"),
624 TrackingEvent(ADDED
, "beta@example.com"),
625 TrackingEvent(SIGN_IN
, "beta@example.com")));
628 observer()->SortEventsByUser();
629 EXPECT_TRUE(observer()->CheckEvents(
630 TrackingEvent(SIGN_OUT
, "alpha@example.com"),
631 TrackingEvent(REMOVED
, "alpha@example.com"),
632 TrackingEvent(SIGN_OUT
, "beta@example.com"),
633 TrackingEvent(REMOVED
, "beta@example.com"),
634 TrackingEvent(SIGN_OUT
, kPrimaryAccountKey
),
635 TrackingEvent(REMOVED
, kPrimaryAccountKey
)));
637 // No events fire at all while profile is signed out.
638 NotifyTokenRevoked("alpha@example.com");
639 NotifyTokenAvailable("gamma@example.com");
640 EXPECT_TRUE(observer()->CheckEvents());
642 // Signing the profile in again will resume tracking all accounts.
643 NotifyLogin(kPrimaryAccountKey
);
644 NotifyTokenAvailable(kPrimaryAccountKey
);
645 ReturnOAuthUrlFetchSuccess("beta@example.com");
646 ReturnOAuthUrlFetchSuccess("gamma@example.com");
647 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
648 observer()->SortEventsByUser();
649 EXPECT_TRUE(observer()->CheckEvents(
650 TrackingEvent(ADDED
, "beta@example.com"),
651 TrackingEvent(SIGN_IN
, "beta@example.com"),
652 TrackingEvent(ADDED
, "gamma@example.com"),
653 TrackingEvent(SIGN_IN
, "gamma@example.com"),
654 TrackingEvent(ADDED
, kPrimaryAccountKey
),
655 TrackingEvent(SIGN_IN
, kPrimaryAccountKey
)));
657 // Revoking the primary token does not affect other accounts.
658 NotifyTokenRevoked(kPrimaryAccountKey
);
659 EXPECT_TRUE(observer()->CheckEvents(
660 TrackingEvent(SIGN_OUT
, kPrimaryAccountKey
)));
662 NotifyTokenAvailable(kPrimaryAccountKey
);
663 EXPECT_TRUE(observer()->CheckEvents(
664 TrackingEvent(SIGN_IN
, kPrimaryAccountKey
)));
667 // Primary/non-primary interactions
669 TEST_F(IdentityAccountTrackerTest
, MultiNoEventsBeforeLogin
) {
670 NotifyTokenAvailable(kPrimaryAccountKey
);
671 NotifyTokenAvailable("user@example.com");
672 NotifyTokenRevoked("user@example.com");
673 NotifyTokenRevoked(kPrimaryAccountKey
);
675 EXPECT_TRUE(observer()->CheckEvents());
678 TEST_F(IdentityAccountTrackerTest
, MultiLogoutRemovesAllAccounts
) {
679 NotifyLogin(kPrimaryAccountKey
);
680 NotifyTokenAvailable(kPrimaryAccountKey
);
681 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
682 NotifyTokenAvailable("user@example.com");
683 ReturnOAuthUrlFetchSuccess("user@example.com");
687 observer()->SortEventsByUser();
689 observer()->CheckEvents(TrackingEvent(SIGN_OUT
, kPrimaryAccountKey
),
690 TrackingEvent(REMOVED
, kPrimaryAccountKey
),
691 TrackingEvent(SIGN_OUT
, "user@example.com"),
692 TrackingEvent(REMOVED
, "user@example.com")));
695 TEST_F(IdentityAccountTrackerTest
, MultiRevokePrimaryDoesNotRemoveAllAccounts
) {
696 NotifyLogin(kPrimaryAccountKey
);
697 NotifyTokenAvailable(kPrimaryAccountKey
);
698 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
699 NotifyTokenAvailable("user@example.com");
700 ReturnOAuthUrlFetchSuccess("user@example.com");
703 NotifyTokenRevoked(kPrimaryAccountKey
);
704 observer()->SortEventsByUser();
706 observer()->CheckEvents(TrackingEvent(SIGN_OUT
, kPrimaryAccountKey
)));
709 TEST_F(IdentityAccountTrackerTest
, GetAccountsPrimary
) {
712 std::vector
<AccountIds
> ids
= account_tracker()->GetAccounts();
713 EXPECT_EQ(1ul, ids
.size());
714 EXPECT_EQ(kPrimaryAccountKey
, ids
[0].account_key
);
715 EXPECT_EQ(AccountKeyToObfuscatedId(kPrimaryAccountKey
), ids
[0].gaia
);
718 TEST_F(IdentityAccountTrackerTest
, GetAccountsSignedOut
) {
719 std::vector
<AccountIds
> ids
= account_tracker()->GetAccounts();
720 EXPECT_EQ(0ul, ids
.size());
723 TEST_F(IdentityAccountTrackerTest
, GetAccountsOnlyReturnAccountsWithTokens
) {
726 NotifyTokenAvailable("alpha@example.com");
727 NotifyTokenAvailable("beta@example.com");
728 ReturnOAuthUrlFetchSuccess("beta@example.com");
730 std::vector
<AccountIds
> ids
= account_tracker()->GetAccounts();
731 EXPECT_EQ(2ul, ids
.size());
732 EXPECT_EQ(kPrimaryAccountKey
, ids
[0].account_key
);
733 EXPECT_EQ(AccountKeyToObfuscatedId(kPrimaryAccountKey
), ids
[0].gaia
);
734 EXPECT_EQ("beta@example.com", ids
[1].account_key
);
735 EXPECT_EQ(AccountKeyToObfuscatedId("beta@example.com"), ids
[1].gaia
);
738 TEST_F(IdentityAccountTrackerTest
, GetAccountsSortOrder
) {
741 NotifyTokenAvailable("zeta@example.com");
742 ReturnOAuthUrlFetchSuccess("zeta@example.com");
743 NotifyTokenAvailable("alpha@example.com");
744 ReturnOAuthUrlFetchSuccess("alpha@example.com");
746 // The primary account will be first in the vector. Remaining accounts
747 // will be sorted by gaia ID.
748 std::vector
<AccountIds
> ids
= account_tracker()->GetAccounts();
749 EXPECT_EQ(3ul, ids
.size());
750 EXPECT_EQ(kPrimaryAccountKey
, ids
[0].account_key
);
751 EXPECT_EQ(AccountKeyToObfuscatedId(kPrimaryAccountKey
), ids
[0].gaia
);
752 EXPECT_EQ("alpha@example.com", ids
[1].account_key
);
753 EXPECT_EQ(AccountKeyToObfuscatedId("alpha@example.com"), ids
[1].gaia
);
754 EXPECT_EQ("zeta@example.com", ids
[2].account_key
);
755 EXPECT_EQ(AccountKeyToObfuscatedId("zeta@example.com"), ids
[2].gaia
);
758 TEST_F(IdentityAccountTrackerTest
,
759 GetAccountsReturnNothingWhenPrimarySignedOut
) {
762 NotifyTokenAvailable("zeta@example.com");
763 ReturnOAuthUrlFetchSuccess("zeta@example.com");
764 NotifyTokenAvailable("alpha@example.com");
765 ReturnOAuthUrlFetchSuccess("alpha@example.com");
767 NotifyTokenRevoked(kPrimaryAccountKey
);
769 std::vector
<AccountIds
> ids
= account_tracker()->GetAccounts();
770 EXPECT_EQ(0ul, ids
.size());
773 TEST_F(IdentityAccountTrackerTest
, FindAccountIdsByGaiaIdPrimary
) {
776 AccountIds ids
= account_tracker()->FindAccountIdsByGaiaId(
777 AccountKeyToObfuscatedId(kPrimaryAccountKey
));
778 EXPECT_EQ(kPrimaryAccountKey
, ids
.account_key
);
779 EXPECT_EQ(kPrimaryAccountKey
, ids
.email
);
780 EXPECT_EQ(AccountKeyToObfuscatedId(kPrimaryAccountKey
), ids
.gaia
);
783 TEST_F(IdentityAccountTrackerTest
, FindAccountIdsByGaiaIdNotFound
) {
786 AccountIds ids
= account_tracker()->FindAccountIdsByGaiaId(
787 AccountKeyToObfuscatedId("notfound@example.com"));
788 EXPECT_TRUE(ids
.account_key
.empty());
789 EXPECT_TRUE(ids
.email
.empty());
790 EXPECT_TRUE(ids
.gaia
.empty());
793 TEST_F(IdentityAccountTrackerTest
,
794 FindAccountIdsByGaiaIdReturnEmptyWhenPrimarySignedOut
) {
797 NotifyTokenAvailable("zeta@example.com");
798 ReturnOAuthUrlFetchSuccess("zeta@example.com");
799 NotifyTokenAvailable("alpha@example.com");
800 ReturnOAuthUrlFetchSuccess("alpha@example.com");
802 NotifyTokenRevoked(kPrimaryAccountKey
);
805 account_tracker()->FindAccountIdsByGaiaId(kPrimaryAccountKey
);
806 EXPECT_TRUE(ids
.account_key
.empty());
807 EXPECT_TRUE(ids
.email
.empty());
808 EXPECT_TRUE(ids
.gaia
.empty());
810 ids
= account_tracker()->FindAccountIdsByGaiaId("alpha@example.com");
811 EXPECT_TRUE(ids
.account_key
.empty());
812 EXPECT_TRUE(ids
.email
.empty());
813 EXPECT_TRUE(ids
.gaia
.empty());