Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / google_apis / gaia / account_tracker_unittest.cc
blob61fded91a1ad6689022140f189ad7fc5b4a990b4
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"
7 #include <algorithm>
8 #include <vector>
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"
21 namespace {
23 const char kPrimaryAccountKey[] = "primary_account@example.com";
25 enum TrackingEventType {
26 ADDED,
27 REMOVED,
28 SIGN_IN,
29 SIGN_OUT
32 std::string AccountKeyToObfuscatedId(const std::string email) {
33 return "obfid-" + email;
36 class TrackingEvent {
37 public:
38 TrackingEvent(TrackingEventType type,
39 const std::string& account_key,
40 const std::string& gaia_id)
41 : type_(type),
42 account_key_(account_key),
43 gaia_id_(gaia_id) {}
45 TrackingEvent(TrackingEventType type,
46 const std::string& account_key)
47 : type_(type),
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";
58 switch (type_) {
59 case ADDED:
60 typestr = "ADD";
61 break;
62 case REMOVED:
63 typestr = "REM";
64 break;
65 case SIGN_IN:
66 typestr = " IN";
67 break;
68 case SIGN_OUT:
69 typestr = "OUT";
70 break;
72 return base::StringPrintf("{ type: %s, email: %s, gaia: %s }",
73 typestr,
74 account_key_.c_str(),
75 gaia_id_.c_str());
78 private:
79 friend bool CompareByUser(TrackingEvent a, TrackingEvent b);
81 TrackingEventType type_;
82 std::string account_key_;
83 std::string gaia_id_;
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) {
95 if (needs_comma)
96 str += ",\n ";
97 needs_comma = true;
98 str += it->ToString();
100 str += "]";
101 return str;
104 } // namespace
106 namespace gaia {
108 class AccountTrackerObserver : public AccountTracker::Observer {
109 public:
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);
135 void Clear();
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;
144 private:
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,
160 bool is_signed_in) {
161 events_.push_back(
162 TrackingEvent(is_signed_in ? SIGN_IN : SIGN_OUT, ids.email, ids.gaia));
165 void AccountTrackerObserver::Clear() {
166 events_.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(
254 (events_ == events)
255 ? testing::AssertionSuccess()
256 : (testing::AssertionFailure()
257 << "Expected " << maybe_newline << Str(events) << ", "
258 << maybe_newline << "Got " << maybe_newline << Str(events_)));
259 events_.clear();
260 return result;
263 class IdentityAccountTrackerTest : public testing::Test {
264 public:
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() {
288 return &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) +
319 "\" }";
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);
334 observer()->Clear();
337 std::string active_account_id() {
338 return identity_provider()->GetActiveAccountId();
341 private:
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(
357 int fetcher_id,
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,
373 net::HTTP_OK,
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);
389 NotifyLogout();
390 EXPECT_TRUE(observer()->CheckEvents());
393 TEST_F(IdentityAccountTrackerTest, PrimaryLoginThenTokenAvailable) {
394 NotifyLogin(kPrimaryAccountKey);
395 NotifyTokenAvailable(kPrimaryAccountKey);
396 EXPECT_TRUE(observer()->CheckEvents());
398 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey);
399 EXPECT_TRUE(
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);
410 EXPECT_TRUE(
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);
421 EXPECT_TRUE(
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);
430 observer()->Clear();
432 NotifyTokenRevoked(kPrimaryAccountKey);
433 EXPECT_TRUE(
434 observer()->CheckEvents(TrackingEvent(SIGN_OUT, kPrimaryAccountKey)));
436 NotifyLogout();
437 EXPECT_TRUE(
438 observer()->CheckEvents(TrackingEvent(REMOVED, kPrimaryAccountKey)));
441 TEST_F(IdentityAccountTrackerTest, PrimaryRevokeThenLogin) {
442 NotifyLogin(kPrimaryAccountKey);
443 NotifyTokenAvailable(kPrimaryAccountKey);
444 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey);
445 NotifyTokenRevoked(kPrimaryAccountKey);
446 observer()->Clear();
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);
457 observer()->Clear();
459 NotifyTokenAvailable(kPrimaryAccountKey);
460 EXPECT_TRUE(
461 observer()->CheckEvents(TrackingEvent(SIGN_IN, kPrimaryAccountKey)));
464 TEST_F(IdentityAccountTrackerTest, PrimaryLogoutThenRevoke) {
465 NotifyLogin(kPrimaryAccountKey);
466 NotifyTokenAvailable(kPrimaryAccountKey);
467 ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey);
468 observer()->Clear();
470 NotifyLogout();
471 EXPECT_TRUE(
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.
483 NotifyLogout();
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) {
497 SetupPrimaryLogin();
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) {
509 SetupPrimaryLogin();
511 account_tracker()->OnRefreshTokenRevoked("user@example.com");
512 EXPECT_TRUE(observer()->CheckEvents());
515 TEST_F(IdentityAccountTrackerTest, AvailableRevokeAvailable) {
516 SetupPrimaryLogin();
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) {
532 SetupPrimaryLogin();
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) {
546 SetupPrimaryLogin();
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) {
561 SetupPrimaryLogin();
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) {
574 SetupPrimaryLogin();
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");
589 EXPECT_TRUE(
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) {
598 SetupPrimaryLogin();
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) {
612 SetupPrimaryLogin();
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")));
626 NotifyLogout();
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);
673 NotifyLogout();
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");
683 observer()->Clear();
685 NotifyLogout();
686 observer()->SortEventsByUser();
687 EXPECT_TRUE(
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");
700 observer()->Clear();
702 NotifyTokenRevoked(kPrimaryAccountKey);
703 observer()->SortEventsByUser();
704 EXPECT_TRUE(
705 observer()->CheckEvents(TrackingEvent(SIGN_OUT, kPrimaryAccountKey)));
708 TEST_F(IdentityAccountTrackerTest, GetAccountsPrimary) {
709 SetupPrimaryLogin();
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) {
723 SetupPrimaryLogin();
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) {
738 SetupPrimaryLogin();
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) {
759 SetupPrimaryLogin();
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) {
773 SetupPrimaryLogin();
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) {
783 SetupPrimaryLogin();
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) {
794 SetupPrimaryLogin();
796 NotifyTokenAvailable("zeta@example.com");
797 ReturnOAuthUrlFetchSuccess("zeta@example.com");
798 NotifyTokenAvailable("alpha@example.com");
799 ReturnOAuthUrlFetchSuccess("alpha@example.com");
801 NotifyTokenRevoked(kPrimaryAccountKey);
803 AccountIds ids =
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());
815 } // namespace gaia