diff options
Diffstat (limited to 'chrome/browser/net')
-rw-r--r-- | chrome/browser/net/gaia/token_service.cc | 30 | ||||
-rw-r--r-- | chrome/browser/net/gaia/token_service.h | 19 | ||||
-rw-r--r-- | chrome/browser/net/gaia/token_service_unittest.cc | 126 | ||||
-rw-r--r-- | chrome/browser/net/gaia/token_service_unittest.h | 130 |
4 files changed, 183 insertions, 122 deletions
diff --git a/chrome/browser/net/gaia/token_service.cc b/chrome/browser/net/gaia/token_service.cc index b46868f..b61ab62 100644 --- a/chrome/browser/net/gaia/token_service.cc +++ b/chrome/browser/net/gaia/token_service.cc @@ -13,6 +13,8 @@ #include "chrome/common/notification_service.h" // Unfortunately kNumServices must be defined in the .h. +// TODO(chron): Sync doesn't use the TalkToken anymore so we can stop +// requesting it. const char* TokenService::kServices[] = {GaiaConstants::kSyncService, GaiaConstants::kTalkService}; TokenService::TokenService() @@ -29,12 +31,18 @@ void TokenService::Initialize(const char* const source, Profile* profile) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); - + if (!source_.empty()) { + // Already initialized. + return; + } getter_ = profile->GetRequestContext(); // Since the user can create a bookmark in incognito, sync may be running. // Thus we have to go for explicit access. web_data_service_ = profile->GetWebDataService(Profile::EXPLICIT_ACCESS); source_ = std::string(source); + registrar_.Add(this, + NotificationType::TOKEN_UPDATED, + NotificationService::AllSources()); } void TokenService::ResetCredentialsInMemory() { @@ -147,6 +155,12 @@ void TokenService::FireTokenRequestFailedNotification( Details<const TokenRequestFailedDetails>(&details)); } +void TokenService::IssueAuthTokenForTest(const std::string& service, + const std::string& auth_token) { + token_map_[service] = auth_token; + FireTokenAvailableNotification(service, auth_token); +} + void TokenService::OnIssueAuthTokenSuccess(const std::string& service, const std::string& auth_token) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); @@ -178,6 +192,11 @@ void TokenService::OnWebDataServiceRequestDone(WebDataService::Handle h, result); LoadTokensIntoMemory(token_result->GetValue(), &token_map_); } + + NotificationService::current()->Notify( + NotificationType::TOKEN_LOADING_FINISHED, + Source<TokenService>(this), + NotificationService::NoDetails()); } // Load tokens from the db_token map into the in memory token map. @@ -207,3 +226,12 @@ void TokenService::LoadTokensIntoMemory( } } } + +void TokenService::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(type == NotificationType::TOKEN_UPDATED); + TokenAvailableDetails* tok_details = + Details<TokenAvailableDetails>(details).ptr(); + OnIssueAuthTokenSuccess(tok_details->service(), tok_details->token()); +} diff --git a/chrome/browser/net/gaia/token_service.h b/chrome/browser/net/gaia/token_service.h index 20ca12d..006423f 100644 --- a/chrome/browser/net/gaia/token_service.h +++ b/chrome/browser/net/gaia/token_service.h @@ -37,12 +37,15 @@ #include <map> #include <string> + +#include "base/gtest_prod_util.h" #include "base/scoped_ptr.h" #include "chrome/browser/webdata/web_data_service.h" #include "chrome/common/net/gaia/gaia_auth_consumer.h" #include "chrome/common/net/gaia/gaia_authenticator2.h" #include "chrome/common/net/gaia/google_service_auth_error.h" -#include "base/gtest_prod_util.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" class URLRequestContextGetter; class Profile; @@ -50,7 +53,8 @@ class Profile; // The TokenService is a Profile member, so all calls are expected // from the UI thread. class TokenService : public GaiaAuthConsumer, - public WebDataServiceConsumer { + public WebDataServiceConsumer, + public NotificationObserver { public: TokenService(); virtual ~TokenService(); @@ -123,6 +127,10 @@ class TokenService : public GaiaAuthConsumer, const bool HasTokenForService(const char* const service) const; const std::string& GetTokenForService(const char* const service) const; + // For tests only. Doesn't save to the WebDB. + void IssueAuthTokenForTest(const std::string& service, + const std::string& auth_token); + // GaiaAuthConsumer implementation. virtual void OnIssueAuthTokenSuccess(const std::string& service, const std::string& auth_token); @@ -133,6 +141,11 @@ class TokenService : public GaiaAuthConsumer, virtual void OnWebDataServiceRequestDone(WebDataService::Handle h, const WDTypedResult* result); + // NotificationObserver implementation. + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + private: void FireTokenAvailableNotification(const std::string& service, @@ -169,6 +182,8 @@ class TokenService : public GaiaAuthConsumer, // Map from service to token. std::map<std::string, std::string> token_map_; + NotificationRegistrar registrar_; + FRIEND_TEST_ALL_PREFIXES(TokenServiceTest, LoadTokensIntoMemoryBasic); FRIEND_TEST_ALL_PREFIXES(TokenServiceTest, LoadTokensIntoMemoryAdvanced); diff --git a/chrome/browser/net/gaia/token_service_unittest.cc b/chrome/browser/net/gaia/token_service_unittest.cc index 512efff..ce0096b 100644 --- a/chrome/browser/net/gaia/token_service_unittest.cc +++ b/chrome/browser/net/gaia/token_service_unittest.cc @@ -4,127 +4,18 @@ // // This file defines a unit test for the profile's token service. -#include "chrome/browser/net/gaia/token_service.h" -#include "chrome/browser/password_manager/encryptor.h" -#include "chrome/browser/webdata/web_data_service.h" -#include "chrome/common/net/gaia/gaia_auth_consumer.h" +#include "chrome/browser/net/gaia/token_service_unittest.h" + #include "chrome/common/net/gaia/gaia_authenticator2_unittest.h" #include "chrome/common/net/gaia/gaia_constants.h" #include "chrome/common/net/test_url_fetcher_factory.h" -#include "chrome/test/signaling_task.h" -#include "chrome/test/test_notification_tracker.h" -#include "chrome/test/testing_profile.h" -#include "testing/gtest/include/gtest/gtest.h" - -// TestNotificationTracker doesn't do a deep copy on the notification details. -// We have to in order to read it out, or we have a bad ptr, since the details -// are a reference on the stack. -class TokenAvailableTracker : public TestNotificationTracker { - public: - const TokenService::TokenAvailableDetails& get_last_token_details() { - return details_; - } - - private: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - TestNotificationTracker::Observe(type, source, details); - if (type == NotificationType::TOKEN_AVAILABLE) { - Details<const TokenService::TokenAvailableDetails> full = details; - details_ = *full.ptr(); - } - } - - TokenService::TokenAvailableDetails details_; -}; - -class TokenFailedTracker : public TestNotificationTracker { - public: - const TokenService::TokenRequestFailedDetails& get_last_token_details() { - return details_; - } - - private: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - TestNotificationTracker::Observe(type, source, details); - if (type == NotificationType::TOKEN_REQUEST_FAILED) { - Details<const TokenService::TokenRequestFailedDetails> full = details; - details_ = *full.ptr(); - } - } - TokenService::TokenRequestFailedDetails details_; -}; - -class TokenServiceTest : public testing::Test { +class TokenServiceTest : public TokenServiceTestHarness { public: - TokenServiceTest() - : ui_thread_(ChromeThread::UI, &message_loop_), - db_thread_(ChromeThread::DB) { - } - virtual void SetUp() { -#if defined(OS_MACOSX) - Encryptor::UseMockKeychain(true); -#endif - credentials_.sid = "sid"; - credentials_.lsid = "lsid"; - credentials_.token = "token"; - credentials_.data = "data"; - - ASSERT_TRUE(db_thread_.Start()); - - profile_.reset(new TestingProfile()); - profile_->CreateWebDataService(false); - WaitForDBLoadCompletion(); - - success_tracker_.ListenFor(NotificationType::TOKEN_AVAILABLE, - Source<TokenService>(&service_)); - failure_tracker_.ListenFor(NotificationType::TOKEN_REQUEST_FAILED, - Source<TokenService>(&service_)); - - service_.Initialize("test", profile_.get()); + TokenServiceTestHarness::SetUp(); service_.UpdateCredentials(credentials_); - - URLFetcher::set_factory(NULL); - } - - virtual void TearDown() { - // You have to destroy the profile before the db_thread_ stops. - if (profile_.get()) { - profile_.reset(NULL); - } - - db_thread_.Stop(); - MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask); - MessageLoop::current()->Run(); - } - - void WaitForDBLoadCompletion() { - // The WebDB does all work on the DB thread. This will add an event - // to the end of the DB thread, so when we reach this task, all DB - // operations should be complete. - WaitableEvent done(false, false); - ChromeThread::PostTask( - ChromeThread::DB, FROM_HERE, new SignalingTask(&done)); - done.Wait(); - - // Notifications should be returned from the DB thread onto the UI thread. - message_loop_.RunAllPending(); } - - MessageLoopForUI message_loop_; - ChromeThread ui_thread_; // Mostly so DCHECKS pass. - ChromeThread db_thread_; // WDS on here - - TokenService service_; - TokenAvailableTracker success_tracker_; - TokenFailedTracker failure_tracker_; - GaiaAuthConsumer::ClientLoginResult credentials_; - scoped_ptr<TestingProfile> profile_; }; TEST_F(TokenServiceTest, SanityCheck) { @@ -145,8 +36,7 @@ TEST_F(TokenServiceTest, NotificationSuccess) { EXPECT_EQ(1U, success_tracker_.size()); EXPECT_EQ(0U, failure_tracker_.size()); - TokenService::TokenAvailableDetails details = - success_tracker_.get_last_token_details(); + TokenService::TokenAvailableDetails details = success_tracker_.details(); // MSVC doesn't like this comparison as EQ. EXPECT_TRUE(details.service() == GaiaConstants::kSyncService); EXPECT_EQ(details.token(), "token"); @@ -160,8 +50,7 @@ TEST_F(TokenServiceTest, NotificationFailed) { EXPECT_EQ(0U, success_tracker_.size()); EXPECT_EQ(1U, failure_tracker_.size()); - TokenService::TokenRequestFailedDetails details = - failure_tracker_.get_last_token_details(); + TokenService::TokenRequestFailedDetails details = failure_tracker_.details(); // MSVC doesn't like this comparison as EQ. EXPECT_TRUE(details.service() == GaiaConstants::kSyncService); @@ -275,8 +164,7 @@ TEST_F(TokenServiceTest, LoadTokensIntoMemoryBasic) { service_.LoadTokensIntoMemory(db_tokens, &memory_tokens); EXPECT_EQ(1U, success_tracker_.size()); - TokenService::TokenAvailableDetails details = - success_tracker_.get_last_token_details(); + TokenService::TokenAvailableDetails details = success_tracker_.details(); // MSVC doesn't like this comparison as EQ. EXPECT_TRUE(details.service() == GaiaConstants::kSyncService); EXPECT_EQ(details.token(), "token"); diff --git a/chrome/browser/net/gaia/token_service_unittest.h b/chrome/browser/net/gaia/token_service_unittest.h new file mode 100644 index 0000000..ad46138 --- /dev/null +++ b/chrome/browser/net/gaia/token_service_unittest.h @@ -0,0 +1,130 @@ +// Copyright (c) 2010 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. +// +// This file defines a unit test harness for the profile's token service. + +#ifndef CHROME_BROWSER_NET_GAIA_TOKEN_SERVICE_UNITTEST_H_ +#define CHROME_BROWSER_NET_GAIA_TOKEN_SERVICE_UNITTEST_H_ +#pragma once + +#include "chrome/browser/net/gaia/token_service.h" +#include "chrome/browser/password_manager/encryptor.h" +#include "chrome/browser/webdata/web_data_service.h" +#include "chrome/common/net/gaia/gaia_auth_consumer.h" +#include "chrome/test/signaling_task.h" +#include "chrome/test/test_notification_tracker.h" +#include "chrome/test/testing_profile.h" +#include "testing/gtest/include/gtest/gtest.h" + +// TestNotificationTracker doesn't do a deep copy on the notification details. +// We have to in order to read it out, or we have a bad ptr, since the details +// are a reference on the stack. +class TokenAvailableTracker : public TestNotificationTracker { + public: + const TokenService::TokenAvailableDetails& details() { + return details_; + } + + private: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + TestNotificationTracker::Observe(type, source, details); + if (type == NotificationType::TOKEN_AVAILABLE) { + Details<const TokenService::TokenAvailableDetails> full = details; + details_ = *full.ptr(); + } + } + + TokenService::TokenAvailableDetails details_; +}; + +class TokenFailedTracker : public TestNotificationTracker { + public: + const TokenService::TokenRequestFailedDetails& details() { + return details_; + } + + private: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + TestNotificationTracker::Observe(type, source, details); + if (type == NotificationType::TOKEN_REQUEST_FAILED) { + Details<const TokenService::TokenRequestFailedDetails> full = details; + details_ = *full.ptr(); + } + } + + TokenService::TokenRequestFailedDetails details_; +}; + +class TokenServiceTestHarness : public testing::Test { + public: + TokenServiceTestHarness() + : ui_thread_(ChromeThread::UI, &message_loop_), + db_thread_(ChromeThread::DB) { + } + + virtual void SetUp() { +#if defined(OS_MACOSX) + Encryptor::UseMockKeychain(true); +#endif + credentials_.sid = "sid"; + credentials_.lsid = "lsid"; + credentials_.token = "token"; + credentials_.data = "data"; + + ASSERT_TRUE(db_thread_.Start()); + + profile_.reset(new TestingProfile()); + profile_->CreateWebDataService(false); + WaitForDBLoadCompletion(); + + success_tracker_.ListenFor(NotificationType::TOKEN_AVAILABLE, + Source<TokenService>(&service_)); + failure_tracker_.ListenFor(NotificationType::TOKEN_REQUEST_FAILED, + Source<TokenService>(&service_)); + + service_.Initialize("test", profile_.get()); + + URLFetcher::set_factory(NULL); + } + + virtual void TearDown() { + // You have to destroy the profile before the db_thread_ stops. + if (profile_.get()) { + profile_.reset(NULL); + } + + db_thread_.Stop(); + MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask); + MessageLoop::current()->Run(); + } + + void WaitForDBLoadCompletion() { + // The WebDB does all work on the DB thread. This will add an event + // to the end of the DB thread, so when we reach this task, all DB + // operations should be complete. + WaitableEvent done(false, false); + ChromeThread::PostTask( + ChromeThread::DB, FROM_HERE, new SignalingTask(&done)); + done.Wait(); + + // Notifications should be returned from the DB thread onto the UI thread. + message_loop_.RunAllPending(); + } + + MessageLoopForUI message_loop_; + ChromeThread ui_thread_; // Mostly so DCHECKS pass. + ChromeThread db_thread_; // WDS on here + + TokenService service_; + TokenAvailableTracker success_tracker_; + TokenFailedTracker failure_tracker_; + GaiaAuthConsumer::ClientLoginResult credentials_; + scoped_ptr<TestingProfile> profile_; +}; + +#endif // CHROME_BROWSER_NET_GAIA_TOKEN_SERVICE_UNITTEST_H_ |