| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2009 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 entry. |
| 4 |
| 5 #include "base/scoped_ptr.h" |
| 6 #include "base/scoped_temp_dir.h" |
| 7 #include "base/test_file_util.h" |
| 8 #include "base/waitable_event.h" |
| 9 #include "chrome/browser/sync/engine/all_status.h" |
| 10 #include "chrome/browser/sync/engine/auth_watcher.h" |
| 11 #include "chrome/browser/sync/engine/net/gaia_authenticator.h" |
| 12 #include "chrome/browser/sync/engine/net/http_return.h" |
| 13 #include "chrome/browser/sync/notifier/listener/talk_mediator_impl.h" |
| 14 #include "chrome/browser/sync/util/user_settings.h" |
| 15 #include "chrome/browser/sync/util/event_sys-inl.h" |
| 16 #include "chrome/test/sync/engine/mock_server_connection.h" |
| 17 #include "chrome/test/sync/engine/test_directory_setter_upper.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" |
| 19 |
| 20 static const wchar_t* kUserSettingsDB = L"Settings.sqlite3"; |
| 21 static const char* kTestUserAgent = "useragent"; |
| 22 static const char* kTestServiceId = "serviceid"; |
| 23 static const char* kTestGaiaURL = "http://gaia_url"; |
| 24 static const char* kUserDisplayName = "Mr. Auth Watcher"; |
| 25 static const char* kUserDisplayEmail = "authwatcherdisplay@gmail.com"; |
| 26 static const char* kTestEmail = "authwatchertest@gmail.com"; |
| 27 static const char* kWrongPassword = "wrongpassword"; |
| 28 static const char* kCorrectPassword = "correctpassword"; |
| 29 static const char* kValidSID = "validSID"; |
| 30 static const char* kValidLSID = "validLSID"; |
| 31 static const char* kInvalidAuthToken = "invalidAuthToken"; |
| 32 static const char* kValidAuthToken = "validAuthToken"; |
| 33 |
| 34 namespace { |
| 35 |
| 36 class GaiaAuthMock : public browser_sync::GaiaAuthenticator { |
| 37 public: |
| 38 GaiaAuthMock() : browser_sync::GaiaAuthenticator( |
| 39 kTestUserAgent, kTestServiceId, kTestGaiaURL), |
| 40 use_bad_auth_token_(false) {} |
| 41 virtual ~GaiaAuthMock() {} |
| 42 |
| 43 void SendBadAuthTokenForNextRequest() { use_bad_auth_token_ = true; } |
| 44 |
| 45 protected: |
| 46 bool PerformGaiaRequest(const AuthParams& params, AuthResults* results) { |
| 47 if (params.password == kWrongPassword) { |
| 48 results->auth_error = browser_sync::BadAuthentication; |
| 49 return false; |
| 50 } |
| 51 if (params.password == kCorrectPassword) { |
| 52 results->sid = kValidSID; |
| 53 results->lsid = kValidLSID; |
| 54 results->auth_token = kValidAuthToken; |
| 55 } |
| 56 if (use_bad_auth_token_) { |
| 57 results->auth_token = kInvalidAuthToken; |
| 58 use_bad_auth_token_ = false; |
| 59 } |
| 60 return true; |
| 61 } |
| 62 |
| 63 bool LookupEmail(AuthResults* results) { |
| 64 results->signin = GMAIL_SIGNIN; |
| 65 return true; |
| 66 } |
| 67 |
| 68 private: |
| 69 // Whether we should send an invalid auth token on the next request. |
| 70 bool use_bad_auth_token_; |
| 71 }; |
| 72 |
| 73 } // namespace |
| 74 |
| 75 namespace browser_sync { |
| 76 |
| 77 class AuthWatcherTest : public testing::Test { |
| 78 public: |
| 79 AuthWatcherTest() : consumer_ready(false, false), |
| 80 event_produced(false, false), |
| 81 metadb_(kUserDisplayEmail) {} |
| 82 virtual void SetUp() { |
| 83 metadb_.SetUp(); |
| 84 connection_.reset(new MockConnectionManager(metadb_.manager(), |
| 85 metadb_.name())); |
| 86 // Mock out data that would normally be sent back from a server. |
| 87 connection()->SetAuthenticationResponseInfo(kValidAuthToken, |
| 88 kUserDisplayName, kUserDisplayEmail, "ID"); |
| 89 allstatus_.reset(new AllStatus()); |
| 90 user_settings_.reset(new UserSettings()); |
| 91 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 92 PathString user_settings_path = temp_dir_.path().value() + kUserSettingsDB; |
| 93 user_settings_->Init(user_settings_path); |
| 94 gaia_auth_ = new GaiaAuthMock(); |
| 95 talk_mediator_.reset(new TalkMediatorImpl()); |
| 96 auth_watcher_ = new AuthWatcher(metadb_.manager(), connection_.get(), |
| 97 allstatus_.get(), kTestUserAgent, kTestServiceId, kTestGaiaURL, |
| 98 user_settings_.get(), gaia_auth_, talk_mediator_.get()); |
| 99 authwatcher_hookup_.reset(NewEventListenerHookup(auth_watcher_->channel(), |
| 100 this, &AuthWatcherTest::HandleAuthWatcherEvent)); |
| 101 } |
| 102 |
| 103 virtual void TearDown() { |
| 104 metadb_.TearDown(); |
| 105 auth_watcher_->Shutdown(); |
| 106 EXPECT_FALSE(auth_watcher()->message_loop()); |
| 107 } |
| 108 |
| 109 void HandleAuthWatcherEvent(const AuthWatcherEvent& event) { |
| 110 if (event.what_happened == AuthWatcherEvent::AUTHWATCHER_DESTROYED) |
| 111 return; |
| 112 consumer_ready.Wait(); // Block progress until the test is ready. |
| 113 |
| 114 last_event_reason_ = event.what_happened; |
| 115 if (event.what_happened == AuthWatcherEvent::AUTH_SUCCEEDED) |
| 116 user_email_ = event.user_email; |
| 117 |
| 118 event_produced.Signal(); |
| 119 } |
| 120 |
| 121 AuthWatcherEvent::WhatHappened ConsumeNextEvent() { |
| 122 consumer_ready.Signal(); |
| 123 event_produced.Wait(); |
| 124 return last_event_reason_; |
| 125 } |
| 126 |
| 127 AuthWatcher* auth_watcher() { return auth_watcher_.get(); } |
| 128 MockConnectionManager* connection() { return connection_.get(); } |
| 129 GaiaAuthMock* gaia_auth() { return gaia_auth_; } |
| 130 const std::string& user_email() { return user_email_; } |
| 131 |
| 132 private: |
| 133 // Responsible for creating / deleting a temp dir containing user settings DB. |
| 134 ScopedTempDir temp_dir_; |
| 135 |
| 136 // The event listener hookup registered for HandleAuthWatcherEvent. |
| 137 scoped_ptr<EventListenerHookup> authwatcher_hookup_; |
| 138 |
| 139 // The sync engine pieces necessary to run an AuthWatcher. |
| 140 TriggeredOpenTestDirectorySetterUpper metadb_; |
| 141 scoped_ptr<MockConnectionManager> connection_; |
| 142 scoped_ptr<AllStatus> allstatus_; |
| 143 scoped_ptr<UserSettings> user_settings_; |
| 144 GaiaAuthMock* gaia_auth_; // Owned by auth_watcher_. |
| 145 scoped_ptr<TalkMediator> talk_mediator_; |
| 146 scoped_refptr<AuthWatcher> auth_watcher_; |
| 147 |
| 148 // This is used to block the AuthWatcherThread when it raises events until we |
| 149 // are ready to read the event. It is not a manual-reset event, so it goes |
| 150 // straight back to non-signaled after one thread (the main thread) is |
| 151 // signaled (or "consumes" the signaled state). |
| 152 base::WaitableEvent consumer_ready; |
| 153 |
| 154 // This is signaled by the AuthWatcherThread after it sets last_event_reason_ |
| 155 // and possibly user_email_ for us to read. |
| 156 base::WaitableEvent event_produced; |
| 157 |
| 158 // The 'WhatHappened' value from the last AuthWatcherEvent we handled. |
| 159 AuthWatcherEvent::WhatHappened last_event_reason_; |
| 160 |
| 161 // Set when we receive an AUTH_SUCCEEDED event. |
| 162 std::string user_email_; |
| 163 |
| 164 DISALLOW_COPY_AND_ASSIGN(AuthWatcherTest); |
| 165 }; |
| 166 |
| 167 TEST_F(AuthWatcherTest, Construction) { |
| 168 EXPECT_TRUE(auth_watcher()->message_loop()); |
| 169 EXPECT_EQ("SyncEngine_AuthWatcherThread", |
| 170 auth_watcher()->message_loop()->thread_name()); |
| 171 EXPECT_TRUE(auth_watcher()->auth_backend_thread_.IsRunning()); |
| 172 EXPECT_EQ(AuthWatcher::NOT_AUTHENTICATED, auth_watcher()->status()); |
| 173 } |
| 174 |
| 175 TEST_F(AuthWatcherTest, AuthenticateGaiaAuthFailure) { |
| 176 auth_watcher()->Authenticate(kTestEmail, kWrongPassword, |
| 177 std::string(), // captcha_token |
| 178 std::string(), // captcha_value |
| 179 false); // persist_creds_to_disk |
| 180 EXPECT_EQ(AuthWatcherEvent::AUTHENTICATION_ATTEMPT_START, ConsumeNextEvent()); |
| 181 EXPECT_EQ(AuthWatcherEvent::GAIA_AUTH_FAILED, ConsumeNextEvent()); |
| 182 } |
| 183 |
| 184 TEST_F(AuthWatcherTest, AuthenticateBadAuthToken) { |
| 185 gaia_auth()->SendBadAuthTokenForNextRequest(); |
| 186 auth_watcher()->Authenticate(kTestEmail, kCorrectPassword, std::string(), |
| 187 std::string(), false); |
| 188 EXPECT_EQ(AuthWatcherEvent::AUTHENTICATION_ATTEMPT_START, ConsumeNextEvent()); |
| 189 EXPECT_EQ(AuthWatcherEvent::SERVICE_AUTH_FAILED, ConsumeNextEvent()); |
| 190 } |
| 191 |
| 192 TEST_F(AuthWatcherTest, AuthenticateSuccess) { |
| 193 auth_watcher()->Authenticate(kTestEmail, kCorrectPassword, std::string(), |
| 194 std::string(), false); |
| 195 EXPECT_EQ(AuthWatcherEvent::AUTHENTICATION_ATTEMPT_START, ConsumeNextEvent()); |
| 196 EXPECT_EQ(AuthWatcherEvent::AUTH_SUCCEEDED, ConsumeNextEvent()); |
| 197 |
| 198 // The server responds with a different email than what we used in the call |
| 199 // to Authenticate, and the AuthWatcher should have told us about. |
| 200 EXPECT_EQ(kUserDisplayEmail, user_email()); |
| 201 } |
| 202 |
| 203 TEST_F(AuthWatcherTest, AuthenticateWithTokenBadAuthToken) { |
| 204 auth_watcher()->AuthenticateWithToken(kTestEmail, kInvalidAuthToken); |
| 205 EXPECT_EQ(AuthWatcherEvent::SERVICE_AUTH_FAILED, ConsumeNextEvent()); |
| 206 } |
| 207 |
| 208 TEST_F(AuthWatcherTest, AuthenticateWithTokenSuccess) { |
| 209 auth_watcher()->AuthenticateWithToken(kTestEmail, kValidAuthToken); |
| 210 EXPECT_EQ(AuthWatcherEvent::AUTH_SUCCEEDED, ConsumeNextEvent()); |
| 211 EXPECT_EQ(kUserDisplayEmail, user_email()); |
| 212 } |
| 213 |
| 214 } // namespace browser_sync |
| OLD | NEW |