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 void OnAccountAdded(const AccountIds
& ids
) override
;
140 void OnAccountRemoved(const AccountIds
& ids
) override
;
141 void OnAccountSignInChanged(const AccountIds
& ids
,
142 bool is_signed_in
) override
;
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 ~IdentityAccountTrackerTest() override
{}
269 void SetUp() override
{
270 fake_oauth2_token_service_
.reset(new FakeOAuth2TokenService());
272 fake_identity_provider_
.reset(
273 new FakeIdentityProvider(fake_oauth2_token_service_
.get()));
275 account_tracker_
.reset(
276 new AccountTracker(fake_identity_provider_
.get(),
277 new net::TestURLRequestContextGetter(
278 message_loop_
.task_runner())));
279 account_tracker_
->AddObserver(&observer_
);
282 void TearDown() override
{
283 account_tracker_
->RemoveObserver(&observer_
);
284 account_tracker_
->Shutdown();
287 AccountTrackerObserver
* observer() {
291 AccountTracker
* account_tracker() {
292 return account_tracker_
.get();
295 // Helpers to pass fake events to the tracker.
297 void NotifyLogin(const std::string account_key
) {
298 identity_provider()->LogIn(account_key
);
301 void NotifyLogout() { identity_provider()->LogOut(); }
303 void NotifyTokenAvailable(const std::string
& username
) {
304 fake_oauth2_token_service_
->AddAccount(username
);
307 void NotifyTokenRevoked(const std::string
& username
) {
308 fake_oauth2_token_service_
->RemoveAccount(username
);
311 // Helpers to fake access token and user info fetching
312 void IssueAccessToken(const std::string
& username
) {
313 fake_oauth2_token_service_
->IssueAllTokensForAccount(
314 username
, "access_token-" + username
, base::Time::Max());
317 std::string
GetValidTokenInfoResponse(const std::string account_key
) {
318 return std::string("{ \"id\": \"") + AccountKeyToObfuscatedId(account_key
) +
322 void ReturnOAuthUrlFetchResults(int fetcher_id
,
323 net::HttpStatusCode response_code
,
324 const std::string
& response_string
);
326 void ReturnOAuthUrlFetchSuccess(const std::string
& account_key
);
327 void ReturnOAuthUrlFetchFailure(const std::string
& account_key
);
329 void SetupPrimaryLogin() {
330 // Initial setup for tests that start with a signed in profile.
331 NotifyLogin(kPrimaryAccountKey
);
332 NotifyTokenAvailable(kPrimaryAccountKey
);
333 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
337 std::string
active_account_id() {
338 return identity_provider()->GetActiveAccountId();
342 FakeIdentityProvider
* identity_provider() {
343 return static_cast<FakeIdentityProvider
*>(
344 account_tracker_
->identity_provider());
347 base::MessageLoopForIO message_loop_
; // net:: stuff needs IO message loop.
348 net::TestURLFetcherFactory test_fetcher_factory_
;
349 scoped_ptr
<FakeOAuth2TokenService
> fake_oauth2_token_service_
;
350 scoped_ptr
<FakeIdentityProvider
> fake_identity_provider_
;
352 scoped_ptr
<AccountTracker
> account_tracker_
;
353 AccountTrackerObserver observer_
;
356 void IdentityAccountTrackerTest::ReturnOAuthUrlFetchResults(
358 net::HttpStatusCode response_code
,
359 const std::string
& response_string
) {
361 net::TestURLFetcher
* fetcher
=
362 test_fetcher_factory_
.GetFetcherByID(fetcher_id
);
363 ASSERT_TRUE(fetcher
);
364 fetcher
->set_response_code(response_code
);
365 fetcher
->SetResponseString(response_string
);
366 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
369 void IdentityAccountTrackerTest::ReturnOAuthUrlFetchSuccess(
370 const std::string
& account_key
) {
371 IssueAccessToken(account_key
);
372 ReturnOAuthUrlFetchResults(gaia::GaiaOAuthClient::kUrlFetcherId
,
374 GetValidTokenInfoResponse(account_key
));
377 void IdentityAccountTrackerTest::ReturnOAuthUrlFetchFailure(
378 const std::string
& account_key
) {
379 IssueAccessToken(account_key
);
380 ReturnOAuthUrlFetchResults(
381 gaia::GaiaOAuthClient::kUrlFetcherId
, net::HTTP_BAD_REQUEST
, "");
384 // Primary tests just involve the Active account
386 TEST_F(IdentityAccountTrackerTest
, PrimaryNoEventsBeforeLogin
) {
387 NotifyTokenAvailable(kPrimaryAccountKey
);
388 NotifyTokenRevoked(kPrimaryAccountKey
);
390 EXPECT_TRUE(observer()->CheckEvents());
393 TEST_F(IdentityAccountTrackerTest
, PrimaryLoginThenTokenAvailable
) {
394 NotifyLogin(kPrimaryAccountKey
);
395 NotifyTokenAvailable(kPrimaryAccountKey
);
396 EXPECT_TRUE(observer()->CheckEvents());
398 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
400 observer()->CheckEvents(TrackingEvent(ADDED
, kPrimaryAccountKey
),
401 TrackingEvent(SIGN_IN
, kPrimaryAccountKey
)));
404 TEST_F(IdentityAccountTrackerTest
, PrimaryTokenAvailableThenLogin
) {
405 NotifyTokenAvailable(kPrimaryAccountKey
);
406 EXPECT_TRUE(observer()->CheckEvents());
408 NotifyLogin(kPrimaryAccountKey
);
409 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
411 observer()->CheckEvents(TrackingEvent(ADDED
, kPrimaryAccountKey
),
412 TrackingEvent(SIGN_IN
, kPrimaryAccountKey
)));
415 TEST_F(IdentityAccountTrackerTest
, PrimaryTokenAvailableAndRevokedThenLogin
) {
416 NotifyTokenAvailable(kPrimaryAccountKey
);
417 EXPECT_TRUE(observer()->CheckEvents());
419 NotifyLogin(kPrimaryAccountKey
);
420 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
422 observer()->CheckEvents(TrackingEvent(ADDED
, kPrimaryAccountKey
),
423 TrackingEvent(SIGN_IN
, kPrimaryAccountKey
)));
426 TEST_F(IdentityAccountTrackerTest
, PrimaryRevokeThenLogout
) {
427 NotifyLogin(kPrimaryAccountKey
);
428 NotifyTokenAvailable(kPrimaryAccountKey
);
429 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
432 NotifyTokenRevoked(kPrimaryAccountKey
);
434 observer()->CheckEvents(TrackingEvent(SIGN_OUT
, kPrimaryAccountKey
)));
438 observer()->CheckEvents(TrackingEvent(REMOVED
, kPrimaryAccountKey
)));
441 TEST_F(IdentityAccountTrackerTest
, PrimaryRevokeThenLogin
) {
442 NotifyLogin(kPrimaryAccountKey
);
443 NotifyTokenAvailable(kPrimaryAccountKey
);
444 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
445 NotifyTokenRevoked(kPrimaryAccountKey
);
448 NotifyLogin(kPrimaryAccountKey
);
449 EXPECT_TRUE(observer()->CheckEvents());
452 TEST_F(IdentityAccountTrackerTest
, PrimaryRevokeThenTokenAvailable
) {
453 NotifyLogin(kPrimaryAccountKey
);
454 NotifyTokenAvailable(kPrimaryAccountKey
);
455 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
456 NotifyTokenRevoked(kPrimaryAccountKey
);
459 NotifyTokenAvailable(kPrimaryAccountKey
);
461 observer()->CheckEvents(TrackingEvent(SIGN_IN
, kPrimaryAccountKey
)));
464 TEST_F(IdentityAccountTrackerTest
, PrimaryLogoutThenRevoke
) {
465 NotifyLogin(kPrimaryAccountKey
);
466 NotifyTokenAvailable(kPrimaryAccountKey
);
467 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
472 observer()->CheckEvents(TrackingEvent(SIGN_OUT
, kPrimaryAccountKey
),
473 TrackingEvent(REMOVED
, kPrimaryAccountKey
)));
475 NotifyTokenRevoked(kPrimaryAccountKey
);
476 EXPECT_TRUE(observer()->CheckEvents());
479 TEST_F(IdentityAccountTrackerTest
, PrimaryLogoutFetchCancelAvailable
) {
480 NotifyLogin(kPrimaryAccountKey
);
481 NotifyTokenAvailable(kPrimaryAccountKey
);
482 // TokenAvailable kicks off a fetch. Logout without satisfying it.
484 EXPECT_TRUE(observer()->CheckEvents());
486 NotifyLogin(kPrimaryAccountKey
);
487 NotifyTokenAvailable(kPrimaryAccountKey
);
488 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
489 EXPECT_TRUE(observer()->CheckEvents(
490 TrackingEvent(ADDED
, kPrimaryAccountKey
),
491 TrackingEvent(SIGN_IN
, kPrimaryAccountKey
)));
494 // Non-primary accounts
496 TEST_F(IdentityAccountTrackerTest
, Available
) {
499 NotifyTokenAvailable("user@example.com");
500 EXPECT_TRUE(observer()->CheckEvents());
502 ReturnOAuthUrlFetchSuccess("user@example.com");
503 EXPECT_TRUE(observer()->CheckEvents(
504 TrackingEvent(ADDED
, "user@example.com"),
505 TrackingEvent(SIGN_IN
, "user@example.com")));
508 TEST_F(IdentityAccountTrackerTest
, Revoke
) {
511 account_tracker()->OnRefreshTokenRevoked("user@example.com");
512 EXPECT_TRUE(observer()->CheckEvents());
515 TEST_F(IdentityAccountTrackerTest
, AvailableRevokeAvailable
) {
518 NotifyTokenAvailable("user@example.com");
519 ReturnOAuthUrlFetchSuccess("user@example.com");
520 NotifyTokenRevoked("user@example.com");
521 EXPECT_TRUE(observer()->CheckEvents(
522 TrackingEvent(ADDED
, "user@example.com"),
523 TrackingEvent(SIGN_IN
, "user@example.com"),
524 TrackingEvent(SIGN_OUT
, "user@example.com")));
526 NotifyTokenAvailable("user@example.com");
527 EXPECT_TRUE(observer()->CheckEvents(
528 TrackingEvent(SIGN_IN
, "user@example.com")));
531 TEST_F(IdentityAccountTrackerTest
, AvailableRevokeAvailableWithPendingFetch
) {
534 NotifyTokenAvailable("user@example.com");
535 NotifyTokenRevoked("user@example.com");
536 EXPECT_TRUE(observer()->CheckEvents());
538 NotifyTokenAvailable("user@example.com");
539 ReturnOAuthUrlFetchSuccess("user@example.com");
540 EXPECT_TRUE(observer()->CheckEvents(
541 TrackingEvent(ADDED
, "user@example.com"),
542 TrackingEvent(SIGN_IN
, "user@example.com")));
545 TEST_F(IdentityAccountTrackerTest
, AvailableRevokeRevoke
) {
548 NotifyTokenAvailable("user@example.com");
549 ReturnOAuthUrlFetchSuccess("user@example.com");
550 NotifyTokenRevoked("user@example.com");
551 EXPECT_TRUE(observer()->CheckEvents(
552 TrackingEvent(ADDED
, "user@example.com"),
553 TrackingEvent(SIGN_IN
, "user@example.com"),
554 TrackingEvent(SIGN_OUT
, "user@example.com")));
556 NotifyTokenRevoked("user@example.com");
557 EXPECT_TRUE(observer()->CheckEvents());
560 TEST_F(IdentityAccountTrackerTest
, AvailableAvailable
) {
563 NotifyTokenAvailable("user@example.com");
564 ReturnOAuthUrlFetchSuccess("user@example.com");
565 EXPECT_TRUE(observer()->CheckEvents(
566 TrackingEvent(ADDED
, "user@example.com"),
567 TrackingEvent(SIGN_IN
, "user@example.com")));
569 NotifyTokenAvailable("user@example.com");
570 EXPECT_TRUE(observer()->CheckEvents());
573 TEST_F(IdentityAccountTrackerTest
, TwoAccounts
) {
576 NotifyTokenAvailable("alpha@example.com");
577 ReturnOAuthUrlFetchSuccess("alpha@example.com");
578 EXPECT_TRUE(observer()->CheckEvents(
579 TrackingEvent(ADDED
, "alpha@example.com"),
580 TrackingEvent(SIGN_IN
, "alpha@example.com")));
582 NotifyTokenAvailable("beta@example.com");
583 ReturnOAuthUrlFetchSuccess("beta@example.com");
584 EXPECT_TRUE(observer()->CheckEvents(
585 TrackingEvent(ADDED
, "beta@example.com"),
586 TrackingEvent(SIGN_IN
, "beta@example.com")));
588 NotifyTokenRevoked("alpha@example.com");
590 observer()->CheckEvents(TrackingEvent(SIGN_OUT
, "alpha@example.com")));
592 NotifyTokenRevoked("beta@example.com");
593 EXPECT_TRUE(observer()->CheckEvents(
594 TrackingEvent(SIGN_OUT
, "beta@example.com")));
597 TEST_F(IdentityAccountTrackerTest
, AvailableTokenFetchFailAvailable
) {
600 NotifyTokenAvailable("user@example.com");
601 ReturnOAuthUrlFetchFailure("user@example.com");
602 EXPECT_TRUE(observer()->CheckEvents());
604 NotifyTokenAvailable("user@example.com");
605 ReturnOAuthUrlFetchSuccess("user@example.com");
606 EXPECT_TRUE(observer()->CheckEvents(
607 TrackingEvent(ADDED
, "user@example.com"),
608 TrackingEvent(SIGN_IN
, "user@example.com")));
611 TEST_F(IdentityAccountTrackerTest
, MultiSignOutSignIn
) {
614 NotifyTokenAvailable("alpha@example.com");
615 ReturnOAuthUrlFetchSuccess("alpha@example.com");
616 NotifyTokenAvailable("beta@example.com");
617 ReturnOAuthUrlFetchSuccess("beta@example.com");
619 observer()->SortEventsByUser();
620 EXPECT_TRUE(observer()->CheckEvents(
621 TrackingEvent(ADDED
, "alpha@example.com"),
622 TrackingEvent(SIGN_IN
, "alpha@example.com"),
623 TrackingEvent(ADDED
, "beta@example.com"),
624 TrackingEvent(SIGN_IN
, "beta@example.com")));
627 observer()->SortEventsByUser();
628 EXPECT_TRUE(observer()->CheckEvents(
629 TrackingEvent(SIGN_OUT
, "alpha@example.com"),
630 TrackingEvent(REMOVED
, "alpha@example.com"),
631 TrackingEvent(SIGN_OUT
, "beta@example.com"),
632 TrackingEvent(REMOVED
, "beta@example.com"),
633 TrackingEvent(SIGN_OUT
, kPrimaryAccountKey
),
634 TrackingEvent(REMOVED
, kPrimaryAccountKey
)));
636 // No events fire at all while profile is signed out.
637 NotifyTokenRevoked("alpha@example.com");
638 NotifyTokenAvailable("gamma@example.com");
639 EXPECT_TRUE(observer()->CheckEvents());
641 // Signing the profile in again will resume tracking all accounts.
642 NotifyLogin(kPrimaryAccountKey
);
643 NotifyTokenAvailable(kPrimaryAccountKey
);
644 ReturnOAuthUrlFetchSuccess("beta@example.com");
645 ReturnOAuthUrlFetchSuccess("gamma@example.com");
646 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
647 observer()->SortEventsByUser();
648 EXPECT_TRUE(observer()->CheckEvents(
649 TrackingEvent(ADDED
, "beta@example.com"),
650 TrackingEvent(SIGN_IN
, "beta@example.com"),
651 TrackingEvent(ADDED
, "gamma@example.com"),
652 TrackingEvent(SIGN_IN
, "gamma@example.com"),
653 TrackingEvent(ADDED
, kPrimaryAccountKey
),
654 TrackingEvent(SIGN_IN
, kPrimaryAccountKey
)));
656 // Revoking the primary token does not affect other accounts.
657 NotifyTokenRevoked(kPrimaryAccountKey
);
658 EXPECT_TRUE(observer()->CheckEvents(
659 TrackingEvent(SIGN_OUT
, kPrimaryAccountKey
)));
661 NotifyTokenAvailable(kPrimaryAccountKey
);
662 EXPECT_TRUE(observer()->CheckEvents(
663 TrackingEvent(SIGN_IN
, kPrimaryAccountKey
)));
666 // Primary/non-primary interactions
668 TEST_F(IdentityAccountTrackerTest
, MultiNoEventsBeforeLogin
) {
669 NotifyTokenAvailable(kPrimaryAccountKey
);
670 NotifyTokenAvailable("user@example.com");
671 NotifyTokenRevoked("user@example.com");
672 NotifyTokenRevoked(kPrimaryAccountKey
);
674 EXPECT_TRUE(observer()->CheckEvents());
677 TEST_F(IdentityAccountTrackerTest
, MultiLogoutRemovesAllAccounts
) {
678 NotifyLogin(kPrimaryAccountKey
);
679 NotifyTokenAvailable(kPrimaryAccountKey
);
680 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
681 NotifyTokenAvailable("user@example.com");
682 ReturnOAuthUrlFetchSuccess("user@example.com");
686 observer()->SortEventsByUser();
688 observer()->CheckEvents(TrackingEvent(SIGN_OUT
, kPrimaryAccountKey
),
689 TrackingEvent(REMOVED
, kPrimaryAccountKey
),
690 TrackingEvent(SIGN_OUT
, "user@example.com"),
691 TrackingEvent(REMOVED
, "user@example.com")));
694 TEST_F(IdentityAccountTrackerTest
, MultiRevokePrimaryDoesNotRemoveAllAccounts
) {
695 NotifyLogin(kPrimaryAccountKey
);
696 NotifyTokenAvailable(kPrimaryAccountKey
);
697 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey
);
698 NotifyTokenAvailable("user@example.com");
699 ReturnOAuthUrlFetchSuccess("user@example.com");
702 NotifyTokenRevoked(kPrimaryAccountKey
);
703 observer()->SortEventsByUser();
705 observer()->CheckEvents(TrackingEvent(SIGN_OUT
, kPrimaryAccountKey
)));
708 TEST_F(IdentityAccountTrackerTest
, GetAccountsPrimary
) {
711 std::vector
<AccountIds
> ids
= account_tracker()->GetAccounts();
712 EXPECT_EQ(1ul, ids
.size());
713 EXPECT_EQ(kPrimaryAccountKey
, ids
[0].account_key
);
714 EXPECT_EQ(AccountKeyToObfuscatedId(kPrimaryAccountKey
), ids
[0].gaia
);
717 TEST_F(IdentityAccountTrackerTest
, GetAccountsSignedOut
) {
718 std::vector
<AccountIds
> ids
= account_tracker()->GetAccounts();
719 EXPECT_EQ(0ul, ids
.size());
722 TEST_F(IdentityAccountTrackerTest
, GetAccountsOnlyReturnAccountsWithTokens
) {
725 NotifyTokenAvailable("alpha@example.com");
726 NotifyTokenAvailable("beta@example.com");
727 ReturnOAuthUrlFetchSuccess("beta@example.com");
729 std::vector
<AccountIds
> ids
= account_tracker()->GetAccounts();
730 EXPECT_EQ(2ul, ids
.size());
731 EXPECT_EQ(kPrimaryAccountKey
, ids
[0].account_key
);
732 EXPECT_EQ(AccountKeyToObfuscatedId(kPrimaryAccountKey
), ids
[0].gaia
);
733 EXPECT_EQ("beta@example.com", ids
[1].account_key
);
734 EXPECT_EQ(AccountKeyToObfuscatedId("beta@example.com"), ids
[1].gaia
);
737 TEST_F(IdentityAccountTrackerTest
, GetAccountsSortOrder
) {
740 NotifyTokenAvailable("zeta@example.com");
741 ReturnOAuthUrlFetchSuccess("zeta@example.com");
742 NotifyTokenAvailable("alpha@example.com");
743 ReturnOAuthUrlFetchSuccess("alpha@example.com");
745 // The primary account will be first in the vector. Remaining accounts
746 // will be sorted by gaia ID.
747 std::vector
<AccountIds
> ids
= account_tracker()->GetAccounts();
748 EXPECT_EQ(3ul, ids
.size());
749 EXPECT_EQ(kPrimaryAccountKey
, ids
[0].account_key
);
750 EXPECT_EQ(AccountKeyToObfuscatedId(kPrimaryAccountKey
), ids
[0].gaia
);
751 EXPECT_EQ("alpha@example.com", ids
[1].account_key
);
752 EXPECT_EQ(AccountKeyToObfuscatedId("alpha@example.com"), ids
[1].gaia
);
753 EXPECT_EQ("zeta@example.com", ids
[2].account_key
);
754 EXPECT_EQ(AccountKeyToObfuscatedId("zeta@example.com"), ids
[2].gaia
);
757 TEST_F(IdentityAccountTrackerTest
,
758 GetAccountsReturnNothingWhenPrimarySignedOut
) {
761 NotifyTokenAvailable("zeta@example.com");
762 ReturnOAuthUrlFetchSuccess("zeta@example.com");
763 NotifyTokenAvailable("alpha@example.com");
764 ReturnOAuthUrlFetchSuccess("alpha@example.com");
766 NotifyTokenRevoked(kPrimaryAccountKey
);
768 std::vector
<AccountIds
> ids
= account_tracker()->GetAccounts();
769 EXPECT_EQ(0ul, ids
.size());
772 TEST_F(IdentityAccountTrackerTest
, FindAccountIdsByGaiaIdPrimary
) {
775 AccountIds ids
= account_tracker()->FindAccountIdsByGaiaId(
776 AccountKeyToObfuscatedId(kPrimaryAccountKey
));
777 EXPECT_EQ(kPrimaryAccountKey
, ids
.account_key
);
778 EXPECT_EQ(kPrimaryAccountKey
, ids
.email
);
779 EXPECT_EQ(AccountKeyToObfuscatedId(kPrimaryAccountKey
), ids
.gaia
);
782 TEST_F(IdentityAccountTrackerTest
, FindAccountIdsByGaiaIdNotFound
) {
785 AccountIds ids
= account_tracker()->FindAccountIdsByGaiaId(
786 AccountKeyToObfuscatedId("notfound@example.com"));
787 EXPECT_TRUE(ids
.account_key
.empty());
788 EXPECT_TRUE(ids
.email
.empty());
789 EXPECT_TRUE(ids
.gaia
.empty());
792 TEST_F(IdentityAccountTrackerTest
,
793 FindAccountIdsByGaiaIdReturnEmptyWhenPrimarySignedOut
) {
796 NotifyTokenAvailable("zeta@example.com");
797 ReturnOAuthUrlFetchSuccess("zeta@example.com");
798 NotifyTokenAvailable("alpha@example.com");
799 ReturnOAuthUrlFetchSuccess("alpha@example.com");
801 NotifyTokenRevoked(kPrimaryAccountKey
);
804 account_tracker()->FindAccountIdsByGaiaId(kPrimaryAccountKey
);
805 EXPECT_TRUE(ids
.account_key
.empty());
806 EXPECT_TRUE(ids
.email
.empty());
807 EXPECT_TRUE(ids
.gaia
.empty());
809 ids
= account_tracker()->FindAccountIdsByGaiaId("alpha@example.com");
810 EXPECT_TRUE(ids
.account_key
.empty());
811 EXPECT_TRUE(ids
.email
.empty());
812 EXPECT_TRUE(ids
.gaia
.empty());