Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/run_loop.h" | 5 #include "base/run_loop.h" |
| 6 #include "base/strings/string_util.h" | |
| 6 #include "google_apis/gaia/google_service_auth_error.h" | 7 #include "google_apis/gaia/google_service_auth_error.h" |
| 7 #include "net/url_request/test_url_fetcher_factory.h" | 8 #include "net/url_request/test_url_fetcher_factory.h" |
| 8 #include "net/url_request/url_request_test_util.h" | 9 #include "net/url_request/url_request_test_util.h" |
| 9 #include "sync/notifier/gcm_network_channel.h" | 10 #include "sync/notifier/gcm_network_channel.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
| 11 | 12 |
| 12 namespace syncer { | 13 namespace syncer { |
| 13 namespace { | |
| 14 | 14 |
| 15 class TestGCMNetworkChannelDelegate : public GCMNetworkChannelDelegate { | 15 class TestGCMNetworkChannelDelegate : public GCMNetworkChannelDelegate { |
| 16 public: | 16 public: |
| 17 TestGCMNetworkChannelDelegate() | 17 TestGCMNetworkChannelDelegate() |
| 18 : register_call_count_(0) {} | 18 : register_call_count_(0) {} |
| 19 | 19 |
| 20 virtual void Initialize() OVERRIDE {} | 20 virtual void Initialize() OVERRIDE {} |
| 21 | 21 |
| 22 virtual void RequestToken(RequestTokenCallback callback) OVERRIDE { | 22 virtual void RequestToken(RequestTokenCallback callback) OVERRIDE { |
| 23 request_token_callback = callback; | 23 request_token_callback = callback; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 }; | 66 }; |
| 67 | 67 |
| 68 class TestGCMNetworkChannel : public GCMNetworkChannel { | 68 class TestGCMNetworkChannel : public GCMNetworkChannel { |
| 69 public: | 69 public: |
| 70 TestGCMNetworkChannel( | 70 TestGCMNetworkChannel( |
| 71 scoped_refptr<net::URLRequestContextGetter> request_context_getter, | 71 scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
| 72 scoped_ptr<GCMNetworkChannelDelegate> delegate) | 72 scoped_ptr<GCMNetworkChannelDelegate> delegate) |
| 73 : GCMNetworkChannel(request_context_getter, delegate.Pass()) { | 73 : GCMNetworkChannel(request_context_getter, delegate.Pass()) { |
| 74 ResetRegisterBackoffEntryForTest(&kTestBackoffPolicy); | 74 ResetRegisterBackoffEntryForTest(&kTestBackoffPolicy); |
| 75 } | 75 } |
| 76 | |
| 77 protected: | |
| 78 // On Android GCMNetworkChannel::BuildUrl hits NOTREACHED(). I still want | |
| 79 // tests to run. | |
| 80 GURL BuildUrl(const std::string& registration_id) { | |
| 81 return GURL("http://test.url.com"); | |
| 82 } | |
| 76 }; | 83 }; |
| 77 | 84 |
| 78 class GCMNetworkChannelTest | 85 class GCMNetworkChannelTest |
| 79 : public ::testing::Test, | 86 : public ::testing::Test, |
| 80 public SyncNetworkChannel::Observer { | 87 public SyncNetworkChannel::Observer { |
| 81 protected: | 88 protected: |
| 82 GCMNetworkChannelTest() | 89 GCMNetworkChannelTest() |
| 83 : delegate_(NULL), | 90 : delegate_(NULL), |
| 84 url_fetchers_created_count_(0) { | 91 url_fetchers_created_count_(0) { |
| 85 } | 92 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 103 this, &GCMNetworkChannelTest::OnIncomingMessage)); | 110 this, &GCMNetworkChannelTest::OnIncomingMessage)); |
| 104 url_fetcher_factory_.reset(new net::FakeURLFetcherFactory(NULL, | 111 url_fetcher_factory_.reset(new net::FakeURLFetcherFactory(NULL, |
| 105 base::Bind(&GCMNetworkChannelTest::CreateURLFetcher, | 112 base::Bind(&GCMNetworkChannelTest::CreateURLFetcher, |
| 106 base::Unretained(this)))); | 113 base::Unretained(this)))); |
| 107 } | 114 } |
| 108 | 115 |
| 109 virtual void TearDown() { | 116 virtual void TearDown() { |
| 110 gcm_network_channel_->RemoveObserver(this); | 117 gcm_network_channel_->RemoveObserver(this); |
| 111 } | 118 } |
| 112 | 119 |
| 120 // Helper functions to call private methods from test | |
| 121 GURL BuildUrl(const std::string& registration_id) { | |
| 122 return gcm_network_channel_->GCMNetworkChannel::BuildUrl(registration_id); | |
| 123 } | |
| 124 | |
| 125 static void Base64EncodeURLSafe(const std::string& input, | |
| 126 std::string* output) { | |
| 127 GCMNetworkChannel::Base64EncodeURLSafe(input, output); | |
| 128 } | |
| 129 | |
| 130 static bool Base64DecodeURLSafe(const std::string& input, | |
| 131 std::string* output) { | |
| 132 return GCMNetworkChannel::Base64DecodeURLSafe(input, output); | |
| 133 } | |
| 134 | |
| 113 virtual void OnNetworkChannelStateChanged( | 135 virtual void OnNetworkChannelStateChanged( |
| 114 InvalidatorState invalidator_state) OVERRIDE { | 136 InvalidatorState invalidator_state) OVERRIDE { |
| 115 } | 137 } |
| 116 | 138 |
| 117 void OnIncomingMessage(std::string incoming_message) { | 139 void OnIncomingMessage(std::string incoming_message) { |
| 118 } | 140 } |
| 119 | 141 |
| 120 GCMNetworkChannel* network_channel() { | 142 GCMNetworkChannel* network_channel() { |
| 121 return gcm_network_channel_.get(); | 143 return gcm_network_channel_.get(); |
| 122 } | 144 } |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 152 private: | 174 private: |
| 153 base::MessageLoop message_loop_; | 175 base::MessageLoop message_loop_; |
| 154 TestGCMNetworkChannelDelegate* delegate_; | 176 TestGCMNetworkChannelDelegate* delegate_; |
| 155 scoped_ptr<GCMNetworkChannel> gcm_network_channel_; | 177 scoped_ptr<GCMNetworkChannel> gcm_network_channel_; |
| 156 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_; | 178 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_; |
| 157 scoped_ptr<net::FakeURLFetcherFactory> url_fetcher_factory_; | 179 scoped_ptr<net::FakeURLFetcherFactory> url_fetcher_factory_; |
| 158 int url_fetchers_created_count_; | 180 int url_fetchers_created_count_; |
| 159 }; | 181 }; |
| 160 | 182 |
| 161 TEST_F(GCMNetworkChannelTest, HappyCase) { | 183 TEST_F(GCMNetworkChannelTest, HappyCase) { |
| 162 GURL url("http://invalid.url.com"); | 184 url_fetcher_factory()->SetFakeResponse(GURL("http://test.url.com"), |
| 163 url_fetcher_factory()->SetFakeResponse(url, std::string(), net::HTTP_OK, | 185 std::string(), |
| 186 net::HTTP_OK, | |
| 164 net::URLRequestStatus::SUCCESS); | 187 net::URLRequestStatus::SUCCESS); |
| 165 | 188 |
| 166 // After construction GCMNetworkChannel should have called Register. | 189 // After construction GCMNetworkChannel should have called Register. |
| 167 EXPECT_FALSE(delegate()->register_callback.is_null()); | 190 EXPECT_FALSE(delegate()->register_callback.is_null()); |
| 168 // Return valid registration id. | 191 // Return valid registration id. |
| 169 delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS); | 192 delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS); |
| 170 | 193 |
| 171 network_channel()->SendMessage("abra.cadabra"); | 194 network_channel()->SendMessage("abra.cadabra"); |
| 172 // SendMessage should have triggered RequestToken. No HTTP request should be | 195 // SendMessage should have triggered RequestToken. No HTTP request should be |
| 173 // started yet. | 196 // started yet. |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 202 // GcmNetworkChannel should give up trying. | 225 // GcmNetworkChannel should give up trying. |
| 203 EXPECT_EQ(2, delegate()->register_call_count_); | 226 EXPECT_EQ(2, delegate()->register_call_count_); |
| 204 | 227 |
| 205 network_channel()->SendMessage("abra.cadabra"); | 228 network_channel()->SendMessage("abra.cadabra"); |
| 206 // SendMessage shouldn't trigger RequestToken. | 229 // SendMessage shouldn't trigger RequestToken. |
| 207 EXPECT_TRUE(delegate()->request_token_callback.is_null()); | 230 EXPECT_TRUE(delegate()->request_token_callback.is_null()); |
| 208 EXPECT_EQ(0, url_fetchers_created_count()); | 231 EXPECT_EQ(0, url_fetchers_created_count()); |
| 209 } | 232 } |
| 210 | 233 |
| 211 TEST_F(GCMNetworkChannelTest, RegisterFinishesAfterSendMessage) { | 234 TEST_F(GCMNetworkChannelTest, RegisterFinishesAfterSendMessage) { |
| 212 GURL url("http://invalid.url.com"); | 235 url_fetcher_factory()->SetFakeResponse(GURL("http://test.url.com"), |
| 213 url_fetcher_factory()->SetFakeResponse(url, "", net::HTTP_OK, | 236 "", |
| 214 net::URLRequestStatus::SUCCESS); | 237 net::HTTP_OK, |
| 238 net::URLRequestStatus::SUCCESS); | |
| 215 | 239 |
| 216 // After construction GCMNetworkChannel should have called Register. | 240 // After construction GCMNetworkChannel should have called Register. |
| 217 EXPECT_FALSE(delegate()->register_callback.is_null()); | 241 EXPECT_FALSE(delegate()->register_callback.is_null()); |
| 218 | 242 |
| 219 network_channel()->SendMessage("abra.cadabra"); | 243 network_channel()->SendMessage("abra.cadabra"); |
| 220 // SendMessage shouldn't trigger RequestToken. | 244 // SendMessage shouldn't trigger RequestToken. |
| 221 EXPECT_TRUE(delegate()->request_token_callback.is_null()); | 245 EXPECT_TRUE(delegate()->request_token_callback.is_null()); |
| 222 EXPECT_EQ(url_fetchers_created_count(), 0); | 246 EXPECT_EQ(url_fetchers_created_count(), 0); |
| 223 | 247 |
| 224 // Return valid registration id. | 248 // Return valid registration id. |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 247 // RequestToken returns failure. | 271 // RequestToken returns failure. |
| 248 delegate()->request_token_callback.Run( | 272 delegate()->request_token_callback.Run( |
| 249 GoogleServiceAuthError::FromConnectionError(1), ""); | 273 GoogleServiceAuthError::FromConnectionError(1), ""); |
| 250 | 274 |
| 251 // Should be no HTTP requests. | 275 // Should be no HTTP requests. |
| 252 EXPECT_EQ(url_fetchers_created_count(), 0); | 276 EXPECT_EQ(url_fetchers_created_count(), 0); |
| 253 } | 277 } |
| 254 | 278 |
| 255 TEST_F(GCMNetworkChannelTest, AuthErrorFromServer) { | 279 TEST_F(GCMNetworkChannelTest, AuthErrorFromServer) { |
| 256 // Setup fake response to return AUTH_ERROR. | 280 // Setup fake response to return AUTH_ERROR. |
| 257 GURL url("http://invalid.url.com"); | 281 url_fetcher_factory()->SetFakeResponse(GURL("http://test.url.com"), |
| 258 url_fetcher_factory()->SetFakeResponse(url, "", net::HTTP_UNAUTHORIZED, | 282 "", |
| 259 net::URLRequestStatus::SUCCESS); | 283 net::HTTP_UNAUTHORIZED, |
| 284 net::URLRequestStatus::SUCCESS); | |
| 260 | 285 |
| 261 // After construction GCMNetworkChannel should have called Register. | 286 // After construction GCMNetworkChannel should have called Register. |
| 262 EXPECT_FALSE(delegate()->register_callback.is_null()); | 287 EXPECT_FALSE(delegate()->register_callback.is_null()); |
| 263 // Return valid registration id. | 288 // Return valid registration id. |
| 264 delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS); | 289 delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS); |
| 265 | 290 |
| 266 network_channel()->SendMessage("abra.cadabra"); | 291 network_channel()->SendMessage("abra.cadabra"); |
| 267 // SendMessage should have triggered RequestToken. No HTTP request should be | 292 // SendMessage should have triggered RequestToken. No HTTP request should be |
| 268 // started yet. | 293 // started yet. |
| 269 EXPECT_FALSE(delegate()->request_token_callback.is_null()); | 294 EXPECT_FALSE(delegate()->request_token_callback.is_null()); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 286 | 311 |
| 287 TEST_F(GCMNetworkChannelTest, RequestTokenNeverCompletes) { | 312 TEST_F(GCMNetworkChannelTest, RequestTokenNeverCompletes) { |
| 288 network_channel()->SendMessage("abra.cadabra"); | 313 network_channel()->SendMessage("abra.cadabra"); |
| 289 // Return valid registration id. | 314 // Return valid registration id. |
| 290 delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS); | 315 delegate()->register_callback.Run("registration.id", gcm::GCMClient::SUCCESS); |
| 291 // RequestToken should be called by now. Let's not complete and see what | 316 // RequestToken should be called by now. Let's not complete and see what |
| 292 // happens. | 317 // happens. |
| 293 EXPECT_FALSE(delegate()->request_token_callback.is_null()); | 318 EXPECT_FALSE(delegate()->request_token_callback.is_null()); |
| 294 } | 319 } |
| 295 | 320 |
| 296 } // namespace | 321 #ifndef ANDROID |
|
rlarocque
2014/03/07 19:42:20
nit: This looked a little unusual to me. I did so
| |
| 322 TEST_F(GCMNetworkChannelTest, BuildUrl) { | |
| 323 GURL url = BuildUrl("registration.id"); | |
| 324 EXPECT_TRUE(url.SchemeIsHTTPOrHTTPS()); | |
| 325 EXPECT_FALSE(url.host().empty()); | |
| 326 EXPECT_FALSE(url.path().empty()); | |
| 327 std::vector<std::string> parts; | |
| 328 Tokenize(url.path(), "/", &parts); | |
| 329 std::string buffer; | |
| 330 EXPECT_TRUE(Base64DecodeURLSafe(parts[parts.size() - 1], &buffer)); | |
| 331 } | |
| 332 #endif | |
| 333 | |
| 334 TEST_F(GCMNetworkChannelTest, Base64EncodeDecode) { | |
| 335 std::string input; | |
| 336 std::string plain; | |
| 337 std::string base64; | |
| 338 // Empty string. | |
| 339 Base64EncodeURLSafe(input, &base64); | |
| 340 EXPECT_TRUE(base64.empty()); | |
| 341 EXPECT_TRUE(Base64DecodeURLSafe(base64, &plain)); | |
| 342 EXPECT_EQ(input, plain); | |
| 343 // String length: 1..7. | |
| 344 for (int length = 1; length < 8; length++) { | |
| 345 input = "abra.cadabra"; | |
| 346 input.resize(length); | |
| 347 Base64EncodeURLSafe(input, &base64); | |
| 348 // Ensure no padding at the end. | |
| 349 EXPECT_NE(base64[base64.size() - 1], '='); | |
| 350 EXPECT_TRUE(Base64DecodeURLSafe(base64, &plain)); | |
| 351 EXPECT_EQ(input, plain); | |
| 352 } | |
| 353 // Presence of '-', '_'. | |
| 354 input = "\xfb\xff"; | |
| 355 Base64EncodeURLSafe(input, &base64); | |
| 356 EXPECT_EQ("-_8", base64); | |
| 357 EXPECT_TRUE(Base64DecodeURLSafe(base64, &plain)); | |
| 358 EXPECT_EQ(input, plain); | |
| 359 } | |
| 360 | |
| 297 } // namespace syncer | 361 } // namespace syncer |
| OLD | NEW |