Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Unified Diff: components/signin/core/browser/account_tracker_service_unittest.cc

Issue 425823002: Create a new AccountTrackerService (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/signin/core/browser/account_tracker_service.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/signin/core/browser/account_tracker_service_unittest.cc
diff --git a/components/signin/core/browser/account_tracker_service_unittest.cc b/components/signin/core/browser/account_tracker_service_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f376d964781c0d976b81775120bf6973bf83eb9d
--- /dev/null
+++ b/components/signin/core/browser/account_tracker_service_unittest.cc
@@ -0,0 +1,509 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <algorithm>
+#include <vector>
+
+#include "base/message_loop/message_loop.h"
+#include "base/prefs/pref_registry_simple.h"
+#include "base/prefs/testing_pref_service.h"
+#include "base/strings/stringprintf.h"
+#include "components/signin/core/browser/account_tracker_service.h"
+#include "google_apis/gaia/fake_oauth2_token_service.h"
+#include "google_apis/gaia/gaia_oauth_client.h"
+#include "net/http/http_status_code.h"
+#include "net/url_request/test_url_fetcher_factory.h"
+#include "net/url_request/url_fetcher_delegate.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+enum TrackingEventType {
+ UPDATED,
+ REMOVED,
+};
+
+std::string AccountIdToEmail(const std::string account_id) {
+ return account_id + "@gmail.com";
+}
+
+std::string AccountIdToGaiaId(const std::string account_id) {
+ return "gaia-" + account_id;
+}
+
+class TrackingEvent {
+ public:
+ TrackingEvent(TrackingEventType type,
+ const std::string& account_id,
+ const std::string& gaia_id)
+ : type_(type),
+ account_id_(account_id),
+ gaia_id_(gaia_id) {}
+
+ TrackingEvent(TrackingEventType type,
+ const std::string& account_id)
+ : type_(type),
+ account_id_(account_id),
+ gaia_id_(AccountIdToGaiaId(account_id)) {}
+
+ bool operator==(const TrackingEvent& event) const {
+ return type_ == event.type_ && account_id_ == event.account_id_ &&
+ gaia_id_ == event.gaia_id_;
+ }
+
+ std::string ToString() const {
+ const char * typestr = "INVALID";
+ switch (type_) {
+ case UPDATED:
+ typestr = "UPD";
+ break;
+ case REMOVED:
+ typestr = "REM";
+ break;
+ }
+ return base::StringPrintf("{ type: %s, account_id: %s, gaia: %s }",
+ typestr,
+ account_id_.c_str(),
+ gaia_id_.c_str());
+ }
+
+ private:
+ friend bool CompareByUser(TrackingEvent a, TrackingEvent b);
+
+ TrackingEventType type_;
+ std::string account_id_;
+ std::string gaia_id_;
+};
+
+bool CompareByUser(TrackingEvent a, TrackingEvent b) {
+ return a.account_id_ < b.account_id_;
+}
+
+std::string Str(const std::vector<TrackingEvent>& events) {
+ std::string str = "[";
+ bool needs_comma = false;
+ for (std::vector<TrackingEvent>::const_iterator it =
+ events.begin(); it != events.end(); ++it) {
+ if (needs_comma)
+ str += ",\n ";
+ needs_comma = true;
+ str += it->ToString();
+ }
+ str += "]";
+ return str;
+}
+
+class AccountTrackerObserver : public AccountTrackerService::Observer {
+ public:
+ AccountTrackerObserver() {}
+ virtual ~AccountTrackerObserver() {}
+
+ void Clear();
+ void SortEventsByUser();
+
+ testing::AssertionResult CheckEvents();
+ testing::AssertionResult CheckEvents(const TrackingEvent& e1);
+ testing::AssertionResult CheckEvents(const TrackingEvent& e1,
+ const TrackingEvent& e2);
+ testing::AssertionResult CheckEvents(const TrackingEvent& e1,
+ const TrackingEvent& e2,
+ const TrackingEvent& e3);
+
+ private:
+ // AccountTrackerService::Observer implementation
+ virtual void OnAccountUpdated(
+ const AccountTrackerService::AccountInfo& ids) OVERRIDE;
+ virtual void OnAccountRemoved(
+ const AccountTrackerService::AccountInfo& ids) OVERRIDE;
+
+ testing::AssertionResult CheckEvents(
+ const std::vector<TrackingEvent>& events);
+
+ std::vector<TrackingEvent> events_;
+};
+
+void AccountTrackerObserver::OnAccountUpdated(
+ const AccountTrackerService::AccountInfo& ids) {
+ events_.push_back(TrackingEvent(UPDATED, ids.account_id, ids.gaia));
+}
+
+void AccountTrackerObserver::OnAccountRemoved(
+ const AccountTrackerService::AccountInfo& ids) {
+ events_.push_back(TrackingEvent(REMOVED, ids.account_id, ids.gaia));
+}
+
+void AccountTrackerObserver::Clear() {
+ events_.clear();
+}
+
+void AccountTrackerObserver::SortEventsByUser() {
+ std::stable_sort(events_.begin(), events_.end(), CompareByUser);
+}
+
+testing::AssertionResult AccountTrackerObserver::CheckEvents() {
+ std::vector<TrackingEvent> events;
+ return CheckEvents(events);
+}
+
+testing::AssertionResult AccountTrackerObserver::CheckEvents(
+ const TrackingEvent& e1) {
+ std::vector<TrackingEvent> events;
+ events.push_back(e1);
+ return CheckEvents(events);
+}
+
+testing::AssertionResult AccountTrackerObserver::CheckEvents(
+ const TrackingEvent& e1,
+ const TrackingEvent& e2) {
+ std::vector<TrackingEvent> events;
+ events.push_back(e1);
+ events.push_back(e2);
+ return CheckEvents(events);
+}
+
+testing::AssertionResult AccountTrackerObserver::CheckEvents(
+ const TrackingEvent& e1,
+ const TrackingEvent& e2,
+ const TrackingEvent& e3) {
+ std::vector<TrackingEvent> events;
+ events.push_back(e1);
+ events.push_back(e2);
+ events.push_back(e3);
+ return CheckEvents(events);
+}
+
+testing::AssertionResult AccountTrackerObserver::CheckEvents(
+ const std::vector<TrackingEvent>& events) {
+ std::string maybe_newline = (events.size() + events_.size()) > 2 ? "\n" : "";
+ testing::AssertionResult result(
+ (events_ == events)
+ ? testing::AssertionSuccess()
+ : (testing::AssertionFailure()
+ << "Expected " << maybe_newline << Str(events) << ", "
+ << maybe_newline << "Got " << maybe_newline << Str(events_)));
+ events_.clear();
+ return result;
+}
+
+} // namespace
+
+class AccountTrackerServiceTest : public testing::Test {
+ public:
+ AccountTrackerServiceTest() {}
+
+ virtual ~AccountTrackerServiceTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ fake_oauth2_token_service_.reset(new FakeOAuth2TokenService());
+
+ pref_service_.registry()->RegisterListPref(
+ AccountTrackerService::kAccountInfoPref);
+
+ account_tracker_.reset(new AccountTrackerService());
+ account_tracker_->Initialize(fake_oauth2_token_service_.get(),
+ &pref_service_,
+ new net::TestURLRequestContextGetter(
+ message_loop_.message_loop_proxy()));
+ account_tracker_->AddObserver(&observer_);
+ }
+
+ virtual void TearDown() OVERRIDE {
+ account_tracker_->RemoveObserver(&observer_);
+ account_tracker_->Shutdown();
+ }
+
+ void SimulateTokenAvailable(const std::string& account_id) {
+ fake_oauth2_token_service_->AddAccount(account_id);
+ }
+
+ void SimulateTokenRevoked(const std::string& account_id) {
+ fake_oauth2_token_service_->RemoveAccount(account_id);
+ }
+
+ // Helpers to fake access token and user info fetching
+ void IssueAccessToken(const std::string& account_id) {
+ fake_oauth2_token_service_->IssueAllTokensForAccount(
+ account_id, "access_token-" + account_id, base::Time::Max());
+ }
+
+ std::string GenerateValidTokenInfoResponse(const std::string& account_id) {
+ return base::StringPrintf("{\"id\": \"%s\", \"email\": \"%s\"}",
+ AccountIdToGaiaId(account_id).c_str(),
+ AccountIdToEmail(account_id).c_str());
+ }
+
+ void ReturnOAuthUrlFetchSuccess(const std::string& account_id);
+ void ReturnOAuthUrlFetchFailure(const std::string& account_id);
+
+ base::MessageLoopForIO* message_loop() { return &message_loop_; }
+ AccountTrackerService* account_tracker() { return account_tracker_.get(); }
+ AccountTrackerObserver* observer() { return &observer_; }
+ OAuth2TokenService* token_service() {
+ return fake_oauth2_token_service_.get();
+ }
+ TestingPrefServiceSimple* pref_service() { return &pref_service_; }
+
+ private:
+ void ReturnOAuthUrlFetchResults(int fetcher_id,
+ net::HttpStatusCode response_code,
+ const std::string& response_string);
+
+ base::MessageLoopForIO message_loop_;
+ net::TestURLFetcherFactory test_fetcher_factory_;
+ scoped_ptr<FakeOAuth2TokenService> fake_oauth2_token_service_;
+ TestingPrefServiceSimple pref_service_;
+ scoped_ptr<AccountTrackerService> account_tracker_;
+ AccountTrackerObserver observer_;
+};
+
+void AccountTrackerServiceTest::ReturnOAuthUrlFetchResults(
+ int fetcher_id,
+ net::HttpStatusCode response_code,
+ const std::string& response_string) {
+ net::TestURLFetcher* fetcher =
+ test_fetcher_factory_.GetFetcherByID(fetcher_id);
+ ASSERT_TRUE(fetcher);
+ fetcher->set_response_code(response_code);
+ fetcher->SetResponseString(response_string);
+ fetcher->delegate()->OnURLFetchComplete(fetcher);
+}
+
+void AccountTrackerServiceTest::ReturnOAuthUrlFetchSuccess(
+ const std::string& account_id) {
+ IssueAccessToken(account_id);
+ ReturnOAuthUrlFetchResults(gaia::GaiaOAuthClient::kUrlFetcherId,
+ net::HTTP_OK,
+ GenerateValidTokenInfoResponse(account_id));
+}
+
+void AccountTrackerServiceTest::ReturnOAuthUrlFetchFailure(
+ const std::string& account_id) {
+ IssueAccessToken(account_id);
+ ReturnOAuthUrlFetchResults(
+ gaia::GaiaOAuthClient::kUrlFetcherId, net::HTTP_BAD_REQUEST, "");
+}
+
+TEST_F(AccountTrackerServiceTest, Basic) {
+}
+
+TEST_F(AccountTrackerServiceTest, TokenAvailable) {
+ SimulateTokenAvailable("alpha");
+ ASSERT_FALSE(account_tracker()->IsAllUserInfoFetched());
+ ASSERT_TRUE(observer()->CheckEvents());
+}
+
+TEST_F(AccountTrackerServiceTest, TokenAvailable_Revoked) {
+ SimulateTokenAvailable("alpha");
+ SimulateTokenRevoked("alpha");
+ ASSERT_TRUE(account_tracker()->IsAllUserInfoFetched());
+ ASSERT_TRUE(observer()->CheckEvents());
+}
+
+TEST_F(AccountTrackerServiceTest, TokenAvailable_UserInfo) {
+ SimulateTokenAvailable("alpha");
+ ReturnOAuthUrlFetchSuccess("alpha");
+ ASSERT_TRUE(account_tracker()->IsAllUserInfoFetched());
+ ASSERT_TRUE(observer()->CheckEvents(TrackingEvent(UPDATED, "alpha")));
+}
+
+TEST_F(AccountTrackerServiceTest, TokenAvailable_UserInfo_Revoked) {
+ SimulateTokenAvailable("alpha");
+ ReturnOAuthUrlFetchSuccess("alpha");
+ ASSERT_TRUE(account_tracker()->IsAllUserInfoFetched());
+ ASSERT_TRUE(observer()->CheckEvents(TrackingEvent(UPDATED, "alpha")));
+ SimulateTokenRevoked("alpha");
+ ASSERT_TRUE(observer()->CheckEvents(TrackingEvent(REMOVED, "alpha")));
+}
+
+TEST_F(AccountTrackerServiceTest, TokenAvailable_UserInfoFailed) {
+ SimulateTokenAvailable("alpha");
+ ReturnOAuthUrlFetchFailure("alpha");
+ ASSERT_TRUE(account_tracker()->IsAllUserInfoFetched());
+ ASSERT_TRUE(observer()->CheckEvents());
+}
+
+TEST_F(AccountTrackerServiceTest, TokenAlreadyExists) {
+ SimulateTokenAvailable("alpha");
+ AccountTrackerService tracker;
+ AccountTrackerObserver observer;
+ tracker.AddObserver(&observer);
+ tracker.Initialize(token_service(),
+ pref_service(),
+ new net::TestURLRequestContextGetter(
+ message_loop()->message_loop_proxy()));
+ ASSERT_FALSE(tracker.IsAllUserInfoFetched());
+ ASSERT_TRUE(observer.CheckEvents());
+ tracker.RemoveObserver(&observer);
+ tracker.Shutdown();
+}
+
+TEST_F(AccountTrackerServiceTest, TwoTokenAvailable_TwoUserInfo) {
+ SimulateTokenAvailable("alpha");
+ SimulateTokenAvailable("beta");
+ ReturnOAuthUrlFetchSuccess("alpha");
+ ReturnOAuthUrlFetchSuccess("beta");
+ ASSERT_TRUE(account_tracker()->IsAllUserInfoFetched());
+ ASSERT_TRUE(observer()->CheckEvents(TrackingEvent(UPDATED, "alpha"),
+ TrackingEvent(UPDATED, "beta")));
+}
+
+TEST_F(AccountTrackerServiceTest, TwoTokenAvailable_OneUserInfo) {
+ SimulateTokenAvailable("alpha");
+ SimulateTokenAvailable("beta");
+ ReturnOAuthUrlFetchSuccess("beta");
+ ASSERT_FALSE(account_tracker()->IsAllUserInfoFetched());
+ ASSERT_TRUE(observer()->CheckEvents(TrackingEvent(UPDATED, "beta")));
+ ReturnOAuthUrlFetchSuccess("alpha");
+ ASSERT_TRUE(account_tracker()->IsAllUserInfoFetched());
+ ASSERT_TRUE(observer()->CheckEvents(TrackingEvent(UPDATED, "alpha")));
+}
+
+TEST_F(AccountTrackerServiceTest, GetAccounts) {
+ SimulateTokenAvailable("alpha");
+ SimulateTokenAvailable("beta");
+ SimulateTokenAvailable("gamma");
+ ReturnOAuthUrlFetchSuccess("alpha");
+ ReturnOAuthUrlFetchSuccess("beta");
+ ReturnOAuthUrlFetchSuccess("gamma");
+
+ std::vector<AccountTrackerService::AccountInfo> infos =
+ account_tracker()->GetAccounts();
+
+ EXPECT_EQ(3u, infos.size());
+ EXPECT_EQ("alpha", infos[0].account_id);
+ EXPECT_EQ(AccountIdToGaiaId("alpha"), infos[0].gaia);
+ EXPECT_EQ(AccountIdToEmail("alpha"), infos[0].email);
+ EXPECT_EQ("beta", infos[1].account_id);
+ EXPECT_EQ(AccountIdToGaiaId("beta"), infos[1].gaia);
+ EXPECT_EQ(AccountIdToEmail("beta"), infos[1].email);
+ EXPECT_EQ("gamma", infos[2].account_id);
+ EXPECT_EQ(AccountIdToGaiaId("gamma"), infos[2].gaia);
+ EXPECT_EQ(AccountIdToEmail("gamma"), infos[2].email);
+}
+
+TEST_F(AccountTrackerServiceTest, GetAccountInfo_Empty) {
+ AccountTrackerService::AccountInfo info =
+ account_tracker()->GetAccountInfo("alpha");
+ ASSERT_EQ("", info.account_id);
+}
+
+TEST_F(AccountTrackerServiceTest, GetAccountInfo_TokenAvailable) {
+ SimulateTokenAvailable("alpha");
+ AccountTrackerService::AccountInfo info =
+ account_tracker()->GetAccountInfo("alpha");
+ ASSERT_EQ("alpha", info.account_id);
+ ASSERT_EQ("", info.gaia);
+ ASSERT_EQ("", info.email);
+}
+
+TEST_F(AccountTrackerServiceTest, GetAccountInfo_TokenAvailable_UserInfo) {
+ SimulateTokenAvailable("alpha");
+ ReturnOAuthUrlFetchSuccess("alpha");
+ AccountTrackerService::AccountInfo info =
+ account_tracker()->GetAccountInfo("alpha");
+ ASSERT_EQ("alpha", info.account_id);
+ ASSERT_EQ(AccountIdToGaiaId("alpha"), info.gaia);
+ ASSERT_EQ(AccountIdToEmail("alpha"), info.email);
+}
+
+TEST_F(AccountTrackerServiceTest, FindAccountInfoByGaiaId) {
+ SimulateTokenAvailable("alpha");
+ ReturnOAuthUrlFetchSuccess("alpha");
+
+ std::string gaia_id = AccountIdToGaiaId("alpha");
+ AccountTrackerService::AccountInfo info =
+ account_tracker()->FindAccountInfoByGaiaId(gaia_id);
+ ASSERT_EQ("alpha", info.account_id);
+ ASSERT_EQ(gaia_id, info.gaia);
+
+ gaia_id = AccountIdToGaiaId("beta");
+ info = account_tracker()->FindAccountInfoByGaiaId(gaia_id);
+ ASSERT_EQ("", info.account_id);
+}
+
+TEST_F(AccountTrackerServiceTest, FindAccountInfoByEmail) {
+ SimulateTokenAvailable("alpha");
+ ReturnOAuthUrlFetchSuccess("alpha");
+
+ std::string email = AccountIdToEmail("alpha");
+ AccountTrackerService::AccountInfo info =
+ account_tracker()->FindAccountInfoByEmail(email);
+ ASSERT_EQ("alpha", info.account_id);
+ ASSERT_EQ(email, info.email);
+
+ // Should also work with "canonically-equal" email addresses.
+ info = account_tracker()->FindAccountInfoByEmail("Alpha@Gmail.COM");
+ ASSERT_EQ("alpha", info.account_id);
+ ASSERT_EQ(email, info.email);
+ info = account_tracker()->FindAccountInfoByEmail("al.pha@gmail.com");
+ ASSERT_EQ("alpha", info.account_id);
+ ASSERT_EQ(email, info.email);
+
+ email = AccountIdToEmail("beta");
+ info = account_tracker()->FindAccountInfoByEmail(email);
+ ASSERT_EQ("", info.account_id);
+}
+
+TEST_F(AccountTrackerServiceTest, Persistence) {
+ // Create a tracker and add two accounts. This should cause the accounts
+ // to be saved to persistence.
+ {
+ AccountTrackerService tracker;
+ tracker.Initialize(token_service(),
+ pref_service(),
+ new net::TestURLRequestContextGetter(
+ message_loop()->message_loop_proxy()));
+ SimulateTokenAvailable("alpha");
+ ReturnOAuthUrlFetchSuccess("alpha");
+ SimulateTokenAvailable("beta");
+ ReturnOAuthUrlFetchSuccess("beta");
+ tracker.Shutdown();
+ }
+
+ // Create a new tracker and make sure it loads the accounts corectly from
+ // persistence.
+ {
+ AccountTrackerService tracker;
+ tracker.AddObserver(observer());
+ tracker.Initialize(token_service(),
+ pref_service(),
+ new net::TestURLRequestContextGetter(
+ message_loop()->message_loop_proxy()));
+ ASSERT_TRUE(observer()->CheckEvents(TrackingEvent(UPDATED, "alpha"),
+ TrackingEvent(UPDATED, "beta")));
+
+ std::vector<AccountTrackerService::AccountInfo> infos =
+ tracker.GetAccounts();
+ ASSERT_EQ(2u, infos.size());
+ EXPECT_EQ(AccountIdToGaiaId("alpha"), infos[0].gaia);
+ EXPECT_EQ(AccountIdToEmail("alpha"), infos[0].email);
+ EXPECT_EQ("beta", infos[1].account_id);
+ EXPECT_EQ(AccountIdToGaiaId("beta"), infos[1].gaia);
+ EXPECT_EQ(AccountIdToEmail("beta"), infos[1].email);
+
+ // Remove account.
+ SimulateTokenRevoked("alpha");
+ tracker.RemoveObserver(observer());
+ tracker.Shutdown();
+ }
+
+ // Create a new tracker and make sure it loads the single account from
+ // persistence.
+ {
+ AccountTrackerService tracker;
+ tracker.Initialize(token_service(),
+ pref_service(),
+ new net::TestURLRequestContextGetter(
+ message_loop()->message_loop_proxy()));
+
+ std::vector<AccountTrackerService::AccountInfo> infos =
+ tracker.GetAccounts();
+ ASSERT_EQ(1u, infos.size());
+ EXPECT_EQ("beta", infos[0].account_id);
+ EXPECT_EQ(AccountIdToGaiaId("beta"), infos[0].gaia);
+ EXPECT_EQ(AccountIdToEmail("beta"), infos[0].email);
+ tracker.Shutdown();
+ }
+}
« no previous file with comments | « components/signin/core/browser/account_tracker_service.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698