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 <stdint.h> | 5 #include <stdint.h> |
6 #include <map> | 6 #include <map> |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
12 #include "base/strings/string_tokenizer.h" | 12 #include "base/strings/string_tokenizer.h" |
13 #include "google_apis/gcm/engine/gcm_registration_request_handler.h" | 13 #include "google_apis/gcm/engine/gcm_registration_request_handler.h" |
14 #include "google_apis/gcm/engine/gcm_request_test_base.h" | 14 #include "google_apis/gcm/engine/gcm_request_test_base.h" |
15 #include "google_apis/gcm/engine/instance_id_get_token_request_handler.h" | 15 #include "google_apis/gcm/engine/instance_id_get_token_request_handler.h" |
16 #include "google_apis/gcm/monitoring/fake_gcm_stats_recorder.h" | 16 #include "google_apis/gcm/monitoring/fake_gcm_stats_recorder.h" |
17 #include "net/base/escape.h" | 17 #include "net/base/escape.h" |
18 #include "net/base/load_flags.h" | 18 #include "net/base/load_flags.h" |
19 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
20 #include "net/url_request/url_request_status.h" | 20 #include "net/url_request/url_request_status.h" |
21 | 21 |
22 namespace gcm { | 22 namespace gcm { |
23 | 23 |
24 namespace { | 24 namespace { |
25 const uint64_t kAndroidId = 42UL; | 25 const uint64_t kAndroidId = 42UL; |
26 const char kAppId[] = "TestAppId"; | 26 const char kAppId[] = "TestAppId"; |
| 27 const char kCategoryForSubtypes[] = "com.chrome.stable.macosx"; |
27 const char kDeveloperId[] = "Project1"; | 28 const char kDeveloperId[] = "Project1"; |
28 const char kLoginHeader[] = "AidLogin"; | 29 const char kLoginHeader[] = "AidLogin"; |
29 const char kRegistrationURL[] = "http://foo.bar/register"; | 30 const char kRegistrationURL[] = "http://foo.bar/register"; |
30 const uint64_t kSecurityToken = 77UL; | 31 const uint64_t kSecurityToken = 77UL; |
31 const int kGCMVersion = 40; | 32 const int kGCMVersion = 40; |
32 const char kInstanceId[] = "IID1"; | 33 const char kInstanceId[] = "IID1"; |
33 const char kScope[] = "GCM"; | 34 const char kScope[] = "GCM"; |
34 | 35 |
35 } // namespace | 36 } // namespace |
36 | 37 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 void CreateRequest(const std::string& sender_ids); | 90 void CreateRequest(const std::string& sender_ids); |
90 }; | 91 }; |
91 | 92 |
92 GCMRegistrationRequestTest::GCMRegistrationRequestTest() { | 93 GCMRegistrationRequestTest::GCMRegistrationRequestTest() { |
93 } | 94 } |
94 | 95 |
95 GCMRegistrationRequestTest::~GCMRegistrationRequestTest() { | 96 GCMRegistrationRequestTest::~GCMRegistrationRequestTest() { |
96 } | 97 } |
97 | 98 |
98 void GCMRegistrationRequestTest::CreateRequest(const std::string& sender_ids) { | 99 void GCMRegistrationRequestTest::CreateRequest(const std::string& sender_ids) { |
99 RegistrationRequest::RequestInfo request_info( | 100 RegistrationRequest::RequestInfo request_info(kAndroidId, kSecurityToken, |
100 kAndroidId, kSecurityToken, kAppId); | 101 kAppId, false /* use_subtype */, |
| 102 kCategoryForSubtypes); |
101 std::unique_ptr<GCMRegistrationRequestHandler> request_handler( | 103 std::unique_ptr<GCMRegistrationRequestHandler> request_handler( |
102 new GCMRegistrationRequestHandler(sender_ids)); | 104 new GCMRegistrationRequestHandler(sender_ids)); |
103 request_.reset(new RegistrationRequest( | 105 request_.reset(new RegistrationRequest( |
104 GURL(kRegistrationURL), request_info, std::move(request_handler), | 106 GURL(kRegistrationURL), request_info, std::move(request_handler), |
105 GetBackoffPolicy(), | 107 GetBackoffPolicy(), |
106 base::Bind(&RegistrationRequestTest::RegistrationCallback, | 108 base::Bind(&RegistrationRequestTest::RegistrationCallback, |
107 base::Unretained(this)), | 109 base::Unretained(this)), |
108 max_retry_count_, url_request_context_getter(), &recorder_, sender_ids)); | 110 max_retry_count_, url_request_context_getter(), &recorder_, sender_ids)); |
109 } | 111 } |
110 | 112 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 ASSERT_TRUE(auth_tokenizer.GetNext()); | 144 ASSERT_TRUE(auth_tokenizer.GetNext()); |
143 EXPECT_EQ(base::Uint64ToString(kAndroidId), auth_tokenizer.token()); | 145 EXPECT_EQ(base::Uint64ToString(kAndroidId), auth_tokenizer.token()); |
144 ASSERT_TRUE(auth_tokenizer.GetNext()); | 146 ASSERT_TRUE(auth_tokenizer.GetNext()); |
145 EXPECT_EQ(base::Uint64ToString(kSecurityToken), auth_tokenizer.token()); | 147 EXPECT_EQ(base::Uint64ToString(kSecurityToken), auth_tokenizer.token()); |
146 | 148 |
147 std::map<std::string, std::string> expected_pairs; | 149 std::map<std::string, std::string> expected_pairs; |
148 expected_pairs["app"] = kAppId; | 150 expected_pairs["app"] = kAppId; |
149 expected_pairs["sender"] = kDeveloperId; | 151 expected_pairs["sender"] = kDeveloperId; |
150 expected_pairs["device"] = base::Uint64ToString(kAndroidId); | 152 expected_pairs["device"] = base::Uint64ToString(kAndroidId); |
151 | 153 |
152 // Verify data was formatted properly. | 154 ASSERT_NO_FATAL_FAILURE(VerifyFetcherUploadData(&expected_pairs)); |
153 std::string upload_data = fetcher->upload_data(); | |
154 base::StringTokenizer data_tokenizer(upload_data, "&="); | |
155 while (data_tokenizer.GetNext()) { | |
156 std::map<std::string, std::string>::iterator iter = | |
157 expected_pairs.find(data_tokenizer.token()); | |
158 ASSERT_TRUE(iter != expected_pairs.end()); | |
159 ASSERT_TRUE(data_tokenizer.GetNext()); | |
160 EXPECT_EQ(iter->second, data_tokenizer.token()); | |
161 // Ensure that none of the keys appears twice. | |
162 expected_pairs.erase(iter); | |
163 } | |
164 | |
165 EXPECT_EQ(0UL, expected_pairs.size()); | |
166 } | 155 } |
167 | 156 |
168 TEST_F(GCMRegistrationRequestTest, RequestRegistrationWithMultipleSenderIds) { | 157 TEST_F(GCMRegistrationRequestTest, RequestRegistrationWithMultipleSenderIds) { |
169 CreateRequest("sender1,sender2@gmail.com"); | 158 CreateRequest("sender1,sender2@gmail.com"); |
170 request_->Start(); | 159 request_->Start(); |
171 | 160 |
172 net::TestURLFetcher* fetcher = GetFetcher(); | 161 net::TestURLFetcher* fetcher = GetFetcher(); |
173 ASSERT_TRUE(fetcher); | 162 ASSERT_TRUE(fetcher); |
174 | 163 |
175 // Verify data was formatted properly. | 164 // Verify data was formatted properly. |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 EXPECT_TRUE(callback_called_); | 380 EXPECT_TRUE(callback_called_); |
392 EXPECT_EQ(RegistrationRequest::REACHED_MAX_RETRIES, status_); | 381 EXPECT_EQ(RegistrationRequest::REACHED_MAX_RETRIES, status_); |
393 EXPECT_EQ(std::string(), registration_id_); | 382 EXPECT_EQ(std::string(), registration_id_); |
394 } | 383 } |
395 | 384 |
396 class InstanceIDGetTokenRequestTest : public RegistrationRequestTest { | 385 class InstanceIDGetTokenRequestTest : public RegistrationRequestTest { |
397 public: | 386 public: |
398 InstanceIDGetTokenRequestTest(); | 387 InstanceIDGetTokenRequestTest(); |
399 ~InstanceIDGetTokenRequestTest() override; | 388 ~InstanceIDGetTokenRequestTest() override; |
400 | 389 |
401 void CreateRequest(const std::string& instance_id, | 390 void CreateRequest(bool use_subtype, |
| 391 const std::string& instance_id, |
402 const std::string& authorized_entity, | 392 const std::string& authorized_entity, |
403 const std::string& scope, | 393 const std::string& scope, |
404 const std::map<std::string, std::string>& options); | 394 const std::map<std::string, std::string>& options); |
405 }; | 395 }; |
406 | 396 |
407 InstanceIDGetTokenRequestTest::InstanceIDGetTokenRequestTest() { | 397 InstanceIDGetTokenRequestTest::InstanceIDGetTokenRequestTest() { |
408 } | 398 } |
409 | 399 |
410 InstanceIDGetTokenRequestTest::~InstanceIDGetTokenRequestTest() { | 400 InstanceIDGetTokenRequestTest::~InstanceIDGetTokenRequestTest() { |
411 } | 401 } |
412 | 402 |
413 void InstanceIDGetTokenRequestTest::CreateRequest( | 403 void InstanceIDGetTokenRequestTest::CreateRequest( |
| 404 bool use_subtype, |
414 const std::string& instance_id, | 405 const std::string& instance_id, |
415 const std::string& authorized_entity, | 406 const std::string& authorized_entity, |
416 const std::string& scope, | 407 const std::string& scope, |
417 const std::map<std::string, std::string>& options) { | 408 const std::map<std::string, std::string>& options) { |
418 RegistrationRequest::RequestInfo request_info( | 409 RegistrationRequest::RequestInfo request_info( |
419 kAndroidId, kSecurityToken, kAppId); | 410 kAndroidId, kSecurityToken, kAppId, use_subtype, kCategoryForSubtypes); |
420 std::unique_ptr<InstanceIDGetTokenRequestHandler> request_handler( | 411 std::unique_ptr<InstanceIDGetTokenRequestHandler> request_handler( |
421 new InstanceIDGetTokenRequestHandler(instance_id, authorized_entity, | 412 new InstanceIDGetTokenRequestHandler(instance_id, authorized_entity, |
422 scope, kGCMVersion, options)); | 413 scope, kGCMVersion, options)); |
423 request_.reset(new RegistrationRequest( | 414 request_.reset(new RegistrationRequest( |
424 GURL(kRegistrationURL), request_info, std::move(request_handler), | 415 GURL(kRegistrationURL), request_info, std::move(request_handler), |
425 GetBackoffPolicy(), | 416 GetBackoffPolicy(), |
426 base::Bind(&RegistrationRequestTest::RegistrationCallback, | 417 base::Bind(&RegistrationRequestTest::RegistrationCallback, |
427 base::Unretained(this)), | 418 base::Unretained(this)), |
428 max_retry_count_, url_request_context_getter(), &recorder_, | 419 max_retry_count_, url_request_context_getter(), &recorder_, |
429 authorized_entity)); | 420 authorized_entity)); |
430 } | 421 } |
431 | 422 |
432 TEST_F(InstanceIDGetTokenRequestTest, RequestSuccessful) { | 423 TEST_F(InstanceIDGetTokenRequestTest, RequestSuccessful) { |
433 std::map<std::string, std::string> options; | 424 std::map<std::string, std::string> options; |
434 options["Foo"] = "Bar"; | 425 options["Foo"] = "Bar"; |
435 | 426 |
436 set_max_retry_count(0); | 427 set_max_retry_count(0); |
437 CreateRequest(kInstanceId, kDeveloperId, kScope, options); | 428 CreateRequest(false /* use_subtype */, kInstanceId, kDeveloperId, kScope, |
| 429 options); |
438 request_->Start(); | 430 request_->Start(); |
439 | 431 |
440 SetResponse(net::HTTP_OK, "token=2501"); | 432 SetResponse(net::HTTP_OK, "token=2501"); |
441 CompleteFetch(); | 433 CompleteFetch(); |
442 | 434 |
443 EXPECT_TRUE(callback_called_); | 435 EXPECT_TRUE(callback_called_); |
444 EXPECT_EQ(RegistrationRequest::SUCCESS, status_); | 436 EXPECT_EQ(RegistrationRequest::SUCCESS, status_); |
445 EXPECT_EQ("2501", registration_id_); | 437 EXPECT_EQ("2501", registration_id_); |
446 } | 438 } |
447 | 439 |
448 TEST_F(InstanceIDGetTokenRequestTest, RequestDataAndURL) { | 440 TEST_F(InstanceIDGetTokenRequestTest, RequestDataAndURL) { |
449 std::map<std::string, std::string> options; | 441 std::map<std::string, std::string> options; |
450 options["Foo"] = "Bar"; | 442 options["Foo"] = "Bar"; |
451 CreateRequest(kInstanceId, kDeveloperId, kScope, options); | 443 CreateRequest(false /* use_subtype */, kInstanceId, kDeveloperId, kScope, |
| 444 options); |
452 request_->Start(); | 445 request_->Start(); |
453 | 446 |
454 // Get data sent by request. | 447 // Get data sent by request. |
455 net::TestURLFetcher* fetcher = GetFetcher(); | 448 net::TestURLFetcher* fetcher = GetFetcher(); |
456 ASSERT_TRUE(fetcher); | 449 ASSERT_TRUE(fetcher); |
457 | 450 |
458 EXPECT_EQ(GURL(kRegistrationURL), fetcher->GetOriginalURL()); | 451 EXPECT_EQ(GURL(kRegistrationURL), fetcher->GetOriginalURL()); |
459 | 452 |
460 // Verify that the no-cookie flag is set. | 453 // Verify that the no-cookie flag is set. |
461 int flags = fetcher->GetLoadFlags(); | 454 int flags = fetcher->GetLoadFlags(); |
(...skipping 10 matching lines...) Expand all Loading... |
472 EXPECT_EQ(kLoginHeader, auth_tokenizer.token()); | 465 EXPECT_EQ(kLoginHeader, auth_tokenizer.token()); |
473 ASSERT_TRUE(auth_tokenizer.GetNext()); | 466 ASSERT_TRUE(auth_tokenizer.GetNext()); |
474 EXPECT_EQ(base::Uint64ToString(kAndroidId), auth_tokenizer.token()); | 467 EXPECT_EQ(base::Uint64ToString(kAndroidId), auth_tokenizer.token()); |
475 ASSERT_TRUE(auth_tokenizer.GetNext()); | 468 ASSERT_TRUE(auth_tokenizer.GetNext()); |
476 EXPECT_EQ(base::Uint64ToString(kSecurityToken), auth_tokenizer.token()); | 469 EXPECT_EQ(base::Uint64ToString(kSecurityToken), auth_tokenizer.token()); |
477 | 470 |
478 std::map<std::string, std::string> expected_pairs; | 471 std::map<std::string, std::string> expected_pairs; |
479 expected_pairs["gmsv"] = base::IntToString(kGCMVersion); | 472 expected_pairs["gmsv"] = base::IntToString(kGCMVersion); |
480 expected_pairs["app"] = kAppId; | 473 expected_pairs["app"] = kAppId; |
481 expected_pairs["sender"] = kDeveloperId; | 474 expected_pairs["sender"] = kDeveloperId; |
482 expected_pairs["X-subtype"] = kDeveloperId; | |
483 expected_pairs["device"] = base::Uint64ToString(kAndroidId); | 475 expected_pairs["device"] = base::Uint64ToString(kAndroidId); |
484 expected_pairs["appid"] = kInstanceId; | 476 expected_pairs["appid"] = kInstanceId; |
485 expected_pairs["scope"] = kScope; | 477 expected_pairs["scope"] = kScope; |
| 478 expected_pairs["X-scope"] = kScope; |
| 479 expected_pairs["X-Foo"] = "Bar"; |
| 480 |
| 481 ASSERT_NO_FATAL_FAILURE(VerifyFetcherUploadData(&expected_pairs)); |
| 482 } |
| 483 |
| 484 TEST_F(InstanceIDGetTokenRequestTest, RequestDataWithSubtype) { |
| 485 std::map<std::string, std::string> options; |
| 486 options["Foo"] = "Bar"; |
| 487 CreateRequest(true /* use_subtype */, kInstanceId, kDeveloperId, kScope, |
| 488 options); |
| 489 request_->Start(); |
| 490 |
| 491 // Get data sent by request. |
| 492 net::TestURLFetcher* fetcher = GetFetcher(); |
| 493 ASSERT_TRUE(fetcher); |
| 494 |
| 495 // Same as RequestDataAndURL except "app" and "X-subtype". |
| 496 std::map<std::string, std::string> expected_pairs; |
| 497 expected_pairs["gmsv"] = base::IntToString(kGCMVersion); |
| 498 expected_pairs["app"] = kCategoryForSubtypes; |
| 499 expected_pairs["X-subtype"] = kAppId; |
| 500 expected_pairs["sender"] = kDeveloperId; |
| 501 expected_pairs["device"] = base::Uint64ToString(kAndroidId); |
| 502 expected_pairs["appid"] = kInstanceId; |
| 503 expected_pairs["scope"] = kScope; |
486 expected_pairs["X-scope"] = kScope; | 504 expected_pairs["X-scope"] = kScope; |
487 expected_pairs["X-Foo"] = "Bar"; | 505 expected_pairs["X-Foo"] = "Bar"; |
488 | 506 |
489 // Verify data was formatted properly. | 507 // Verify data was formatted properly. |
490 std::string upload_data = fetcher->upload_data(); | 508 std::string upload_data = fetcher->upload_data(); |
491 base::StringTokenizer data_tokenizer(upload_data, "&="); | 509 base::StringTokenizer data_tokenizer(upload_data, "&="); |
492 while (data_tokenizer.GetNext()) { | 510 while (data_tokenizer.GetNext()) { |
493 std::map<std::string, std::string>::iterator iter = | 511 auto iter = expected_pairs.find(data_tokenizer.token()); |
494 expected_pairs.find(data_tokenizer.token()); | |
495 ASSERT_TRUE(iter != expected_pairs.end()); | 512 ASSERT_TRUE(iter != expected_pairs.end()); |
496 ASSERT_TRUE(data_tokenizer.GetNext()); | 513 ASSERT_TRUE(data_tokenizer.GetNext()); |
497 EXPECT_EQ(iter->second, data_tokenizer.token()); | 514 EXPECT_EQ(iter->second, data_tokenizer.token()); |
498 // Ensure that none of the keys appears twice. | 515 // Ensure that none of the keys appears twice. |
499 expected_pairs.erase(iter); | 516 expected_pairs.erase(iter); |
500 } | 517 } |
501 | 518 |
502 EXPECT_EQ(0UL, expected_pairs.size()); | 519 EXPECT_EQ(0UL, expected_pairs.size()); |
503 } | 520 } |
504 | 521 |
505 TEST_F(InstanceIDGetTokenRequestTest, ResponseHttpStatusNotOK) { | 522 TEST_F(InstanceIDGetTokenRequestTest, ResponseHttpStatusNotOK) { |
506 std::map<std::string, std::string> options; | 523 std::map<std::string, std::string> options; |
507 CreateRequest(kInstanceId, kDeveloperId, kScope, options); | 524 CreateRequest(false /* use_subtype */, kInstanceId, kDeveloperId, kScope, |
| 525 options); |
508 request_->Start(); | 526 request_->Start(); |
509 | 527 |
510 SetResponse(net::HTTP_UNAUTHORIZED, "token=2501"); | 528 SetResponse(net::HTTP_UNAUTHORIZED, "token=2501"); |
511 CompleteFetch(); | 529 CompleteFetch(); |
512 | 530 |
513 EXPECT_FALSE(callback_called_); | 531 EXPECT_FALSE(callback_called_); |
514 | 532 |
515 SetResponse(net::HTTP_OK, "token=2501"); | 533 SetResponse(net::HTTP_OK, "token=2501"); |
516 CompleteFetch(); | 534 CompleteFetch(); |
517 | 535 |
518 EXPECT_TRUE(callback_called_); | 536 EXPECT_TRUE(callback_called_); |
519 EXPECT_EQ(RegistrationRequest::SUCCESS, status_); | 537 EXPECT_EQ(RegistrationRequest::SUCCESS, status_); |
520 EXPECT_EQ("2501", registration_id_); | 538 EXPECT_EQ("2501", registration_id_); |
521 } | 539 } |
522 | 540 |
523 } // namespace gcm | 541 } // namespace gcm |
OLD | NEW |